# Intel VMX by Design: Why the VMCS Looks the Way It Does

*A design-oriented guide to Chapters 26 and 27 of the Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 3C.*

Intel's manual is precise about **what** VMX does, but a first reading can feel like walking through an inventory: root mode, non-root mode, VMCS fields, bitmaps, target values, and dozens of controls. The inventory becomes easier to remember when each item is tied to the problem it solves.

The unifying idea is this:

> **VMX lets ordinary guest code run directly, while giving the hypervisor a hardware-enforced contract for state, interception, and transitions. The VMCS is that contract for one virtual CPU.**

This article concentrates on Chapters 26 and 27. It explains both the specified mechanism and the engineering logic behind it. When Intel states a purpose explicitly, that purpose is presented as fact. When the manual specifies behavior but not the designers' motive, the rationale below is labeled as a **design reading** rather than an Intel claim.

## Chapter 26: why VMX adds another execution axis

The old x86 privilege model has rings 0 through 3. Operating-system kernels expect to run at CPL 0, where they can manage paging, interrupts, and privileged processor state. A hypervisor also needs ultimate control over those resources. Merely putting the guest kernel in ring 1 or ring 3 would change the environment the kernel was written for and would not provide a clean interception rule for every sensitive operation.

VMX adds a separate axis:

| VMX operation | Typical occupant | CPL can still be |
|---|---|---|
| Root | Hypervisor/VMM | 0 through 3 |
| Non-root | Guest OS and its applications | 0 through 3 |

A guest kernel can therefore execute in **VMX non-root operation at CPL 0**. Its ring-based assumptions remain largely intact, but VMX controls can still restrict or redirect its behavior. Root/non-root answers "who controls the physical machine?" while CPL answers "what privilege does this code have inside its current environment?"

### Why not emulate every instruction?

Because most instructions do not need hypervisor involvement. VMX is designed around **direct execution with selective interception**:

1. The hypervisor establishes guest state and a policy in the VMCS.
2. A VM entry moves the logical processor into non-root operation.
3. Guest instructions execute natively until a configured instruction, event, or condition causes a VM exit.
4. A VM exit records why it happened, saves VMCS-managed guest state, loads host state, and transfers control to the hypervisor.
5. The hypervisor handles the event and enters the guest again.

```mermaid
stateDiagram-v2
    [*] --> OutsideVMX
    OutsideVMX --> VMXRoot: VMXON
    VMXRoot --> VMXNonRoot: VMLAUNCH or VMRESUME
    VMXNonRoot --> VMXRoot: Configured VM exit
    VMXRoot --> OutsideVMX: VMXOFF
```

**Design reading:** The boundary is event-driven because transition cost matters. Native execution is the fast path; an exit is a policy decision. The controls exist to make the fast path as wide as the hypervisor can safely allow.

### Why is there no simple "I am a guest" bit?

Section 26.3 notes that no software-visible bit directly indicates VMX non-root operation. This keeps the mechanism separate from the guest's ordinary architectural state. The hypervisor may deliberately identify itself through CPUID, paravirtual interfaces, or emulated devices, but VMX does not force detection through a mode flag.

**Design reading:** Transparency is useful for running unmodified software. More importantly, a guest-mode bit would itself become another value that had to be virtualized consistently across instructions, saved state, and nested virtualization.

## Why VMX has an explicit lifecycle

Chapter 26 presents VMX as a lifecycle rather than a mode bit:

```text
discover -> enable -> VMXON -> configure VMCS -> enter/exit guests -> VMCLEAR -> VMXOFF
```

Each step establishes a different invariant.

### CPUID plus capability MSRs: discover, do not assume

`CPUID.01H:ECX.VMX[5]` reports basic VMX support. VMX capability MSRs then describe details such as control-bit legality, VMCS size and revision, supported activity states, fixed `CR0`/`CR4` bits, and optional features.

**Why this split makes sense:** CPUID answers the small binary question needed before touching VMX. MSRs provide an extensible description of a much larger feature set. A hypervisor can run on multiple processor generations by constructing a supported policy at boot instead of compiling in one model's control words.

### `IA32_FEATURE_CONTROL`: why firmware gets a lock

`VMXON` is gated by `IA32_FEATURE_CONTROL`. Its lock bit prevents further writes until a power-up reset; separate enable bits govern VMXON inside and outside SMX operation.

**Why this makes sense:** Enabling a hypervisor changes the machine's security boundary. Firmware can establish a platform-wide policy before the operating system starts, then lock it so later software cannot silently rewrite that decision. The cost is operational: if firmware locks VMX off, the OS cannot repair the setting without rebooting through firmware that enables it.

The lock is not a mutex protecting a running hypervisor. It is a one-way policy latch for the current boot:

```text
power-up reset
    -> firmware chooses whether VMX is permitted
    -> firmware sets IA32_FEATURE_CONTROL.Lock
    -> the setting cannot change again until the next power-up reset
```

This ordering closes an awkward security gap. If an operating system could enable VMX and later untrusted privileged software could disable or repurpose the platform policy, measured-launch and virtualization assumptions could change underneath already-running software. Locking the decision early makes the boot chain, rather than whichever ring-0 component runs last, the authority.

### `CR4.VMXE` plus `VMXON`: why two steps?

Software first sets `CR4.VMXE`, then executes `VMXON` with the physical address of a VMXON region. `VMXOFF` leaves VMX operation; only then may software clear `CR4.VMXE`.

The manual specifies the checks and ordering but does not state why enablement is split. A useful **design reading** is that the two steps separate:

- architectural permission to execute VMX instructions (`CR4.VMXE`), from
- creation of live VMX processor state (`VMXON` and its region).

That separation gives faults precise meanings and provides an explicit lifetime around processor-owned VMX state.

### Why a VMXON region is per logical processor

Before `VMXON`, software allocates a naturally aligned region, writes the VMCS revision identifier into its first 31 bits, and supplies its physical address. The required region size is implementation-specific but no larger than 4 KiB in the architecture described here. Each logical processor must use a separate VMXON region, and software must not modify it between `VMXON` and `VMXOFF`.

The VMXON region is **not** a VMCS and does not describe a guest. It supports the logical processor's participation in VMX operation.

**Design reading:** A per-logical-processor region matches the fact that each CPU enters and leaves VMX independently. A physical, page-aligned region gives the processor a stable object that does not depend on the current virtual address space. The opaque region also lets an implementation maintain VMX bookkeeping without exposing microarchitectural layout as an ABI.

