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
 
Format Legacy
Opcode F2 0F 00 /6
Extension LKGS

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