VMX Non-Root Operation

[0x00] Concept

이전 챕터에서는 VMCS Data 와 관련된 매우 많은 내용에 대해 조사하였습니다.

메뉴얼을 보면서 이전에는 미처 알지 못했던 부분들에 대해 이해할 수 있는 시간이었습니다.

프로젝트가 끝나갈 때 쯤에는 VMCS Data 구성에 있는 많은 부분을 활용해보려고 합니다.

우선 이번 챕터에서도 마찬가지로 Intel SDM 에 초점을 맞춰 VMX 에서 필요한 개념에 대해 계속해서 확인하겠습니다. (Intel SDM Vol.3C Chapter 25, April.2022)

이번 챕터의 주 내용은 VMX Non-root operation 에 대한 여러가지 지침과 주의사항에 대해 알아보겠습니다.

해당 챕터에서 VMX ControlVM-execution controls 을 의미합니다.

[0x01] Instruction that cause VM Exits

VMX non-root operation 에서 특정 명령이 실행되는 경우 VM Exit 가 발생할 수 있습니다.

별도의 핸들러가 지정되지 않은 VM Exit 는 오류와 같이 취급되며 이는 VM Exit 를 유발하는 명령이 실패하고 명령에 의해 프로세서 상태가 변경되지 않았음을 의미합니다.

추후에 이러한 VM Exit 에 대한 컨텍스트는 자세하게 다루게 됩니다.

[-] Relative Priority of Faults and VM Exits