It helps to separate the two objects explicitly:

| Object | Scope | Selected by | Purpose |
|---|---|---|---|
| VMXON region | One logical processor while it is in VMX operation | `VMXON` | Establishes that processor's VMX lifetime and implementation-private bookkeeping |
| VMCS region | Normally one virtual CPU | `VMPTRLD` | Describes guest state, the host exit target, execution policy, and exit information |

One VMXON region cannot replace the VMCS because a processor may run many vCPUs during one VMX lifetime. Conversely, a VMCS cannot replace the VMXON region because VMX must have processor-wide state before any particular guest object is selected. Keeping the lifetimes separate also makes failure recovery and ownership clear: `VMXOFF` ends the CPU's VMX lifetime, while `VMCLEAR` and `VMPTRLD` manage individual VMCS objects.

### Fixed `CR0` and `CR4` bits: protecting mode invariants

While VMX is active, some `CR0` and `CR4` bits may be required to be zero or one. Software discovers the valid masks through `IA32_VMX_CR0_FIXED0/1` and `IA32_VMX_CR4_FIXED0/1`. `VMXON`, VM entry, and VM exit refuse states that violate these rules.

For either control register, the rule can be written as:

```text
(value & FIXED0) == FIXED0       every required-1 bit is set
(value & ~FIXED1) == 0           every required-0 bit is clear
```

A bit that is 1 in `FIXED0` must be 1. A bit that is 0 in `FIXED1` must be 0. A bit permitted by both masks remains software-selectable.

**Why this makes sense:** VM entry and exit are already complex state changes. Fixed bits let a processor generation define the base execution invariants under which its VMX machinery is valid. Later processors added the `unrestricted guest` control, allowing a non-root guest to present states such as real-address mode even when root operation retains stricter requirements. That is a recurring VMX pattern: keep a safe base contract, then add a capability-negotiated relaxation.

The masks are capability data, not saved register values. They let a processor generation say, for example, that its transition machinery assumes protected-mode or paging-related infrastructure is enabled, or that an unsupported control-register feature must remain disabled. This is safer than letting a transition begin and fail halfway through after some state has already changed.

## Chapter 27: the VMCS is a bidirectional contract

A VMCS is normally associated with one virtual processor. A four-vCPU VM therefore normally has four VMCS regions plus software-owned state for each vCPU.

The six logical VMCS groups answer six different questions:

| VMCS group | Question answered |
|---|---|
| Guest-state area | What architectural state should the guest resume with, and what should be saved on exit? |
| Host-state area | Where and in what architectural environment should the exit handler begin? |
| VM-execution controls | What may the guest do directly, and what should be intercepted or virtualized? |
| VM-exit controls | What extra state transformation should happen on the way to the host? |
| VM-entry controls | What extra state transformation or event delivery should happen on the way to the guest? |
| VM-exit information | Why did control return, and what facts does the handler need? |

```mermaid
flowchart TD
    A[VMCS for one vCPU] --> B[State]
    A --> C[Policy]
    A --> D[Diagnostics]
    B --> E[Guest state and host state]
    C --> F[Execution, entry, and exit controls]
    D --> G[Exit reason and context]
```

This organization is more than filing. State describes **what the two contexts are**; controls describe **how and when to cross the boundary**; exit information describes **what just happened**.

## Why the VMCS region is opaque and versioned

A VMCS region is 4-KiB aligned and contains:

| Byte offset | Contents |
|---:|---|
| 0 | Bits 30:0: VMCS revision identifier; bit 31: shadow-VMCS indicator |
| 4 | VMX-abort indicator |
| 8 onward | Implementation-specific VMCS data |

Software does not cast the region to a structure. It uses `VMREAD` and `VMWRITE` with architectural field encodings.

### Revision identifier

The revision identifier prevents a processor from consuming a VMCS memory image in an incompatible internal format. `VMPTRLD` fails if the identifier does not match the processor.

**Why this makes sense:** Intel can change the internal representation without changing the architectural field interface. This permits processor-local caching, different physical layouts, and future fields while keeping hypervisor code source-compatible.

### Shadow indicator

Bit 31 distinguishes an ordinary VMCS from a shadow VMCS. An ordinary VMCS can drive VM entry. A shadow VMCS cannot; it exists so a guest hypervisor can execute selected `VMREAD` and `VMWRITE` operations without exiting to the outer hypervisor every time.

**Why one bit in the region header makes sense:** The processor must know the object's role before interpreting the rest of it. Keeping the type beside the revision lets `VMPTRLD` reject an unsupported or inappropriate object early.

### VMX-abort indicator

The processor writes a nonzero value here if a VMX abort occurs. It does not control ordinary execution.

**Why this makes sense:** A VMX abort is a severe transition failure in which ordinary exit reporting may not be available. A fixed, software-readable word in the region provides a last-resort diagnostic channel independent of the implementation-specific body.

### Alignment and write-back memory

The manual requires 4-KiB alignment and recommends the memory type reported by `IA32_VMX_BASIC`, normally write-back cacheable memory. Uncacheable mappings can make transitions substantially slower.

Intel does not state that page alignment was chosen for operating-system convenience. Still, the **design reading** is natural: a page-sized, page-aligned physical object is easy to allocate, pin, map with one memory type, protect from guest access, and move between logical processors under explicit ownership rules.

## Why VMCS fields have encodings instead of offsets

Every VMCS field has a 32-bit architectural encoding. Important parts of the encoding are:

| Encoding bits | Meaning |
|---|---|
| 14:13 | Width: 16-bit, 64-bit, 32-bit, or natural width |
| 11:10 | Type: control, exit information, guest state, or host state |
| 9:1 | Index within that width/type class |
| 0 | Full access, or high-half access for a 64-bit field |

The high-half form exists so 32-bit software can access both halves of a 64-bit VMCS field.

**Why encodings make sense:** An offset would expose the private in-memory layout. A semantic encoding says what a field *is* while leaving the processor free to store it anywhere, cache it internally, or synthesize it. Width and type bits also make decoding systematic, and the high-half access form avoids requiring 64-bit operands from 32-bit hypervisors.

## Current, active, clear, and launched: why the VMCS has a lifecycle too

These terms solve different ownership problems:

