[0x00] Concept
이전에는 Intel
에서 제공하는 가상화 확장인 VMX
를 확인하였고, 이에 따라 논리 프로세서를 가상화하는 방법에 대해 다뤘습니다.
이로 인해 논리 프로세서들은 VMXON
명령을 통해 VMX Operation
을 활성화 할 수 있었습니다.
이번 포스트에서는 개념적으로 조금 더 접근합니다. VMCS Region
에 대해 이전 챕터에서 확인하였고 실제 VMCS Data
에는 어떠한 것들이 포함되는지 확인합니다.
매우 많은 내용들이 포함되어 있으며, Intel SDM
을 번역하며 이해하기 어려웠던 내용들을 정리하고, 이를 구조화 하였습니다.
조금 길지만, Intel SDM Vol.3C 31-6
에 있는 VMM
에서 Guest VM
을 설정하고 시작하는데 필요한 최소 단계에 대한 내용입니다.(마찬가지로 2022.04 개정판에서는 삭제되어 있습니다.)
[0x01] VMCS Data
우선은 이전 파트에서 지나쳤던 VMCS Data
의 구조에 대해서 살펴 보겠습니다.
Intel SDM
에서 VMCS Data
구조에 대한 내용은 매우 긴 분량을 차지합니다. 우선 크게 다섯 가지로 나눌 수 있습니다.
- Guest-state area
- 프로세서의 상태는
VM Exit
에 의해Guest-state area
에 저장되고,VM Entry
에 의해Guest-state area
에서 로드 됩니다.
- 프로세서의 상태는
- Host-state area
- 프로세서의 상태는
VM Exit
에 의해Host-state area
에서 로드 됩니다.
- 프로세서의 상태는
- VM-execution Control Fields
- 해당 필드는
VMX Non-root Operation
에서 프로세서 행위를 제어합니다.VM Exit
의 원인을 부분적으로 결정합니다.
- 해당 필드는
- VM-exit, VM-entry Control Fields
- 해당 필드는
VM Exit
,VM Entry
를 제어합니다.
- 해당 필드는
- VM-exit Information Fields
- 해당 필드는
VM Exit
에 대한 정보를 수신하고 원인과 특성을 설명합니다. 일부 프로세서에서 해당 필드는 읽기 전용입니다.(IA32_VMX_MISC
를 통해 읽기 전용인지 확인 가능)
- 해당 필드는
위에서 VM-execution, exit, entry fields
를 집합적으로 VMX Control
이라고 하는 경우도 있습니다.
각 필드들에는 지원되는지를 확인하기 위해 특정 MSR
을 이용합니다. 해당 내용은 아래와 같습니다.
#define IA32_VMX_MISC_MSR 0x485
typedef struct _IA32_VMX_MISC
{
union
{
ULONG64 Features;
struct
{
ULONG64 VMXPreemptionTSCRelationship : 5; // 00-04
ULONG64 StoreEferLmaOnVmEntryControl : 1; // 05
/*
* Bits 8:6 report, as a bitmap, the activity states supported by the implementation:
* Bit 6 reports (if set) the support for activity state 1 (HLT).
* Bit 7 reports (if set) the support for activity state 2 (shutdown).
* Bit 8 reports (if set) the support for activity state 3 (wait-for-SIPI).
* If an activity state is not supported, the implementation causes a VM entry to fail if it attempts to establish that activity state.
* All implementations support VM entry to activity state 0 (active).
*/
ULONG64 SupportedActivityState : 3; // 06-08
ULONG64 Reserved_1 : 5; // 09-13
ULONG64 SupportProcessorTrace : 1; // 14
ULONG64 SupportReadSMBASEMsr : 1; // 15
ULONG64 Cr3TargetCount : 9; // 16-24
ULONG64 MaxNumberOfMSR : 3; // 25-27
ULONG64 CanSMMMonitorCtlBit2 : 1; // 28
ULONG64 SupportVMWriteVmExitInfo : 1; // 29
ULONG64 ZeroInstructionVMEntryInjection : 1; // 30
ULONG64 Reserved_2 : 1; // 31
ULONG64 MsegIdentifier : 32; // 32-63
};
};
}IA32_VMX_MISC,* PIA32_VMX_MISC;
[0x02] Guest-State Area
위에서 설명한 것과 같이 Guest-state area
에는 VM Exit
발생 시 프로세서의 특정 상태들이 저장되고 VM Entry
에 의해 해당 영역에서 프로세서의 상태들이 로드 됩니다.
총 두 가지로 Guest Register State
와 Guest Non-Register State
로 나눠집니다.
[-] Guest Register State
해당 프로세서의 레지스터 상태 값이 존재하며 아래와 같은 레지스터 값이 존재합니다.
- Control Register(64 bits or 32 bits)
- CR0
- CR3
- CR4
- Debug Register(64 bits or 32 bits)
- DR7
- RSP, RIP, RFLAGS(64 bits or 32 bits)
- CS, SS, DS, ES, FS, GS, LDTR, TR
- Selector(16 bits), Base Address(64 bits), Segment Limit(32 bits), Access rights(32 bits)
- 기본적으로
x64 Segment Register
를 따른다. Selector
외에도Segment Descriptor
까지 필요,Segment Register
의Descriptor Cache
와 선택자가 참조하는 메모리(GDT
,LDT
)에 있는Segment Descriptor
와 일치하지 않을 수 있기 때문에VMCS
에 포함
- GDTR, IDTR
- Base Address(64 bits or 32 bits)
- Limit(32 bits)
- MSR
- IA32_DEBUGCTL(64 bits)
- IA32_SYSENTER_CS(32 bits)
- IA32_SYSENTER_ESP, EIP (64 bits or 32 bits)
- 그 외 각
VMX Control
필드에서 해당하는 비트가 1로 설정 가능한 경우(자세한VMX Control
내용 생략)IA32_PERF_GLOBAL_CTRL
,IA32_PAT
,IA32_EFER
,IA32_BNDCFGS
,IA32_RTIT_CTL
,IA32_LBR_CTL
,IA32_S_CET
,IA32_INTERRUPT_SSP_TABLE_ADDR
,IA32_PKRS
- ex :
IA32_PERF_GLOBAL_CTRL
:VM-entry Control
의load IA32_PERF_GLOBAL_CTRL
- Shadow-Stack Pointer Register SSP(64 bits or 32 bits)
VM-entry control
의load CET state
가 설정된 경우
- Register SMBASE(32 bits)
- 해당 레지스터는 논리 프로세서의
SMRAM
이미지의 기본 주소를 포함 SMRAM
은System Management Mode(SMM)
에서 생성되는 메모리 영역(System Management RAM
)
- 해당 레지스터는 논리 프로세서의
[-] Guest Non-Register State
Guest Register State
외에도 프로세서 레지스터에 해당하지 않는 게스트 상태의 특성을 지닌 필드가 존재합니다.
- Activity State(32 bits)
- 논리 프로세서의 활동 상태를 식별
- 논리 프로세서가 명령을 정상적으로 실행하고 있을 때
Active
상태 - 특정 명령을 실행하고 특정 이벤트가 발생하면 논리 프로세서가 명령 실행을 중단하는 비활성화 상태로 전환될 수 있음
- 아래와 같이 활동 상태가 정의
Active
: 논리 프로세서가 정상적으로 명령을 실행 중입니다.HLT
: 논리 프로세서가HLT
명령을 실행했기 때문에 비활성화 되었습니다.Shutdown
: 논리 프로세서가Triple Fault
또는 심각한 오류가 발생했기 때문에 비활성화 되었습니다.Wait-for-SIPI
: 논리 프로세서가 (SIPI(Startup-IPI
) 를 기다리고 있기 때문에 비활성화 상태 입니다.
- 지원되는 활동 상태는
MSR IA32_VMX_MISC
를 읽어야 합니다. (bit 6 - 8)
- Interruptibility State(32 bits)
IA-32
아키텍처에는 일정 시간 동안 특정 이벤트를 차단할 수 있는 기능이 포함되어 있습니다.- 해당 필드에는 이러한 차단 정보가 포함됩니다.
typedef struct _INTERRUPTIBILITY_STATE { union { ULONG All; struct { ULONG BlockSTI : 1; // 00 ULONG BlockMOVSS : 1; // 01 ULONG BlockSMI : 1; // 02 ULONG BlockNMI : 1; // 03 ULONG EnclaveInterruption : 1; // 04 ULONG Reserved : 27; // 05-31 }Fields; }; }INTERRUPTIBILITY_STATE, * PINTERRUPTIBILITY_STATE;
- Pending Debug Exception(64 bits or 32 bits)
IA-32
프로세서는 하나 이상의 디버그 예외를 인식할 수 있습니다. 해당 필드는 이러한 예외에 대한 정보가 포함됩니다.
typedef struct _PENDING_DEBUG_EXCEPTION { union { ULONG64 All; struct { ULONG64 B0 : 1; // 00 ULONG64 B1 : 1; // 01 ULONG64 B2 : 1; // 02 ULONG64 B3 : 1; // 03 ULONG64 Reserved_1 : 8; // 04-11 ULONG64 EnableBreakpoint : 1; // 12 ULONG64 Reserved_2 : 1; // 13 ULONG64 BS : 1; // 14 ULONG64 Reserved_3 : 1; // 15 ULONG64 RTM : 1; // 16 (Restricted Transactional Memory) ULONG64 Reserved_4 : 47; // 17-63 }Fields; }; }PENDING_DEBUG_EXCEPTION, * PPENDING_DEBUG_EXCEPTION;
- VMCS Link Pointer(64 bits)
VM-execution control
내VMCS Shadowing
비트가 1이면,VMREAD
및VMWRITE
명령은 이 포인터가 참조하는VMCS
에 액세스합니다. 그렇지 않으면VMM
은VM Entry
실패를 피하기 위해 이 필드를FFFFFFFF'FFFFFFFF
으로 설정해야 합니다.
- VMX-Preemption Timer Value(32 bits)
- 이 필드는
VM-execution control
내activate VMX-preemption timer
가 1로 설정이 가능한 프로세서에서만 지원 됩니다.
- 이 필드는
- Page-Directory-Pointer-Table Entries(PDPTEs; 64 bits each)
- 4 개의 필드로 구성(
PDPTE0 ~ 3
)되며,VM-execution control
내Enable EPT
가 1로 설정이 가능한 프로세서에서만 지원됩니다.PAE
페이징이 사용 중일 때CR3
에서 참조하는PDPTE
에 해당합니다.
- 4 개의 필드로 구성(
- Guest Interrupt Status(16 bits)
- 이 필드는
VM-execution control
내Virtual-Interrupt Delivery
가 1로 설정 가능한 프로세서에서만 지원됩니다. - Requesting Virtual Interrupt(RVI)
- 이것은
Guest Interrupt Status
의 하위 바이트 입니다. 프로세서는 이 값을 서비스 중 가장 높은 우선 순위의 가상 인터럽트의 벡터로 취급합니다. (0인 경우 이러한 인터럽트가 존재하지 않음을 의미합니다.)
- 이것은
- Servicing Virtual Interrupt(SVI)
- 이것은
Guest Interrupt Status
의 상위 바이트 입니다. 프로세서는 이 값을 서비스 중 가장 높은 우선 순위의 가상 인터럽트의 벡터로 취급합니다. (0인 경우 이러한 인터럽트가 존재하지 않음을 의미합니다.)
- 이것은
- 이 필드는
- PML Index(16 bits)
- 이 필드는
VM-execution control
내Enable PML
가 1로 설정 가능한 프로세서에서만 지원됩니다. 이 필드에는 페이지 수정 로그에 있는 다음Entry
의 논리적 인덱스가 포함됩니다. - 페이지 수정 로그는 512개의
Entry
로 구성되기 때문에PML Index
는 일반적으로 0-511 범위의 값 입니다.
- 이 필드는
[0x03] Host-State Area
해당 영역에는 앞서 설명한 것과 같이 모든 VM Exit
에 대해 해당 영역에서 프로세서 상태를 로드 합니다.
Host-State Area
의 모든 필드는 프로세서 레지스터에 해당합니다.
[-] Processor Register
- Control Register(64 bits each or 32 bits)
- CR0, CR3, CR4
- RSP and RIP(64 bits each or 32 bits)
- Selector Fields(16 bits each) (For Segment Register)
- CS, SS, DS, ES, FS, GS, TR
- LDTR Selector에 대한 필드는
Host-State Area
에는 존재하지 않습니다.
- Base-address Fields(64 bits each) (For Segment Register)
- FS, GS, TR, GDTR, IDTR
- MSR
- IA32_SYSENTER_CS(32 bits)
- IA32_SYSENTER_ESP, EIP(64 bits or 32 bits)
VM-exit control
내 각 해당하는 비트가 1로 설정을 지원하는 경우IA32_PERF_GLOBAL_CTRL
,IA32_PAT
,IA32_EFER
,IA32_S_CET
,IA32_INTERRUPT_SSP_TABLE_ADDR
,IA32_PKRS
- Shadow-Stack Pointer Register SSP(64 bits)
VM-exit control
내load CET state
가 1로 설정을 지원하는 경우에만 지원됩니다.
[0x04] VM-Execution Control Fields
VMX-execution control
필드는 VMX Non-root operation
을 제어 합니다.
[-] Pin-Based VM-Execution Controls
Intel PIN
기반의 제어는 비동기 이벤트(ex. Interrupt)의 처리를 제어하는 32비트의 벡터를 구성합니다.
해당 필드의 다른 모든 비트는 예약되어 있으며, 일부는 0이고 일부는 1입니다. VMM
은 이러한 예약된 비트를 설정하는 방법을 결정하기 위해 MSR IA32_VMX_PINBASED_CTLS(0x481)
, MSR IA32_VMX_TRUE_PINBASED_CTLS(0x48D)
를 참조해야 합니다.
IA32_VMX_PINBASED_CTLS
의 경우에는 bit 1, 2, 4 비트가 항상 1로 설정되어야 했습니다.
이러한 비트의 0으로의 설정을 지원하는 논리 프로세서는 IA32_VMX_TRUE_PINBASED_CTLS
를 지원하며, VMM
은 이 MSR
을 참조하여 해당 비트를 0으로의 설정에 대한 지원 여부를 확인해야 합니다.
추가로, 현재 지속적으로 등장하는 MSR
의 경우, VMX
와 연관이 있는 MSR
은 0x480부터 일반적으로 시작됩니다.
대부분 기능에 대한 보고 레지스터라고 설명되며, 이는 필요한 비트 설정등이나 기능 활성 가능 여부 등을 나타냅니다.
우선 실제로 구현할 때, 참조해야 하는 부분은 IA32_VMX_BASIC
을 읽어 참조해야 합니다. 해당 MSR
에서 bit 55 에 있는 VmxControls
은 IA32_TRUE_PINBASED_CTLS
에 대한 지원 여부를 포함합니다.
즉 IA32_VMX_BASIC.VmxControls == 1
인 경우에는 IA32_TRUE_PINBASED_CTLS
를 지원함을 의미합니다.
#define IA32_VMX_PINBASED_CTLS_MSR 0x481
#define IA32_VMX_TRUE_PINBASED_CTLS_MSR 0x48D
typedef struct _IA32_VMX_PINBASED_CTLS
{
union
{
ULONG64 Features;
struct
{
ULONG64 ExternalInterruptExiting : 1; // 00
ULONG64 Reserved_1 : 2; // 01-02
ULONG64 NMIExiting : 1; // 03
ULONG64 Reserved_2 : 1; // 04
ULONG64 VirtualNMIs : 1; // 05
ULONG64 Activate_VMX_PreemptionTimer : 1; // 06
ULONG64 ProcessPostedInterrupts : 1; // 07
ULONG64 Reserved_3 : 56; // 08-63
}Fields;
};
}IA32_VMX_PINBASED_CTLS, * PIA32_VMX_PINBASED_CTLS;
[-] Processor-Based VM-Execution Controls
프로세서 기반의 제어는 주로 특정 명령어의 실행으로 인해 발생하는 동기 이벤트를 제어하는 세 가지 벡터로 구성됩니다.
Primary Processor-Based VM-Execution Controls(32 bits)
, Secondary Processor-Based VM-Execution Controls(32 bits)
, Tertiary Processor-Based VM-Execution Controls(64 bits)
입니다.
아래부터는 Primary, Secondary, Tertiary Control
으로 표현하겠습니다.
이 필드 또한 Pin-Based
와 동일하게 다른 모든 비트는 예약되어 있고 0이거나 1입니다. 해당 필드는 예약된 비트를 설정하는 방법을 결정하기 위해 MSR IA32_VMX_PROCBASED_CTLS(0x482)
및 MSR IA32_VMX_TRUE_PROCBASED_CTLS(0x48E)
를 참조해야 합니다. (마찬가지로 IA32_VMX_BASIC.Fields.VmxControls
에 따라 MSR IA32_VMX_TRUE_PROCBASED_CTLS
지원 여부가 결정됨)
MSR IA32_VMX_PROCBASED_CTLS
는 1, 4, 5, 6, 8, 13, 14, 15, 16, 26 비트에 대해 항상 1로 설정되어야 한다고 보고되었습니다.(보고 레지스터 이기 때문)
이러한 비트의 0으로의 설정을 지원하는 논리 프로세서는 IA32_VMX_TRUE_PROCBASED_CTLS
를 지원하며, VMM
은 이 MSR
을 참조하여 해당 비트를 0으로의 설정에 대한 지원 여부를 확인해야 합니다.
Bit 31 은 Secondary Control
이 사용되는지 여부를 결정합니다. 해당 비트가 0인 경우 VM Entry
및 VM Non-root operation
은 모든 Secondary Processor-Based VM-execution Control
이 0인 것 처럼 동작합니다.
Primary Control
의 Bit 31 이 0에 대한 설정만 지원하는 프로세서는 Secondary Control
을 지원하지 않습니다.
아래는 Primary
에 대한 필드 설명입니다.
#define IA32_VMX_PROCBASED_CTLS_MSR 0x482
#define IA32_VMX_TRUE_PROCBASED_CTLS_MSR 0x48E
typedef struct _IA32_VMX_PROCBASED_CTLS
{
union
{
ULONG64 Features;
struct
{
ULONG64 Reserved_1 : 2; // 00-01
ULONG64 InterruptWindowExiting : 1; // 02
ULONG64 UseTSCOffsetting : 1; // 03
ULONG64 Reserved_2 : 3; // 04-06
ULONG64 HLT_Exiting : 1; // 07
ULONG64 Reserved_3 : 1; // 08
ULONG64 INVLPG_Exiting : 1; // 09
ULONG64 MWAIT_Exiting : 1; // 10
ULONG64 RDPMC_Exiting : 1; // 11
ULONG64 RDTSC_Exiting : 1; // 12
ULONG64 Reserved_4 : 2; // 13-14
ULONG64 CR3Load_Exiting : 1; // 15
ULONG64 CR3Store_Exiting : 1; // 16
ULONG64 Activate_TertiaryControls : 1; // 17
ULONG64 Reserved_5 : 1; // 18
ULONG64 CR8Load_Exiting : 1; // 19
ULONG64 CR8Stor_Exiting : 1; // 20
ULONG64 UseTPRShadow : 1; // 21
ULONG64 NMIWindow_Exiting : 1; // 22
ULONG64 MOV_DR_Exiting : 1; // 23
ULONG64 Unconditional_IO_Exiting : 1; // 24
ULONG64 Use_IO_Bitmaps : 1; // 25
ULONG64 Reserved_6 : 1; // 26
ULONG64 MonitorTrapFlag : 1; // 27
ULONG64 UseMSRBitmaps : 1; // 28
ULONG64 MONITOR_Exiting : 1; // 29
ULONG64 PAUSE_Exiting : 1; // 30
ULONG64 Activate_SecondaryControls : 1; // 31
ULONG64 Reserved_7 : 32; // 32-63
}Fields;
};
}IA32_VMX_PROCBASED_CTLS, * PIA32_VMX_PROCBASED_CTLS;
Secondary Control
의 경우 MSR IA32_VMX_PROCBASED_CTLS2
를 참조하여 1로 설정할 수 있는 비트를 결정해야 합니다. 0으로 설정할 수 있는 비트에 대한 MSR
은 존재하지 않습니다.
아래는 Secondary Control
에 대한 필드입니다.
#define IA32_VMX_PROCBASED_CTLS2 0x48B
typedef struct _IA32_VMX_PROCBASED_CTLS2
{
union
{
ULONG64 Features;
struct
{
ULONG64 VirtualizeAPIC_Access : 1; // 00
ULONG64 EnableEPT : 1; // 01
ULONG64 DescriptorTable_Exiting : 1; // 02
ULONG64 EnableRDTSCP : 1; // 03
ULONG64 Virtualize_x2APICMode : 1; // 04
ULONG64 EnableVPID : 1; // 05
ULONG64 WBINVD_Exiting : 1; // 06
ULONG64 UnrestrictedGuest : 1; // 07
ULONG64 APICRegister_Virtualization : 1; // 08
ULONG64 VirtualInterruptDelivery : 1; // 09
ULONG64 PAUSE_Loop_Exiting : 1; // 10
ULONG64 RDRAND_Exiting : 1; // 11
ULONG64 EnableINVPCID : 1; // 12
ULONG64 EnableVMFunction : 1; // 13
ULONG64 VMCSShadowing : 1; // 14
ULONG64 EnableENCLS_Exiting : 1; // 15
ULONG64 RDSEED_Exiting : 1; // 16
ULONG64 EnablePML : 1; // 17 Page-Modification Logging
ULONG64 EPT_Violation_VE : 1; // 18
ULONG64 ConcealVMX_FromPT : 1; // 19
ULONG64 EnableXSAVES_XRSTORS : 1; // 20
ULONG64 Reserved_1 : 1; // 21
ULONG64 ModeBasedExecuteControlForEPT : 1; // 22
ULONG64 SubPageWritePermissionsForEPT : 1; // 23
ULONG64 IntelPT_UsesGuestPhysicalAddress : 1; // 24
ULONG64 UseTSCScaling : 1; // 25
ULONG64 EnableUserWaitAndPause : 1; // 26
ULONG64 EnablePCONFIG : 1; // 27
ULONG64 EnableENCLV_Exiting : 1; // 28
ULONG64 Reserved_2 : 35; // 29-63
}Fields;
};
}IA32_VMX_PROCBASED_CTLS2, * PIA32_VMX_PROCBASED_CTLS2;
개정된 Intel SDM
에는 Primary Control
필드에서 bit 17에 대한 값이 추가되었습니다.
해당 Bit 17은 Tertiary Control
이 사용되는지에 대한 여부를 나타냅니다. 해당 비트가 0이면 VM Entry
와 VMX Non-root operation
은 모든 Tertiary Control
이 0인 것 처럼 동작합니다.
VMM
은 MSR IA32_VMX_PROCBASED_CTLS3
를 참조하여 1로 설정할 수 있는 비트를 결정해야 합니다.
Tertiary Control
필드는 아래와 같습니다.
#define IA32_VMX_PROCBASED_CTLS3_MSR 0x492
typedef struct _IA32_VMX_PROCBASED_CTLS3
{
union
{
ULONG64 Features;
struct
{
ULONG64 LOADIWKEY_Exiting : 1; // 00
ULONG64 EnableHLAT : 1; // 01
ULONG64 EPTPagingWriteControl : 1; // 02
ULONG64 GuestPagingVerification : 1; // 03
ULONG64 Reserved : 60; // 04-63
}Fields;
};
}IA32_VMX_PROCBASED_CTLS3, * PIA32_VMX_PROCBASED_CTLS3;
[-] Exception Bitmap
Exception Bitmap
은 각 예외에 대해 하나의 비트를 포함하는 32bit 필드 입니다. 예외가 발생하면 해당 벡터를 사용하여 이 필드에서 비트를 선택합니다.
비트가 1이면 예외로 인해 VM Exit
가 발생합니다. 비트가 0이면 예외 벡터에 해당하는 Descriptor
를 사용하여 IDT
를 통해 예외가 정상적으로 전달됩니다.
Page Fault
(벡터 14의 예외)로 인해 VM Exit
가 발생했는지 여부는 Exception Bitmap
의 Bit 14와 VMCS
의 페이지 폴트 및 두 개의 32bit 필드에 의해 생성된 오류 코드에 의해 결정됩니다.
[-] I/O-Bitmap Addresses
VM-execution control
필드에는 I/O Bitmap A,B(각 4kb)의 64bit 물리 주소가 포함됩니다. 각 I/O Bitmap 에는 I/O Port에 대해 하나의 비트를 포함합니다.
- I/O Bitmap A 범위 : 0000h - 7FFFh
- I/O Bitmap B 범위 : 8000h - FFFFh
논리 프로세서는 Use I/O Bitmaps
필드가 1인 경우에만 이러한 Bitmap 을 사용합니다.(IA32_VMX_PROCBASED_CTLS
내 bit 25)
Bitmap을 사용하는 경우 해당 주소는 4kb 로 정렬되어야 합니다.
[-] Time-Stamp Counter Offset And Multiplier
VM-execution control
필드에는 64bit TSC Offset이 포함됩니다.
만약 RDTSC Exiting
필드(IA32_VMX_PROCBASED_CTL
내 bit 12) 값이 0이고, Use TSC Offsetting
필드(IA32_VMX_PROCBASED_CTL
내 bit 5) 값이 1인 경우 이 필드(TSC-Offset
)는 RDTSC
, RDTSCP
명령의 실행을 제어합니다.
또한 IA32_TIME_STAMP_COUNTER MSR
에서 읽는 RDMSR
명령의 실행을 제어합니다. 이 모든 것에 대해 TSC Offset 값이 TSC 값에 추가되고 합계가 EDX:EAX
의 게스트 소프트웨어로 반환됩니다.
use TSC scaling
필드(IA32_VMX_PROCBASED_CTLS2
내 bit 25) 값을 1으로의 설정을 지원하는 프로세서는 64bit TSC-Multiplier
필드도 지원합니다.
만약 RDSTSC Exiting
필드가 0이고, Use TSC Offsetting
필드가 1인 경우 이 필드(TSC-Multiplier
)는 위에서 식별된 RDTSC, RDTSCP, RDMSR
명령어의 실행에도 영향을 미칩니다.
특히 TSC의 값은 오프셋 값을 추가하기 전에 먼저 TSC-Multiplier
를 곱합니다.
[-] Guest/Host Masks and Read Shadows for CR0 and CR4
VM-execution control
필드에는 Guest/Host Mask와 CR0 및 CR4 에 대한 Read Shadow
가 포함됩니다.
이러한 필드는 해당 레지스터(CLTS, LMSW, MOV CR 및 SMSW 포함)에 접근하는 명령의 실행을 제어합니다.
일반적으로 Guest/Host Mask 에서 1로 설정된 비트는 Host 가 Owned
비트에 해당합니다.
- Guest가
CLTS, LMSW, MOV CR
을 사용하여 해당Read Shadow
의 비트와 다른 값을 설정하려고 시도하면VM Exit
가 발생합니다. - Guest가
MOV CR, SMSW
을 사용하면Read Shadow
에서 이러한 비트에 대한 값을 반환합니다.
Guest/Host Mask 에서 0으로 설정된 비트는 Guest Owned
비트에 해당합니다. Guest가 수정을 시도하면 성공하고 Guest는 Control Register 자체에서 이러한 비트에 대한 반환 값을 읽습니다.
64bit 또는 32bit 일 수 있습니다.
[-] CR3-Target Controls
VM-execution control
필드에는 4개의 CR3-Target
값과 CR3-Target
개수 세트가 포함됩니다. CR3-Target
값은 64bit or 32 bits이며, CR3-Target
개수는 32bit 입니다.
VMX Non-root operation
에서 CR3로 값을 복사하는 명령(MOV to CR3)을 실행해도 소스 피연산자가 이러한 값 중 하나와 일치하는 경우 VM Exit
가 발생하지 않습니다.
CR3-Target
개수가 n인 경우, 처음 n개의 CR3-Target
값만 고려됩니다. CR3-Target
개수가 0인 경우 MOV to CR3 가 발생하면 항상 VM Exit
가 발생합니다.
CR3-Target
값에 대해 쓸 수 있는 값에는 제한이 없습니다. CR3-Target
개수가 4보다 크면 VM Entry
가 실패합니다.
VMM
은 지원되는 값의 개수를 결정하기 위해 MSR IA32_VMX_MISC
를 읽어야 합니다.(bit 16-24)
[-] Controls for APIC Virtualization
VMM
이 논리 프로세서의 로컬 APIC
레지스터에 접근하는 세 가지 메커니즘이 있습니다.
- 로컬
APIC
가xAPIC
모드인 경우IA32_APIC_BASE MSR
의 물리 주소가 참조하는 4kb 페이지의 주소에 대한 메모리 매핑 액세스를 수행할 수 있습니다. - 로컬
APIC
가x2APIC
모드인 경우RDMSR, WRMSR
을 사용하여 로컬APIC
레지스터에 접근할 수 있습니다. - 64bit 모드에서는
MOV CR8
명령을 실행하여 로컬APIC
의TPR(Task-Priority Register)
에 접근할 수 있습니다.
이러한 접근을 제어하는 필드는 5가지로 Processor-Based VM-execution control
에 있습니다.(Primary&Secondary Control
)
use TPR shadow
, virtualize APIC accesses
, virtualize x2APIC mode
virtual-interrupt delivery
, APICregister virtualization
필드 입니다.
이러한 5가지 필드는 다음의 필드와 상호작용합니다.
- APIC-access address(64 bits)
- 이 필드는 4kb 크기의
APIC-access
페이지의 물리 주소를 포함합니다. - 만약
virtualize APIC accesses
(IA32_VMX_PROCBASED_CTLS2
내 bit 0) 값이 1인 경우, 이 페이지에 접근하면VM Exit
가 발생하거나 프로세서에 의해 해당 페이지가 가상화될 수 있습니다. APIC-access
주소는virtualize APIC accesses
를 1로 설정할 수 있는 프로세서에만 존재합니다.
- 이 필드는 4kb 크기의
- Virtual-APIC Address(64 bits)
- 이 필드는 4kb 크기의
Virtual-APIC
페이지의 물리 주소를 포함합니다. - 프로세서는
Virtual-APIC
페이지를 사용하여APIC
레지스터에 대한 특정 액세스를 가상화하고 가상 인터럽트를 관리합니다. - 앞에서 설명한 설정에 따라 다음 작업으로
Virtual-APIC
페이지에 접근할 수 있습니다.MOV CR8
명령어virtualize APIC accesses
필드가 1인 경우APIC-access
페이지에 액세스 합니다.ECX
값이 800h-8ffh 범위에 있고virtualize x2APIC mode
(IA32_VMX_PROCBASED_CTLS2
내 bit 4)가 1인 경우RDMSR, WRMSR
명령어.- 만약
use TPR shadow
(IA32_VMX_PROCBASED_CTLS
내 bit 21) 값이 1인 경우,VM Entry
는Virtual-APIC
의 주소가 4kb로 정렬되도록 합니다. Virtual-APIC
의 주소는use TPR shadow
필드를 1로 설정 가능한 프로세서에만 존재합니다.
- 만약
- 이 필드는 4kb 크기의
- TPR threshold(32 bits)
- 이 필드의
bit 3:0
은VTPR(Virtual Task-Priority Register)
의bit 7:4
가 떨어질 수 없는 임계 값을 결정합니다. - 만약
virtual-interrupt delivery
필드(IA32_VMX_PROCBASED_CTLS2
내 bit 9) 값이 0이면, 해당 비트의 값을TPR threshold
아래로 줄이는 작업(ex. MOV to CR8) 후에VM Exit
가 발생합니다. TPR threshold
는use TPR shadow
필드를 1로 설정 가능한 프로세서에서만 존재합니다.
- 이 필드의
- EOI-exit bitmap(4 fields, 64 bits each)
- 이 필드는
virtual-interrupt delivery
필드를 1로 설정 가능한 프로세서에서만 지원됩니다.APIC
의EOI(End Of Interrupt) Register
에 대한 가상화된write
로 인해VM Exit
가 발생하는 것을 결정하는데 사용합니다. EOI_EXIT0
: 0-63까지의 벡터에 대한 비트를 포함합니다.EOI_EXIT1
: 64-127까지의 벡터에 대한 비트를 포함합니다.EOI_EXIT2
: 128-191까지의 벡터에 대한 비트를 포함합니다.EOI_EXIT3
: 192-255까지의 벡터에 대한 비트를 포함합니다.
- 이 필드는
- Posted-Interrupt Notification Vecotr(16 bits)
- 이 필드는
process posted interrupts
필드(IA32_VMX_PINBASED_CTLS
내 bit 7) 값을 1로 설정 가능을 지원하는 프로세서에서만 지원됩니다. - 하위 8bit에는 가상 인터럽트가 게시(post)되었음을 논리 프로세서에게 알리는데 사용되는 인터럽트가 포함되어 있습니다.
- 이 필드는
- Posted-Interrupt Descriptor Address(64 bits)
- 이 필드는
process posted interrupts
필드 값을 1로 설정 가능을 지원하는 프로세서에서만 지원됩니다. - 64-byte로 정렬되있는
Posted-Interrupt
에 대한 설명자의 물리 주소 입니다.
- 이 필드는
[-] MSR-Bitmap Address
use MSR bitmaps
필드(IA32_VMX_PROCBASED_CTLS
내 bit 28) 값을 1로 설정 가능한 프로세서에만 존재합니다.
VM-execution control
필드에는 크기가 각 1kb인 4개의 연속되는 MSR Bitmap
의 64-bit 물리 주소가 포함됩니다.
4개의 연속되는 물리주소는 각 Read(RDMSR)
, Write(WRMSR)
에 대한 분류로 2가지로 나뉩니다.
- Read bitmap for low, high MSRs (
MSR-Bitmap
Base Address, Base Address + 1024)- low msr(00000000h - 00001FFFh), high msr(C0000000h - C0001FFFh) 범위의 각
MSR
주소에 대한 하나의 비트가 포함됩니다. - 이 비트는 해당
MSR
에 적용된RDMSR
의 실행이VM Exit
를 발생시키는지에 대한 여부를 결정합니다.
- low msr(00000000h - 00001FFFh), high msr(C0000000h - C0001FFFh) 범위의 각
- Write bitmap for low, high MSRs(BaseAddress + 2048, BaseAddress + 3072)
- low msr(00000000h - 00001FFFh), high msr(C0000000h - C0001FFFh) 범위의 각
MSR
주소에 대한 하나의 비트가 포함됩니다. - 이 비트는 해당
MSR
에 적용된WRMSR
의 실행이VM Exit
를 발생시키는지에 대한 여부를 결정합니다.
- low msr(00000000h - 00001FFFh), high msr(C0000000h - C0001FFFh) 범위의 각
논리 프로세서는 use MSR bitmaps
필드가 1인 경우에만 이러한 비트맵을 사용합니다. 비트맵이 사용되는 경우 RCX
값이 해당 범위에 없는 경우 RDMSR
, WRMSR
을 실행하면 VM Exit
가 발생합니다.
위의 설명에 있듯이 비트맵이 사용되는 경우 해당 주소는 4kb 로 정렬되어야 합니다.
[-] Executive-VMCS Pointer
Executive-VMCS Pointer
는 System Management Interrupt(SMI)
및 System Management Mode(SMM)
의 이중 모니터 처리에 사용되는 64bit 필드입니다.
[-] Extended-Page-Table Pointer (EPTP)
EPTP
는 EPT PML4
테이블의 기본 주소와 기타 EPT
의 구성 정보가 포함됩니다. 해당 내용은 이후에 가상화에서의 페이징과 관련한 내용에서 자세하게 다룹니다.
EPTP
는 enable EPT
필드(IA32_VMX_PROCBASED_CTLS2
내 bit 1) 값을 1로 설정을 지원하는 프로세서에만 존재합니다.
- Bit 0:2 까지는
EPT Paging-Structure
에 대한 메모리 유형을 결정하는데 사용됩니다.VMM
은 지원되는 메모리 유형을 결정하기 위해MSR IA32_VMX_EPT_VPID_CAP
을 읽어야 합니다. - Bit 6 은
EPT
에 대한 접근과Dirty Flag
지원에 대한 필드 입니다. 다만 모든 프로세서에서 이를 지원하는 것은 아닙니다. 때문에VMM
은 마찬가지로MSR IA32_VMX_EPT_VPID_CAP
을 읽어야 합니다. - Bit 7 은
Shadow-stack page
의 접근 권한을 적용하는 것에 대한 필드입니다. 마찬가지로MSR IA32_VMX_EPT_VPID_CAP
을 읽어 지원 여부를 확인해야 합니다. - Bit 12부터
N-1
까지는 4kb로 정렬된EPT PML4 Table
의 물리 주소 비트 입니다. 여기서N
은 논리 프로세서가 지원하는 물리 주소의 너비 입니다.VMM
은CPUID
실행에EAX
값을8000'0008h
로 실행하여 프로세서의 물리 주소 너비를 확인할 수 있습니다. 물리 주소의 너비는EAX
의 bit 7:0 에서 반환됩니다.
typedef struct _EXTENDED_PAGE_TABLE_POINTER
{
union
{
ULONG64 Features;
struct
{
/*
* EPT paging-structure memory type (see Section 28.3.7): 0 = Uncacheable (UC) 6 = Write-back (WB) Other values are reserved.
*/
ULONG64 EPTPagingStructureMemoryType : 3; // 00-02
/*
* This value is 1 less than the EPT page-walk length (see Section 28.3.2)
*/
ULONG64 EPTPageWalkLength : 3; // 03-05
/*
* Setting this control to 1 enables accessed and dirty flags for EPT (see Section 28.3.5)
*/
ULONG64 EnableAccessAndDirtyFlags : 1; // 06
/*
* Setting this control to 1 enables enforcement of access rights for supervisor shadow-stack pages (see Section 28.3.3.2)
*/
ULONG64 EnableAccessForSupervisorShadowStackPage : 1; // 07
ULONG64 Reserved_1 : 4; // 08-11
/*
* Bits N–1:12 of the physical address of the 4-KByte aligned EPT PML4 table
*/
ULONG64 PageFrameNumber : 36; // 12-47
ULONG64 Reserved_2 : 16; // 48-63
}Fields;
};
}EPTP, * PEPTP;
[-] Virtual-Processor Identifier(VPID)
가상 프로세서 식별자라고 불리는 VPID
는 16bit 의 필드 입니다. enable VPID
필드(IA32_VMX_PROCBASED_CTLS2
내 bit 5) 값의 설정을 1로 지원하는 프로세서에만 존재합니다.
[-] Controls for PAUSE-Loop Exiting
PAUSE-loop exiting
필드(IA32_VMX_PROCBASED_CTLS2
bit 10) 값의 설정을 1로 지원하는 프로세서에서 존재하며, 32 bit의 필드가 포함됩니다.
[-] VM-Function Controls
VM-Function Control
은 VMX non-root operation
에서 VMFUNC
명령의 사용을 제어하는 64bit의 벡터를 구성합니다.
해당 필드는 activate secondary controls
필드(IA32_VMX_PROCBASED_CTLS
내 bit 31) 값과 enable VM functions
필드(IA32_VMX_PROCBASED_CTLS2
내 bit 13) 값을 1로 설정 가능한 프로세서 에서만 지원됩니다.
VMM
은 비트를 결정하기 위해 MSR IA32_VMX_VMFUNC(0x491)
을 참조해야 합니다.
#define IA32_VMX_VMFUNC_MSR 0x491
typedef struct _IA32_VMX_VMFUNC
{
union
{
ULONG64 Features;
struct
{
ULONG64 EPTPSwitching : 1; // 00
ULONG64 Reserved : 63; // 01-63
}Fields;
};
}IA32_VMX_VMFUNC;
EPTP switching
필드의 값을 1로 설정을 지원하는 프로세서는 EPTP-list address
라고 하는 64bit 필드도 지원합니다. 이 필드는 4kb EPTP list의 물리 주소를 포함합니다. EPTP List
는 512개의 8-byte 엔트리(각 EPTPT
)로 구성되며 EPTP-switching
에 의해 사용됩니다.[-] VMCS Shadowing Bitmap Addresses
VMCS Shadowing
필드(IA32_VMX_PROCBASED_CTLS2
내 bit 14) 값을 1로 설정을 지원하는 프로세서에서 VM-execution control
필드에는 VMREAD
Bitmap, VMWRITE
Bitmap 의 각 64bit 물리 주소가 포함됩니다.
[-] ENCLS-Exiting Bitmap
ENCLS-Exiting Bitmap
은 64bit 필드 입니다. enable ENCLS Exiting
필드(IA32_VMX_PROCBASED_CTLS2
내 bit 15) 값이 1인 경우 EAX
값에 이 비트가 1이면 ENCLS
를 실행하면 VM Exit
가 발생합니다.
[-] ENCLV-Exiting Bitmap
ENCLS-Exiting Bitmap
설명과 동일합니다. neable ENCLV exiting
필드(IA32_VMX_PROCBASED_CTLS2
내 bit 28) 값이 1인 경우 EAX
값에 해당 비트가 1인 상태에서 ENCLV
가 실행되면 VM Exit
가 발생합니다.
[-] PCONFIG-Exiting Bitmap
64bit 필드이며, Enable PCONFIG
필드(IA32_VMX_PROCBASED_CTLS2
내 bit 27) 값이 1인 경우 EAX
값에 해당하는 비트가 1인 상태에서 PCONFIG
명령을 실행하면 VM Exit
가 발생합니다.
[-] Control Field for Page-Modification Logging
Page-Modification Logging
주소는 64bit 필드 입니다. 페이지 수정 로그의 4kb로 정렬된 주소 입니다. 페이지 수정 로그는 512개의 64bit 엔트리로 구성됩니다.
Enable PML
필드(IA32_VMX_PROCBASED_CTLS2
내 bit 17) 값이 1인 경우 VM Entry
는 Page-Modification Logging
주소가 4kb 로 정렬되도록 합니다. 마찬가지로 1로의 설정을 지원하는 프로세서에만 지원됩니다.
[-] Control for Virtualization Exceptions
EPT-violation #VE
필드(IA32_VMX_PROCBASED_CTLS2
내 bit 18) 값의 1로 설정을 지원하는 프로세서에서 VM-execution control
필드에는 다음 필드가 포함됩니다.
- Virtualization-exception information address(64 bits)
- 이 필드는
Virtualization-exception
정보 영역의 물리 주소가 포함됩니다. - 논리 프로세서에서 가상화 예외가 발생하면 가상화 예외 정보 주소에 가상화 예외 정보를 저장합니다.
- 이 필드는
- EPTP Index(16 bits)
EPT Violation
으로 인해 가상화 예외가 발생하면 프로세서는 이 필드의 값을 가상화 예외 정보 영역에 저장합니다.EPTP-Switching
은 이 필드를 업데이트 합니다.
[-] XSS-Exiting Bitmap
enable XSAVES/XRSTORS
필드(IA32_VMX_PROCBASED_CTLS2
내 bit 20) 값을 1로 설정 가능한 프로세서에서 VM-execution control
필드에는 64bit의 XSS-Exiting Bitmap
이 포함됩니다.
만약 enable XAVES/XRSTORS
필드가 1인 경우 XSAVES
, XRSTORS
의 실행은 이 비트맵을 참조합니다.
[-] Sub-Page-Permission-Table Pointer(SPPTP)
sub-page write-permission feature of EPT
필드(IA32_VMX_PROCBASED_CTLS2
내 bit 23) 값이 활성화된 경우 EPT
쓰기 권한은 128-byte 단위로 결정될 수 있습니다. 이러한 권한은 메모리의 하위 페이지 권한 구조 계층을 사용하여 결정됩니다.
sub-page write-permission feature of EPT
필드 값을 1로 설정 가능한 프로세서에서만 존재합니다.
// Sub-Page-Permission-Table Pointer
typedef struct _SPPT_POINTER
{
union
{
ULONG64 Featurs;
struct
{
ULONG64 Reserved_1 : 12; // 00-11
ULONG64 SPPTablePyhsicalAddress : 36; // 12-47
ULONG64 Reserved_2 : 16; // 48-63
}Fields;
};
}SPPTP, * PSPPTP;
[-] Fields Related to Hypervisor-Managed Linear-Address Translation(HLAT)
Enable HLAT
필드(IA32_VMX_PROCBASED_CTLS3
내 bit 1) 값이 1로 설정된 경우 두 개의 필드(PWT, PCD
)가 사용되어 HLAT
페이징을 활성화 합니다.
Hypervisor-Managed Linear-Address Translation Pointer(HLAT Pointer 또는 HLATP)
는 선형 주소 변환에 사용되는 첫 번째 페이징 구조를 찾고 접근하기 위해 HLAT
페이징에서 사용됩니다.
// Hypervisor-Managed Linear-Address Translation Pointer
typedef struct _HLAT_POINTER
{
union
{
ULONG64 Features;
struct
{
ULONG64 Reserved_1 : 3; // 00-02
/*
* Page-level write-through; indirectly determines the memory type used to access the first HLAT paging structure during linear-address translation
*/
ULONG64 PWT : 1; // 03
/*
* Page-level cache disable; indirectly determines the memory type used to access the first HLAT paging structure during linear-address translation.
*/
ULONG64 PCD : 1; // 04
ULONG64 Reserved_2 : 7; // 05-11
/*
* Guest-physical address (4KB-aligned) of the first HLAT paging structure during linear-address translation.
*/
ULONG64 GuestPhysicalAddress : 36; // 12-47
ULONG64 Reserved_3 : 16; // 48-63
}Fields;
};
}HLATP, * PHLATP;
[0x05] VM-Exit Control Fields
VM-Exit Control
필드는 VM Exit
동작을 제어 합니다.
VM-Exit Control
은 VM Exit
의 기본 동작을 제어하는 두 개의 벡터로 구성됩니다. 각각 Primary VM-exit controls(32 bits)
, Secondary VM-exit controls(64 bits)
입니다.
이후에는 Primary, Secondary Exit Control
으로 작성됩니다.
[-] Primary VM-Exit Controls
이 필드의 다른 모든 비트는 예약되어 있으며 일부는 0이고 일부는 1 입니다. VMM
은 예약된 비트를 설정하는 방법을 결정하기 위해 MSR IA32_VMX_EXIT_CTLS(0x483)
, MSR IA32_VMX_TRUE_EXIT_CTLS(0x48F)
를 참조해야 합니다.
MSR IA32_VMX_EXIT_CTLS
는 bit 0-8, 10-11, 13-14, 16, 17 에 대해 항상 1로 설정되어야 한다고 보고되었습니다.
이러한 비트의 0으로의 설정을 지원하는 논리 프로세서는 IA32_VMX_TRUE_EXIT_CTLS
를 지원하며, VMM
은 이 MSR
을 참조하여 해당 비트를 0으로의 설정에 대한 지원 여부를 확인해야 합니다.
#define IA32_VMX_EXIT_CTLS_MSR 0x483
#define IA32_VMX_TRUE_EXIT_CTLS_MSR 0x48F
typedef struct _IA32_VMX_EXIT_CTLS
{
union
{
ULONG64 Features;
struct
{
ULONG64 Reserved_1 : 2; // 00-01
/*
* This control determines whether DR7 and the IA32_DEBUGCTL MSR are saved on VM exit.
* The first processors to support the virtual-machine extensions supported only the 1-setting of this control.
*/
ULONG64 SaveDebugControls : 1; // 02
ULONG64 Reserved_2 : 6; // 03-08
/*
* On processors that support Intel 64 architecture, this control determines whether a logical processor is in 64-bit mode after the next VM exit.
* Its value is loaded into CS.L, IA32_EFER.LME, and IA32_EFER.LMA on every VM exit.
* This control must be 0 on processors that do not support Intel 64 architecture.
*/
ULONG64 HostAddressSpaceSize : 1; // 09
ULONG64 Reserved_3 : 2; // 10-11
/*
* This control determines whether the IA32_PERF_GLOBAL_CTRL MSR is loaded on VM exit.
*/
ULONG64 Load_IA32_PERF_GLOBAL_CTRL : 1; // 12
ULONG64 Reserved_4 : 2; // 13-14
/*
* This control affects VM exits due to external interrupts:
* - If such a VM exit occurs and this control is 1, the logical processor acknowledges the interrupt controller, acquiring the interrupt's vector.
The vector is stored in the VM-exit interruption-information field, which is marked valid.
* - If such a VM exit occurs and this control is 0, the interrupt is not acknowledged and the VM-exit interruption-information field is marked invalid.
*/
ULONG64 AcknowledgeInterruptOnExit : 1; // 15
ULONG64 Reserved_5 : 2; // 16-17
/*
* This control determines whether the IA32_PAT MSR is saved on VM exit.
*/
ULONG64 Save_IA32_PAT : 1; // 18
/*
* This control determines whether the IA32_PAT MSR is loaded on VM exit.
*/
ULONG64 Load_IA32_PAT : 1; // 19
/*
* This control determines whether the IA32_EFER MSR is saved on VM exit.
*/
ULONG64 Save_IA32_EFER : 1; // 20
/*
* This control determines whether the IA32_EFER MSR is loaded on VM exit.
*/
ULONG64 Load_IA32_EFER : 1; // 21
/*
* This control determines whether the value of the VMX-preemption timer is saved on VM exit
*/
ULONG64 Save_VMX_PreemptionTimerValue : 1; // 22
/*
* This control determines whether the IA32_BNDCFGS MSR is cleared on VM exit.
*/
ULONG64 Clear_IA32_BNDCFGS : 1; // 23
/*
* If this control is 1, Intel Processor Trace does not produce a paging information packet (PIP) on a VM exit or a VMCS packet on an SMM VM exit (see Chapter 32).
*/
ULONG64 Conceal_VMXfromPT : 1; // 24
/*
* This control determines whether the IA32_RTIT_CTL MSR is cleared on VM exit.
*/
ULONG64 Clear_IA32_RTIT_CTL : 1; // 25
/*
* This control determines whether the IA32_LBR_CTL MSR is cleared on VM exit
*/
ULONG64 Clear_IA32_LBR_CTL : 1; // 26
ULONG64 Reserved_6 : 1; // 27
/*
* This control determines whether CET-related MSRs and SPP are loaded on VM exit.
*/
ULONG64 Load_CETState : 1; // 28
/*
* This control determines whether the IA32_PKRS MSR is loaded on VM exit
*/
ULONG64 Load_PKRS : 1; // 29
/*
* This control determines whether the IA32_PERF_GLOBAL_CTL MSR is saved on VM exit.
*/
ULONG64 Save_IA32_PERF_GLOBAL_CTL : 1; // 30
/*
* This control determines whether the secondary VM-exit controls are used. If this control is 0, the logical processor operates as if all the secondary VM-exit controls were also 0.
*/
ULONG64 Activate_SecondaryControls : 1; // 31
ULONG64 Reserved_7 : 32; // 32-63
}Fields;
};
}IA32_VMX_EXIT_CTLS, * PIA32_VMX_EXIT_CTLS;
현재는 Secondary Exit Control
이 정의되지 않아 해당 부분은 0으로 예약되어 있습니다.
[-] VM-Exit Controls for MSRs
VMM
은 VM Exit
발생 시 저장하고 로드할 MSR
목록을 지정할 수 있습니다. 다음 필드는 MSR
이 VM Exit
에 의해 저장되는 방식을 결정합니다.
- VM-exit MSR-store(load) count(32 bits)
- 이 필드는
VM Exit
에서 저장, 로드할MSR
의 개수를 지정합니다. 해당 개수는 512개를 초과하지 않는 것이 좋습니다. 그렇지 않으면 예측할 수 없는 문제가 발생할 수 있습니다.
- 이 필드는
- VM-exit MSR-store(load) address(64 bits)
- 이 필드는
VM-exit MSR-store(load) Area
의 물리 주소를 포함합니다. - 이 영역은 엔트리 당 16-byte 의 엔트리 테이블로, 엔트리 수는
VM-exit MSR-store(load) count
로 지정됩니다.
- 이 필드는
// MSR store & load entry
typedef struct _MSR_ENTRY
{
union
{
ULONG64 Header;
struct
{
ULONG64 MSRIndex : 32; // 00-31
ULONG64 Reserved : 32; // 32-64
}Fields;
};
union
{
ULONG64 MSRData;
struct
{
ULONG64 Reserved : 64; // 00-63
}Fields;
};
}MSR_ENTRY, *PMSR_ENTRY;
typedef struct _VMX_VMEXIT_MSR_TABLE
{
MSR_ENTRY* MSREntry; // safe limit count 512
}VMX_VMEXIT_MSR_TABLE, * PVMX_VMEXIT_MSR_TABLE;
[0x06] VM-Entry Control Fields
VM-Entry Control
필드는 VM Entry
동작을 제어합니다.
VM-Entry Control
은 VM Entry
의 기본 동작을 제어하는 32bit인 하나의 벡터로 구성됩니다.
[-] VM-Entry Controls
이 필드의 다른 모든 비트는 예약되어 있으며 일부는 0이고 일부는 1 입니다. VMM
은 예약된 비트를 설정하는 방법을 결정하기 위해 MSR IA32_VMX_ENTRY_CTLS(0x484)
, MSR IA32_VMX_TRUE_ENTRY_CTLS(0x490)
를 참조해야 합니다.
MSR IA32_VMX_ENTRY_CTLS
는 bit 0-8, 12 에 대해 항상 1로 설정되어야 한다고 보고되었습니다.
이러한 비트의 0으로의 설정을 지원하는 논리 프로세서는 IA32_VMX_TRUE_ENTRY_CTLS
를 지원하며, VMM
은 이 MSR
을 참조하여 해당 비트를 0으로의 설정에 대한 지원 여부를 확인해야 합니다.
#define IA32_VMX_ENTRY_CTLS_MSR 0x484
#define IA32_VMX_TRUE_ENTRY_CTLS_MSR 0x490
typedef struct _IA32_VMX_ENTRY_CTLS
{
union
{
ULONG64 Features;
struct
{
ULONG64 Reserved_1 : 2; // 00-01
/*
* This control determines whether DR7 and the IA32_DEBUGCTL MSR are loaded on VM entry.
* The first processors to support the virtual-machine extensions supported only the 1-setting of this control.
*/
ULONG64 LoadDebugControls : 1; // 02
ULONG64 Reserved_2 : 6; // 03-08
/*
* On processors that support Intel 64 architecture, this control determines whether the logical processor is in IA-32e mode after VM entry.
* Its value is loaded into IA32_EFER.LMA as part of VM entry. (This control must be 0 on processors that do not support Intel 64 architecture.)
*/
ULONG64 IA32eModeGuest : 1; // 09
/*
* This control determines whether the logical processor is in system-management mode (SMM) after VM entry. This control must be 0 for any VM entry from outside SMM.
*/
ULONG64 EntryToSMM : 1; // 10
/*
* If set to 1, the default treatment of SMIs and SMM is in effect after the VM entry (see Section 31.15.7). This control must be 0 for any VM entry from outside SMM
*/
ULONG64 DeactivateDualMonitorTreatment : 1; // 11
ULONG64 Reserved_3 : 1; // 12
/*
* This control determines whether the IA32_PERF_GLOBAL_CTRL MSR is loaded on VM entry.
*/
ULONG64 Load_IA32_PERF_GLOBAL_CTRL : 1; // 13
/*
* This control determines whether the IA32_PAT MSR is loaded on VM entry.
*/
ULONG64 Load_IA32_PAT : 1; // 14
/*
* This control determines whether the IA32_EFER MSR is loaded on VM entry.
*/
ULONG64 Load_IA32_EFER : 1; // 15
/*
* This control determines whether the IA32_BNDCFGS MSR is loaded on VM entry.
*/
ULONG64 Load_IA32_BNDCFGS : 1; // 16
/*
* If this control is 1, Intel Processor Trace does not produce a paging information packet (PIP) on a VM entry or a VMCS packet on a VM entry that returns from SMM (see Chapter 32).
*/
ULONG64 Conceal_VMXfromPT : 1; // 17
/*
* This control determines whether the IA32_RTIT_CTL MSR is loaded on VM entry.
*/
ULONG64 Load_IA32_RTIT_CTL : 1; // 18
ULONG64 Reserved_4 : 1; // 19
/*
* This control determines whether CET-related MSRs and SPP are loaded on VM entry.
*/
ULONG64 Load_CETState : 1; // 20
/*
* This control determines whether the IA32_LBR_CTL MSR is loaded on VM entry
*/
ULONG64 Load_Guest_IA32_LBR_CTL : 1; // 21
/*
* This control determines whether the IA32_PKRS MSR is loaded on VM entry.
*/
ULONG64 Load_PKRS : 1; // 22
ULONG64 Reserved_5 : 10; // 23-31
/*
* It's actually 32 bits, but for unity, it's aligned to 64 bits.
*/
ULONG64 Reserved_6 : 32; // 32-63
}Fields;
};
}IA32_VMX_ENTRY_CTLS, * PIA32_VMX_ENTRY_CTLS;
[-] VM-Entry Conrols for MSRs
VMM
은 VM Entry
에 로드 할 MSR
목록을 지정할 수 있습니다.
- VM-entry MSR-load count(32 bits)
- 이 필드는
VM Entry
에서 저장, 로드할MSR
의 개수를 지정합니다. 해당 개수는 512개를 초과하지 않는 것이 좋습니다. 그렇지 않으면 예측할 수 없는 문제가 발생할 수 있습니다.
- 이 필드는
- VM-entry MSR-load Address(64 bits)
- 이 필드는
VM-entry MSR-load Area
의 물리 주소를 포함합니다. - 이 영역은 엔트리 당 16-byte 의 엔트리 테이블로, 엔트리 수는
VM-entry MSR-load count
로 지정됩니다.
- 이 필드는
[-] VM-Entry Controls for Event Injection
VM Entry
는 IDT(모든 게스트 상태 및 MSR이 로드된 후)
를 통해 이벤트를 전달하여 종료되도록 구성할 수 있습니다.
이러한 과정을 이벤트 주입이라고 하며 다음 세 가지 VM-entry control fields
에 의해 제어됩니다.
- VM-entry interruption-information field(32 bits)
- 주입 할 이벤트에 대한 세부 정보를 제공합니다.
typedef struct _VMX_VMENTRY_INTERRUPT_INFORMATION
{
union
{
ULONG64 Features;
struct
{
/*
* Vector of interrupt or exception
*/
ULONG64 Vector : 8; // 00-07
/*
* Interruption type:
* 0: External interrupt
* 1: Reserved
* 2: Non-maskable interrupt (NMI)
* 3: Hardware exception (e.g,. #PF)
* 4: Software interrupt (INT n)
* 5: Privileged software exception (INT1)
* 6: Software exception (INT3 or INTO)
* 7: Other event
*/
ULONG64 InterruptType : 3; // 08-10
/*
* Deliver error code (0 = do not deliver; 1 = deliver)
*/
ULONG64 DeliverErrorCode : 1; // 11
ULONG64 Reserved_1 : 19; // 12-30
ULONG64 Valid : 1; // 31
/*
* It's actually 32 bits, but for unity, it's aligned to 64 bits.
*/
ULONG64 Reserved_2 : 32; // 32-63
}Fields;
};
}VMX_VMENTRY_INTERRUPT_INFORMATION, * PVMX_VMENTRY_INTERRUPT_INFORMATION;
- VM-entry exception error code(32 bits)
- 이 필드는 interruption information 필드 내
Valid
비트와delivererror-code
비트가 모두 설정된 경우에만 사용됩니다.
- 이 필드는 interruption information 필드 내
- VM-entry instruction length(32 bits)
- 인터럽트, 예외 유형의 이벤트 주입인 경우 이 필드는 스택에 푸시되는
RIP
값을 결정하는데 사용됩니다.
- 인터럽트, 예외 유형의 이벤트 주입인 경우 이 필드는 스택에 푸시되는
VM Exit
는 VM-entry interruption-information
필드에서 Valid
비트를 지웁니다.
[0x07] VM-Exit Information Fields
해당 필드는 가장 최근의 VM Exit
가 발생한 것에 대한 정보가 포함된 필드 입니다. 일부 프로세서에서는 VMWRITE
를 이용하여 이러한 필드에 쓰기를 시도하는 경우 실패합니다.
[-] Basic VM-Exit Information
다음의 VM-exit information
필드는 VM Exit
에 대한 기본 정보를 제공합니다.
- Exit Reason(32 bits)
- 이 필드는
VM Exit
이유를 인코딩하며, 아래의 구조로 구성되어 있습니다.
typedef struct _VMX_VMEXIT_REASON { union { ULONG Features; struct { /* * Basic Exit Reason */ ULONG BasicExitReason : 16; // 00-15 /* * Always cleared to 0 */ ULONG AlwaysZero : 1; // 16 ULONG Reserved_1 : 10; // 17-26 /* * A VM exit saves this bit as 1 to indicate that the VM exit was incident to enclave mode */ ULONG bEnclaveMOde : 1; // 27 /* * Pending MTF VM exit */ ULONG PendingMTF : 1; // 28 /* * VM exit from VMX root operation */ ULONG ExitFromRootOperation : 1; // 29 ULONG Reserved_2 : 1; // 30 /* * VM-entry failure (0 = true VM exit; 1 = VM-entry failure) */ ULONG VMEntryFailure : 1; // 31 }Fields; }; }VMX_VMEXIT_REASON, * PVMX_VMEXIT_REASON;
- 이 필드는
- Exit qualification(64 bits or 32 bits)
- 이 필드에는 다음으로 인한
VM Exit
원인에 대한 추가 정보가 포함됩니다. 필드의 형식은 원인에 따라 다릅니다.
debug exceptions page-fault exceptions startup IPIs(SIPIs) task switchs INVEPT, INVLPG, INVVPID LGDT, LIDT, LLDT, LTR, SGDT, SIDT, SLDT, STR VMCLEAR, VMPTRLD, VMPTRST, VMREAD, VMWRITE, VMXON XRSTORS, XSAVES Control Register Accesses MOV DR I/O Instruction MWAIT
- 이 필드에는 다음으로 인한
- Guest-linear address(64 bits or 32 bits)
- 이 필드는 아래의 경우에 사용됩니다.
- LMSW 을 메모리 피연산자와 사용하여
VM Exit
가 발생한 경우 INS
또는OUTS
실행 시도로 인해VM Exit
가 발생한 경우- I/O 명령어가 폐기된 이후에 도착한
SMI(System Management Interrupt)
로 인해VM Exit
가 발생한 경우 EPT Violation
으로 인한VM Exit
발생
- LMSW 을 메모리 피연산자와 사용하여
- 이 필드는 아래의 경우에 사용됩니다.
- Guest-physical address(64 bits)
- 이 필드는
EPT Violation
및EPT Misconfiguration
으로 인해VM Exit
가 발생하는 경우 사용됩니다.
- 이 필드는
[-] Information for VM Exits Due to Vectored Events
벡터 이벤트로 인해 VM Exit
에 대한 이벤트별 다음과 같은 정보가 제공됩니다.
Exceptions(INT3, INT0, INT1, BOUND, UD0, UD1, UD2 포함)
VM-Exit Control 내 "acknowledge interrupt on exit" 비트가 1인 동안 발생하는 외부 인터럽트
Non-maskable 인터럽트(NMIs)
- VM-exit interruption information(32 bits)
- 이 필드는
VM Exit
를 발생시키는 이벤트와 관련된 기본 정보를 수신합니다.
typedef struct _VMX_VMEXIT_INTERRUPT_INFORMATION { union { ULONG64 Features; struct { /* * Vector of interrupt or exception */ ULONG64 Vector : 8; // 00-07 /* * Interruption type: * 0: External interrupt * 1: Not used * 2: Non-maskable interrupt (NMI) * 3: Hardware exception * 4: Software interrupt * 5: Privileged software exception * 6: Software exception * 7: Other event */ ULONG64 InterruptType : 3; // 08-10 /* * Error code valid (0 = invalid; 1 = valid) */ ULONG64 ErrorCode : 1; // 11 /* * NMI unblocking due to IRET */ ULONG64 UnblockNMI_IRET : 1; // 12 ULONG64 Reserved_1 : 19; // 13-30 ULONG64 Valid : 1; // 31 /* * It's actually 32 bits, but for unity, it's aligned to 64 bits. */ ULONG64 Reserved_2 : 32; // 32-63 }Fields; }; }VMX_VMEXIT_INTERRUPT_INFORMATION, * PVMX_VMEXIT_INTERRUPT_INFORMATION;
- 이 필드는
- VM-exit interruption error code(32 bits)
- 스택에 오류 코드를 전달했을 때 하드웨어 예외로 인한
VM Exit
일 경우 이 필드는 해당 오류 코드를 수신합니다.
- 스택에 오류 코드를 전달했을 때 하드웨어 예외로 인한
[-] Information for VM Exits That Occur During Event Delivery
VMX Non-root operation
에서 이벤트 전달 중 발생하는 VM Exit
에 대한 추가 정보를 제공합니다. 이 정보는 다음 필드를 통해 전달됩니다.
- IDT-vectoring information(32 bits)
- 이 필드는
VM Exit
가 발생할 때 전달되고 있던 이벤트와 관련된 기본 정보를 수신합니다. 대부분의 인터럽트 정보는 유사합니다.
- 이 필드는
- IDT-vectoring error code(32 bits)
- 스택에 오류 코드를 전달했을 때 하드웨어 예외 전달 중에 발생하는
VM Exit
의 경우 이 필드는 해당 오류 코드를 수신합니다.
- 스택에 오류 코드를 전달했을 때 하드웨어 예외 전달 중에 발생하는
[-] Information for VM Exits Due to Instruction Execution
다음 필드는 VMX Non-root operation
에서 특정 명령을 실행하려는 시도로 인해 VM Exit
가 발생하는 경우에 사용 되는 정보 입니다.
- VM-exit instruction length(32 bits)
- 특정 명령 실행으로 인한
VM Exit
발생의 경우 이 필드는VM Exit
로 이어진 명령어의 길이를 바이트 단위로 수신합니다.
- 특정 명령 실행으로 인한
- VM-exit instruction information(32 bits)
- 이 필드는 아래의 명령 실행 시도로 인한
VM Exit
발생 시 사용됩니다.
INS, OUTS INVEPT, INVVPID LIDT, LGDT, LLDT, LTR SIDT, SGDT, SLDT, STR VMCLEAR, VMPTRLD, VMPTRSR, VMREAD, VMWRITE, VMXON
- 이 필드는 아래의 명령 실행 시도로 인한
- I/O RCX, RSI, RDI, RIP(each 64 bits)
- 각 64bit인 해당 필드들은 I/O 명령 폐기 이후 도착하는
SMI
로 인해VM Exit
가 발생한 경우 사용됩니다. - I/O 명령이 시작 되기 전의 RCX, RSI, RDI, RIP(I/O 명령을 처리한 RIP) 값입니다.
- 각 64bit인 해당 필드들은 I/O 명령 폐기 이후 도착하는
[-] VM-Instruction Error Fields
32bit 로 이루어진 이 필드는 가장 최근에 발생한 VM Exit
에 대한 정보를 제공하지 않습니다. 대신 VMX
명령 중 하나를 오류 없이 실행할 때 발생하는 오류에 대한 정보를 제공합니다.
[0x08] VMCS Types : Ordinary and Shadow
모든 VMCS
는 일반적인 VMCS
와 Shadow VMCS
로 나눠집니다. VMCS Type
은 VMCS Region
의 shadow-VMCS indicator
필드(VMCS Region
내 bit 31) 값에 의해 결정 됩니다.
해당 값이 0인 경우 Ordinary VMCS
이고, 1인 경우 Shadow VMCS
를 나타냅니다.
Shadow VMCS
는 VMCS Shadowing
필드(IA32_VMX_PROCBASED_CTLS2
내 bit 14) 값을 1로 설정을 지원하는 프로세서 에서만 지원됩니다.
Shadow VMCS
는 Ordinary VMCS
와 두 가지 면에서 다릅니다.
Ordinary VMCS
는VM Entry
를 사용할 수 있지만Shadow VMCS
는 사용할 수 없습니다. 현재VMCS
가Shadow VMCS
일 때VM Entry
를 시도하면 실패합니다.VMREAD, VMWRITE
명령어는VMX Non-root operation
에서Shadow VMCS
에 접근하기 위해 사용할 수 있지만Ordinary VMCS
에는 접근할 수 없습니다. 이는 아래와 같은 이유 때문입니다.- 만약
VMCS shadowing
비트가 0인 경우,VMX Non-root operation
에서VMREAD, VMWRITE
명령을 실행하면 항상VM Exit
가 발생합니다. - 만약
VMCS shadowing
비트가 1인 경우,VMX Non-root operation
에서VMREAD, VMWRITE
명령을 실행하면VMCS Link Pointer
가 참조하는VMCS
에 접근할 수 있습니다. - 만약
VMCS shadowing
비트가 1인 경우,VM Entry
는VMCS Link Pointer
가 참조하는 모든VMCS
가Shadow VMCS
임을 보장합니다.
- 만약
VMX Root operation
에서 VMREAD, VMWRITE
명령어를 사용하여 두 가지 유형의 VMCS
에 모두 액세스 할 수 있습니다.
VMM
은 Active
상태의 VMCS
의 VMCS Region
에 있는 shadow-VMCS indicator
를 수정해서는 안됩니다. 그렇게 되면 VMCS
가 손상될 수 있습니다.
shadow-VMCS indicator
를 수정하기 전에 VMM
은 VMCS
의 활성 여부에 대해 확인하기 위해 VMCLEAR
를 실행해야 합니다.
[0x09] Remarks
매우 많은 내용의 VMCS Data
에 대해 알아보았습니다. 실제로 구현에 따라 사용되지 않는 데이터도 매우 많을 것으로 보입니다.
우선 위의 내용들을 토대로 프로그래밍을 하기 전에, 마지막으로 관련된 데이터를 사용할 때 VMM
이 준수해야 하는 여러가지 지침에 대해 알아보겠습니다.
기본적으로 VMCS
활성화 여부에 대한 지침이 존재합니다. 이는 이전 챕터에서도 작성하였기 때문에 넘어가겠습니다.
[-] VMREAD, VMWRITE, and Encodings of VMCS Fields
VMCS
의 모든 필드는 32 bit의 값의 인코딩 값과 연관되어 있습니다. VMM
은 해당 필드를 읽거나 쓰기를 원할 때 VMREAD, VMWRITE
명령에 대한 피연산자로 인코딩 된 값을 제공해야 합니다.
이러한 명령어는 64bit 모드에서 인코딩 비트를 bit 32 이상으로 설정하여 전달하면 실패합니다.
VMCS
구성요서의 32bit 인코딩 구조는 주로 VMCS
에서 너비와 기능에 따라 결정됩니다.
typedef struct _VMCS_COMPONENT_ENCODING
{
union
{
ULONG Features;
struct
{
/*
* Access type (0 = full; 1 = high); must be full for 16-bit, 32-bit, and natural-width fields
*/
ULONG AccessType : 1; // 00
/*
* Index
*/
ULONG Index : 9; // 01-09
/*
* Type:
* 0: control
* 1: VM-exit information
* 2: guest state
* 3: host state
*/
ULONG Type : 2; // 10-11
ULONG Reserved_1 : 1; // 12
/*
* Width:
* 0: 16-bit
* 1: 64-bit
* 2: 32-bit
* 3: natural-width
*/
ULONG Width : 2; // 13-14
ULONG Reserved_2 : 17; // 15-31
}Fields;
};
}VMCS_COMPONENT_ENCODING, * PVMCS_COMPONENT_ENCODING;
각 필드에 대한 자세한 설명은 아래와 같습니다.
- Field Width(bits 14:13)
- 필드의 너비를 나타냅니다.
nature-width
는 프로세서에 따라 64bit or 32 bits 인 필드입니다.
- 필드의 너비를 나타냅니다.
- Field Type(bits 11:10)
VMX Control
,VM-Exit information
,Guest-State
,Host-State
으로 선택할 수 있습니다.
- Index(Bits 9:1)
- 필드 너비와 유형이 동일한 구성 요소를 구별합니다.
때문에 지금까지 학습한 VMCS Data
들에 필드들에 크기에 대한 내용이 필수적으로 있었던 것 입니다.
이어지는 내용에서는 원하는 필드의 값에 대해 VMREAD, VMWRITE
를 하기 위해 사용되는 인코딩 된 값을 확인할 수 있습니다.
예를 들어 Guest
의 CR4
를 읽는다고 가정해보겠습니다.
- 먼저
Guest State
에서 정보를 읽어야 하기 때문에 bit 11 이 1으로 설정됩니다. - CR4 의 경우 32 bit가 될 수도 있고 64 bit가 될 수 있기 때문에 nature width 로 설정해야 합니다. bit14:13 은 모두 1로 설정됩니다.
- 여기서 인덱스를 찾아야 하는데 이 부분은
Intel SDM
에 문서화가 잘되어 있습니다.(Appendix B Field Encoding in VMCS
) - Guest CR4 의 인덱스 값은 0000’0010b 로 값이 4입니다.
위의 과정을 거치면 명령에 전달되는 인코딩 값은 0x6804h
가 됩니다.
[-] Initializing a VMCS
VMM
은 VM Entry
에 VMCS
를 사용하기 전에 VMCS
의 필드를 초기화 해야 합니다. (VMWRITE
사용)
논리 프로세서가 사용하지 않을 필드를 초기화할 필요는 업습니다. 예를 들어 use MSR bitmaps
필드가 0인 경우 VM-execution control
필드에 포함되어 있는 MSR-bitmap address
를 초기화할 필요가 없습니다.
프로세서는 VMWRITE
로 수정 불가능한 일부 VMCS
정보에 대해 유지하고 관리합니다. 여기에는 VMCS
의 Launch State
가 포함됩니다.
이러한 정보는 VMCS Region
의 VMCS Data
부분에 저장될 수 있습니다. 이 정보의 포맷은 구현에 따라 다르기 때문에 VMM
이 VMCS Region
으로 사용할 메모리 영역을 처음 할당 할 때 프로세서가 메모리 영역의 내용에서 이 정보를 결정하는 방법을 알 수 있는 방법이 없습니다.
추가적으로 다른 기능 외에도 VMCLEAR
명령어는 피연산자가 참조하는 VMCS Region
의 구현 관련 정보를 초기화 합니다. 구현별 동작의 불확실성을 피하기 위해 VMM
은 처음으로 VMPTRLD
와 함께 해당 VMCS
를 활성화하기 전에 VMCS Region
에서 VMCLEAR
를 실행해야 합니다.
- VMCLEAR → VMPTRLD
아래의 VMM
사용법은 이러한 제한 사항과 일치합니다.
VMCLEAR
는 처음VM Entry
로 전환되기 전에VMCS
에 대해 실행되어야 합니다.VMLAUNCH
는 해당VMCS
에 대해VMCLEAR
가 실행된 후VMCS
를 사용하는 첫 번째VM Entry
에 사용해야 합니다.VMRESUME
은VMCS
를 사용하는 모든 후속VM Entry
에 사용해야 합니다.(VMCS
에 대해VMCLEAR
가 실행될 때 까지)
[0x0A] Conclusion
이로써 VMCS Data
에 대한 내용을 모두 살펴봤습니다.
실제로 Intel SDM
을 정독하며 알게 된 내용이 매우 많았습니다. 목표로 하는 바는 하이퍼바이저를 만드는 것 입니다. 여러 튜토리얼들과 오픈소스를 참조하였으나, 이해가 되지 않는 부분이 많았습니다.
매우 많은 양에 겁 먹을 필요 없습니다. 꽤 많은 오픈소스가 존재하고 이를 이용하여 비교하며 중요한 내용에 대해 이해하면 됩니다.
[0x0B] Reference
- Intel 64 and IA-32 Architectures Software Developer’s Manual
- Hypervisor From Scratch
- Tandasat DdiMon
- Gbps Gbhv