lkgs
Load Kernel GS Base
LKGS r16
Loads the kernel GS base address (FRED support).
Details
Loads a 16-bit selector or handle into the kernel GS base register, supporting FRED event delivery. The instruction reads from the specified register and updates the MSR-backed kernel GS base, used for exception handler context. This is a privileged instruction (CPL = 0) and does not modify any flags.
Pseudocode Operation
IA32_KERNEL_GS_BASE ← src;
Example
LKGS ax
Encoding
Binary Layout
F2
+0
0F
+1
00
+2
ModRM
+3
Operands
-
src
Reg
Reference (Intel® SDM)
Instruction Forms
| Opcode | Instruction | Op/En | 64/32-bit Mode | CPUID | Description |
|---|---|---|---|---|---|
| F2 0F 00 /6 | LKGS r/m16 | A | Valid N.E. | Load GS using r/m16, placing the base address instead in the IA32_KERNEL_GS_BASE MSR. |
Instruction Operand Encoding
| Op/En | Operand 1 | Operand 2 | Operand 3 | Operand 4 |
|---|---|---|---|---|
| A | 16-bit selector | N/A | N/A | N/A |
Description
LKGS operates in the same way as MOV to GS except that the descriptor’s base address is loaded into the
IA32_KERNEL_GS_BASE MSR instead of the GS segment’s descriptor cache.
LKGS takes a single (source) operand, which can be a general-purpose register or a memory location. The operand must be a valid segment selector. The instruction loads the segment descriptor referenced by that segment selector into the GS descriptor cache, with the exception of the base address. The base address in the GS descriptor cache is not modified; the base address from the segment descriptor is loaded into the
IA32_KERNEL_GS_BASE MSR. (Since the base address in the descriptor is only 32 bits, the upper 32 bits of the
MSR are cleared.)
A null segment selector (values 0000-0003) can be loaded without causing an exception. However, any subsequent attempt to reference GS outside 64-bit mode causes a general protection exception (#GP) and no memory reference occurs. LKGS with a null segment selector loads zero into IA32_KERNEL_GS_BASE.
Operation
IF CPL > 0 OR logical processor not in 64-bit mode THEN #UD; FI; IF SRC is null THEN GS.selector := SRC; mark GS as null; IA32_KERNEL_GS_BASE := 0; ELSE IF SRC.index is outside descriptor table limits THEN #GP(selector); FI; read referenced descriptor for descriptor table; IF the descriptor is not for a data or readable code segment OR SRC.RPL > descriptor.DPL THEN #GP(selector); FI; IF the descriptor is not marked present THEN #NP(selector); ELSE GS.selector := SRC; GS.attributes := descriptor.attributes; IA32_KERNEL_GS_BASE := descriptor.base; // bits 63:32 cleared FI; FI;
Flags Affected
None.
Exceptions
Protected Mode Exceptions
#UD The LKGS instruction is not recognized in protected mode.
LKGS—Load Kernel GS Base Vol. 2A 3-556
Real-Address Mode Exceptions
#UD The LKGS instruction is not recognized in real-address mode.
Virtual-8086 Mode Exceptions
#UD The LKGS instruction is not recognized in virtual-8086 mode.
Compatibility Mode Exceptions
#UD The LKGS instruction is not recognized in compatibility mode.
64-Bit Mode Exceptions
#UD If CPL > 0.
If CPUID.07H.01H:EAX.LKGS[18] is not 1.
If the LOCK prefix is used.
#GP(0) If the memory address is in a non-canonical form.
#GP(selector) If segment selector index is outside descriptor table limits.
If the memory access to the descriptor table is non-canonical.
If the referenced descriptor is not for a data or readable code segment or the selector RPL is
greater than the descriptor DPL.
#SS(0) If the memory address is in a non-canonical form.
#PF(fault-code) If a page fault occurs.
LKGS—Load Kernel GS Base Vol. 2A 3-557