- **Current:** the VMCS implicitly addressed by `VMREAD`, `VMWRITE`, `VMLAUNCH`, and `VMRESUME` on this logical processor. `VMPTRLD` selects it.
- **Active:** associated with a logical processor and potentially represented partly in processor-local state.
- **Clear:** not yet successfully launched since the last `VMCLEAR`.
- **Launched:** has completed a successful `VMLAUNCH`; later entries use `VMRESUME`.

`VMPTRLD` means **load the VMCS pointer**. Its memory operand contains the physical address of a VMCS region. After validation, that VMCS becomes current on the logical processor; `VMREAD`, `VMWRITE`, `VMLAUNCH`, and `VMRESUME` then refer to it implicitly. The instruction does not enter the guest, load guest registers, or copy the entire VMCS into architectural registers. It selects the control object that later VMX instructions will use.

```text
VMPTRLD [address-of-physical-address]
              |
              +-> current VMCS pointer

VMWRITE ...   updates fields in that current VMCS
VMLAUNCH      enters using that current VMCS
VMRESUME      re-enters using that current VMCS
```

The operand's extra indirection is worth noticing: the instruction reads a physical address from memory. The VMCS itself is identified physically because it must remain stable across changes to `CR3` and virtual-address mappings.

No VMCS may be active on more than one logical processor. To migrate one, the old processor executes `VMCLEAR` so processor-maintained data reaches memory and the VMCS becomes inactive; the new processor then uses `VMPTRLD`. Because `VMCLEAR` also resets launch state, the next entry is `VMLAUNCH`.

**Design reading:**

- The implicit current pointer keeps frequent VMCS operations compact.
- Exclusive active ownership lets hardware cache VMCS state without cross-CPU coherence rules for the opaque body.
- `VMCLEAR` is both a write-back/ownership handoff and a launch-state reset.
- Distinguishing `VMLAUNCH` from `VMRESUME` gives hardware a well-defined first-entry path; Intel notes that `VMRESUME` is generally expected to have lower latency.

## The guest-state area: enough state to resume precisely

The guest-state area is not simply "all registers." It contains the architectural and boundary state that VM entry/exit machinery must manage directly.

| State family | Representative fields | Why hardware needs them |
|---|---|---|
| Execution mode and translation | `CR0`, `CR3`, `CR4` | They select protection, paging, address-space, and architectural features that determine how the next instruction is interpreted. |
| Debug environment | `DR7`, `IA32_DEBUGCTL`, pending debug exceptions | Breakpoint configuration and deferred debug delivery must remain guest-specific. |
| Continuation point | `RIP`, `RSP`, `RFLAGS` | They define where execution resumes, its stack, and its control/status flags. |
| Segmentation | CS, SS, DS, ES, FS, GS, LDTR, TR selector/base/limit/access rights | The visible selector alone does not capture the hidden descriptor state actually used by the processor. |
| Descriptor tables | GDTR and IDTR base/limit | They locate and bound the guest's descriptor and interrupt tables. |
| Mode-coupled MSRs | `IA32_EFER`, `IA32_PAT`, SYSENTER state, CET/FRED-related state, and others when supported | These values change instruction semantics, memory typing, entry paths, protection, or tracing. |
| Non-register execution state | activity, interruptibility, VMCS link, timer, cached PDPTEs, virtual interrupt status, PML index, deadline | These describe what may happen at the next boundary even though no ordinary instruction reads them as one register. |

### Why `RIP`, `RSP`, and `RFLAGS`, but not every GPR?

`RIP`, `RSP`, and `RFLAGS` are required to establish an execution context at a boundary. The VMCS does not contain fields for general-purpose registers such as `RAX`, `RBX`, and `RCX`.

The manual specifies the set, but not the microarchitectural reason for excluding GPRs. The practical **design reading** is that GPRs need not be interpreted to establish the protected guest/host environment. A VM-exit assembly stub can save them immediately into the software vCPU structure before clobbering them. Keeping that policy in software also lets each hypervisor choose its own frame and calling convention rather than forcing a fixed hardware save area.

The important implementation consequence is firm: **the VMCS is not a complete vCPU snapshot.** A migratable or suspendable vCPU needs both VMCS-managed state and software-managed state.

### What "mode-coupled MSRs" means

"Mode-coupled" is a useful description, not a separate architectural MSR class. It means that an MSR participates directly in the execution environment being installed at VM entry. Letting a host value accidentally remain active could change the meaning of guest instructions or memory accesses before the hypervisor gets another chance to intervene.

The guest-state area therefore has dedicated fields for `IA32_DEBUGCTL` and the three SYSENTER MSRs, plus capability-dependent fields for state such as `IA32_PERF_GLOBAL_CTRL`, `IA32_PAT`, `IA32_EFER`, `IA32_BNDCFGS`, `IA32_RTIT_CTL`, `IA32_LBR_CTL`, CET state, `IA32_PKRS`, FRED state, and `IA32_SPEC_CTRL`.

The coupling differs by register:

| Example | What it changes |
|---|---|
| `IA32_EFER` | Long-mode, execute-disable, and system-call semantics |
| `IA32_PAT` | How page-table memory types are interpreted |
| SYSENTER MSRs | The privilege-entry target selected by `SYSENTER` |
| `IA32_DEBUGCTL`, `IA32_LBR_CTL`, `IA32_RTIT_CTL` | Debugging, branch recording, and tracing behavior |
| CET state and `SSP` | Control-flow enforcement and shadow-stack behavior |
| `IA32_PKRS` | Supervisor protection-key permissions |
| FRED state | Event-delivery stacks and entry configuration |
| `IA32_SPEC_CTRL` | Speculative-execution policy |

Dedicated fields are not evidence that these are the only MSRs a guest may use. They are the MSRs for which Intel provides tightly defined transition handling. Other guest MSRs can be intercepted and emulated, or switched with the variable-length VM-entry/VM-exit MSR lists described later.

## Why segment registers need four fields

For each of CS, SS, DS, ES, FS, GS, LDTR, and TR, the guest area holds:

- a 16-bit selector;
- a base address;
- a 32-bit, byte-granular effective limit;
- a 32-bit access-rights field.

This looks redundant only if a segment register is imagined as its visible selector. Loading a segment register also fills a hidden **descriptor cache** with base, limit, type, privilege, present, granularity, and mode information. That cached state can legitimately differ from the descriptor currently stored in the GDT or LDT: software may load the segment, then modify the table entry.

If VM entry re-read the descriptor from memory, it could reconstruct a different state from the one that existed at VM exit. Therefore the VMCS saves both:

