[0x00] Concept
VM Exits -1- 파트에 이어서 작성됩니다.
왜 여러가지 상태나 레지스터들을 저장하고 로드하는가 대해서 설명하는가를 이해하는 것이 좋습니다.(참고 : 링크)
- Guest-State Area(게스트 상태 영역)
- VM Exit : 프로세서의 상태를 저장
- VM Entry : 프로세서의 상태(저장된 상태)를 로드
- Host-State Area(호스트 상태 영역)
- VM Exit : 프로세서의 상태(저장된 상태)를 로드
VMM은 게스트 소프트웨어의 실행 시점을 직접 제어할 수 있습니다. 그 말은 실행 전에 호스트 상태 영역을 설정할 수 있다는 의미입니다.- 즉
VM Entry, Exit가 발생할 때의 저장과 로드와는 별개의 의미로VMM에서 미리 설정을 하기 때문에(VM Entry가 실패하는 경우 돌아올RIP저장 등) 필요하지 않은 것으로 이해했습니다.
[0x01] Saving Guest State
위에서 설명한 것과 같이 VM Exit 는 프로세서 상태의 특정 구성 요소들을 VMCS 의 게스트 상태 영역에 있는 필드에 저장합니다.
Intel 64 아키텍처를 지원하는 프로세서는 natural-width field(아키텍처에 따라 가변적인 필드) 에 해당하는 필드의 값은 VM Exit 전, 후의 프로세서 모드에 관계없이 저장됩니다.
[-] Saving Control Registers, Debug Registers, and MSRs
특정 Control Register, Debug Register, MSR 은 Guest Register State 에 포함되며 아래와 같이 저장됩니다.
CR0, CR3, CR4, IA32_SYSENTER_CS, IA32_SYSENTER_ESP, EIP MSR의 내용이 게스트 상태 영역에 저장됩니다.IA32_SYSENTER_CS MSR의 bits 63:32 는 저장되지 않으며,Intel 64아키텍처를 지원하지 않는 경우IA32_SYSENTER_ESP, EIP의 bits 63:32 는 저장되지 않습니다.VMExit_save debug controls제어 비트가 1이면DR7의 값과IA32_DEBUGCTL MSR이 해당 필드에 저장됩니다.VMExit_save IA32_PAT제어 비트가 1이면IA32_PAT MSR의 내용이 필드에 저장됩니다.VMExit_save IA32_EFER제어 비트가 1이면IA32_EFER MSR의 내용이 필드에 저장됩니다.VMEntry_load IA32_BNDCFGS제어가 1로 설정 가능한 경우, 또는VMExit_clear IA32_BNDCFGS제어가 1으로의 설정을 지원하는 경우IA32_BNDCFGS MSR의 내용이 필드에 저장됩니다.VMEntry_load IA32_RTIT_CTL제어가 1로 설정 가능한 경우, 또는VMExit_clear IA32_RTIT_CTL제어가 1으로의 설정을 지원하는 경우IA32_RTIT_CTL MSR의 내용이 필드에 저장됩니다.VMEntry_load CET제어가 1로 설정을 지원하는 경우IA32_S_CET,IA32_INTERRUPT_SSP_TABLE_ADDR MSR의 내용이 필드에 저장됩니다.VMEntry_load guest IA32_LBR_CTL제어가 1로 설정 가능한 경우, 또는VMExit_clear IA32_LBR_CTL제어가 1으로의 설정을 지원하는 경우IA32_LBR_CTL MSR의 내용이 필드에 저장됩니다.VMEntry_load PKRS제어가 1로 설정 가능한 경우IA32_PKRS MSR의 내용이 필드에 저장됩니다.VMExit_save IA32_PERF_GLOBAL_CTL제어 비트가 1이면IA32_PERF_GLOBAL_CTL MSR의 내용이 필드에 저장됩니다.SMBASE필드의 값은SMM VM Exit를 제외한 모든VM Exit후에 정의되지 않습니다.
[-] Saving Segment Registers and Descriptor-Table Registers
각 세그먼트 레지스터(CS, SS, DS, ES, FS, GS, LDTR, TR)에 대해 Base-Address, Segment-Limit, Access-Right 에 대해 저장되는 값은 각 레지스터가 VM Exit 발생하기 전에 Access-Right 필드의 bit 16(unusable)에 따라 결정됩니다.
- 레지스터가
unusable인 경우Base-Address,Segment-Limit필드와Access-Right필드의 bits 7:0, bits 15:12 값은 정의되지 않습니다. 다만 다음의 레지스터의 경우 예외가 존재합니다.CS의 경우BaseAddress,Segment-Limit필드가 저장됩니다. 또한Access-Right필드의 bits 15:13(L,D,G) 값이 저장됩니다.SS의 경우Access-Right필드의 bits 6:5(DPL, Descriptor Privilege Level) 이 저장되며Intel 64아키텍처를 지원하는 경우Base-Address필드에 대해 저장되는 값의 bits 63:32 는 항상 0 입니다.DS,ES의 경우Intel 64아키텍처를 지원하는 경우Base Address에 대해 저장되는 값의 bits 63:32 는 항상 0 입니다.FS,GS의 경우Base-Address필드를 저장합니다.LDTR의 경우 저장되는Base Address는 항상 정규 주소 입니다.
- 레지스터가
unusable이 아닌 경우,Base-Address,Segment-Limit와Access-Right필드의 bits 7:0, bits 15:12 에 저장된 값은VM Exit가 발생하기 전에 레지스터에 있던 값입니다. Access-Right필드의 bits 31:17, bits 11:8은 항상 지워집니다. bit 16은 세그먼트를 사용할 수 없는 경우에만 1으로 설정됩니다.
GDTR, IDTR 레지스터의 경우 Base-Address, Segment-Limit 필드가 저장됩니다.
[-] Saving RIP, RSP, RFLAGS, and SSP
RIP, RSP, RFLAGS, SSP 레지스터의 내용은 아래와 같이 저장됩니다.
RIP필드에 저장되는 값은VM Exit의 특성과 원인에 따라 결정됩니다.Enclave모드에서VM Exit가 발생한 경우 저장되는 값은 중단된Enclave스레드의AEP(Asynchronous Exit Pointer)입니다.- 무조건
VM Exit가 발생하는 명령이나VM-execution controls를 통해VM Exit가 유발되는 명령을 실행하려는 시도로 인해VM Exit가 발생한 경우 저장된 값은 해당 명령을 참조합니다.(참조의 의미는 해당 명령이 실행된IP를 의미하는 것으로 보입니다.) VM Exit가INIT Signal,start-up IPI(SIPI),SMI중 하나의 발생으로 인해 발생한 경우 저장되는 값은 이벤트가 발생하기 전에RIP값 입니다.PR_interrupt-window exiting제어 비트나PR_NMI-window exiting제어 비트가 1로 설정됨에 따라VM Exit가 발생하는 경우 저장되는 값은VM Exit가 발생하지 않은 경우의RIP값 입니다.(아마 정상적으로 실행됐을 때의RIP을 의미하는 것으로 보입니다.)VM Exit가external interrupt,NMI,hardware exception으로 인한 경우 저장되는 값은 이벤트 처리에 따라 저장된 값의 반환 포인터 입니다.(trap또는interrupt gate를 통해 이벤트가 전달되었다면 스택, 이벤트가task-gate를 통해 전달된 경우 이전task-state segment)VM Exit가Triple-Fault로 인한 경우 저장되는 값은 위의 이벤트 처리와 동일합니다.VM Exit가software exception(INT3 또는 INTO 실행으로 인해) 또는privileged software exception(INT1 실행으로 인해)으로 인한 경우 저장되는 값은 해당 예외를 일으킨INT3,INTO,INT1명령어를 참조합니다.VM Exit가IDT에서task-gate가 발생시킨CALL,IRET,JMP의 실행이나software interrupt(INT n),software exception(INT3, INTO),privileged software exception(INT 1) 으로 인해 발생한 경우, 저장되는 값은task switch를 발생시킨 명령을 참조합니다.(CALL, IRET, JMP, INT n, INT3, INTO, INT1)VM Exit가software interrupt또는software exception에 의한 직접 액세스를 제외하고IDT의task-gate로 인한task switch때문인 경우 저장되는 값은 정상적으로 완료됐을 때의 이전task-statue segment에 저장되었을 값입니다.VM Exit가VTPR(Virtual Task-Priority Register)의 bits 7:4 값을APIC Virtualization과 연관된VM-execution control fields내TPR threshold값 아래로 줄여 발생한 경우(ex. MOV to CR8)MOV to CR8또는WRMSR명령을 참조합니다.
RSP필드에 저장되는 값은RSP레지스터의 값이 저장됩니다.RFLAGS필드에는 bit 16(RF, Resume Flag)를 제외하고RFLAGS레지스터의 값이 저장됩니다.RFLAGS.RF의 경우 아래와 같이 저장됩니다.Enclave모드에서VM Exit가 발생한 경우 저장되는 값은 0입니다.VM Exit가Triple-Fault로 인해 발생한 경우 저장되는 값은 논리 프로세서가Triple-Fault가 발생하고shutdown상태로 전환된 경우RF에 있는 값입니다.- 조건
VM Exit가 발생하는 명령이나VM-execution controls를 통해VM Exit가 유발되는 명령을 실행하려는 시도로 인해VM Exit가 발생한 경우 저장되는 값은 0 입니다. - 위의 내용과 생략한
APIC-access,task switch등으로 인한VM Exit가 아닌 경우 원래의 값이 저장됩니다.
SSP필드에 저장되는 값은 프로세서가VMEntry_load CET제어가 1 설정을 지원하는 경우에만SSP레지스터의 값이 저장됩니다.
[-] Saving Non-Register State
※ 참고 : 링크
Guest Non-Register State 에 저장되는 내용은 아래와 같습니다.
Activity-State Field의 경우VM Exit전에 논리 프로세서의Activity state와 함께 저장됩니다.Interruptibility-State Field는VM Exit전에 논리 프로세서의 인터럽트가 발생할 가능성을 반영하기 위해 저장합니다.Pending Debug Exception Field는 다음을 제외한 모든VM Exit에 대해 0으로 저장됩니다.INIT Signal,Machine-Check,SMI로 인한VM Exit가 발생한 경우Basic Exit Reason이TPR below threshold,virtualized EOI,APIC write,monitor trap flag로 인한VM Exit입니다.debug exception으로 발생한 것이 아니고debug exception에 대한MOV-SS차단 중에 발생한VM Exit입니다.
Pending Debug Exception Field가 0이 아닌 값으로 저장되는 경우의 저장되는 값에 대한 설명은 아래와 같습니다.- bits 3:0(B0-B3) 각각은 일치하는 중단점에 해당하는 경우 1로 설정됩니다.
DR7에서 해당 중단점이 활성화되지 않은 경우에도 마찬가지 일 수 있습니다. VM Exit가INIT Signal,Machine-Check,SMI로 인해 발생했거나Basic Exit Reason이TPR below threshold,monitor trap flag인 경우가 있다고 가정합니다. 이러한 경우에 저장되는 값은VM Exit발생 시 보류 중인debug exception의 원인에 해당하는 비트로 설정됩니다.- bit 12(
enable breakpoint) 는 아래의 경우에 1로 설정됩니다.DR7에서 활성화 된 일치하는 데이터 또는I/O breakpoint가 하나 이상 있는 경우VM Entry에 설정된 경우 유효한 보류 중인debug exception이 발생하고, 해당 예외가 전달되거나 손실되기 전에VM Exit가 발생하는 경우VM Exit직전에XBEGIN명령이 실행되고RTM Transactional region의 디버깅이 활성화 된 경우- 그 외의 경우에는 0으로 설정됩니다.
- bit 14(
BS) 는 다음의 경우에 해당하고RFLAGS.TF = 1인 경우 1로 설정됩니다.IA32_DEBUGCTL.BTF= 0이고 보류 중인debug exception의 원인이Single Instruction입니다.IA32_DEBUGCTL.BTF = 1이고 보류 중인debug exception의 원인이Taken Branch입니다.
- bit 16(
RTM)은 생략합니다. (Advanced Debugging of RTM transactional regions)
- bit 12(
VM Exit가debug exception이 아닌 다른 이유 때문이고debug exception의MOV-SS차단되는 동안 발생했다고 가정합니다. 이러한 경우 저장되는 값은VM Exit시점에 보류 중인debug exception의 원인에 해당하는 비트를 설정합니다.VM Entry직후에VM Exit가 발생하는 경우(VMX non-root operation에서 실행된 명령이 없는 상태) 저장되는 값은VM Entry에 로드된 값과 일치할 수 있습니다.
- bits 3:0(B0-B3) 각각은 일치하는 중단점에 해당하는 경우 1로 설정됩니다.
VMExit_save VMX-preemption timer value제어 비트가 1인 경우 타이머 값은VMX-preemption timer-value field에 저장됩니다. 이것은VM Entry에서 이 필드에서 로드된 이후부터 줄어듭니다. 타이머 만료로 인해VM Exit가 발생하면 0을 저장합니다.- 논리 프로세서가
Second_enable EPT의 1로 설정을 지원하는 경우 값은 아래와 같이 4개의PDPTE필드에 저장됩니다.-
Second_enable EPT제어 비트가 1이고 논리 프로세서가VM Exit시PAE paging을 사용 중이면 현재 사용 중인PDPTE의 값이 저장됩니다.
- 각 필드(4개의 필드)의 bits 11:9는 정의되지 않았습니다.
- 각 필드 중 하나의 필드에 저장된 값의 bit 0(
present)이 0으로 설정된 경우 해당 필드의 bits 63:1 은 정의되지 않습니다. 이 값은VM Entry에 의해 로드된 값 또는VMX non-root operation에서 로드되었을 수 있는 값과 일치하지 않아도 됩니다. - 각 필드 중 하나의 필드에 저장된 값의 bit 0(
present)이 1으로 설정된 경우 bits 63:12 에 저장된 값은 게스트 물리 주소 입니다.
-
Second_enable EPT제어가 0이거나PAE paging을 사용하지 않는 경우 저장되는 값은 정의되지 않습니다.
-
[0x02] Saving MSRs
프로세서 상태가 게스트 상태 영역에 저장된 후 MSR 값은 VM-exit MSR-store area 에 저장될 수 있습니다.
특히 해당 영역의 각 엔트리(VM-exit MSR-store count 에 지정된 수 까지)는 bits31:0(RDMSR 을 통해 읽음)으로 인덱싱된 MSR 값을 비트에 저장하여 순서대로 처리됩니다. 아래와 같은 경우 처리가 실패합니다.
- bits 31:8 의 값이 8이며 이는
Local APIC가x2APIC mode에 있을 때 인덱싱된MSR이APIC register에 대한 접근을 허용하는 값을 의미합니다. - bits 31:0의 값은
SMM에서만 읽을 수 있는MSR으로 표시되어 있고,VM Exit는SMM에서 발생하지 않습니다.(IA32_SMBASE MSR은SMM에서만 읽을 수 있습니다.) - bits 31:0의 값은 모델별 이유로
VM Exit에 저장할 수 없는MSR으로 표시되어 있습니다. 프로세서는RDMSR에서 정상적으로 읽을 수 있는 경우에도 특정MSR(bits 31:0 기반)이VM Exit발생 시 저장되는 것을 방지할 수 있습니다. - 엔트리의 bits 63:32 는 0이 아닌 값입니다.
- bits 31:0 으로 인덱싱된
MSR을 읽으려는 시도는CPL = 0상태에서RDMSR을 통해 실행되는Genral-Protection Exception을 발생 시킵니다.
해당 항목에 대한 처리가 실패하면 VMX Abort 가 발생됩니다.
[0x03] Loading Host State
프로세서의 상태는 VM Exit 에서 다음과 같은 방식으로 업데이트 합니다.
- 일부 상태는 호스트 상태 영역에서 로드되거나 결정됩니다.
- 일부 상태는
VM-exit controls에 의해 결정됩니다. - 일부 상태는 모든
VM Exit에서 동일한 방식으로 설정됩니다. Page-Directory Pointer는 특정Control Register의 값을 기반으로 로드됩니다.
이러한 로딩의 순서는 임의의 순서로 진행됩니다.
Intel 64 아키텍처를 지원하는 프로세서에서 로드된 각 64 bits 필드의 전체 값(ex. GDTR 의 Base Address)은 VM Exit 전후의 논리 프로세서 모드와 관계없이 로드됩니다.
별도의 언급이 없는 이상 ~ 에서 로드되는 필드는 호스트 상태 영역을 의미합니다.
[-] Loading Host Control Registers, Debug Registers, MSRs
VM Exit 는 Control Register, Debug Register, 일부 MSR 에 대한 새로운 값을 로드합니다.
CR0, CR3, CR4는 아래의 경우를 제외하고 각 필드에서 로드됩니다.- 아래의 경우에 비트는 수정되지 않습니다.
CR0, ET, CD, NW의 경우 bits 63:32, bits 28:19, bit 17, bits 15:6 및VMX Operation에서 고정된 모든 비트CR3의 경우 프로세서의 물리 주소 너비를 초과하는 비트 bits 63:52 및 bits 51:32 범위의 비트(0으로 지워짐)CR4의 경우VMX Operation에서 고정된 모든 비트
CR4.PAE는VMExit_host address-space size제어가 1인 경우 1로 설정됩니다.CR4.PCIDE는VMExit_host address-space size제어가 0인 경우 0으로 설정됩니다.DR7은0400h로 설정됩니다.
- 아래의 경우에 비트는 수정되지 않습니다.
MSR의 경우 아래와 같이 설정됩니다.IA32_DEBUGCTL MSR은 0으로 지워집니다.IA32_SYSENTER_CS MSR은IA32_SYSENTER_CS필드에서 로드됩니다. 해당 필드에는 32bits 만 존재하므로 bits 63:32 는 0으로 지워집니다.IA32_SYSENTER_ESP, EIP MSR은IA32_SYSENTER_ESP, EIP에서 로드됩니다.- 다음 내용은
Intel 64아키텍처를 지원하는 프로세서에서 수행됩니다.FS, GS.base MSR은 각FS, GS에 대한Base-Address필드에서 로드됩니다.IA32_EFER MSR의LMA, LME비트는VMExit_host address-space size제어 설정으로 로드됩니다.
VMExit_load IA32_PERF_GLOBAL_CTRL제어가 1이면IA32_PERF_GLOBAL_CTRL MSR은IA32_PERF_GLOBAL_CTRL필드에서 로드됩니다. 예약된 비트의 값은 유지됩니다.VMExit_load IA32_PAT제어가 1이면IA32_PAT MSR은IA32_PAT필드에서 로드됩니다. 예약된 비트의 값은 유지됩니다.VMExit_load IA32_EFER제어가 1이면IA32_EFER MSR은IA32_EFER필드에서 로드됩니다. 예약된 비트의 값은 유지됩니다.VMExit_clear IA32_BNDCFGS제어가 1이면IA32_BNDCFGS MSR은 0으로 지워집니다. 그렇지 않으면 수정되지 않습니다.VMExit_clear IA32_RTIT_CTL제어가 1이면IA32_RTIT_CTL MSR은 0으로 지워집니다. 그렇지 않으면 수정되지 않습니다.VMExit_load CET제어가 1이면IA32_S_CET MSR,IA32_INTERRUPT_SSP_TABLE_ADDR MSR이 각각IA32_S_CET,IA32_INTERRUPT_SSP_TABLE_ADDR필드에서 로드됩니다.VMExit_load PKRS제어가 1이면IA32_PKRS MSR은IA32_PKRS필드에서 로드됩니다.
[-] Loading Host Segment and Descriptor-Table Registers
각 레지스터 CS, SS, DS, ES, FS, GS, TR 은 다음과 같이 로드됩니다.
Selector는Selector필드에서 로드됩니다.Selector가 0으로 로드되면 세그먼트는unusable속성이 됩니다.SS는Intel 64아키텍처를 지원하는 프로세서에서만 0으로 로드할 수 있으며VM Exit가 64-bit 모드인 경우에만 로드할 수 있습니다.Base Address는 아래와 같이 설정됩니다.CS의 경우 0으로 지워집니다.SS, DS, ES의 경우unusable상태이면 정의되지 않습니다. 그렇지 않으면 0으로 지워집니다.FS, GS의 경우unusable상태이고VM Exit가 64-bit 모드가 아니면 정의되지 않습니다. 그렇지 않으면Base-Address필드에서 로드됩니다.TR의 경우 호스트 상태 영역에서 로드됩니다.
Segment Limit은 아래와 같이 설정됩니다.CS의 경우FFFFFFFFh으로 설정됩니다.SS, DS, ES, GS의 경우unusable상태이면 정의되지 않습니다. 그 외에는FFFFFFFFh으로 설정됩니다.TR의 경우00000067h으로 설정됩니다.
Segment Type,S(Descriptor Type)은 아래와 같이 설정됩니다.(Access-Right Field)CS의 경우S는 1으로 설정되고,Segment Type의 경우 11(execute/read, accessed, non-conforming code segment)으로 설정됩니다.SS, DS, ES, FS, GS의 경우unusable상태이면 정의되지 않습니다. 그렇지 않으면S는 1으로 설정되고Segment Type은 3으로 설정됩니다.(read/write, accessed, expand-up data segment)TR의 경우S는 0(system)으로 설정되고Segment Type은 11(busy 32-bit TSS)으로 설정됩니다.
DPL은 아래와 같이 설정됩니다.(Access-Right Field)CS, SS, TR의 경우 0으로 설정됩니다.VM Exit가 완료된 후에CPL은 0이 됩니다.DS, ES, FS, GS의 경우unusable상태이면 정의되지 않습니다. 그렇지 않으면 0으로 설정됩니다.
P(Segment Present)는 아래와 같이 설정됩니다.(Access-Right Field)CS,TR의 경우 1로 설정됩니다.SS, DS, ES, FS, GS의 경우unusable이면 정의되지 않습니다. 그렇지 않으면 1으로 설정됩니다.
L(64-bit mode active)은 아래와 같이 설정됩니다.(Access-Right Field), 부가 설명을 하면 bit 13인 해당 비트는 오직CS에서만 기능이 존재하며 그 외에는 예약된 비트로 사용됩니다.VMExit_host address-space size제어 비트로 로드됩니다. 이 제어의 값이IA32_EFER.LMA에도 로드되기 때문에VM Exit는 호환성 모드(IA32_EFER.LMA = 1, CS.L = 0 이 필요함)로 전환되지 않습니다.
D/B(Default operation size)의 경우 아래와 같이 설정됩니다.(Access-Right Field)CS의 경우VMExit_host address-space size제어 값의 역으로(inverse) 로드됩니다. 예를 들어host address-space size가 0이면 32-bit 게스트를 나타내며, 이러한 경우CS.D/B = 1으로 설정됩니다.SS의 경우 1로 설정됩니다.DS, ES, FS, GS의 경우unusable이면 정의되지 않습니다. 그렇지 않으면 1으로 설정됩니다.TR의 경우 0으로 설정됩니다.
G(Granularity)의 경우 아래와 같이 설정됩니다.(Access-Right Field)CS의 경우 1로 설정됩니다.SS, DS, ES, FS, GS의 경우unusable이면 정의되지 않습니다. 그렇지 않으면 1로 설정됩니다.TR의 경우 0으로 설정됩니다.
호스트 상태 영역에는 LDTR 에 대한 Selector 필드가 없습니다. LDTR 은 모든 VM Exit 에서 다음과 같이 설정됩니다.
Selector는0000h로 지워지고 세그먼트는unusable상태로 표시되며 그렇지 않으면 정의되지 않습니다.
GDTR, IDTR 에 대한 Base address 는 각각의 Base-Address 필드에서 로드됩니다.
[-] Loading Host RIP, RSP, RFLAGS, and SSP
RIP, RSP 는 각각의 필드에서 로드됩니다. RFLAGS 는 항상 설정되는 bit 1 을 제외하고 모두 지워집니다.
VMExit_load CET 제어가 1인 경우 SSP 는 SSP 필드에서 로드됩니다.
[-] Checking and Loading Host Page-Directory-Pointer-Table Entries
CR0.PG = 1, CR4.PAE = 1, IA32_EFER_LMA = 0 의 조건이 성립하면 논리 프로세서는 PAE Paging 을 사용합니다.
PAE Paging 이 사용 중일 때 CR3 의 물리 주소는 PDPTE 테이블을 참조합니다. 또한 MOV to CR3 은 PDPTE 의 유효성을 검사하고 유효한 경우 프로세서로 로드합니다.
VM Exit 는 아래와 같은 경우 PAE Paging 을 사용하는 VMM 에 대한 것 입니다.
CR4.PAE가VMCS의 호스트 상태 영역에 설정되어 있는 경우VMExit_host address-space size제어가 0인 경우
이러한 VM Exit 는 VMCS 의 호스트 상태 영역에서 CR3 필드가 참조하는 PDPTE 의 유효성을 확인할 수 있습니다.
또한 VM Exit 발생 전에 PAE Paging 이 사용되지 않았거나 VM Exit 의 결과로 CR3 값이 변경되는 경우 유효성을 확인해야 합니다.
PAE Paging 을 사용하지 않는 VMM 에 대한 VM Exit 는 PDPTE 의 유효성 검사를 해서는 안 됩니다.
PAE Paging 이 사용 중일 때 CR3 가 MOV to CR3 로 인해 로드되는 것과 동일하게 PDPTE 의 유효성을 검사해야 합니다. MOV to CR3 이 로드되는 PDPTE 로 인해 General-Protection Exception(#GP) 가 발생하는 경우(ex. 예약된 비트를 설정) VMX Abort 가 발생합니다.
PAE Paging 을 사용하는 VMM 에 대한 VM Exit 가 VMX Abort 를 발생시키지 않는 경우, VM Exit 에 의해 로드되는 CR3 값을 사용하여 MOV to CR3 와 같이 PDPTE 가 로드됩니다.
[-] Updating Non-Register State
VM Exit 는 다음과 같이 프로세서의 Non-Register State 에 영향을 미칩니다.
- 논리 프로세서는
VM Exit후 항상active상태 입니다. - 이벤트 차단은 아래와 같이 영향을 받습니다.
VM Exit후STI또는MOV SS에 의한 차단이 없습니다.(blocking by STI, MOV SS)NMI로 인해VM Exit가 직접 종료되면blocking by NMI가 발생합니다. 다른VM Exit는 영향을 미치지 않습니다.VM Exit후 보류 중인debug exception은 없습니다.
추후에 자세히 설명될 내용에서는 VMX 아키텍처 논리 프로세서의 TLB 및 Paging-Structure Cache 정보를 관리하고 제어하는 방법을 설명하게 됩니다. 먼저 다음 항목은 VM Exit 가 캐시된 매핑을 무효화하는 방법을 자세히 설명합니다.
Second_enable VPID제어 비트가 0인 경우 논리 프로세서는VPID0000h(모든PCID에 대해)와 관련된 선형 매핑 및 결합된 매핑을 무효화 합니다.VPID0000h 에 대한 결합된 매핑은 모든EP4TA값에 대해 무효화 됩니다.(EP4TA는EPTP필드의 bits 51:12)- 게스트 물리 매핑을 무효화 하는데
VM Exit는 필요하지 않으며Second_enable VPID제어가 1인 경우 선형 매핑 또는 결합된 매핑을 무효화할 필요가 없습니다.
[-] Clearing Address-Range Monitoring
VMM 은 MONITOR 및 MWAIT 명령을 이용하여 지정된 주소 범위를 모니터링 할 수 있습니다. VM Exit 는 적용될 수 있는 모든 Address-range monitoring 을 지웁니다.
[0x04] Loading MSRs
VM Exit 는 VM-exit MSR-load area 에서 MSR 을 로드할 수 있습니다.
해당 영역의 각 엔트리(VM-exit MSR-load count 값까지)은 WRMSR 에 의해 기록되는 bits 127:64 의 내용과 함께 bits 31:0으로 인덱싱 된 MSR 을 로드하여 순서대로 처리됩니다.
다음과 같은 경우 처리가 실패합니다.
- bits 31:0 의 값이
C00000100h(IA32_FS_BASE MSR)또는C0000101h(IA32_GS_BASE MSR)입니다. - bits 31:8 의 값이
000008h이며, 이는 로컬APIC가x2APIC mode에 있을 때 인덱싱 된MSR이APIC레지스터에 대한 액세스를 허용하는 것을 의미합니다. - bits 31:0 의 값은
SMM에서만 쓸 수 있는MSR을 나타내며VM Exit가SMM에서 끝나지 않습니다. (IA32_SMM_MONITOR CTL은SMM에서만 쓸 수 있는MSR) - bits 31:0 의 값은 모델별 이유로
VM Exit에 로드할 수 없는MSR을 나타냅니다. 프로세서는 특정MSR이 일반적으로WRMSR에 의해 기록될 수 있는 경우에도 로드를 방지할 수 있습니다. - bits 63:32 가 0이 아닙니다.
- 엔트리의 bits 31:0 으로 인덱싱된
MSR에 bits 127:64 를 쓰려는 시도가CPL = 0인WRMSR을 통해 실행되는 경우 #GP 를 발생시킵니다.
해당 처리가 실패하면 VMX Abort 가 발생합니다.
[0x05] VMX Aborts
VM Exit 중에 문제가 발생하게 되면 VMX Abort 가발생합니다. VMX Abort 는 아래에 설명된 대로 프로세서를 shutdown 상태로 전환합니다.
VMX Abort 는 active VMCS 의 VMCS Region 에 있는 VMCS Data 를 변경하지 않습니다. 따라서 이러한 데이터의 내용은 VMX Abort 후에는 확실하지 않습니다.
VMX Abort 가 발생 시 프로세서는 잘못된 구성으로 인해 오류가 발생한 VMCS 의 VMCS Region 필드의 Byte Offset4(VMX-abort indicator) 에 0이 다음의 값을 저장합니다.
- 게스트
MSR을 저장하는 데 실패했습니다. PDPTE에 대한 호스트 확인에 실패했습니다.current VMCS가 손상되어(VMCS Region에 쓰기를 통해) 프로세서가VM Exit를 제대로 완료할 수 없습니다.- 호스트
MSR을 로드하는 동안 오류가 발생했습니다. VM Exit중Machine-Check Event가 발생했습니다.VM Exit전에 프로세서가IA-32e mode에 있었고VMExit_host address-space size제어가 0이었습니다.
이러한 원인 중 일부는 호스트 상태 영역에서 상태를 로드하는 동안의 오류에 해당합니다. 상태를 로드하는 것은 임의의 순서로 수행될 수 있으므로 VM Exit 는 여러 가지 이유로 인해 VMX Abort 가 발생할 수 있습니다. 때문에 여러가지 이유 중 VMX-abort indicator 에는 하나만 기록되므로 다른 문제가 없다는 것은 아닙니다.
VMX-abort indicator 는 하나의 논리 프로세서의 VMM 이 다른 논리 프로세서의 VMX Abort 를 진단할 수 있도록 합니다.
이러한 이유로 VMX root operation 에서 실행되는 VMM 은 사용하는 VMCS 의 VMCS Region 에서 VMX-abort indicator 를 0으로 설정하는 것이 좋습니다.
VMX-abort indicator 를 저장한 후 VMX Abort 가 발생한 논리 프로세서의 동작은 SMX Operation 상태인지에 따라 달라집니다.
- 만약
SMX Operation(Safer Mode Extension)에 있다면Intel TXT shutdown condition이 발생합니다.
[0x06] Machine-Check Event During VM Exit
VM Exit 중에 Machine-Check Event 가 발생하면 다음 중 하나가 발생합니다.
Machine-Check Event는VM Exit전에 처리됩니다.CR4.MCE = 0인 경우 프로세서의 동작은SMX Operation상태인 경우Intel TXT shutdown condition이 발생하고, 아닌 경우shutdown상태로 전환됩니다.CR4.MCE = 1인 경우machine-check exception(#MC)가 생성됩니다.Exception bitmap의 bit 18(#MC)이 0이면 게스트IDT를 통해 예외가 전달됩니다.Exception bitmap의 bit 18이 1이면VM Exit가 발생합니다.
Machine-Check Event는VM Exit가 완료된 후 처리됩니다.VM Exit가CR4.MCE = 0로 끝나는 경우 프로세서의 동작은SMX Operation상태인 경우 오류 코드 000Ch와 함께Intel TXT shutdown condition이 발생하고, 아닌 경우shutdown상태로 전환됩니다.VM Exit가CR4.MCE = 1으로 끝나는 경우 호스트IDT를 통해machine-check exception이 전달됩니다.
VMX Abort가 생성됩니다. 논리 프로세서는VMX Abort에서 정상적으로 수행되는 이벤트를 차단합니다.VMX-abort indicator는 5(machine-check event during VM exit) 입니다.
호스트 상태가 로드된 후 Machine-Check Event 가 발생하는 경우 첫 번째 내용은 사용되지 않습니다. 두 번째 내용은 VM Entry 가 모든 호스트 상태를 로드할 수 있는 경우에만 사용됩니다.
[0x07] Conclusion
아직도 이해가 되지 않는 부분이나 용어들이 꽤 많이 있습니다.
구현은 하지 않고 계속 보고 있으니 인텔 메뉴얼에 매우 익숙해진다는 장점은 있습니다.
[0x08] Reference
- Intel 64 and IA-32 Architectures Software Developer’s Manual