x86s EAS v1 4 17 23 1
x86s EAS v1 4 17 23 1
EXTERNAL ARCHITECTURAL
SPECIFICATION
Rev. 1.0
April 2023
Document Number: 351407-001
X86-S ISA
External Architectural Specification
Notice: This document contains information on products in the design phase of development. The
information here is subject to change without notice. Do not finalize a design with this information.
Intel technologies may require enabled hardware, software or service activation.
No computer system can be absolutely secure. Intel does not assume any liability for lost or stolen data or
systems or any damages resulting from such losses.
Your costs and results may vary.
You may not use or facilitate the use of this document in connection with any infringement or other legal
analysis concerning Intel products described herein. You agree to grant Intel a non-exclusive, royalty-free
license to any patent claim thereafter drafted which includes subject matter disclosed herein.
No license (express or implied, by estoppel or otherwise) to any intellectual property rights is granted by this
document.
All product plans and roadmaps are subject to change without notice.
The products described may contain design defects or errors known as errata which may cause the product to
deviate from published specifications. Current characterized errata are available on request.
Intel disclaims all express and implied warranties, including without limitation, the implied warranties of
merchantability, fitness for a particular purpose, and non-infringement, as well as any warranty arising from
course of performance, course of dealing, or usage in trade.
Copies of documents which have an order number and are referenced in this document may be obtained by
calling 1-800-548-4725 or by visiting [Link]/design/[Link].
Copyright © 2023, Intel Corporation. Intel, the Intel logo, and other Intel marks are trademarks of Intel
Corporation or its subsidiaries. Other names and brands may be claimed as the property of others.
Contents
Figures
Figure 1. CR0 Register .............................................................................................. 14
Figure 2. CR4 Register .............................................................................................. 15
Figure 3. RFLAGS Register ......................................................................................... 15
Tables
Table 1. Supported Operating Modes ......................................................................... 13
Table 2. Fixed EFER Bits .......................................................................................... 15
Table 3. Behavior of Obsolete RFLAGS ....................................................................... 16
Table 4. IA32_SIPI_ENTRY_STRUCT_PTR MSR ............................................................ 17
Table 5. SIPI_ENTRY_STRUCT Structure in Memory .................................................... 17
Table 6. Removed MTRR MSRs .................................................................................. 19
Table 7. VMCS Fields Changed (Guest State) .............................................................. 20
Table 8. VMCS Exit Control Changes .......................................................................... 21
Table 9. Secondary Processor-Based Execution Control Changes ................................... 21
Table 10. VMX Enumeration Changes .......................................................................... 21
Table 11. Summary of Removals ................................................................................ 22
Table 12. Summary of Additions ................................................................................. 23
Table 13. RFLAGS Changes with the POPF Instruction.................................................... 24
Table 14. Removed Instructions ................................................................................. 24
Table 15. Changed Instructions .................................................................................. 25
Table 16. List of Segmentation Instructions.................................................................. 43
2 Introduction
X86-S is a legacy-reduced-OS ISA that removes outdated execution modes and operating system
ISA.
The presence of the X86-S ISA is enumerated by a single, main CPUID feature bit
LEGACY_REDUCED_OS_ISA in a future CPUID field. The bit implies all the ISA removals described
in this document. Some of the additional features, like 64bit SIPI or the 5 Level page table switch,
have separate CPUID feature flags and can be implemented independently of X86-S.
3 Architectural Changes
3.1 Removal of 32-Bit Ring 0
32-bit ring 0 is not supported anymore and cannot be entered.
Jumps with 0x66 prefix that previously did truncate RIP to 16bit (Jump Short 0x7*, Jump Near
0x0f 8*, LOOP 0xE0-2, JECZ 0xE3, JMP near 0xE9 and 0xEB, CALL rel 0xE8, JMP near 0xFF/4,
CALL indirect near 0xff/2, RET near 0xC2-3, JMP far 0xEA and 0xFF/5, CALL indirect far 0xFF/3,
CALL far 0x9A, RET far 0xCA-B) will now #UD.
Jumps with 0x67 prefix that previously did truncate to 16bit (CALL indirect near mem 0xff/2 mem,
JMP far 0xea and 0xff /5, CALL indirect far 0xff /3) will now #GP(0)
Note that there is no fault for operations which do not modify memory or jump, like LEA or NOPs.
An attempt to load from SS that has SS.B==0 (16bit data segment) in compatibility mode will
generate a #GP(sel) exception.
3.5 CPUID
The LEGACY_REDUCED_OS_ISA feature bit in a future CPUID field indicates all the ISA removals
described in this document.
LA57SWITCH in a future CPUID field indicates support for 5-level paging switch.
No gates are supported in the GDT/LDT; it only supports data segments, non conforming
code segments, and TSSs.
Bases are supported for FS, GS, GDT, IDT, LDT, and TSS registers; the base for CS, DS,
ES, and SS is ignored for 32-bit mode, same as 64-bit mode (treated as zero).
Limits are supported for GDT, IDT, LDT, and TSS; the limit for CS, DS, ES, FS, GS, and SS
is treated as infinite.
IRET can switch rings from 0 to 3, or stay within a ring, but cannot cause a task switch or
enter into VM86 mode.
Descriptor accessed bits will not be set in memory, but appear to be set when accessed
through the LAR instruction.
Segment override prefixes (other than FS/GS) are ignored when they refer to segments.
The segment override prioritization is not changed; any group of overrides that resolves to
something other than FS or GS is forced to use DS.
No #GP exception will be generated when loading a segment with a non-infinite limit or non-zero
base.
anymore. Instead, #GP exceptions will be generated. All descriptor loads with desc.P==0 will
generate a #GP(sel) exception.
Fixed
CR0 Bit Bit Implication
Value
PE 1 0 Protection enable: always in protected mode.
MP 1 1 Monitor coprocessor: always enabled.
EM 0 2 FP emulation.
TS - 3 Task switch. Disable FPU. This bit is still flexible.
ET 1 4 Extension type (ignored on input).
NE 1 5 Numeric error.
WP - 16 Write protect page tables. This bit is still flexible.
AM - 18 Enable alignment checks with [Link].
NW 0 29 Write through. Always disabled.
CD - 30 Cache disable. This bit is still flexible.
PG 1 31 Paging is always enabled.
Fixed
CR4 Bit Bit Implication
Value
VME 0 0 No support for VM86 mode (ignored on input).
No support for Protected-mode virtual
PVI 0 1
interrupts.
PAE 1 5 8-byte PTEs. Always enabled in 64-bit mode.
To boot APs in paged 64-bit mode, a 64-bit startup sequence is used. Booting CPUs is triggered by
triggering INIT or SIPI messages through the X2APIC ICR register after 64-bit SIPI is enabled in
the IA32_SIPI_ENTRY_STRUCT_PTR MSR, as well as in the in-memory entry structure features bit
pointed to by the MSR. Legacy INIT/SIPI are not supported. The presence of 64bit SIPI is
enumerated with the SIPI64 CPUID feature bit.
3.10.1 IA32_SIPI_ENTRY_STRUCT_PTR
The IA32_SIPI_ENTRY_STRUCT_PTR package scope MSR, shown in Table 4, defines the execution
context of the target CPU after receiving a SIPI message. It points to an entry structure in
[Link] MSR is read only after the package BIOS_DONE MSR bit is set.
On receiving a SIPI, the target CPU loads the register state from the entry struct and starts
executing at the specified RIP. The vectors delivered in the vector field of the INIT/SIPI IPI
messages are ignored. Any consistency check failures in the SIPI_ENTRY_STRUCT will also lead to
a shutdown on the target CPU.
FI
RFLAGS = 2 # clear all modifiable bits in RFLAGS
Clear flexible bits in CR2/CR3/CR4
Clear TS and AM bits in CR0, preserve [Link] # rest is fixed values
Set CS/SS/DS/ES/FS/GS/GDTR/IDTR/LDTR/TS selector to 0, with P=1, W=1
Set IDTR/TS/GDTR/LDTR limits to 0
Clear FS/GS bases
Clear KERNEL_GS MSR
Set RDX to 0x000n06xxx, where n is extended model value and x is a stepping number
Clear all other GPRs
Clear DR0/DR1/DR2/DR3
Set DR6 to 0xffff0ff0
Set DR7 to 0x400
Set x87 FPU control word to 0x37f
Set x87 FPU status word to 0
Set x87 FPU tag word to 0xffff
Flush all TLBs
IF IA32_APICBASE.BSP = 1 THEN
Force 64bit supervisor mode as in reset
Execute 64bit reset vector using CR3 value from reset
ELSE
Enter wait for SIPI state
FI
The ExtINT decoding in the local APIC is removed. If an interrupt is received with ExtInt encoding,
it will trigger a Receive Error with bit[6] set in the APIC error status register. This slightly
redefines the meaning of bit[6].
Both CR3_LOAD_4LPGTBL and CR3_LOAD_5LPGTBL are only available when the CPU supports 5-
level page tables as indicated by the LA57 CPUID feature bit and reports a LA57SWITCH CPUID
feature bit in a future CPUID field.
“Fixed” fields are consistency checked and VM entry will fail if they do not match the fixed value.
39
IA32_VMX_PROCBASED_CTLS2 Unrestricted guest 0 No unrestricted guest.
1
31 PG: Paging Enabled
(legacy)
IA32_VMX_CR4_FIXED0 No changes
No support for
PVI: Protected-mode
IA32_VMX_CR4_FIXED1 1 Protected-mode virtual
Virtual Interrupts 0
interrupts.
Real mode
64-bit SIPI and INIT Boot APs in paged 64-bit mode
removal
Real mode
4L/5L paging switch MSRs No real mode
removal
For legacy behavior, please refer to Intel® 64 and IA-32 Architectures Software Developer’s
Manual Combined Volumes: 1, 2A, 2B, 2C, 2D, 3A, 3B, 3C, 3D and 4 .
3.18.1 SYSRET
SYSRET will generate a #GP(0) exception if a non-zero value is loaded into [Link],
[Link], or [Link].
3.18.2 IRET
IRET cannot jump to 16-bit mode, task gates or conforming segments. IRET will generate a
#GP(0) exception if a non-zero value is loaded into [Link], [Link], or [Link]
when in ring 0. The details of the IRET instruction are shown in the pseudocode in Section 4.2.6.
64-Bit Compatibility/
Opcode Instruction Op/ En Description
Mode Legacy Mode
9D POPFD ZO N.E. Valid Pop top of stack into EFLAGS.
Pop top of stack and zero-extend into
9D POPFQ ZO Valid N.E.
RFLAGS.
POPF pops a doubleword (POPFD) from the top of the stack (if the current operand size attribute is 32)
and stores the value in the EFLAGS register, or pops a word from the top of the stack (if the operand
size attribute is 16) and stores it in the lower 16 bits of the EFLAGS register (that is, the FLAGS
register). These instructions reverse the operation of the PUSHF/PUSHFD/PUSHFQ instructions.
The IOPL, VM, VIP, and VIF flags are always zero and are ignored on POPF.
The POPF instruction never raises an #SS exception, but only a #GP(0) or a #PF exception.
Operand 21 20 19 18 17 16 14 13:12 11 10 9 8 7 6 4 2 0
Mode Size CPL
ID VIP VIF AC VM RF NT IOPL OF DF IF TF SF ZF AF PF CF
User32, User64 32, 64 * S N N S N 0 S N S S N S S S S S S
and Supervisor
modes
Key
S Updated from stack
N No change in value
0 Value is cleared
Pseudocode:
If required for guest compatibility, the VMM is responsible for (a) setting the exception bitmap
such that #UD and #GP cause a VMexit and then (b) emulating to determine the cause of the
exception and appropriate response. Some examples:
- Some variants of CLI will spuriously #GP(0), for example, if a legacy guest tried to
execute a CLI in ring 3 and [Link]==3. Since [Link] is always 0, this ring 3
CLI will always #GP(0). If the guest requires these IOPL semantics, it is up to the VMM to
emulate this instruction with the emulated legacy guest [Link] value. Note that that
are un-virtualizable aspects of non-zero IOPL that are discussed later.
- #SS and #NP are converted to #GP. If the guest expects to see the #SS/#NP, the VMM
will need to detect cases where a #GP would have been an #SS or #NP and inject them to
the guest.
Some guest CR values are ignored on VMENTRY (they retain the fixed values and are not
consistency checked). If required by the guest, the VMM can virtualize differences, some of which
are described below. In general these are expected to be uncommon in Intel64 guests.
1. VMM changes required for mainstream Intel64 guest using legacy SIPI or non-64-bit boot
a. Emulate 16-bit modes (real mode, virtual 8086 mode)
b. Emulate unpaged modes
c. Emulate legacy INIT/SIPI
2. Optional VMM changes for handling uncommon cases
a. IOPL != 0 (if guest wants ring 3 I/O port access or ring 3 CLI/STI)
i. Catch CLI #GP in CPL3 and emulate
ii. Catch STI #GP in CPL3 and emulate
iii. Catch IN/OUT #GP in CPL3 and emulate
iv. IRET in CPL0 will #GP if attempting to change IOPL, catch and emulate
v. Note that that are un-virtualizable aspects of non-zero IOPL in the next
section.
b. INS/OUTS instructions are removed: Catch #UD and emulate
c. Call gates: VMM needs to catch relevant #GPs and emulate
d. #SS removal: VMM can catch relevant #GPs and report #SS back to guest
e. #NP removal: VMM can catch relevant #GPs and report #NP back to guest
f. [Link] catch and emulate associated #GPs
g. Emulate 16-bit addressing by catching #GPs/#UDs
h. [Link], [Link]: Emulate v8086 mode
i. Emulate 32-bit ring 0 and run 32-bit ring 3 with shadow paging in legacy paging
modes
j. Support for unsupported obscure segmentation features like expand down or non
conforming code segments: Can be emulated by catching #GPs
3. Uncommon cases with expensive SW solutions:
a. CPL1/2 requires partial emulation
b. Non-flat CS/DS/ES/SS segments or setting access bits in descriptors in memory
requires full emulation trigged by Descriptor Table Exiting and then setting
GDT/LDT limit to zero (or read/write protect GDT/LDT) to catch segmentation
instructions
c. When [Link] is cleared, a set NX bit in PTE requires shadow paging
d. Segmentation permission checking on load/store/execute: Would require full
emulation
4. Cases that are un-virtualizable
4 Appendix
This appendix gives further details on limited segmentation and exception compatibility.
Check_CS_desc_for_IRET(selector, Descriptor):
IF Descriptor is not non-conforming code segment
OR (Descriptor.L == 0 AND Descriptor.D == 0) // prevents 16b size
OR [Link] == 1
OR [Link] == 2
OR [Link] != [Link]
OR [Link] < CPL
OR Descriptor.L == 0 AND [Link] == 0 THEN // prevents SUP32
#GP(selector);
FI
IF descriptor.P == 0 THEN
#GP(selector);
FI
END
Load_descriptor_from_GDT_LDT(selector):
IF (selector & 0xFFF8) != 0x0 THEN
IF [Link] == 1 THEN BASE := LDT Base;
ELSE BASE := GDT Base; FI;
Desc := load_physical_sup(BASE + (selector & 0xFFF8));
Set accessed bit in Descriptor copy, not in memory;
Return Desc;
ELSE
Return 0;
FI
END
Load_descriptor_from_IDT(vector):
Desc := load physical_sup(IDT base + vector << 4);
Return Desc;
END
Check_selector(newCS);
newCSdesc := Load_descriptor_from_GDT_LDT(tempCS);
Check_CS_desc(tempCS, newCSdesc, CPL);
IF newRIP is non-cannonical THEN
#GP(0)
FI
Push CS;
Push RIP;
CS := newCS;
RIP := newRIP;
Save newCSdesc;
Do shadow stack pushes if enabled
Do end branch state transition if enabled
4.2.2 ERETU
Enforces RFLAGS restrictions. Mode restrictions are enforced, as well as limits on code selector
types. No access bits for descriptors are set. #NP and #SS are replaced with #GP.
4.2.3 ERETS
Enforces RFLAGS restrictions.
FI;
gate := Read_descriptor_from_IDT(vector_number);
IF [Link] not in {intGate64, trapGate64} THEN
#GP(error_code(vector_number,1,EXT));
FI;
IF software interrupt (* does not apply to INT1 *) THEN
IF [Link] < CPL THEN
#GP(error_code(vector_number,1,0));
FI;
FI;
IF gate.P == 0 THEN
#GP(error_code(vector_number,1,EXT));
FI
newCS := [Link];
IF newCS is NULL THEN
#GP(EXT); (* Error code contains NULL selector *)
FI;
Check_selector(newCS);
newCSdesc := Load_descriptor_from_GDT_LDT(newCS);
Check_CS_desc(newCS, newCSdesc, 0);
IF [Link] < CPL THEN
GOTO INTER-PRIVILEGE-LEVEL-INTERRUPT;
ELSIF [Link] = CPL THEN
GOTO INTRA-PRIVILEGE-LEVEL-INTERRUPT;
ELSE
#GP(error_code(new code-segment selector,0,EXT));
FI
END;
INTER-PRIVILEGE-LEVEL-INTERRUPT:
IF [Link] == 0 THEN
TSSstackAddress := ([Link] « 3) + 4;
ELSE
TSSstackAddress := ([Link] « 3) + 28;
FI;
IF (TSSstackAddress + 7) > [Link] THEN
#TS(error_code([Link],0,EXT);
FI;
NewRSP := 8 bytes loaded from ([Link] + TSSstackAddress);
NewSS := [Link]; (* NULL selector with RPL = new CPL *)
IF [Link] = 0 THEN
NewSSP := IA32_PLi_SSP; (* where i = [Link] *)
ELSE
NewSSPAddress := IA32_INTERRUPT_SSP_TABLE_ADDR + ([Link] « 3);
IF ShadowStackEnabled(CPL0) THEN
NewSSP := 8 bytes loaded from NewSSPAddress;
FI;
FI;
IF NewRSP is non-canonical THEN
#GP(EXT); (* Error code contains NULL selector *)
FI;
IF [Link] is non-canonical THEN
#GP(EXT); (* Error code contains NULL selector *)
FI;
RSP := NewRSP & FFFFFFFFFFFFFFF0H;
SS := NewSS;
SSdesc := const;
Push(SS);
Push(RSP);
Push(RFLAGS); (* 8-byte push *)
Push(CS);
PUSH(RIP);
Push(ErrorCode); (* If needed, 8-bytes *)
RIP := [Link];
CS := newCS;
IF ShadowStackEnabled(CPL) AND CPL == 3 THEN
IA32_PL3_SSP := LA_adjust(SSP);
FI;
CPL := [Link];
[Link] := CPL;
IF ShadowStackEnabled(CPL) THEN
oldSSP := SSP
SSP := NewSSP
IF (SSP & 0x07 != 0) THEN
#GP(0);
FI
IF (CS.L = 0 AND SSP[63:32] != 0) THEN
#GP(0);
FI
FI;
expected_token_value := SSP; (* busy bit- must be clear *)
new_token_value := SSP | BUSY_BIT; (* Set the busy bit *)
IF (shadow_stack_lock_cmpxchg8b(SSP, new_token_value,
expected_token_value) !=
expected_token_value) THEN
#GP(0);
FI;
IF [Link] != 3
ShadowStackPush8B(oldCS);
ShadowStackPush8B(oldRIP);
ShadowStackPush8B(oldSSP);
FI;
IF EndbranchEnabled (CPL)
IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH;
IA32_S_CET.SUPPRESS = 0
FI;
IF [Link] is intGate64 THEN
[Link] := 0 (* Interrupt flag set to 0, interrupts disabled *);
FI;
[Link] := 0;
[Link] := 0;
[Link] := 0;
END;
INTRA-PRIVILEGE-LEVEL-INTERRUPT:
NewSSP := SSP;
CHECK_SS_TOKEN := 0;
IF [Link] != 0 THEN
TSSstackAddress := (IDT-descriptor IST « 3) + 28;
IF (TSSstackAddress + 7) > [Link] THEN
#TS(error_code(current TSS selector,0,EXT));
FI;
NewRSP := 8 bytes loaded from (current TSS base +
TSSstackAddress);
ELSE
NewRSP := RSP;
FI;
IF ShadowStackEnabled(CPL) THEN
NewSSPAddress := IA32_INTERRUPT_SSP_TABLE_ADDR + (IDT gate IST « 3)
NewSSP := 8 bytes loaded from NewSSPAddress
CHECK_SS_TOKEN := 1
FI;
IF NewRSP is non-canonical THEN
#GP(EXT); (* Error code contains NULL selector *)
FI;
IF [Link] is non-canonical THEN
#GP(EXT); (* Error code contains NULL selector *)
FI;
RSP := NewRSP & FFFFFFFFFFFFFFF0H;
Push(SS);
Push(RSP);
Push(RFLAGS); // 8-byte push – including .IF, not affected by IOPL,CPL
Push(CS);
PUSH(RIP);
Push(ErrorCode); (* If needed, 8-bytes *)
oldCS := CS;
oldRIP := RIP;
RIP := [Link];
CS := newCS;
[Link] := CPL;
IF ShadowStackEnabled(CPL) AND CHECK_SS_TOKEN == 1 THEN
IF NewSSP & 0x07 != 0 THEN
#GP(0);
FI;
IF (CS.L = 0 AND NewSSP[63:32] != 0) THEN
#GP(0);
FI;
expected_token_value := NewSSP (* busy bit – (0)- must be clear *)
new_token_value := NewSSP | BUSY_BIT (* Set the busy bit *)
IF shadow_stack_lock_cmpxchg8b(NewSSP, new_token_value,
expected_token_value) !=
expected_token_value THEN
#GP(0);
FI;
FI;
IF ShadowStackEnabled(CPL) THEN
(* Align to next 8 byte boundary *)
tempSSP = SSP;
Shadow_stack_store 4 bytes of 0 to (NewSSP − 4)
SSP := newSSP & 0xFFFFFFFFFFFFFFF8H;
ShadowStackPush8B(oldCS);
ShadowStackPush8B(oldRIP);
ShadowStackPush8B(tempSSP);
FI;
IF EndbranchEnabled (CPL)
IF CPL == 3 THEN
IA32_U_CET.TRACKER = WAIT_FOR_ENDBRANCH;
IA32_U_CET.SUPPRESS = 0;
ELSE
IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH;
IA32_S_CET.SUPPRESS = 0;
FI;
FI;
IF IDT gate is interrupt gate THEN
[Link] := 0; (* Interrupt flag set to 0; interrupts disabled *)
FI;
[Link] := 0;
[Link] := 0;
[Link] := 0;
END;
4.2.6 IRET
IRET cannot enter 16-bit mode, VM86 mode, task gates or conforming segments. Descriptor
access bits are not set. Mode restrictions are enforced. #NP and #SS are replaced with #GP.
IF [Link] == 1 THEN
#GP(0);
FI
tempRIP := POP(); // according to operand size
tempCS := POP(); // according to operand size
tempFlags := POP();// according to operand size
IF CPL == 3 THEN
tempFlags(VIP, VIF, IOPL) := (0, 0, 0);
ELSIF tempFlags(VIF, VIP, IOPL) != (0,0,0) THEN
#GP(0);
FI
Check_selector(tempCS);
Descriptor := Load_descriptor_from_GDT_LDT(tempCS);
Check_CS_desc_for_IRET(tempCS, Descriptor);
IF [Link] > CPL THEN
IF [Link] THEN
#GP(tempCS);
ELSE
GOTO RETURN_TO_OUTER_PRIVLEDGE_LEVEL; // must be level 3
FI
ELSIF Started_in_64b_mode THEN
GOTO RETURN_FROM_IA32e;
ELSE
GOTO RETURN_FROM_SAME_PRIVLEDGE_LEVEL;
FI
RETURN_FROM_SAME_PRIVLEDGE_LEVEL:
IF tempRIP is not canonical THEN
#GP(0); // Restoring RSP
FI
IF ShadowStackEnabled(CPL) THEN
Perform normal Shadow Stack operations as described in the SDM;
FI
CS := tempCS;
RIP := tempRIP;
Save_descriptor_for_VMX(CS, Descriptor);
RFLAGS(CF, PF, AF, ZF, SF, TF, DF, OF, NT, RF, AC, IC) := tempFlags;
IF CPL == 0 THEN RFLAGS(IF) := tempFlags; FI;
Unmask NMI;
END;
RETURN_FROM_IA32e:
tempRSP := POP();
tempSS := POP();
Check_sel(tempSS);
tempSSdesc := Load_descriptor_from_GDT_LDT(tempSS);
check_SS_desc(tempSS, tempSSdesc, newCPL);
SS := tempSS;
RSP := tempRSP;
GOTO RETURN_FROM_SAME_PRIVLEDGE_LEVEL;
RETURN_TO_OUTER_PRIVLEDGE_LEVEL:
IF [Link] != 3 THEN
#GP(tempCS);
FI
tempRSP := POP();
tempSS := POP();
RFLAGS(CF, PF, AF, ZF, SF, TF, DF, OF, NT, RF, AC, IC) := tempFlags;
IF CPL == 0 THEN RFLAGS(IF) := tempFlags; FI;
Unmask NMI;
END;
Pseudocode:
IF 0x66 prefix THEN #UD ; FI
Check_Selector(selector);
// If failure return with ZF := 0
Desc := Load_descriptor_from_GDT_LDT(selector);
// If failure return with ZF := 0
Check_Data_Desc(selector, Desc, CPL);
// if failure return with ZF := 0
// For LAR always return Access = 1
// LSL/LAR/VERW/VERR flow to return information from Desc
Pseudocode:
If newSel is NULL AND LSS AND NOT (CPL0 AND CS.L) THEN
#GP(0);
FI
Check_selector(newSel);
newDesc := Load_descriptor_from_GDT_LDT(newSel);
IF LSS THEN
Check_SS_desc(newSEL, newDesc);
ELSE
Check_Data_desc(newSel, newDesc);
Dest(sel) := newSel;
Dest(offset) := offest;
Save newDesc;
4.2.10 LGDT
Behaves as described in the SDM.
4.2.11 LLDT
Behaves as described in the SDM.
4.2.12 LIDT
Behaves as described in the SDM.
4.2.13 LKGS
Follows modified selector load checks, similar to MOV to segment register below.
4.2.14 LSL
Behaves as described in the SDM.
4.2.15 LTR
Behaves as described in the [Link] TSS busy bit is set.
If newSel is NULL AND MOV SS AND NOT (CPL0 AND CS.L) THEN
#GP(0);
FI
Check_selector(newSel);
newDesc := Load_descriptor_from_GDT_LDT(newSel);
IF MOV SS THEN
Check_SS_desc(newSEL, newDesc);
ELSE
Check_Data_desc(newSel, newDesc);
Dest(sel) := newSel;
Save newDesc;
IF SS THEN MOV SS instruction blocking FI;
4.2.19 POPF
Will ignore attemps to change IOPL in CPL0.
4.2.21 PUSHF
Behaves as described in the SDM.
Pseudocode:
4.2.24 SGDT
Behaves as described in the SDM.
4.2.25 SLDT
Behaves as described in the SDM.
4.2.26 SIDT
Behaves as described in the SDM.
4.2.27 STR
Behaves as described in the SDM.
4.2.28 SWAPGS
Behaves as described in the SDM.
4.2.29 SYSCALL
Behaves as described in the SDM and FRED EAS, except for enforcing RFLAGS restrictions.
4.2.30 SYSENTER
Behaves as described in the SDM.
4.2.31 SYSEXIT
Behaves as described in the SDM.
4.2.32 SYSRET
Behaves as described in the SDM and FRED EAS, except it faults if incoming RFLAGS (R11) has
VIF, VIP, or IOPL != 0.
4.2.34 VERR
Behaves as described in the SDM, but follows the modified segment load procedures documented
above.
4.2.35 VERW
Behaves as described in the SDM, but follows the modified segment load procedures documented
above.
4.2.36 VMEntry
Check_CS_Desc(newCS, newDesc, newCPL)
// If failure report VMEntry entry error
Check_SS_Desc(newSS, newDesc, newCPL)
// If failure report VMEntry entry error
For all of DS/ES/FS/GS:
Check_Data_Selector(newSelector, newCPL)
// If failure report VMEntry entry error
Load all descriptors as in 64bit mode.
Instruction Behavior
SIDT No change to Intel64 behavior.
SLDT No change to Intel64 behavior.
STR No change to Intel64 behavior.
LGDT No change to Intel64 behavior.
LIDT No change to Intel64 behavior.
LLDT No change to Intel64 behavior.
LTR No change to Intel64 behavior.
Behavior changed to follow the modified segmentation architecture described in
VERR
Section 4.1.
Behavior changed to follow the modified segmentation architecture described in
VERW
Section 4.1.
ARPL No change to Intel64 behavior.
Behavior changed to follow the modified segmentation architecture described in
FAR CALL
Section 4.2. #UD on 0x66 prefix. #GP on 0x67 prefix in 32bit mode and indiret.
Behavior changed to follow the modified segmentation architecture described in
FAR JMP
Section 4.2. #UD on 0x66 prefix. #GP on 0x67 prefix in 32bit mode
Behavior changed to follow the modified segmentation architecture described in
FAR RET
Section 4.2. #UD on 0x66 prefix.
IRET The behavior of the IRET instruction is described in Section 4.2.
LDS Load far pointer in DS with the segment check rules described in Section 4.1.
LES Load far pointer in ES with the segment check rules described in Section 4.1.
LFS Load far pointer in FS with the segment check rules described in Section 4.1.
LGS Load far pointer in GS with the segment check rules described in Section 4.1.
LSS Load far pointer in SS with the segment check rules described in Section 4.1.
LKGS Move to Kernel GS Base with the segment check rules described in Section 4.1.
MOV to DS Move to DS with the segment check rules described in Section 4.1.
MOV to ES Move to ES with the segment check rules described in Section 4.1.
MOV to SS Move to SS with the segment check rules described in Section 4.1.
MOV to FS Move to FS with the segment check rules described in Section 4.1.
MOV to GS Move to GS with the segment check rules described in Section 4.1.
MOV from DS No change to Intel64 behavior.
MOV from ES No change to Intel64 behavior.
MOV from SS No change to Intel64 behavior.
MOV from FS No change to Intel64 behavior.
MOV from GS No change to Intel64 behavior.
POP DS Pop top of stack into DS with the segment check rules described in Section 4.1.
POP ES Pop top of stack into ES with the segment check rules described in Section 4.1.
POP SS Pop top of stack into SS with the segment check rules described in Section 4.1.
POP FS Pop top of stack into FS with the segment check rules described in Section 4.1.
POP GS Pop top of stack into GS with the segment check rules described in Section 4.1.
PUSH CS No change to Intel64 behavior.
PUSH DS No change to Intel64 behavior.
PUSH ES No change to Intel64 behavior.
PUSH SS No change to Intel64 behavior.
Instruction Behavior
PUSH FS No change to Intel64 behavior.
PUSH GS No change to Intel64 behavior.
SWAPGS No change to Intel64 behavior.
RSM No changes to segmentation, but enforces other mode and RFLAGS restrictions.
WRFSBASE No change to Intel64 behavior.
WRGSBASE No change to Intel64 behavior.
RDFSBASE No change to Intel64 behavior.
RDGSBASE No change to Intel64 behavior.
SYSENTER Cannot enter 16-bit mode or VM86.
SYSEXIT Cannot enter 16-bit mode or VM86.
SYSCALL Enforces RFLAGS restrictions.
SYSRET Enforces RFLAGS restrictions.
ERETU Modified segment check rules. Enforces RFLAGS restrictions.
FRED entry No change to Intel64 behavior.
IDT entry Modified segment check rules and FRED restrictions.
Similarly, the 5-level page switch MSRs can be implemented on non-X86-S systems using its own
CPUID bit to allow compatibility.