| Part | Purpose |
|---|---|
| Selector | Guest-visible name and privilege bits |
| Base | Cached address added during translation where applicable |
| Limit | Cached effective byte limit used for bounds checks |
| Access rights | Cached type, privilege, presence, mode, size, and granularity semantics |

### Why the access-rights bits look like a descriptor, but not exactly

Bits 0:7 and 12:15 of the VMCS access-rights field correspond to descriptor attributes such as type, S, DPL, P, AVL, L, D/B, and G. Bits 11:8 are reserved even though the corresponding descriptor bits hold the upper four encoded limit bits.

That difference is logical: the VMCS already stores the **expanded effective limit in bytes** as a separate 32-bit field. Repeating the descriptor's upper limit nibble would create two sources of truth. The `G` bit remains because it is part of architectural segment state and validation, but the VMCS limit itself is not a raw 20-bit descriptor encoding.

Bit 16 adds an **unusable** state. A null selector typically makes a segment unusable, but ordinary access-right bits have no single descriptor encoding that means "this segment register currently has no usable cached descriptor." The explicit bit lets VM entry reproduce that processor state without inventing a descriptor.

### Why are some base fields 64 bits if only 32 bits are architecturally defined?

On Intel 64 processors the VMCS base fields are 64 bits, including CS, SS, DS, and ES even though only 32 bits are architecturally defined for those bases. Intel states this width but does not give a motive. A conservative interpretation is that the VMCS uses the processor's broad address container consistently while VM-entry checks enforce the architecture's meaningful subset. Hypervisor code should follow those checks rather than treating field width as proof that every bit is usable.

## Why GDTR and IDTR have exactly base and limit

Chapter 27 says the guest area contains the following for each of GDTR and IDTR:

- a base address: 64 bits on Intel 64 processors;
- a limit stored in a 32-bit VMCS field.

This is a useful contrast with segment registers.

`GDTR` and `IDTR` do not select a descriptor and do not have selector, type, DPL, or present fields. Architecturally, each register simply identifies a memory table by **where it begins** and **the last valid byte offset** (so the table size is limit + 1). Base and limit are therefore sufficient to reproduce the register.

The base must span the architectural linear-address width because a descriptor table can reside anywhere permitted in the address space. The architectural GDTR/IDTR limit is only 16 bits. VMX nevertheless places it in a 32-bit field, and VM entry requires bits 31:16 to be zero.

Intel does not explain why it chose a 32-bit VMCS container instead of the available 16-bit field class. The defensible conclusion is limited: **only the low 16 bits carry architectural information; the high 16 are storage width, not extra table size.** A likely design benefit is regularity with other limit fields and 32-bit VMCS accesses, but that is interpretation, not a documented guarantee.

### Why LDTR and TR are different from GDTR and IDTR

LDTR and TR *do* select descriptors: an LDT descriptor and a TSS descriptor. Like ordinary segment registers, they have visible selectors and hidden cached descriptor state. That is why their VMCS representation includes selector, base, limit, and access rights rather than just base and limit.

The rule is simple:

> If a register is just a table pointer and bound, base plus limit is enough. If it selects a descriptor whose decoded state is cached, the VMCS must preserve both the selector and that cache.

## Why non-register guest state exists

Some processor conditions affect the next event boundary but are not fully represented by the ordinary register file.

### Activity state

The activity-state field distinguishes:

| Value | State | Meaning |
|---:|---|---|
| 0 | Active | Execute instructions normally |
| 1 | HLT | Wait for an event that wakes a halted processor |
| 2 | Shutdown | The virtual CPU has entered shutdown, commonly after a triple fault |
| 3 | Wait-for-SIPI | An application processor is waiting for a startup IPI |

Saving only `RIP` cannot tell the processor whether it should execute that instruction now, sleep until an interrupt, or wait for startup. Supported inactive states are capability-reported because not every processor generation must implement every state.

### Interruptibility state

Bits record blocking by STI, MOV/POP SS, SMI, and NMI, plus enclave-interruption state. These are short-lived pipeline/architectural conditions. For example, STI can defer maskable interrupts across the following instruction boundary.

**Why this field is essential:** Resuming with the right `RFLAGS.IF` but the wrong interrupt shadow changes architectural behavior. An interrupt could be delivered one instruction too early, or remain blocked too long. Precise virtualization requires saving the boundary condition, not just the durable flag.

| Bit | Condition | Why a durable register is insufficient |
|---:|---|---|
| 0 | Blocking by `STI` | `STI` can set `RFLAGS.IF` while still deferring interrupt recognition across the next instruction boundary. `IF=1` alone loses that one-instruction shadow. |
| 1 | Blocking by `MOV SS`/`POP SS` | These instructions suppress certain interrupts, NMIs, and debug exceptions across the following boundary, historically allowing software to update the stack selector and stack pointer as a pair. |
| 2 | Blocking by SMI | While in SMM, further SMIs are blocked. That condition is not an ordinary bit in the guest's general register file. |
| 3 | Blocking by NMI | Delivering an NMI blocks another NMI until `IRET`; with virtual NMIs, the bit instead records the guest's virtual-NMI readiness. |
| 4 | Enclave interruption | Records that the exit occurred in, or incident to an event associated with, enclave execution. |

For the stack-switch case, consider legacy code that does:

```asm
mov ss, ax
mov esp, new_stack_top
```

An interrupt between those instructions could otherwise observe a new stack segment with the old stack pointer. The temporary `MOV SS` blocking state makes that sequence architecturally usable. A VM exit between the instructions must preserve the shadow so resumption does not introduce an interrupt at a boundary where bare hardware would not.

### Pending debug exceptions

The processor may recognize a debug condition but defer its delivery. The VMCS preserves that pending condition so a transition does not erase, duplicate, or reorder the guest's debug event.

### VMCS link pointer

With VMCS shadowing enabled, this points to the shadow VMCS used by non-root `VMREAD`/`VMWRITE`. Otherwise it is set to all ones to avoid an invalid linked object.

### Timer, PDPTE, virtual-interrupt, PML, and deadline state

These fields exist only when the related capability/control exists:

| Field | State represented |
|---|---|
| VMX-preemption timer | Remaining hardware-enforced guest time slice |
| PDPTE0-PDPTE3 | Cached page-directory-pointer entries used by PAE paging |
| Guest interrupt status | Requested virtual-interrupt priority (`RVI`) and in-service priority (`SVI`) |
| PML index | Current position in the page-modification log buffer |
| Guest deadline | Virtual APIC timer deadline when APIC-timer virtualization is active |