아래의 원칙은 기존의 오류와 VM Exit 간의 순서를 설명합니다.

  • 특정 예외는 VM Exit 보다 우선 시 됩니다.
    • invalid-opcode (#UD)
    • 권한 수준 기반의 오류
    • TSS(Task State Segment) 에서 I/O 권한 비트 확인을 기반으로 하는 General-protection
    • 예를 들어 CPL(Current Privilege Level) 이 3인 경우 RDMSR 을 실행하면 VM Exit 가 아닌 #GP 가 발생합니다.
  • 명령어 피연산자를 가져오는 동안 발생하는 오류의 경우 VM Exit 보다 우선 시 됩니다. VM Exit 의 경우 피연산자의 내용에 따라 조절되기 떄문입니다.
  • INS, OUTS 명령 실행으로 인한 VM Exit (unconditional I/O exiting 필드가 1이거나, use I/O bitmaps 필드가 1 일 때)는 아래의 오류보다 우선 시 합니다.
    • 세그먼트 관련 #GP
    • alignment-check 예외
  • 오류와 같이 취급되는 VM Exit 는 위의 내용 이외의 예외보다 우선 시 됩니다.
    • 예를 들어 CPL=0 으로 존재하지 않는 MSR 을 이용하여 RDMSR 을 발생시키는 경우 #GP 가 아닌 VM Exit 가 발생합니다.

위의 내용에서는 이해가지 않는 부분이 꽤 많았습니다. 다만 이 부분은 논리 프로세서가 가상화되어 VM Exit 가 유발되는 내용과 일반적인 프로세서에서 발생 가능한 오류 간의 우선순위에 대한 내용으로 이해하였습니다.

[-] Instructions That Cause VM Exits Unconditionally

해당 내용은 무조건 VM Exit 를 유발 시키는 명령에 대한 내용입니다.

아래 명령어는 VMX non-root operation 에서 실행 될 때 VM Exit 를 발생 시킵니다.

CPUID, GETSEC, INVD, XSETBV
INVEPT, INVVPID, 
VMCALL, VMCLEAR, VMLAUNCH, VMPTRLD, VMPTRST, VMRESUME, VMXON, VMXOFF ..(VMX instruction)

[-] Instructions That Cause VM Exits Conditionally

해당 내용은 특정 조건에 따라 VM Exit 를 유발 시키는 명령에 대한 내용입니다.

VMCS Data 내에서는 각 VMX Control 필드 기준으로 특정 필드가 1인 경우 특정 명령을 실행하면 VM Exit 가 발생한다라는 식으로 정리 했었습니다. 두 내용을 번갈아가면서 봐야 할 것 같습니다.

  • CLTS(Clear Task-Switched)
    • CLTS 명령은 CR0.TS 가 설정된 경우 VM Exit 를 발생시킵니다.
  • ENCLS(Execute Enclave System)
    • ENCLS 명령은 VMX Control 필드 내 enable ENCLS exiting 비트가 1로 설정된 경우 VM Exit 를 발생 시킵니다. 또한 아래의 조건 중에도 부합하면 발생합니다.
  • ENCLV(Execute Enclave VMM)
    • ENCLV 명령은 VMX Control 필드 내 enable ENCLV exiting 비트가 1로 설정된 경우와 아래 조건 중 부합하면 VM Exit 가 발생합니다.
  • HLT(Halt Processor)
    • HLT 명령은 VMX Control 필드 내 HLT exiting 비트가 1인 경우 VM Exit 가 발생합니다.
  • IN, INS/INSB/INSW/INSD, OUT, OUTS/OUTSB/OUTSW/OUTSD
    • 각 명령어들은 VMX Control 필드 내 unconditional I/O exiting 비트, use I/O bitmaps 비트의 설정에 따라 결정됩니다.
      • 해당 비트들이 모두 0이면 명령어는 정상적으로 동작합니다.
      • unconditional I/O exiting 비트가 1, use I/O bitmaps 가 0일 때, VM Exit 가 발생합니다.
      • use I/O bitmaps 가 1로 설정된 경우, 해당 I/O 비트맵에서 1로 설정된 비트에 해당하는 I/O 포트로 접근을 시도하는 경우 VM Exit 가 발생합니다.
      • I/O Operation 이 16bit의 I/O-port 공간을 감싸는 경우(port FFFFh, 0000h 에 접근) I/O 명령으로 인해 VM Exit 가 발생합니다.
  • INVLPG(Invalidate TLB Entry)
    • INVLPG 명령은 VMX Control 필드 내 INVLPG exting 비트가 1로 설정된 경우 VM Exit 를 발생시킵니다.
  • INVPCID(Invalidate Process-Context Identifier)
    • INVPCID 명령은 VMX Control 필드 내 INVLPG exting , enable INVPCID 비트가 모두 1인 경우 VM Exit 를 발생시킵니다.
  • LGDT, LIDT, LLDT, LTR, SGDT, SIDT, SLDT, STR
    • 각 명령어들은 VMX Control 필드 내 descriptor-table exiting 비트가 1인 경우 VM Exit 가 발생합니다. (Interrupt, global, local descriptor table, task register)
  • LMSW(Load Machine Status Word)
    • 참고 : 링크
    • LMSW 명령은 VMX Control 필드 내 CR0 Guest/Host Mask 의 하위 4비트에 설정된 비트가 CR0 Read Shadow의 동일한 하위 4비트와 다른 값을 쓰려고 하는 경우 VM Exit 가 발생합니다.
      • bit 0(CR0.PE)은 CR0 Guest/Host Mask 모두에 설정되고, CR0 Read Shadow 에서는 지워집니다.
  • LOADIWKEY(Load Internal Wrapping Key with Key Locker)
    • LOADIWKEY 명령은 VMX Control 필드 내 LOADIWKEY exiting 비트가 1인 경우 VM Exit 가 발생합니다.
  • MONITOR
    • MONITOR 명령은 VMX Control 필드 내 MONITOR exiting 비트가 1인 경우 VM Exit 가 발생합니다.
  • MOV from CR3
    • CR3 에서 복사하는 명령의 경우 VMX ControlCR3-store exiting 비트가 1인 경우 VM Exit 가 발생합니다.
  • MOV from CR8
    • CR8 에서 복사하는 명령의 경우 VMX ControlCR8-store exiting 비트가 1인 경우 VM Exit 가 발생합니다.
  • MOV to CR0
    • CR0 로 값을 쓰는 경우, 피연산자의 값이 CR0 Guest/Host Mask 에 설정 된 각 비트의 위치에 대해 CR0 Read Shadow 의 해당 비트와 일치하지 않으면 VM Exit 가 발생합니다.
  • MOV to CR3
    • 참고 : 링크
    • CR3 로 값을 쓰는 경우, VMX ControlCR3-load exting 비트가 0이거나 피연산자의 값이 VMCS 에 지정된 CR3-target 값이 동일하지 않는 경우 VM Exit 가 발생합니다. 처음 n개의 CR3-target 값 만 고려되며, 여기서 n은 CR3-target 개수 입니다.
    • CR3-load exting 비트가 1이고, CR3-target 개수가 0인 경우 해당 명령을 실행하면 무조건 VM Exit 가 발생합니다.
  • MOV to CR4
    • 참고 : 링크
    • 피연산자의 값이 CR4 Guest/Host Mask 에 설정된 값과 CR4 Read Shadow 에 설정된 비트와 일치하지 않으면 VM Exit 가 발생합니다.
  • MOV to CR8
    • CR8 로 값을 쓰는 경우, VMX Control 필드 내 CR8-load exiting 비트가 1이면 VM Exit 가 발생합니다.
  • MOV DR
    • MOV DR 명령의 경우 VMX Control 필드 내 MOV-DR exiting 비트가 1이면 VM Exit 가 발생합니다.
  • MWAIT(Monitor Wait)
    • MWAIT 명령의 경우 VMX Control 필드 내 MWAIT exiting 비트가 1이면 VM Exit 가 발생합니다.
    • 해당 비트가 0이면 MWAIT 명령의 행위가 변경될 수 있습니다. 이 내용은 아래에서 자세하게 다룹니다.
  • PAUSE
    • PAUSE 명령의 동작은 CPL, VMX Control 필드 내 PAUSE exiting 비트에 따라 달라집니다.
    • CPL = 0
      • PAUSE exiting 비트, PAUSE-loop exiting 비트가 모두 0 이면 정상적으로 실행됩니다.
      • PAUSE exiting 비트가 1인 경우 VM Exit 가 발생합니다.
      • 반대로 PAUSE exiting 비트가 0이고 PAUSE-loop exiting 비트가 1 인 경우는 아래와 같습니다.
      • 프로세서는 PAUSE 실행과 실행 이전의 시간을 확인합니다. 이 시간이 VMX Control 필드 내 PLE_Gap 값을 초과하면 프로세서는 이 실행을 루프에서 첫 번째 실행으로 간주합니다. 이 시간이 VMX Control 필드 내 PLE_WIndow 값을 초과하면 VM Exit 가 발생합니다.
    • CPL > 0
      • PAUSE exiting 비트가 0인 경우 정상적으로 실행됩니다.
      • PAUSE exiting 비트가 1인 경우 VM Exit 가 발생합니다.
      • CPL 이 0보단 큰 경우 PAUSE-loop exiting 비트는 무시됩니다.
  • PCONFIG(Platform Configuration)
    • 참고 : 링크
    • PCONFIG 명령은 VMX controlenable PCONFIG 비트가 1인 경우, 그리고 아래의 조건에 부합하는 경우 VM Exit 가 발생합니다.
      • EAX 값이 64보다 작고 PCONFIG-exiting bitmap 비트가 1인 경우
      • EAX 값이 63보다 크거나 같고 PCONFIG-exiting bitmap 비트가 1인 경우
    • enable PCONFIG 비트가 1이고 위의 두 항목 중 하나라도 일치되지 않는 경우에는 정상적으로 실행됩니다.
  • RDMSR(Read from Model Specific Register)
    • 참고 : 링크
    • RDMSR 명령의 경우 아래의 경우 중 해당하는 경우에 VM Exit 가 발생합니다.
      • VMX Control 필드 내 use MSR bitmaps 비트가 0인 경우
      • ECX 값이 범위 0000'0000h - 0000'1FFFh, C000'0000h - C000'CFFFh 가 아닌 경우
      • ECX 값이 범위 0000'0000h - 0000'1FFFh 에 있으며 Read bitmap for low MSRsECX 값에 해당하는 비트가 1인 경우
      • ECX 값이 범위 C000'0000h - C000'CFFFh 에 있으며 Read bitmap for high MSRsECX&1FFFh 값이 1인 경우
  • RDPMC(Read Performance Monitoring Counters)
    • RDPMC 명령의 경우 VMX Control 필드 내 RDPMC exiting 비트가 1인 경우 VM Exit 가 발생합니다.
  • RDRAND(Read Random Number)
    • RDRAND 명령의 경우 VMX Control 필드 내 RDRAND exiting 비트가 1인 경우 VM Exit 가 발생합니다.
  • RDSEED(Read Random SEED)
    • RDSEED 명령의 경우 VMX Control 필드 내 RDSEED exiting 비트가 1인 경우 VM Exit 가 발생합니다.
  • RDTSC(Read Time-Stamp Counter)
    • RDTSC 명령의 경우 VMX Control 필드 내 RDTSC exiting 비트가 1인 경우 VM Exit가 발생합니다.
  • RDTSCP(Read Time-Stamp Counter and Processor ID)
    • RDTSCP 명령의 경우 VMX Control 필드 내 RDTSC exiting 비트가 1이고 enable RDTSCP 비트가 1인 경우 VM Exit 가 발생합니다.
  • RSM(Resume from System Management Mode)
    • RSM 명령의 경우 SMM 에서 실행된 경우 VM Exit 가 발생합니다.
  • TPAUSE(Timed Pause)
    • TPAUSE 명령의 경우 VMX Control 필드 내 RDTSC exiting 비트가 1이고, enable user wait and pause 비트가 1인 경우 VM Exit 가 발생합니다.
  • UMWAIT(User Level Monitor Wait)
    • UMWAIT 명령의 경우 VMX Control 필드 내 RDTSC exiting 비트가 1이고, enable user wait and pause 비트가 1인 경우 VM Exit가 발생합니다.
  • VMREAD(Read Field from Virtual-Machine Control Structure)
    • VMREAD 명령의 경우 아래의 조건일 때 VM Exit 가 발생합니다.
      • VMX Control 필드 내 VMCS shadowing 비트가 0인 경우
      • 피연산자의 bit 63:15 가 0이 아닌 경우,
    • VMREAD 명령으로 인해 VM Exit가 발생하지 않는 경우, VMCS Link Pointer 참조를 통해 VMCS에서 읽습니다.
  • VMWRITE(Write Field to Virtual-Machine Control Structure)
    • VMREAD와 동일합니다.
  • WBINVD(Write Back and Invalidate Cache)
    • VMX Control 필드 내 WBINVD exiting 비트가 1인 경우 VM Exit가 발생합니다.
  • WBNOINVD(Write Back and Do Not Invalidate Cache)
    • VMX Control 필드 내 WBNOINVD exiting 비트가 1인 경우 VM Exit가 발생합니다.
  • WRMSR(Write to Model Specific Register)
    • WRMSR 명령은 아래에 해당하는 경우 VM Exit가 발생합니다.
      • VMX Control 필드 내 use MSR bitmaps 비트가 0인 경우
      • ECX 값의 범위가 0000'0000h - 0000'1FFFh , C000'0000h - C000'1FFFh 가 아닌 경우
      • ECX 값이 범위 0000'0000h - 0000'1FFFh 에 있으며 Write bitmap for low MSRsECX 값에 해당하는 비트가 1인 경우
      • ECX 값이 범위 C000'0000h - C000'CFFFh 에 있으며 Write bitmap for high MSRsECX&1FFFh 값이 1인 경우
  • XRSTORS(Restore Processor Extended States Supervisor)
    • 참고 : 링크
    • XRSTORS 명령은 VMX Control 필드 내 enable XSAVES/XRSTORS 비트가 1이고, EDX:EAX, IA32_XSS MSR, XSS-exiting bitmap 까지 세 값의 논리 AND 를 통해 설정된 모든 비트가 VM Exit를 발생시킵니다.
  • XSAVES(Save Processor Extended State Supervisor)
    • 참고 : 링크
    • XSAVES 명령은 VMX Control 필드 내 enable XSAVES/XRSTORS 비트가 1이고, EDX:EAX, IA32_XSS MSR, XSS-exiting bitmap 까지 세 값의 논리 AND 를 통해 설정된 모든 비트가 VM Exit를 발생시킵니다.

[0x02] Changes to Instruction Behavior in VMX Non-Root Operation

일부 명령어들의 동작은 VMX non-root operation 에서 변경됩니다. 즉 기존에 알고 있던 명령이라도 변경되어 예상과 다른 결과를 가지고 올 수 있을 수도 있고, 원하는 결과를 얻을 수도 있습니다.

때문에 해당 부분 또한 매우 중요하다고 생각됩니다.

아래는 이렇게 변경되는 명령어들과 어떻게 변경되는지에 대한 설명입니다. 각 설명 중 VM Exit가 발생하지 않는 조건에 대한 내용들이 있습니다. 해당 내용은 위에서 VM Exit가 발생하는 조건의 반대로 생각하면 이해하기 쉽습니다.

  • CLTS
    • CR0 guest/host maskCR0 read shadow 의 비트에 의해 동작이 결정됩니다.
      • CR0 guest/host mask 의 bit 3이 0이면 VMX Operation 에서 CR0.TS 가 1로 고정되지 않는 한 CLTSCR0.TS 를 정상적으로 지웁니다.
      • CR0 guest/host mask 의 bit 3이 1이고, CR0 read shadow 의 bit 3이 0이면, CLTS가 완료되지만 실제로 CR0.TS 값은 변경되지 않습니다.
      • 두 개의 비트맵이 모두 1인 경우 CLTSVM Exit가 발생합니다.
  • INVPCID
    • VMX Control 필드 내 enable INVPCID 비트에 따라 동작이 결정됩니다.
      • enable INVPCID 비트가 0이면, INVPCID 명령은 invalid-opcode 예외가 발생합니다.(#UD)
      • enable INVPCID 비트가 1인 경우, VMX Control 필드 내 INVLPG exiting 비트를 기반으로 나눠집니다.
        • INVLPG exiting 비트가 0인 경우 INVPCID 명령은 정상 실행됩니다.
        • INVLPG exiting 비트가 1인 경우, VM Exit가 발생합니다.
  • MOV from CR0
    • CR0 guest/host maskCR0 read shadow 에 의해 동작이 결정됩니다.
      • CR0 guest/host mask 에 0으로 설정된 비트에 해당하는 피연산자는 CR0 의 해당 비트 값으로 로드됩니다.
        • CR0 guest/host mask 에서 모든 비트가 0이면, MOV from CR0 의 경우 정상적으로 CR0 을 읽습니다.
      • CR0 read shadow 에 1으로 설정된 비트에 해당하는 피연산자는 CR0 read shadow 의 해당 비트 값으로 로드됩니다.
        • CR0 guest/host mask 에서 모든 비트가 1이면, CR0 read shadow 의 해당 비트 값으로 로드됩니다.
  • MOV from CR3
    • CR3-load exiting 비트가 0이고(VM Exit 가 발생하는 조건), enable EPT 비트가 1인 경우 CR3 에서 로드되는 값은 게스트의 물리 주소 입니다.
  • MOV from CR4
    • CR4 guest/host maskCR4 read shadow 에 의해 동작이 결정됩니다.
      • CR4 guest/host mask 에 0으로 설정된 비트에 해당하는 피연산자는 CR4 의 해당 비트 값으로 로드됩니다.
        • CR4 guest/host mask 에서 모든 비트가 0이면, MOV from CR4 의 경우 정상적으로 CR4 을 읽습니다.
      • CR4 read shadow 에 1으로 설정된 비트에 해당하는 피연산자는 CR4 read shadow 의 해당 비트 값으로 로드됩니다.
        • CR4 guest/host mask 에서 모든 비트가 1이면, CR4 read shadow 의 해당 비트 값으로 로드됩니다.
  • MOV from CR8
    • CR8-load exiting 비트가 0이고(VM Exit 가 발생하는 조건), use TPR shadow 비트가 1인 경우 동작이 변경됩니다. 해당 동작의 경우에는 다루지 않습니다.
  • MOV to CR0
    • VM Exit가 발생하지 않는 경우, CR0 guest/host mask 에 설정된 비트에 해당하는 CR0 의 모든 비트는 수정되지 않습니다. CR0 의 다른 비트를 수정하려는 시도의 처리는 unrestricted guest 비트에 따라 다릅니다.
    • 해당 내용은 다루지 않습니다. 일반적으로 CR0.PE,PG 에 따라 다릅니다.
  • MOV to CR3
    • VM Exit 가 발생하지 않고, enable EPT 비트가 1인 경우 CR3 의 값은 게스트의 물리 주소입니다.
      • PAE(Physical Address Extension) 페이징이 사용되지 않는 경우, 해당 명령은 게스트의 물리 주소에 접근하지 않으며 EPT를 통해 변환되지 않습니다.
      • PAE 페이징이 사용되는 경우, EPT를 통해 게스트의 물리 주소를 변환하고 그 결과를 사용하여 4개의 PDPTE(Page Directory Pointer Table Entries) 를 로드합니다.
        • 해당 명령은 게스트의 물리 주소를 사용하지 않고 PDPTE 를 통해 메모리에 접근하며 EPT 를 통해 변환되지 않습니다.
  • MOV to CR4
    • VM Exit가 발생하지 않는 경우, CR4 guest/host mask 에 1로 설정된 비트에 해당하는 CR4 의 비트는 수정되지 않습니다. 이러한 실행으로 인해 CR4 비트를 VMX Operation 에서 지원되지 않는 값으로 설정하려고 하면 general-protection exception(#GP) 가 발생합니다.
  • MOV to CR8
    • VM Exit 가 발생하지 않는 경우, use TPR shadow 에 따라 동작이 변경됩니다. 마찬가지로 해당 동작의 경우에는 다루지 않습니다.
  • MWAIT
    • CPL > 0 인 경우 발생하는 invalid-opcode exception(#UD)MWAIT exiting 비트에 의해 결정됩니다.
      • MWAIT exiting 비트가 1인 경우 VM Exit 가 발생합니다.
      • MWAIT exiting 비트가 0이고 아래의 경우에 해당하면 MWAIT 는 정상 동작합니다.
        • ECX[0] = 0, RFLAGS.IF = 1 또는 interrupt-window exiting 비트가 0이고, 논리 프로세서가 보류 중인 가상 인터럽트를 인시하지 못한 경우
        • 위와 반대의 경우에는 제어가 MWAIT 다음에 오는 명령으로 넘어가게 됩니다.
  • PCONFIG
    • enalbe PCONFIG 비트에 의해 동작이 결정됩니다.
      • enable PCONFIG 비트가 0으로 설정된 경우, PCONFIGinvalid-opcode exception(#UD) 를 발생시킵니다.
      • enable PCONFIG 비트가 1으로 설정된 경우, 지정된 대로 VM Exit 가 발생합니다. VM Exit 가 발생하지 않는 경우 정상적으로 동작합니다.
  • RDMSR
    • CPL > 0 로 인한 오류 또는 VM Exit 가 발생하지 않으면 ECX의 특정 값에 대해 동작이 변경됩니다.
    • 만약 ECX0000'0010h(IA32_TIME_STAMP_COUNTER MSR) 이 포함된 경우 명령에서 반환되는 값은 use TSC offsetting 에 따라 결정됩니다.
      • use TSC offsetting 비트가 0인 경우, RDMSR 정상적으로 동작합니다.
      • use TSC offsetting 비트가 1인 경우에는 use TSC scaling 비트에 따라 동작이 결정됩니다.
        • use TSC scaling 비트가 0인 경우 IA32_TIME_STAMP_COUNTER MSR 값과 TSC Offset 값의 합으로 반환합니다.
        • use TSC scaling 비트가 1인 경우 IA32_TIME_STAMP_COUNTER MSR 갑과 TSC multiplier 값을 곱합니다. 그 다음 해당 값을 48bit 오른쪽으로 시프트하고, 이동 된 값과 TSC Offset 값의 합으로 반환됩니다.
  • RDPID(Read Processor ID)
    • enable RDTSCP 비트의 값에 따라 결정됩니다.
      • enable RDTSCP 비트가 0인 경우, RDPID 명령은 invalid-opcode exception(#UD) 가 발생합니다.
      • enable RDTSCP 비트가 1인 경우, 정상적으로 동작합니다.
  • RDTSC
    • RDTSC exiting 비트와 use TSC offsetting 비트에 따라 결정됩니다.
      • 두 비트가 모두 0이면, RDSTC 는 정상적으로 동작합니다.
      • RDTSC exiting 비트가 0이고 use TSC offsetting 비트가 1인 경우에는 use TSC scaling 비트에 따라 결정됩니다.
        • use TSC scaling 비트가 0인 경우, IA32_TIME_STAMP_COUNTER MSR 의 값과 TSC offset 의 값의 합을 반환합니다.
        • use TSC scaling 비트가 1인 경우, IA32_TIME_STAMP_COUNTER MSR 의 값과 TSC multiflier 값을 곱합니다. 그 다음 해당 값을 48bit 오른쪽으로 시프트하고, 이동 된 값과 TSC offset 값의 합으로 반환됩니다.
      • RDTSC exiting 비트는 1인 경우 VM Exit 가 발생합니다.
  • RDTSCP
    • enable RDTSCP 비트에 의해 결정됩니다.
      • enable RDTSCP 비트가 0이면 invalid-opcode exception(#UD) 가 발생합니다.
      • enable RDTSCP 비트가 1이면 RDTSC exiting 비트와 TSC offsetting 비트에 따라 동작이 결정됩니다.
        • 두 비트가 모두 0이면 정상적으로 동작합니다.
        • RDTSC exiting 비트가 0이고 use TSC offsetting 비트가 1인 경우에는 use TSC scaling 비트에 따라 결정됩니다.
          • use TSC scaling 비트가 0인 경우, IA32_TIME_STAMP_COUNTER MSR 의 값과 TSC offset 의 값의 합을 반환합니다.
          • use TSC scaling 비트가 1인 경우, IA32_TIME_STAMP_COUNTER MSR 의 값과 TSC multiflier 값을 곱합니다. 그 다음 해당 값을 48bit 오른쪽으로 시프트하고, 이동 된 값과 TSC offset 값의 합으로 반환됩니다.
        • RDTSC exiting 비트는 1인 경우 VM Exit 가 발생합니다.
  • SMSW(Store Machine Status Word)
    • CR0 guest/host maskCR0 read shadow 에 의해 결정됩니다.
    • MOV from CR0 내용과 동일합니다. 단 WORD 값이기 때문에 CR0 guest/host maskCR0 read shadow 에서 하위 16비트만 사용됩니다.
  • TPAUSE(Timed Pause)
    • enable user wait and pause 비트에 의해 결정됩니다.
      • enable user wait and pause 비트가 0이면 invalid-opcode exception(#UD) 가 발생합니다.
      • enable user wait and pause 비트가 1이면 RDTSC exiting 비트에 따라 동작이 결정됩니다.
        • RDTSC exiting 비트가 0인 경우 physical delay 라고 하는 시간 동안 명령이 지연됩니다. physical delay 는 먼저 virtual delay (게스트의 TSC와 관련된 지연 시간)를 통해 계산됩니다.
        • 만약 IA32_UMWAIT_CONTROL[31:2] 가 0이면 virtual delay 는 EDX:EAX 의 값에서 RDTSC 가 반환하는 값을 뺀 값입니다. 반대의 경우 virtual delay 는 해당 차이와 AND(IA32_UMWAIT_CONTROL, FFFFFFFCh) 값의 최소 값 입니다.
        • physical delayenable TSC offsetting 비트와 use TSC scaling 비트에 따라 달라집니다.
          • 두 비트가 모두 0이면 physical delayvirtual delay 는 동일합니다.
          • 두 비트가 모두 1이면 virtual delay 에 2를 곱하여(시프트 연산 사용) 128 bit의 정수를 생성합니다. 그 다음 해당 값을 TSC multiplier 값과 나누어 64 bit 정수를 생성합니다. physical delay 는 해당하는 몫입니다.
        • RDTSC exiting 비트가 1인 경우 VM Exit 가 발생합니다.
  • UMONITOR(User Level Set Up Monitor Address)
    • enable user wait and pause 비트에 의해 결정됩니다.
      • enable user wait and pause 가 0인 경우 invalid-opcode exception(#UD) 가 발생합니다.
      • enable user wait and pause 가 1인 경우 명령은 정상 동작합니다.
  • UMWAIT
    • TPAUSE 명령과 동일합니다.
  • WRMSR
    • CPL > 0 으로 인한 오류 또는 VM Exit 가 아닌 경우 ECX 의 특정 값에 대해 동작이 변경됩니다.
    • ECX0000'0079h(IA32_BIOS_UPDT_TRIG MSR)가 포함되어 있으면 microcode 가 업데이트가 로드되지 않고 제어가 다음 명령어로 넘어갑니다. 이는 VMX non-root operation 에서 microcode 업데이트를 로드할 수 없음을 의미합니다.
    • Intel PT(Processor Trace) 를 지원하지만 VMX Operation 에서 사용할 수 없는 프로세서에 0000'0570h(IA32_RTIT_CTL MSR)이 포함되어 있으면 해당 명령은 general-protection exception(#GP) 가 발생합니다.
  • XSAVES/XRSTORS
    • enable XSAVES/XRSTORS 비트에 따라 동작이 결정됩니다.
      • enable XSAVES/XRSTORS 비트가 0인 경우 invalid-opcode exception(#UD) 가 발생합니다.
      • enable XSAVES/XRSTORS 비트가 1인 경우 XSS-exiting bitmap 을 기반으로 동작합니다.
        • 기존 VM Exit 발생 조건과 동일합니다. 그 외에는 정상 동작합니다.

[0x03] Features Specific To VMX Non-Root Operation

몇몇의 VM-execution controlsVMX non-root operation 과 관련된 기능들을 지원합니다.

VMX Preemption Timer, Monitor Trap Flag, 게스트 물리 주소 변환, APIC 가상화, VM Functions, 가상화 예외입니다.

[-] VMX-Preemption Timer

마지막 VM Entryactivate VMX-preemption timer 비트가 1로 설정되어 수행된 경우, VMX non-root operation 에서 VMX-preemption timerVM Entry 에 의해 로드된 값에서 카운트 다운됩니다.

타이머가 0이 되면 카운트다운은 중지되고 VM Exit 가 발생합니다.

VMX-preemption timerTSC에 비례하는 속도로 카운트 다운이 진행됩니다. 특히 타이머는 TSC 증가로 인해 TSC 의 비트 x가 변경될 때 마다 1씩 카운트다운 됩니다. x 값은 0-31 범위에 있으며 MSR IA32_VMX_MISC 를 참조하여 결정할 수 있습니다.

SMM(System Management Mode 의 경우 해당 챕터에서는 생략합니다.

[-] Monitor Trap Flag

Monitor Trap Flag(MTF)VMX non-root operation 의 특정 명령 경계에서 VM Exit 가 발생하도록 하는 디버깅 기능입니다. 이러한 VM EixtMTF VM Exit 라고 합니다. MTF VM Exit 는 다음과 같이 발생할 수 있습니다.

  • VMX Control 필드 내 monitor trap flag 비트가 1이고, VM Entryvectored event 를 주입하는 경우 MTF VM ExitVM Entry 다음에 오는 첫 번째 명령어 이전 명령의 경계에서 보류합니다.
  • VM Entry 가 보류 중인 MTF VM Exit 를 주입하는 경우, MTF VM ExitVM Entry 다음에 오는 첫 번째 명령 이전 명령의 경계에서 보류합니다. 이는 monitor trap flag 비트가 0인 경우에도 마찬가지 입니다.
  • monitor trap flag 가 1이고, VM Entry 가 이벤트를 주입하지 않고, 명령을 실행할 수 있기 전에 보류 중인 이벤트(ex. debug exception, interrupt…)가 전달되면 이벤트(또는 중첩된 예외) 전달 후 MTF VM Exit 는 보류됩니다.
  • 예를 들어, monitor trap flag 가 1이고 VM Entry 가 이벤트를 주입하지 않고 다음의 첫 번째 명령이 REP 접두사가 붙은 문자열 명령이라고 가정합니다.
    • 명령의 첫 번째 반복으로 인해 오류가 발생하면 오류(또는 중첩된 예외)가 전달된 후 명령 경계에서 MTF VM Exit 가 보류됩니다.
    • 명령의 첫 번째 반복이 오류를 일으키지 않으면 MTF VM Exit 는 해당 반복 후에 명령 경계에서 보류됩니다.
  • MTF VM Exit 가 보류 중인 명령 경계에 도착하기 전에 VM Exit 가 발생하는 경우(ex. triple fault) MTF VM Exit 는 발생하지 않습니다.

[-] Translation of Guest-Physical Addresses Using EPT

EPT(Extended Page-Table Mechanism) 은 물리 메모리의 가상화를 지원하는 데 사용할 수 있는 기능입니다. EPT 가 사용 중일 때 특정 물리 주소는 게스트의 물리 주소로 취급되며 메모리에 직접 액세스하는 데 사용되지 않습니다.

대신 게스트 물리 주소는 메모리 액세스에 사용되는 별도의 물리 주소를 생성하기 위해 일련의 EPT 페이징 구조를 통해 변환됩니다. EPT 에 대한 상세 메커니즘은 추후에 다루게 됩니다.

[-] Translation of Guest-Physical Addresses Used by Intel Processor Trace

Trace 출력은 물리 주소를 이용하여 메모리에 기록되도록 Intel PT 를 구성할 수 있습니다. 예를 들어 ToPA(Table Of Physical Addresses) 출력 메커니즘이 사용되는 경우 IA32_RTIT_OUTPUT_BASE MSR 에는 현재 ToPA 의 기본 물리 주소가 포함됩니다.

해당 테이블의 각 엔트리는 메모리에 있는 출력 영역의 물리 주소가 포함됩니다. 출력 영역이 가득 차면 ToPA 출력 메커니즘은 trace 출력을 ToPA 에 표시된 대로 다음 출력 영역으로 보내게 됩니다.

VMX Control 필드 내 Intel PT uses guest physical addresses 가 1인 경우 논리 프로세서는 Intel PT 에서 사용하는 주소(출력 주소 및 출력 주소를 검색하는데 사용되는 주소)를 게스트 물리 주소로 처리하여 trace 출력이 메모리에 기록되기 전에 EPT 를 사용하여 물리 주소로 변환합니다.

EPT 를 통해 변환하는 것은 Trace-output mechanismEPT violation, VM Exit 를 유발할 수 있음을 의미합니다.

  • EPT violation 또는 EPT misconfiguration 오류가 발생하지 않고 Page-Modification Logging 이 활성화 된 경우 출력 영역의 주소가 Page-Modification Log 에 포함될 수 있습니다. 로그가 가득차면 Page-Modification Logfull 이벤트가 발생하여 VM Exit 가 발생합니다.
  • virtualize APIC accesses 가 1인 경우, Trace-output 프로세스에서 사용하는 게스트 물리 주소가 APIC-access page 의 주소로 변환될 수 있습니다.

[+] Trace-Address Pre-Translation(TAPT)

트레이스 출력을 메모리에 쓰기 전에 Intel PT 에서 생성된 추적 데이터를 버퍼링하기 때문에 프로세서는 VM ExitIntel PT 를 사용하지 않도록 설정해도 버퍼링된 데이터가 손실되지 않도록 보장합니다.

특히 프로세서는 현재 출력 페이지에 버퍼링 된 데이터를 위한 충분한 공간이 있는지 확인합니다. 이렇게 하지 않으면 버퍼링 된 트레이스 데이터가 손실되고 결과가 손상될 수 있습니다.

버퍼링 된 트레이스 데이터의 손실을 방지하기 위해 프로세서는 TAPT 라는 메커니즘을 사용합니다. TAPT 를 사용하면 프로세서는 EPT를 사용하여 현재 출력 영역의 게스트 주소를 변환한 다음 해당 주소를 사용하여 버퍼링 된 트레이스 데이터를 메모리에 기록합니다.

TAPT 덕분에 출력이 메모리에 기록 될 때 변환, EPT Violation 이 발생하지 않습니다. 메모리에 쓰기는 TAPT 의 일부로 캐시된 변환을 사용합니다. TAPT 는 출력 영역에 대한 쓰기가 EPT Violation 을 발생시킬 경우, 해당 영역이 사용되기 전에 TAPT 시점에 VM Exit 가 전달되도록 합니다. 이를 통해 VMM 은 해당 시점에 EPT Violation 을 해결할 수 있으며 버퍼링 된 트레이스 데이터를 ㅔㅁ모리에 기록해야 할 때 해당 데이터가 EPT Violation 으로 인해 손실되는 것을 방지할 수 있습니다.

[-] APIC Virtualization

APIC 가상화는 인터럽트 가상화 및 APIC(Advanced Programmable Interrupt Controller) 를 지원하는 데 사용할 수 있는 다수의 기능입니다. APIC 가상화가 활성화되면, 프로세서는 APIC에 대한 많은 액세스를 에뮬레이트하고 가상 APIC 의 상태를 추적하며 가상 인터럽트를 전달합니다. 이 모든 것은 VM Exit 없이 VMX non-root operation 에서 이루어집니다.

[-] VM Functions

VM FunctionVM Exit 없이 VMX non-root operation 에서 호출할 수 있는 프로세서에서 제공하는 기능입니다. VM FunctionVMCS의 다른 필드 설정에 의해 활성화되고 구성됩니다.

VMX non-root operation 의 소프트웨어는 VMFUNC 명령을 통해 각 기능을 호출합니다. EAX 의 값은 호출되는 특정 기능을 선택합니다.

[+] Enabling VM Functions

VMM 은 일반적으로 VMX Control 필드 내 enable VM functions 기능을 통해 VM Function 을 활성화할 수 있습니다. 몇몇 기능은 VM-function control 을 통해 활성화합니다.

예를 들어 VMMEPTP switching 기능을 활성화한다고 가정해보겠습니다.

그러기 위해선 우선 activate secondary controls 를 설정해야 합니다. 그리고 난 후, enable VM functions 를 활성화하고 VM-function control 필드 내 EPTP swithcing 비트를 설정해야 합니다.

[+] General Operation of the VMFUNC Instruction

VMFUNC 명령은 enable VM functions 가 0이거나 EAX 값이 63보다 큰 경우 invalid-opcode exception(#UD) 가 발생합니다. 그렇지 않고 VM-function control 에서 EAX 위치가 0이면 명령은 VM Exit 가 발생합니다.(선택한 VM function 은 활성화되지 않음)

이러한 VM Exit 가 발생하면 사용되는 기본 종료 사유는 VMFUNC 를 나타내는 59(3Bh) 이며 VMFUNC 명령의 길이는 VM-exit instruction-length 필드에 저장됩니다.

위와 같은 경우들이 아닌 경우 EAX 값으로 지정된 VM function 을 호출합니다.

VM Function 의 기능들은 추가 오류 검사를 수행할 수 있습니다. 예를 들어 CPL > 0 인 경우 general-protection exception(#GP) 같은 경우 입니다. 또한 특정 VM Function 에는 VM Exit 가 발생할 수 있는 것에 대한 검사가 포함될 수 있습니다.

이러한 경우 VM Exit 가 발생하면 VM Exit 정보를 저장합니다.

[+] EPTP Switching

※ 참고 : 링크1, 링크2

EPTPT SwitchingVM Function 0에 해당합니다. 이 기능이 호출되면 VMX non-root operationVMMEPTP 에 대한 새 값을 로드할 수 있도록 다른 EPT 페이징 구조 계층을 설정할 수 있습니다.

VMMVMX root operation 에서 VMM 에 의해 미리 구성된 잠재적 EPTP 값 목록에서 선택하는 것으로 제한됩니다.

특히 ECX 값은 EPTP-list address 에서 참조하는 4kb 구조인 EPTP-list 에서 엔트리를 선택하는 데 사용됩니다. 선택한 엔트리가 유효한 EPTP 값이면 현재 VMCSEPTP 필드에 저장되고 게스트 물리 주소에 접근하는데 사용됩니다.

아래는 이에 대한 의사코드 입니다.

EPTP-switching 실행(VM function)은 레지스터의 상태와 플래그가 수정되지 않습니다. Intel PT uses guest physical address 비트가 1이고 IA32_RTIT_CTL.TraceEn = 1 인 경우 해당 기능이 호출되면 VM Exit가 발생합니다.

VMFUNC 를 통해 EPTP-list 에서 EPTP를 로드하는 것에 대해 EPTP-switching VMFUNC 라고 부릅니다.

EPTP-switching VMFUNC 실행 후에 제어는 다음 명령으로 넘어갑니다. 논리 프로세서는 EPTP 의 bit 51:12 의 새로운 값과 관련된 게스트 물리 매핑 및 결합된 매핑을 생성하고 사용하기 시작합니다.

생성된 매핑은 현재 VPIDPCID 와 연결됩니다.

EPTP-switching VMFUNC 실행은 게스트 물리 주소의 변환을 변경할 수 있으므로 CR3 에서 게스트 물리 주소 사용에 영향을 미칠 수 있습니다. EPTP-switching VMFUNC 은 새로운 EPT 페이징 구조를 통한 게스트 물리 주소 변환으로 발생한 EPT Violation 또는 EPT misconfiguration 으로 인해 VM Exit 가 발생할 수 없습니다.

다음은 CR0Paging 비트가 1인 경우 적용되는 세부 사항에 대한 내용입니다.

  • 32bit 페이징 또는 4-Level Paging 이 사용 중인 경우(CR4.PAE = 0 or IA32_EFER.LMA = 1) 선형 주소를 사용하는 다음 메모리 액세스는 새로운 EPT 페이징 구조를 통해 CR3 의 게스트 물리 주소 변환을 사용합니다. 따라서 액세스로 인해 EPT Violation 이 발생할 수 있으며, 변환 중에 발생하는 EPT Misconfiguration 으로 인해 VM Exit 가 발생할 수 있습니다.
  • PAE 페이징이 사용 중인 경우(CR4.PAE = 1, IA32_EFER.LMA = 0) EPTP-switching VMFUNCCR3 의 게스트 물리 주소에서 4개의 PDPTE 를 로드하지 않습니다. 논리 프로세서는 PDPTE 에 이미 있는 4개의 게스트 물리 주소를 계속해서 사용합니다. CR3 의 게스트 물리 주소는 새로운 EPT 페이징 구조를 통해 변환되지 않습니다.

EPTP-switching VMFUNCPDPTE 에서 게스트 물리 주소를 변환하는 동안 EPT Violation 또는 EPT Misconfiguration 으로 인한 VM Exit가 발생할 수 없습니다. 선형 주소를 사용하는 후속 메모리 접근은 새로운 EPT 페이징 구조를 통해 적절한 PDPTE 의 게스트 물리 주소 변환을 사용합니다. 따라서 이러한 액세스로 인해 EPT Violation 이 발생할 수 있으며, 변환 중에 발생하는 EPT Misconfiguration 으로 인해 VM Exit 가 발생할 수 있습니다.

[-] Virtualization Exceptions

가상화 예외는 새로운 프로세서 예외입니다. 벡터 20을 사용하며 #VE 라고 합니다.

가상화 예외는 VMX non-root operation 에서만 발생할 수 있으며, 특정한 VMX Control 필드의 설정에 의해서만 발생합니다.

일반적으로 이러한 설정은 VM Exit 를 발생시키는 특정 조건에 따라 가상화 예외를 유발시킬 수 있음을 의미합니다.

특히 EPT-violation #VE 제어를 1로 설정하는 경우 일부 EPT Violation 으로 인한 VM Exit 대신 가상화 예외가 생성되도록 합니다.

[+] Convertible EPT Violations

EPT-violation #VE 제어가 0인 경우 EPT Violation 으로 인해 항상 VM Exit 가 발생하게 됩니다. 해당 비트가 1인 경우에는 특정 EPT Violation 은 변환되어 가상화 예외가 발생합니다. 이러한 변환에 대해 convertible (변환 가능한) EPT Violation 이라고 합니다. 상세 내용은 생략합니다.

[+] Virtualization-Exception Information

가상화 예외는 Virtualization-exception information 영역에 정보가 저장됩니다. VMM 은 이러한 영역에 Guest 가 접근할 수 있도록 허용할 수 있습니다. 그러면 Guest 는 해당 메모리를 수정할 수 있습니다.

[+] Delivery of Virtualization Exceptions

Virtualization-exception information 을 저장한 후 프로세서는 다른 예외와 마찬가지로 가상화 예외를 처리합니다.

※ 참고 : 링크

  • VMCSException bitmap 에서 bit 20(#VE)이 1이면 가상화 예외로 인해 VM Exit 가 발생합니다. 비트가 0이면 IDTgate descriptor 20을 사용하여 가상화 예외가 전달됩니다.
  • 가상화 예외는 오류 코드를 생성하지 않습니다. 가상화 예외는 전달되면 스택에 오류 코드가 푸시되지 않습니다.
  • 가상화 예외로 인한 VM Exit 가 직접 발생(Exception bitmap 내 bit 20 = 1)하는 경우 예외에 대한 정보는 VMCSVM-exit interruption information 필드에 저장됩니다.

[0x04] Conclusion

현재 본인이 추구하는 바와는 다른 불필요한 내용도 분명이 섞여있다고 느껴집니다.

다만 한 챕터의 번역을 끝내고, 해당 내용을 토대로 복습을 하니 이해하지 못했던 부분들이 이해가 가고 있습니다.

빨리 모든 챕터를 끝내고 구현해보고 싶습니다.

[0x05] Reference

  1. Intel 64 and IA-32 Architectures Software Developer’s Manual