They are good examples of **control-gated state**: a hypervisor need not initialize data that the active controls will not use. They are also reminders that two CPUs with identical visible registers may still behave differently on the next instruction or event boundary. The difference is precisely the kind of non-register execution state the VMCS must preserve.

This gating keeps the base VMCS extensible. New acceleration features can add state without forcing every older or minimal hypervisor to understand and populate it.

## Why the host-state area is smaller

The word **restore** can be misleading here. VM entry does not automatically save a complete host snapshot into the VMCS. The hypervisor writes a prepared landing environment into the host-state fields, and every VM exit loads that environment.

The complete host-state inventory in Chapter 27 is:

| Family | Host-state fields |
|---|---|
| Control and continuation | `CR0`, `CR3`, `CR4`, `RSP`, `RIP` |
| Segment selectors | CS, SS, DS, ES, FS, GS, TR |
| Bases | FS, GS, TR, GDTR, IDTR |
| Always-represented MSRs | `IA32_SYSENTER_CS`, `IA32_SYSENTER_ESP`, `IA32_SYSENTER_EIP` |
| Control-gated state | `IA32_PERF_GLOBAL_CTRL`, `IA32_PAT`, `IA32_EFER`, `IA32_S_CET`, `IA32_INTERRUPT_SSP_TABLE_ADDR`, `IA32_PKRS`, FRED MSRs, and `IA32_SPEC_CTRL` |
| Control-gated register | CET shadow-stack pointer `SSP` |

The FRED group consists of `IA32_FRED_CONFIG`, `IA32_FRED_RSP1` through `RSP3`, `IA32_FRED_STKLVLS`, and `IA32_FRED_SSP1` through `SSP3`. Optional fields exist only when the corresponding VM-exit control is supported.

### The state needed before the first host instruction

Some fields really are bootstrapping requirements:

- `CR3` must select host page tables before the processor fetches from `HOST_RIP`.
- `CR0`, `CR4`, and mode-related EFER state must establish the interpretation and protection rules under which that fetch occurs.
- `HOST_RIP` identifies the exit trampoline.
- `HOST_RSP` provides a safe host stack before the trampoline executes `PUSH`, `CALL`, or takes an event.
- `CS` and the synthesized segment cache establish ring-0 code semantics.

Leaving guest `CR3` active while fetching the host handler could fetch from a guest-controlled mapping or fault before the hypervisor has executed even one instruction. Leaving guest `RSP` active would make the first push overwrite guest memory. No software prologue can repair state that it needs in order to run that prologue.

Other fields make the machine safe and internally consistent immediately after the boundary:

- `FS.base` and `GS.base` commonly address host thread-local or per-CPU data.
- `TR`, GDTR, and IDTR support segmentation and event delivery. `RFLAGS.IF=0` blocks ordinary maskable interrupts, but exceptions, NMIs, and machine-check conditions still make valid event infrastructure important.
- `IA32_PAT` affects the memory types used for host accesses.
- CET, `SSP`, and FRED state affect protected control transfers and event delivery.
- `IA32_PKRS` affects whether supervisor accesses to protected pages are permitted.
- `IA32_SPEC_CTRL` applies the host's speculative-execution policy before host instructions run.

SYSENTER and performance-control state are not strictly required to fetch the first instruction. They are hardware-managed because they are common, transition-sensitive state for which atomic loading avoids repeated software boilerplate. The boundary is therefore not simply "impossible in software" versus "possible in software"; it also reflects security, frequency, and transition cost.

### Segment state is deliberately normalized

The host area does not contain guest-style base, limit, and access-right fields for every segment. VM exit constructs a conventional ring-0 environment:

- CS, SS, DS, and ES bases are fixed or cleared rather than loaded from fields.
- Usable code/data segment limits are set to fixed large values.
- CS is constructed as a present ring-0 code segment.
- Usable data segments are constructed as present ring-0 data segments.
- TR is constructed as a busy 32-bit TSS segment with a fixed limit.
- LDTR is cleared and marked unusable.
- GDTR and IDTR bases come from the VMCS, while both limits become `FFFFH`.

The guest must be able to resume strange but architecturally valid legacy segment caches. The host exit target is constrained to a normalized environment chosen by the hypervisor. That is a major reason its representation is smaller.

### What happens to host `RFLAGS`?

There is no `HOST_RFLAGS` field. On VM exit the processor synthesizes:

```text
RFLAGS = 0000000000000002H
```

Bit 1 has its architecturally fixed value and the meaningful flags are clear. In particular:

- `IF=0`: ordinary maskable interrupts initially remain disabled;
- `DF=0`: string operations proceed toward higher addresses;
- `TF=0`: the handler does not inherit single-step behavior;
- arithmetic condition codes are cleared;
- the guest's STI/MOV-SS interrupt shadows are not inherited by the host.

This is possible because VM exit does not resume an arbitrary interrupted host instruction. It starts a new handler at a known entry point. The handler can execute `STI` later, after it has saved guest registers and established whatever software state it needs.

The pre-entry host flags are not automatically restored. A successful `VMLAUNCH` or `VMRESUME` does not later fall through to the next host instruction; the next root-mode instruction normally begins at `HOST_RIP` after a VM exit.

### Other state established without host fields

VM exit also supplies fixed or control-selected state, including:

| State | VM-exit result |
|---|---|
| `DR7` | `400H` |
| `IA32_DEBUGCTL` | Cleared |
| LDTR | Selector zero and unusable |
| Activity state | Active |
| STI and MOV-SS blocking | Cleared |
| Pending debug exceptions | Cleared |
| NMI blocking | Determined by how the VM exit occurred |

Additional controls can clear state such as UINV, `IA32_BNDCFGS`, and `IA32_RTIT_CTL`. Host address-space-size and related rules determine mode-coupled pieces such as `CS.L`, EFER long-mode bits, and adjustments to `CR4`.

### What the exit trampoline still saves in software

General-purpose registers other than the hardware-loaded `RSP` are not replaced with host values. Immediately after exit, `RAX`, `RBX`, `RCX`, `R8`-`R15`, and the others normally still contain guest values. `HOST_RIP` therefore points to a small assembly trampoline that saves them before using them:

```asm
vmexit_entry:
    push rax
    push rbx
    push rcx
    ; save the rest of the guest register frame
```

The host's earlier general-purpose values were not secretly saved in the VMCS either. A vCPU-run wrapper preserves whatever host calling-convention state must survive, arranges the exit stack, and later reconstructs the software return path. VM exit itself is a jump to a configured landing pad, not a hardware return to the instruction after `VMRESUME`.

Floating-point, x87, SSE, AVX, and other `XSAVE` state are also not automatically switched by VMX. The hypervisor or host operating system manages them using an eager, lazy, or ownership-based policy. Additional MSRs can be handled by VM-exit load/store lists or explicit software operations.

The design boundary is therefore:

> Hardware establishes the state needed to reach a safe, self-consistent host landing point. Software manages state that can wait until the exit trampoline is executing, especially large or policy-dependent state.

This avoids copying a complete architectural image on every VM exit while still guaranteeing that the very first host instruction runs in the intended address space, privilege level, and protection environment.

## Execution controls: policy encoded for the fast path

The execution controls are grouped by the kind of thing they govern:

- **Pin-based controls** govern asynchronous events such as external interrupts and NMIs.
- **Processor-based controls** govern mainly synchronous instruction behavior and enable acceleration facilities.
- **Associated fields and bitmaps** supply addresses, masks, thresholds, identifiers, and per-resource policy.

**Why the split makes sense:** Asynchronous arrival policy and instruction semantics are different hardware paths. The grouping also allows later secondary and tertiary control vectors to be activated only when supported.

### Exception bitmap: one bit per architectural exception

A 32-bit bitmap selects which exception vectors cause exits. For page faults, error-code mask/match fields allow finer filtering.

**Why this makes sense:** Most exceptions should often stay inside the guest; the guest OS is supposed to handle its own divide errors and ordinary page faults. The hypervisor intercepts only exceptions needed for debugging, memory virtualization, security policy, or special emulation. Page faults need extra filtering because different error-code classes may belong to the guest or to a shadow-paging mechanism.

### I/O bitmaps: why exactly two 4-KiB pages?

x86 has 65,536 I/O-port numbers. One interception bit per port requires 65,536 bits, exactly 8 KiB. VMX divides that into:

- bitmap A: ports `0000H`-`7FFFH`, 4 KiB;
- bitmap B: ports `8000H`-`FFFFH`, 4 KiB.

A set bit means an access to that port causes a VM exit.

This is an unusually transparent design choice: the two aligned pages are simply a dense, constant-time policy table for the complete port namespace. It is more selective than unconditional I/O exiting and far cheaper than a variable-length rule search in hardware.

### MSR bitmaps: why four 1-KiB regions?

The 4-KiB MSR-bitmap page contains four 1-KiB maps:

| Sub-bitmap | MSR range | Operation |
|---|---|---|
| 0 | `00000000H`-`00001FFFH` | Read |
| 1 | `C0000000H`-`C0001FFFH` | Read |
| 2 | `00000000H`-`00001FFFH` | Write |
| 3 | `C0000000H`-`C0001FFFH` | Write |

Each covered range contains 8,192 MSR indices, which needs 8,192 bits or 1 KiB. Reads and writes need separate policy because a value may be safe to reveal but unsafe to modify. Accesses outside the covered ranges exit when MSR bitmaps are active.

The bitmap therefore covers 16K distinct indices, but **not the first contiguous 16K**. It covers 8K low indices and 8K indices beginning at `C0000000H`. The high window matters because it contains extended system MSRs such as `IA32_EFER` at `C0000080H` and the 64-bit syscall MSRs.

For a low MSR, the bit number is simply the index. `IA32_TSC`, for example, is index `10H`, so its policy is bit 16: byte 2, bit 0. The read bit lives in the first sub-bitmap; the corresponding write bit lives at byte `2048 + 2`.

For a high MSR, first subtract `C0000000H`. `IA32_EFER` becomes offset `80H`, so its bit is byte 16, bit 0 within each high-range sub-bitmap.

Covering every possible 32-bit MSR index would require 512 MiB for one bit per index, or 1 GiB for separate read and write policies. Most of that table would describe unimplemented holes. The two dense windows capture commonly used architectural MSRs in one page.

Outside those windows there is no policy bit, so VM exit is the conservative default. That protects model-specific or package-wide machinery and provides forward compatibility: an MSR introduced by a future processor does not silently become guest-accessible to an older hypervisor. If the `use MSR bitmaps` control is disabled, all guest `RDMSR` and `WRMSR` instructions exit.

### A clear bitmap bit means native access, not emulation

For an MSR represented by the bitmap:

| Bit | Result |
|---:|---|
| 0 | The logical processor performs the real `RDMSR` or `WRMSR` |
| 1 | The instruction causes a VM exit before the access completes |

The bitmap is an interception mechanism; it does not create a private bank of arbitrary MSRs for every VM.

On the direct path, ordinary architectural validation and side effects still apply. If the index is unimplemented or the value violates that MSR's rules, the processor produces the normal exception, commonly `#GP`, subject to the VM's exception-interception policy.

Consider `IA32_LSTAR`, the 64-bit `SYSCALL` target. If its write bit is clear, a guest `WRMSR` changes the real logical processor's LSTAR value. While that guest is running, a subsequent guest `SYSCALL` uses the value natively. The hypervisor can preserve isolation by context-switching the MSR:

```text
VM entry:       load guest LSTAR from an MSR-load list
guest WRMSR:    real LSTAR becomes the guest's new value
VM exit store:  save that value back to guest software state
VM exit load:   load the host's LSTAR
```

This is hardware-assisted context switching, not instruction emulation. Dedicated VMCS fields provide similar transition handling for selected MSRs such as SYSENTER state and, under controls, EFER or PAT. The generic VM-entry/VM-exit MSR lists handle a configurable long tail.

If the bitmap bit is one, the hypervisor receives the index in `ECX` and, for `WRMSR`, the attempted value in `EDX:EAX`. It can validate the value, store a purely virtual copy, update hardware selectively, advance guest `RIP`, or inject `#GP`. In that path the hypervisor is emulating the access.

Direct access is appropriate only when the MSR is safe for the guest while it runs and can be switched or otherwise isolated at the boundary. MSRs with package-wide effects, physical-address information, tracing controls, power policy, or irreversible side effects normally remain intercepted. Specialized VMX features provide a third case: state such as virtual time or parts of the APIC interface can receive purpose-built hardware virtualization rather than either ordinary pass-through or a full exit.

### TSC offset and multiplier: virtual time without trapping every read

TSC offsetting adds a per-vCPU offset to the time-stamp value returned to the guest. TSC scaling applies a multiplier before the offset when supported.

The offset lets a VM's clock remain continuous across pauses, migration, or a chosen virtual epoch. The multiplier gives the guest a virtual rate. Doing the transformation in hardware lets `RDTSC`, `RDTSCP`, and selected TSC MSR reads remain on the native path instead of exiting on every clock read.

Conceptually, scaling uses a fixed-point multiplier:

```text
guest_TSC = ((physical_TSC * multiplier) >> 48) + offset
```

`2^48` represents a multiplier of 1.0. A multiplier near `2^47` produces half-speed virtual time; one near `2^49` produces double-speed virtual time.

Two examples show why both terms exist:

1. If a VM is paused while the physical TSC advances by five seconds, the hypervisor can adjust the offset so the first post-resume guest timestamp follows the last pre-pause timestamp without a five-second jump.
2. If migration moves the vCPU to a machine whose TSC has a different origin or rate, the offset aligns the origin while the multiplier compensates for the rate difference.

Without hardware transformation, every frequent timestamp read would need a VM exit, software arithmetic, and emulation of the result. The controls turn virtual time into a data-path operation instead of a control transfer.

### CR0/CR4 guest-host masks and read shadows: two views of one register

For each bit in `CR0` or `CR4`:

- mask bit 0 means the guest owns it; reads and allowed writes use the actual control-register bit;
- mask bit 1 means the host owns it; guest reads obtain the read-shadow bit, and an attempt to write a different value causes a VM exit.

This separates the guest's **architectural view** from the hardware setting the hypervisor must maintain.

**Why this makes sense:** Control registers mix harmless guest policy with machine-critical state. A single "exit on every control-register access" switch would be expensive, while direct access to every bit would be unsafe. Per-bit ownership lets hardware execute ordinary accesses and involve the hypervisor only when the guest tries to cross the chosen boundary.

For example, suppose the host must keep `CR4.VMXE=1` while a guest should believe VMX is unavailable:

```text
actual CR4.VMXE      = 1
guest-host mask bit  = 1       host owns the bit
read-shadow bit      = 0       guest observes zero
```

A guest read of `CR4` reports VMXE as zero. A guest attempt to keep it zero is consistent with its virtual view and need not change the hardware bit. An attempt to write one crosses the policy boundary and causes an exit.

As a second example, a shadow-paging hypervisor may need real `CR0.PG=1` even while presenting a guest state in which paging is logically disabled. Masking the bit and exposing zero through the shadow preserves the hardware translation environment without forcing every harmless access to the rest of `CR0` through software.

Conversely, a bit the guest may safely control gets mask bit zero. A write then updates the actual control register without an exit for that bit, and a later read returns the actual value. The mask is ownership; the shadow is the guest-facing value for host-owned bits.

### CR3-target values: a small whitelist for hot address spaces

The mechanics are exact:

- If `CR3-load exiting` is 0, `MOV to CR3` does not exit for this reason.
- If it is 1, the source value is compared with the first *n* CR3-target values, where *n* is the CR3-target count.
- A match avoids the exit.
- With count zero, every `MOV to CR3` exits.
- The implementation described provides four target slots; software checks `IA32_VMX_MISC` rather than assuming the number.

Why is this useful? Operating systems change `CR3` during address-space switches. A hypervisor using shadow page tables may need to intercept a new guest page-table root so it can select or construct the corresponding shadow root. But the guest often cycles through a small set of hot roots - for example, the current process and a kernel-related address space. Targets allow those known values to pass without paying for an exit every time.

```text
CR3-load exiting = 1

new CR3 matches a target?  yes -> load CR3 directly
                           no  -> VM exit for hypervisor policy
```

Why only a small target set? Intel does not state the rationale. The sensible **design reading** is that a tiny parallel comparison is cheap hardware and captures locality without turning the VMCS into a large address-space cache. The capability mechanism leaves room for a different number on future processors.

With EPT, a guest `CR3` change does not by itself change the guest-physical-to-host-physical mapping. A modern hypervisor that does not need to observe guest address-space switches can often set `CR3-load exiting` to zero, making targets irrelevant. Targets still make sense when the hypervisor deliberately intercepts most CR3 changes but wants selected exact values to remain fast.

The target values are **exceptions to an enabled exit policy**, not a translation cache and not a list of valid page tables.

### Interrupt-window and NMI-window exiting: notify me when delivery becomes possible

Sometimes the hypervisor has a virtual interrupt ready, but the guest currently blocks it. Polling the guest after every instruction would be absurd. Window exiting asks the processor to exit precisely when the guest reaches a boundary at which the event can be delivered.

**Why this makes sense:** It converts a "wait until condition" problem into a hardware notification. The guest runs freely while blocked; the hypervisor regains control at the first useful moment.

### VMX preemption timer and PAUSE-loop exiting

The preemption timer bounds how long a guest runs before an exit, independent of guest cooperation. PAUSE-loop exiting uses a gap and window to distinguish isolated `PAUSE` instructions from a sustained spin loop.

These fields encode scheduling intent:

- a short spin may be cheaper than descheduling;
- a long spin wastes a physical CPU and should return control to the scheduler;
- a time bound ensures the hypervisor eventually regains control even if the guest masks interrupts.

## Why entry and exit controls are separate

Execution controls govern the guest while it runs. Entry and exit controls govern the boundary itself.

Examples include:

- whether debug controls, `IA32_PAT`, `IA32_EFER`, CET, FRED, protection-key state, and other supported components are loaded or saved;
- whether the guest enters IA-32e mode;
- whether the host exit target uses a 64-bit address space;
- whether an external interrupt is acknowledged during exit;
- whether selected MSRs are loaded or stored through list areas;
- whether an event is injected as entry completes.

**Why direction-specific controls make sense:** Guest and host do not necessarily need symmetric treatment. A hypervisor may want to save a guest value, load a different host value, clear sensitive state on exit, or leave a component unchanged for performance. Separate controls express those choices without forcing every transition to copy every possible register.

### Dedicated fields plus MSR lists

Frequently transition-coupled MSRs receive dedicated VMCS fields and controls. Additional MSRs can be handled through count-and-address list areas containing 16-byte entries.

**Design reading:** Dedicated fields make common, mode-sensitive state straightforward and validatable. Lists provide an extensible long tail without permanently enlarging the fixed VMCS interface for every MSR Intel may add.

### Event injection fields

VM entry can conclude by delivering a selected interrupt, NMI, exception, or other supported event. The VMCS provides the vector, type, validity, error-code information, and - for software events - an instruction length used in constructing the guest-visible return point.

**Why injection belongs to VM entry:** The processor can deliver the event only after the intended guest state is installed. Making injection part of the atomic entry sequence avoids a race in which guest instructions run before a pending virtual event is delivered.

## Why exit-information fields are rich

An exit reason alone is rarely enough to emulate an operation. Chapter 27 defines fields for:

- basic exit reason and flags such as failed VM entry;
- exit qualification, whose format depends on the reason;
- guest linear and guest-physical addresses when applicable;
- exiting-event vector/type/error information;
- original-event information when an exit interrupts event delivery;
- instruction length and instruction information for supported instruction exits;
- VM-instruction errors, which are distinct from VM exits.

### Why provide instruction information instead of making software decode?

The processor has already decoded the instruction and knows the addressing details that caused the exit. Reporting those details can avoid a second decode in the hypervisor, including difficult cases involving address size, segment selection, or an inaccessible instruction page.

### Why preserve the original event during nested delivery?

An exit can occur while the processor is attempting to deliver an interrupt or exception - for example, if event delivery itself encounters a protected memory access. If only the new exit were reported, the original event could be lost or injected twice. Original-event fields preserve the interrupted delivery context so the hypervisor can resume architectural behavior correctly.

This reflects a broader rule: virtualization must preserve not only register values, but also **causal history at an architectural boundary**.

## Why shadow VMCSs exist

Nested virtualization introduces three roles:

- L0: the real hypervisor in VMX root operation;
- L1: a guest hypervisor in VMX non-root operation;
- L2: the guest that L1 believes it controls.

Without VMCS shadowing, every L1 `VMREAD` and `VMWRITE` would exit to L0. A shadow VMCS lets selected accesses execute directly. VMREAD and VMWRITE bitmaps let L0 decide which field encodings are safe to access without an exit.

The shadow VMCS cannot itself be used for real VM entry. That separation is the security boundary: L1 receives a hardware-accelerated *view* of a VMCS, while L0 retains control of the ordinary VMCS that actually governs non-root execution.

L0 is still responsible for validating and synchronizing the relevant shadow values into the ordinary VMCS before real L2 entry. Shadowing delegates selected field accesses, not authority to launch an unchecked hardware context.

## Capability-negotiated controls: why "allowed zero" and "allowed one" both matter

For the traditional 64-bit capability-MSR format:

- the low 32 bits report zero-settings: a low-half bit of 1 means the control cannot be zero and is therefore required to be one;
- the high 32 bits report one-settings: a high-half bit of 0 means the control cannot be one and is therefore required to be zero.

A common normalization of a desired control word is:

```c
uint32_t legal = desired;
legal |= (uint32_t)capability;          // force required-1 bits
legal &= (uint32_t)(capability >> 32); // clear disallowed-1 bits
```

Both halves are needed because a processor may require an old default behavior, permit a feature optionally, or reserve a newer feature to zero. The `IA32_VMX_BASIC` MSR indicates when the "true" control MSRs should be used for complete reporting of older default-one controls. Secondary and tertiary controls use their documented capability formats and enabling controls; the formula above should not be copied blindly to every newer vector.

**Why this design ages well:** A control word is negotiated between software intent and hardware capability. Unknown bits remain safe, required legacy behavior is retained, and a new processor can add optional functionality without changing the basic VM-entry instruction.

## A field-design checklist for reading Chapter 27

When encountering an unfamiliar VMCS field, ask these questions:

1. **Is it state, policy, or diagnostic information?** That identifies the VMCS group and when it is meaningful.
2. **Is it visible architectural state or hidden boundary state?** Segment caches and interrupt shadows explain many fields that appear redundant.
3. **Which control activates it?** Many addresses and optional fields are ignored when their feature is disabled.
4. **Why is the granularity a bit, bitmap, exact target, threshold, or list?** The representation usually matches the lookup the fast path must perform.
5. **Which side owns the value?** Guest-host masks, read shadows, and entry/exit direction encode ownership.
6. **What must survive migration?** Processor-cached VMCS data requires `VMCLEAR`; software-managed GPRs require a separate vCPU frame.
7. **What must be validated before entry?** Reserved bits, canonical addresses, alignment, mode consistency, and control dependencies define the safety contract.

## The design in one paragraph

VMX creates an execution environment in which a guest can keep its native privilege structure while the hypervisor retains final control. The VMCS is deliberately not a memory-mapped register dump. It is a versioned, opaque, per-vCPU contract divided into resumable state, interception policy, transition policy, and exit diagnostics. Fields exist when hardware must reproduce hidden architectural state, make a fast-path decision, or explain a transition without ambiguity. Bitmaps handle large dense namespaces; masks divide ownership bit by bit; small target lists exempt hot exact values; pointers attach page-sized acceleration structures; entry and exit controls express asymmetric state changes. Once those patterns are visible, Chapter 27 stops looking like a bag of fields and starts looking like a carefully layered boundary between direct execution and hypervisor policy.

---

## Source and scope

This article is an explanatory synthesis of **Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 3 (3A, 3B, 3C, & 3D): System Programming Guide**, Order Number **325384-092US**, June 2026.

Primary reading:

- Sections 26.2-26.5: VM architecture, root/non-root operation, lifecycle, and VMCS introduction
- Sections 26.6-26.8: discovery, enablement, VMXON, and VMX restrictions
- Sections 27.1-27.3: VMCS state, region format, and logical organization
- Sections 27.4-27.5: guest-state and host-state areas
- Sections 27.6.1-27.6.27: execution controls and associated fields
- Sections 27.7-27.9: exit controls, entry controls, injection, and exit information
- Sections 27.10-27.11: shadow VMCSs, ownership rules, encodings, and initialization
- Section 30.5: exact state loaded, synthesized, or cleared on VM exit

Sections in Chapters 28-33 define the run-time behavior and validation that consume these fields. Appendix A describes capability reporting; Appendix B lists VMCS field encodings; Appendix C lists basic exit reasons.

The rationale marked as a **design reading** is engineering interpretation of the specified behavior, not a claim that Intel has documented that historical or microarchitectural motive. Production hypervisor code must follow the manual's exact checks, capability rules, memory-ordering requirements, instruction pseudocode, and applicable processor errata.
