[0x00] Concept
이전 챕터에서는 VMX Non-Root Operation 에 대한 내용에 대해 알아보았습니다. 대부분의 내용은 VM Exit 가 발생하는 조건에 대해 초점이 맞춰있으며 그 외에는 VM Function 등이 있었습니다.
아직도 매우 먼 길이 남았습니다.
본인은 해당 내용을 우선적으로 번역하며 이해하려고 노력할 것이고 그 이후에 구현을 할 예정입니다.
이번 챕터에서는 주로 VM Entry 에서 발생하는 여러가지 검사에 대한 내용을 다루게 됩니다.
양이 방대하여 2개의 파트로 나누어 게시됩니다.
대부분은 번역의 내용입니다.
우선 VM Entry 는 아래의 순서대로 수행됩니다.
VM Entry가 시작될 수 있는지 확인하기 위한 기본 검사가 수행됩니다.VMCS의 제어 및 호스트 상태 영역은VMX non-root operation을 지원하는데 적절하고VMCS가 다음VM Exit를 지원하도록 올바르게 구성되어 있는지 확인합니다.- 다음은 병렬 또는 임의의 순서로 수행될 수 있습니다.
VMCS의 게스트 상태 영역은VM Entry가 완료된 후 논리 프로세서의 상태가IA-32, IA64아키텍처와 일치하는지 확인합니다.- 프로세서 상태는 게스트 상태 영역에서 로드되며
VMCS의 제어를 기반으로 합니다. Address-range monitoring을 지웁니다.
MSR은VM-entry MSR-load area에서 로드됩니다.VMLAUNCH가 실행되면VMCS의launch state를launched로 설정합니다.Second_Intel PT uses guest physical address제어가 1인 경우TAPT(Trace-Address Pre-Translation)이 발생할 수 있습니다.- 게스트 컨텍스트에서 이벤트가 주입될 수 있습니다.
위의 1-4 단계는 VM Entry 실패를 유발할 수 있는 검사를 수행합니다.
[0x01] Basic VM-Entry Checks
VM Entry 가 시작되기 전에 논리 프로세서의 현재 상태가 다음 순서로 확인됩니다.
- 논리 프로세서가
Virtual-8086모드 또는Compatibility모드에 있는 경우invalid-opcode exception이 발생합니다. CPL이 0이 아니면general-protection exception이 발생합니다.Current상태의VMCS가 없으면RFLAGS.CF가 1로 설정되고 제어가 다음 명령으로 넘어갑니다.Current상태의VMCS가 있지만Current상태의VMCS가Shadow VMCS인 경우RFLAGS.CF가 1로 설정되고 제어는 다음 명령어로 넘어갑니다.Shadow VMCS가 아닌Current상태의VMCS가 존재하는 경우 다음 조건을 순서대로 평가합니다.MOV-SS blocking이 설정되어 있는 경우(Interruptibility State)VM Entry가VMLAUNCH에 의해 호출되고VMCS의Launch State가Clear상태가 아닌 경우VM Entry가VMRESUME에 의해 호출되고VMCS의Launch State가Launched상태가 아닌 경우
위에 검사 중 하나라도 확인되어 실패하게 되면 RFLAGS.ZF=1 으로 설정되고 제어가 다음 명령어로 넘어갑니다. VM-instruction error 필드에는 원인을 나타내는 에러 번호가 저장됩니다.
[0x02] Checks On VMX Controls And Host-State Area
위의 검사에서 실패하지 않고 통과하게 되면 VMCS 의 Control 및 Host-State Area 가 VMX non-root operation 을 지원하기에 적합한지, 올바르게 구성되었는지 확인합니다.
해당 검사가 실패하면 RFLAGS.ZF=1 으로 설정되며 VM-instruction error 필드에는 오류가 VMX Control 때문인지, Host-State Area 때문인지를 나타내는 오류 번호가 저장됩니다.
이러한 검사는 어떤 순서로든 수행할 수 있습니다. 따라서 하나의 원인의 오류 번호로 표시하는 것이 다른 오류가 없음을 의미하지는 않습니다. 따라서 다른 프로세서는 동일한 VMCS에 대해 다른 오류 번호를 제공할 수 있습니다.
[-] VM-Execution Control Fields
VM Entry 는 VM-execution control fields 에서 다음 검사를 수행합니다. 각 설명에 예약된 비트란 MSR 에 따라 0 또는 1 로 설정되어야 하는 값을 의미하는 것으로 이해하였습니다.
각각의 VMX Control 의 경우 각각에 앞 글자에 맞게 접두사를 넣어 사용하겠습니다.
예를 들어, Primary Processor-Based VM-execution controls 필드 내 activate secondary controls 를 표현하면 PR_activate secondary controls 입니다.
Pin-Based VM-execution controls의 예약된 비트는 올바르게 설정되어야 합니다.VMM은VMX관련MSR을 참조하여 예약된 비트를 결정할 수 있습니다.(참고 : 링크)
Processor-Based VM-execution controls의 예약된 비트는 올바르게 설정되어야 합니다.VMM은VMX관련MSR을 참조하여 예약된 비트를 결정할 수 있습니다.(참고 : 링크)
PR_activate secondary controls비트가 1로 설정된 경우Secondary Processor-Based VM-execution controls예약된 비트를 모두 0으로 설정해야 합니다.VMM은VMX관련MSR을 참조하여 예약된 비트를 결정할 수 있습니다.(위의 참고와 동일)
PR_activate tertiary controls비트가 1로 설정된 경우Tertiary Processor-Based VM-execution controls의 예약된 비트를 모두 0으로 설정해야 합니다.VMM은VMX관련MSR을 참조하여 예약된 비트를 결정할 수 있습니다.(위의 참고와 동일)
CR3-target count는 4보다 커서는 안됩니다.VMM은MSR IA32_VMX_MISC를 읽어 지원되는 개수를 결정해야 합니다.(참고 : 링크)
PR_use I/O bitmaps비트가 1인 경우 각I/O-bitmap address의 bit 11:0 은 0이어야 합니다. 두 주소 모두 물리 주소의 너비를 초과하는 비트를 설정하면 안됩니다.PR_use MSR bitmaps비트가 1인 경우MSR-bitmap address의 bit 11:0 은 0이어야 합니다. 주소는 물리 주소 너비를 초과하는 비트를 설정하면 안됩니다.PR_use TPR shadow비트가 1인 경우virtual-APIC address의 bit 11:0 은 0이어야 합니다. 주소는 물리 주소 너비를 초과하는 비트를 설정하면 안됩니다.PR_use TPR shadow비트가 1이고,Second_virtual-interrupt delivery비트가 0인 경우,TPR threshold의 bit 31:4 는 0이어야 합니다.PR_use TPR shadow비트가 1이고,Second_virtualize APIC accesses,virtual-interrupt delivery비트가 모두 0인 경우TPR threshold의 bit 3:0 값이VTPR의bit 7:4보다 커서는 안됩니다.PR_use TPR shadow비트가 0일 때는 아래의 제어 역시 0이어야 합니다.Second_virtualize x2APIC mode,APIC-register virtualization,virtual-interrupt delivery
Second_virtualize X2APIC mode가 1인 경우,virtualize APIC accesses제어는 0이어야 합니다.Second_virtualize APIC-accesses비트가 1인 경우APIC-access address의 bit 11:0 은 0이어야 하며, 주소는 물리 주소 너비를 초과하는 비트를 설정하면 안됩니다.Second_virtual-interrupt delivery비트가 1인 경우Pin_external-interrupt exiting비트가 1이어야 합니다.Pin_process posted interrupts비트가 1인 경우 아래 조건이 참이어야 합니다.Second_virtual-interrupt delivery비트가 1이어야 합니다.VM-exit controls내acknowledge interrupt on exit비트가 1이어야 합니다.posted-interrupt notification벡터의 범위는 0-255 입니다. 즉, bits 15:8 은 0이어야 합니다.posted-interrupt descriptor의 bits 5:0은 모두 0이어야 합니다.posted-interrupt descriptor의 주소는 물리 주소 너비를 초과해서는 안됩니다.
Pin_NMI exiting비트가 1인 경우virtual NMIs비트는 0이어야 합니다.Pin_virtual NMIs비트가 0인 경우PR_NMI-window exiting비트가 0이어야 합니다.Second_enable VPID비트가 1인 경우,VPID의 값은 0이 아니어야 합니다. (참고 : 링크)Second_enable EPT비트가 1인 경우EPTP필드는 아래 사항을 충족해야 합니다. (참고 : 링크)EPT paging-structure memory type(bits 2:0)은IA32_VMX_EPT_VPID_CAP MSR에 표시된 대로 프로세서에서 지원하는 값이어야 합니다.1 less than EPT page-walk length(bits 5:3)은 3이어야 하며, 이는EPT page-walk length가 4임을 의미합니다.enable bit for accessed and dirty flags for EPT(bit 6)는IA32_VMX_EPT_VPID_CAP_MSR의 bit 21이 0으로 읽혀지면 0이어야 합니다. 이는 프로세서가EPT에 대한 액세스 및dirty flag를 지원하지 않음을 나타냅니다.- 예약된 비트 bits 11:8 및 63:N 은 모두 0이어야 합니다.(EPTP)
Second_enable EPT비트가 1인 경우 다음 제어 비트 중 하나는 반드시 1이어야 합니다.Second_enable PML,Second_unrestricted guest,Second_mode-based execute control for EPT,Second_sub-page write permissions for EPT,Second_Interl PT uses guest physical addressesTertiary_enable HLAT,Tertiary_EPT paging-write control,Tertiary_guest-paging verification
Second_enable PML이 1인 경우PML address의 bit 11:0 은 0이어야 하며, 주소는 물리 주소 너비를 초과하는 비트를 설정하면 안됩니다.Second_sub-page write permissions for EPT가 1인 경우SPPTP는 bit 11:0 은 0이어야 하며, 주소는 물리 주소 너비를 초과하는 비트를 설정하면 안됩니다.Second_enable VM functions제어가 1인 경우VM-function control의 예약된 비트들은 0으로 설정해야 합니다.VMM은VMX관련MSR을 참조하여 예약된 비트를 결정할 수 있습니다.(참고 : 링크)
VM-function control에 설정되는 값에 따라 아래의 검사가 수행됩니다.EPTP switching제어가 1이면Second_enable EPT제어도 1이어야 합니다.EPTP-list주소는 bit 11:0 은 0이어야 하며, 물리 주소 너비를 초과하는 비트를 설정하면 안됩니다.
Second_VMCS shadowing제어가 1이면VMREAD-bitmap,VMWRITE_bitmap주소의 bit 11:0 은 0이어야 하며, 물리 주소 너비를 초과하는 비트를 설정하면 안됩니다.Second_EPT-violation #VE제어가 1인 경우virtualization-exception information주소의 bit 11:0 은 0이어야 하며, 물리 주소 너비를 초과하는 비트를 설정하면 안됩니다.- 논리 프로세서가
VM Entry시점에Intel PT가 활성화 된 경우(IA32_RITI_CTL.TraceEn=1)VMEntry_load IA32_RTIT_CTL제어는 반드시 0이어야 합니다.
[-] VM-Exit Control Fields
VM Entry 는 VM-Exit Control Fields 에서 아래의 내용에 부합하는지에 대한 검사가 수행됩니다.
Primary VM-exit controls의 예약된 비트는 올바르게 설정되어야 합니다.VMM은VMX관련MSR을 참조하여 예약된 비트를 결정할 수 있습니다.(참고 : 링크)
VMExit_activate secondary controls제어가 1이면Secondary VM-Exit controls의 예약된 비트를 0으로 설정해야 합니다.VMM은VMX관련MSR을 참조하여 예약된 비트를 결정할 수 있습니다.(현재 정의되어 있지 않음)
Pin_activate VMX-preemption timer제어가 0이면VMExit_save VMX-preemption timer value제어도 0이어야 합니다.VMExit_MSR-store count필드가 0이 아닌 경우,MSR-store주소에 대해 아래 검사가 수행됩니다.MSR-store주소의 하위 4비트는 0이어야 합니다. 주소는 물리 주소 너비를 초과하는 비트를 설정하면 안됩니다.MSR-store영역의 마지막 바이트 주소는MSR-store 주소 + (MSR count * 16) -1입니다.
VMExit_MSR-load count필드가 0이 아닌 경우,MSR-load주소에 대해 아래 검사가 수행됩니다.MSR-load주소의 하위 4비트는 0이어야 합니다. 주소는 물리 주소 너비를 초과하는 비트를 설정하면 안됩니다.MSR-load영역의 마지막 바이트 주소는MSR-load주소 + (MSR count * 16) -1입니다.
[-] VM-Entry Control Fields
VM Entry 는 VM-Entry Control Fields 에서 아래의 검사를 수행합니다.
VM-Entry Controls의 예약된 비트는 적절하게 설정되어야 합니다.VMM은VMX관련MSR을 참조하여 예약된 비트를 결정할 수 있습니다.(참고 : 링크)
VM-Entry Event Injection과 관련된 필드를 올바르게 설정해야 합니다. 해당 필드는VM-entry interruption-information,VM-entry exception error code,VM-entry instruction length필드 입니다.VM-entry interruption-information필드의Valid(bit 31)가 1인 경우 아래와 같아야 합니다.interruption type(bits 10:8)이 예약된 값으로 설정되면 안됩니다. 두 개의 값으로Reserved(1)의 경우 모든 논리 프로세서에 예약되어 있습니다.Other Event type(7)은MTF설정을 지원하지 않는 논리 프로세서에 예약되어 있습니다.Vector(bits 7:0)는interruption type과 일치해야 합니다.interruption type이NMI(2)인 경우Vector는 2이어야 합니다.interruption type이hardware exception(3)인 경우 벡터는 최대 31입니다.interruption type이Other event(7)인 경우 벡터는 0입니다.(MTF VM Exit보류)
deliver-error-code(bit 11)은 다음 항목이 성립하는 경우 1로 고정됩니다.interruption type이hardware exception입니다.CR0.PE비트가Guest-State Area의CR0에 설정됩니다.IA32_VMX_BASIC[56](deliver a Hardware exception)은 0 입니다.- 벡터가 다음 중 하나를 나타냅니다.(
#DF(8), #TS(10), #NP(11), #SS(12), #GP(13), #PF(14), #AC(17))
deliver-error-code은 위와 반대의 경우에는 0으로 고정됩니다.deliver-error-code가 1인 경우VM-entry exception error-code필드의 bits 31:16 은 0입니다.interruption type이software interrup, software exception, privileged software exception인 경우VM-entry instruction-length필드는 0-15 범위 안에 있습니다.VM-entry instruction-length가 0일 수 있는 조건은IA32_VMX_MISC[30](allow zero length event injection)가 1로 설정된 경우에만 가능합니다.
VM-entry MSR-load count필드가 0인 경우VM-entry MSR-load address필드에 대해 아래 검사가 수행됩니다.VM-entry MSR-load address의 하위 4비트는 0이어야 합니다. 주소는 프로세서의 물리 주소 너비를 초과하는 비트를 설정하면 안됩니다.VM-entry MSR-load address의 마지막 바이트 주소는VM-entry MSR-load address + (MSR count * 16) -1입니다.IA32_VMX_BASIC[48](is 32bit addresses limit bit)가 1로 설정된 경우 bits 63:32 범위의 비트를 설정해서는 안됩니다.
- 프로세서가
System Management Mode가 아닌 경우VMEntry_entry to SMM,VMEntry_deactivate dual-monitor treatment제어가 0이어야 합니다.VMEntry_entry to SMM,VMEntry_deactivate dual-monitor treatment두 개의 제어 비트는 한번에 1일 수 없습니다.(둘 중 하나만 1)
[-] Checks on Host Control Register, MSRs and SSP(Shadow-Stack Pointer)
Control Register 및 MSR 에 해당하는 Host-State Area 의 필드에 대해 다음 검사가 수행됩니다.
CR0,CR4필드는VMX Operation에서 지원되지 않는 비트를 설정해서는 안됩니다. (참고 : 링크,IA32_VMX_CR0,4_FIXED0,1)CR4필드의 bit 23(CET, Control-flow Enforcement Technology)가 1이면CR0필드의 bit 16(WP, Write-Protected) 또한 1이어야 합니다.Intel 64아키텍처를 지원하는 프로세서에서CR3필드는 bits 63:52 및 프로세서 물리 주소 너비를 초과하는 bits 51:32 범위의 비트가 0이어야 합니다.Intel 64아키텍처를 지원하는 프로세서에서IA32_SYSENTER_RSP필드와IA32_SYSENTER_EIP필드는 각각 정규 주소로 포함해야 합니다. (정규 주소 :Interl SDM Vol.1 3.3.7.1 Canonical Addressing)VMExit_load IA32_PERF_GLOBAL_CTRL제어가 1인 경우,IA32_PERF_GLOBAL_CTRL MSR에 예약된 비트는 해당 레지스터의 필드에서 0이어야 합니다.VMExit_load IA32_PAT제어가 1인 경우IA32_PAT MSR에 대한 필드 값은CPL = 0에서 오류 없이WRMSR에 의해 기록될 수 있는 값이어야 합니다. 필드의 각 8바이트는0(UC), 1(WC), 4(WT), 5(WP), 6(WB), 7(UC-)중 하나를 가져야 합니다.VMExit_load IA32_EFER제어가 1인 경우IA32_EFER_MSR에 예약된 비트는 해당 레지스터의 필드에서 0이어야 합니다. 또한 필드의LMA(Long Mode Active),LME(Long Mode Enable)비트 값은 각각VMExit_host address-space size값이어야 합니다.VMExit_load CET state제어가 1인 경우IA32_S_CET필드는IA32_S_CET MSR에 예약된 비트를 설정해서는 안되며, 필드의 bit 10(SUPPRESS) 및 bit 11(TRACKER) 둘 다 설정할 수 없습니다.VMExit_load CET state제어가 1인 경우SSP필드의 bits 1:0 은 반드시 0이어야 합니다.VMExit_load PKRS제어가 1인 경우IA32_PKRS필드의 bits 63:32 는 반드시 0이어야 합니다.
[-] Checks on Host Segment and Descriptor-Table Registers
Segment 및 Descriptor-Table Register 에 해당하는 Host-State Area 필드에 대해 다음 검사가 수행됩니다.
CS,SS,DS,ES,FS,GS,TR각각에 대한Selector필드에서 bits 1:0(RPL, Request Privilege Level) 및 bit 2(TI, Table Indicator) 는 0이어야 합니다.CS,TR의Selector는0000h일 수 없습니다.VMExit_host address-space size가 0인 경우SS에 대한Selector필드는0000h일 수 없습니다.Intel 64아키텍처를 지원하는 프로세서에서FS,GS,GDTR,IDTR,TR에 대한Base-Address Fields에는 정규 주소로 포함되어야 합니다.
[-] Checks Related to Address-Space Size
Intel 64 아키텍처를 지원하는 프로세서에서 VMX Controls, Host-State Area 필드에서 address-space size 와 관련하여 다음 검사가 수행됩니다.
VM Entry시점에IA-32e mode가 아닌 경우(IA32_EFER_LMA = 0인 경우) 다음과 같아야 합니다.VMEntry_IA-32e mode guest제어는 0 이어야 합니다.VMExit_host address-space size제어는 0 이어야 합니다.
VM Entry시점에IA-32e mode인 경우(IA32_EFER_LMA = 1인 경우)VMExit_host address-space size제어는 1이어야 합니다.VMExit_host address-space size제어가 0인 경우 다음과 같아야 합니다.VMEntry_IA-32e mode guest제어가 0 이어야 합니다.CR4.PCIDE = 0이어야 합니다.RIP의 bits 63:32 는 0이어야 합니다.VMExit_load CET state제어가 1인 경우,IA32_S_CET필드와SSP필드의 bits 63:32 는 0이어야 합니다.
VMExit_load CET state제어가 1인 경우IA32_INTERRUPT_SSP_TABLE_ADDR필드에는 정규 주소가 포함됩니다.
Intel 64 아키텍처를 지원하지 않는 프로세서에서는 VMEntry_IA-32e mode guest 와 VMExit_host address-space size 제어가 모두 0인지 검사하게 됩니다.
[0x03] Checking and Loading Guest State
VMX control, Host-state area 에 대한 모든 검사가 통과하면 다음 작업이 동시에 수행됩니다.
VMCS의Guest-state area는VM Entry가 완료된 후 논리 프로세서의 상태가IA-32및Intel 64아키텍처와 일치하는지 확인하기 위해 검사합니다.- 프로세서 상태는
Guest-state area에서 로드되거나VM-entry control필드에 의해 지정된 대로 로드됩니다. address-range monitoring이 해제 됩니다.
검사와 로딩이 동시에 일어나기 때문에 어떤 상태가 로딩된 후에야 장애를 발견할 수 있습니다. 이러한 이유 때문에 논리 프로세서는 VM Exit 에서와 같이 Host-state area 에서 상태를 로드하여 이러한 실패에 대해 응답합니다.
[-] Checks on the Guest State Area
Guest-State Area (이하 “게스트 상태 영역”)의 필드에서 수행되는 검사에 대해 설명합니다. 해당 검사는 특정 순서가 없이 어떤 순서로든 수행될 수 있습니다.
[+] Checks on Guest Control Registers, Debug Registers, and MSRs
Control Register, Debug Register, MSR 에 해당하는 게스트 상태 영역의 필드에 대해 아래 내용에 부합하는지에 대한 검사가 수행됩니다.
CR0,CR4필드는VMX Operation에서 지원되지 않는 비트를 설정해서는 안됩니다.Second_unrestricted guest제어가 1인 경우CR0.PE, PG비트는 검사하지 않습니다.CR0.NW, CD비트는VM Entry에 의해 값이 변경되지 않기 때문에 검사하지 않습니다.
CR0.PG = 1이면CR0.PE =1이어야 합니다.CR4.CET = 1이면CR0.WP = 1이어야 합니다.VMEntry_load debug controls제어가 1이면IA32_DEBUGCTL MSR에 예약된 비트는 해당 레지스터의 필드에서 0이어야 합니다.Intel 64아키텍처를 지원하는 프로세서는 아래 검사가 수행됩니다.VMEntry_IA-32e mode guest제어가 1이면CR0.PG = 1,CR4.PAE = 1이어야 합니다.VMEntry_IA-32e mode guest제어가 0이면CR4.PCIDE = 0이어야 합니다.CR3필드는 bits 63:52 및 프로세서 물리 주소 너비를 초과하는 bits 51:32 범위의 비트가 0이어야 합니다.VMEntry_load debug controls제어가 1인 경우DR7필드의 bits 63:32 는 0이어야 합니다.IA32_SYSENTER_RSP필드와IA32_SYSENTER_EIP필드는 각각 정규 주소로 포함해야 합니다. (정규 주소 :Interl SDM Vol.1 3.3.7.1 Canonical Addressing)VMEntry_load CET state제어가 1인 경우IA32_INTERRUPT_SSP_TABLE_ADDR필드에는 정규 주소가 포함되어야 합니다.
VMEntry_load IA32_PERF_GLOBAL_CTRL제어가 1인 경우IA32_PERF_GLOBAL_CTRL MSR에 예약된 비트는 해당 레지스터의 필드에서 0이어야 합니다.VMEntry_load IA32_PAT제어가 1인 경우IA32_PAT MSR에 대한 필드 값은CPL = 0에서 오류 없이WRMSR에 의해 기록될 수 있는 값이어야 합니다. 필드의 각 8바이트는0(UC), 1(WC), 4(WT), 5(WP), 6(WB), 7(UC-)중 하나를 가져야 합니다.VMEntry_load IA32_EFER제어가 1인 경우IA32_EFER MSR필드에서 아래의 내용에 부합하는지에 대한 검사가 수행됩니다.IA32_EFER MSR에 예약된 비트들은 0이어야 합니다.IA32_EFER.LMA의 값은VMEntry_IA-32e mode guest제어의 값과 일치해야 합니다. 또한CR0.PG = 1인 경우IA32_EFER.LME와 동일해야 합니다.
VMEntry_load IA32_BNDCFGS제어가 1이면IA32_BNDCFGS MSR필드에서 아래의 내용에 부합하는지에 대한 검사가 수행됩니다.IA32_BNDCFGS에 예약된 비트들은 0이어야 합니다.- bits 63:12 의 선형 주소는 정규 주소여야 합니다.
VMEntry_load IA32_RTIT_CTL제어가 1이면IA32_RTIT_CTL MSR에 예약된 비트는 해당 레지스터의 필드에서 0이어야 합니다.VMEntry_load CET state제어가 1인 경우IA32_S_CET필드는IA32_S_CET MSR에 예약된 비트를 설정해서는 안되며, 필드의 bit 10(SUPPRESS) 및 bit 11(TRACKER) 둘 다 설정할 수 없습니다.VMEntry_load guest IA32_LBR_CTL제어가 1인 경우IA32_LBR_CTL MSR에 예약된 비트는 해당 레지스터의 필드에서 0이어야 합니다.VMEntry_load PKRS제어가 1인 경우IA32_PKRS필드의 bits 63:32 는 0이어야 합니다.
[+] Checks on Guest Segment Registers
해당 내용에서는 CS, SS, DS, ES, FS, GS, TR, LDTR 의 필드에 대한 검사를 확인합니다. 이러한 검사를 확인하는 데 사용되는 용어는 아래와 같습니다.
- 게스트 상태 영역의
RFLAGS.VM = 1이면 게스트는virtual-8086입니다. VMEntry_IA-32e mode guest제어가 1인 경우 게스트는IA-32e모드가 됩니다.Access-rights(32bit)필드에서 bit 16(unsuable segment) 가 0이면 해당 레지스터는 사용할 수 있다(Usable)고 표현됩니다.
다음은 각 필드에 대한 확인 사항입니다.
-
Selector Fields(16 bits)

TR:TI, Table Indicator(bit 2)가 0이어야 합니다. (TI = 0은 테이블 지시자가GDT임을 의미합니다.)LDTR:LDTR을 사용 가능한 경우TI는 0이어야 합니다.SS: 게스트가virtual-8086이 아니고,Second_unrestricted guest제어가 0인 경우RPL, Requested Privilege Level(bits 1:0)은CS의Selector필드의RPL과 같아야 합니다.
- Base-address Fields(64 bits)
CS, SS, DS, ES, FS, GS: 게스트가virtual-8086인 경우 주소는 왼쪽으로 4비트 시프트한(16을 곱함)Selector필드여야 합니다.Intel 64아키텍처를 지원하는 프로세서에서는 다음의 내용과 부합한지 검사가 수행됩니다.TR, FS, GS: 정규 주소여야 합니다.LDTR:LDTR을 사용 가능한 경우 주소는 정규 주소여야 합니다.CS: 주소의 bits 63:32 는 0이어야 합니다.SS, DS, ES: 만약 해당 레지스터들이 사용 가능한 경우 주소의 bits 63:32 는 0이어야 합니다.
- Limit Fields(32 bits)
CS, SS, DS, ES, FS, GS: 게스트가virtual-8086인 경우 필드는0000FFFFh여야 합니다.
-
Access-Rights Fields(32 bits)



CS, SS, DS, ES, FS, GS- 게스트가
virtual-8086인 경우 해당 필드는000000F3h여야 합니다. 이것은 아래를 의미합니다.- Bits 3:0(
Segment Type) 은expand-up Read/Write accessed접근 권한을 가진Data세그먼트를 나타내는 3 이어야 합니다. - Bit 4(
S, Descriptor type) 은 설명자 유형이code또는data를 나타내는 1 이어야 합니다. - Bits 6:5(
DPL, Descriptor Privilege Level) 은 3 이어야 합니다. - Bits 7(
P, Segment Present) 은 1 이어야 합니다. - Bits 11:8(
Reserved), Bit 12(AVL, Available for use by system software), Bit 13(Reserved_L), Bit 14(D/B, Default operation size), Bit 15(G, Granularity) Bit 16(Segment unusable), Bits 31:17(Reserved) 값은 모두 0이어야 합니다.
- Bits 3:0(
- 게스트가
virtual-8086이 아닌 경우 다른 하위 필드가 레지스터 별로 고려됩니다.- Bits 3:0(Type)
CS:Second_unrestricted guest제어의 설정에 따라 허용되는 값이 달라집니다.- 0인 경우 9, 11, 13, 15(accessed code segment) 중 하나입니다.
- 1인 경우 3(expand-up read/write accessed data segment)와 9, 11, 13, 15 중 하나여야 합니다.
SS: 만약SS가 사용 가능한 경우 3 또는 7(read/write accessed data segment) 중 하나입니다.DS, ES, FS, GS: 각 레지스터가 사용 가능한 경우에서bit 0 = 1로 설정(accessed) 되어야 하며,bit 3 = 1로 설정(code segment)이면 bit 1(readable) 또한 1로 설정되어야 합니다.
- Bit 4(S)
- 레지스터가
CS이거나 사용 가능한 레지스터의 경우 1이어야 합니다.
- 레지스터가
- Bits 6:5(DPL)
CSSegment Type이 3 인 경우에DPL은 0이어야 합니다. (Second_unrestricted guest가 1로 설정된 경우에만Segment Type이 3일 수 있습니다.)Segment Type이 9 또는 11(non-conforming code segment)인 경우DPL은SS의Access-rights fields의DPL값과 같아야 합니다.Segment Type이 13 또는 15(conforming code segment)인 경우DPL은SS의Access-rights fields의DPL값 보다 클 수 없습니다.Second_unrestricted guest가 0이면DPL은Selector Fields의RPL(bits 1:0)값과 같아야 합니다.Segment Type이 3이거나CR0.PE = 0인 경우DPL은 0입니다.
DS, ES, FS, GS: 아래와 같은 경우에DPL은Selector Fields의RPL값 보다 작을 수 없습니다.Second_unrestricted guest가 0인 경우- 레지스터가 사용 가능한 경우
Segment Type이 0에서 11 사이 값인 경우(data segment 또는 non-conforming code segment)
- Bit 7(P)
- 레지스터가
CS이거나 사용 가능한 레지스터의 경우 1이어야 합니다.
- 레지스터가
- Bits 11:8(Reserved)
- 레지스터가
CS이거나 사용 가능한 레지스터의 경우 모두 0이어야 합니다.
- 레지스터가
- Bit 14(D/B)
CS: 게스트가IA-32e mode이고Access-rights fields의 bit 13(L) 비트가 1이면 해당 비트는 0이어야 합니다.
- Bit 15(G)
- 레지스터가
CS이거나 사용 가능한 레지스터의 경우 다음과 부합한지 검사합니다.Limit Fields의 bits 11:0 이 0이면 해당 비트는 0이어야 합니다.Limit Fields의 bits 31:20 이 1이면 해당 비트는 1이어야 합니다.
- 레지스터가
- Bits 31:17(Reserved) : 레지스터가
CS이거나 사용 가능한 레지스터의 경우 모두 0으로 설정되어야 합니다.
- Bits 3:0(Type)
- 게스트가
TR- Bits 3:0 : 게스트가
IA-32e mode가 아닌 경우Segment Type은 3(16-bit Busy TSS) 또는 11(32-bit Busy TSS) 이어야 합니다. - Bit 4, 7 : 0이어야 합니다.
- Bits 11:8 : 0이어야 합니다.
- Bits 15 :
Limit Fields의 bits 11:0 이 0인 경우 0, bits 31:20 이 1인 경우 1로 설정해야 합니다. - Bit 16 : 0이어야 합니다.
- Bits 31:17 : 0이어야 합니다.
- Bits 3:0 : 게스트가
LDTRLDTR이 사용 가능한 경우에만 아래의 검사가 동작합니다.- Bits 3:0 :
Segment Type의 경우 2(LDT)로 설정되야 합니다. - Bit 4, 7 : 0이어야 합니다.
- Bits 11:8 : 0이어야 합니다.
- Bit 15 :
Limit Fields의 bits 11:0 이 0인 경우 0, bits 31:20 이 1인 경우 1로 설정해야 합니다. - Bits 31:17 : 0이어야 합니다.
- Bits 3:0 :
[+] Checks on Guest Descriptor-Table Registers
GDTR 및 IDTR 의 필드는 아래의 내용에 부합하는지 검사가 수행됩니다.
Intel 64아키텍처를 지원하는 프로세서에서Base-Address Fields에는 정규 주소가 포함되어야 합니다.Limit Fields의 Bits 31:16 은 0이어야 합니다.
[+] Check on Guest RIP, RFLAGS, and SSP
RIP, RFLAGS, SSP 에 해당하는 게스트 영역의 필드에 대해 아래와 같이 검사를 수행합니다.
- RIP
VMEntry_IA-32e mode guest제어 비트가 0이거나CS의Access-right fields내 bit 13(L)이 0인 경우, bits 63:32 는 0이어야 합니다.- 프로세서가 N < 64 linear-address bits 를 지원하는 경우
VMEntry_IA-32e mode guest제어 비트가 1이고CS의Access-right fields내 bit 13(L)이 1이면 bits 63:N 이 동일해야 합니다.(프로세서가 64개의 선형 주소 비트를 지원하는 경우 검사가 적용되지 않습니다.)
-
RFLAGS

- 예약된 bits 63:22(
Intel 64아키텍처 미지원의 경우 bits 31:22), bit 15, bit 3은 0이어야 하고 예약된 bit 1 은 1이어야 합니다.(위의 그림 참조) - bit 17(VM flag)은
VMEntry_IA-32e mode guest제어 비트가 1이거나CR0.PE = 0인 경우 0이어야 합니다. - bit 9(IF flag)는
VM-entry interruption-information field내valid(bit 31)가 1이고,interruption type(bits 10:8)이external interrupt인 경우 1이어야 합니다.
- 예약된 bits 63:22(
- SSP
VMEntry_load CET state제어 비트가 1인 경우 bits 1:0 은 0이어야 합니다.VMEntry_load CET state제어 비트가 1이고Intel 64아키텍처를 지원하는 경우 bits 64:N 이 동일해야 합니다. 여기서 N은 CPU의 최대 선형 주소 너비입니다.
[+] Checks on Guest Non-Register State
Non-Register 에 해당하는 게스트 상태 영역의 필드에 대해 다음과 같은 검사가 수행됩니다.
- Activity State(32 bits)
Activity-State Field는 지원하는 상태를 나타내는 0-3 범위의 값을 포함해야 합니다.(Active, HLT, Shutdown, Wait-for-SPIP)MSR IA32_VMX_MISC의 bits 8:6 를 읽어 결정할 수 있습니다.SS의Access-right field내 bits 6:5(DPL)이 0이 아닌 경우Activity-State Field는HLT(1)이면 안됩니다.Interruptibility-state field내 Bit 1(Blocking by MOV SS) 또는 Bit 0(Blocking by STI) 차단이 설정된 경우Activity-state field는active(0)이어야 합니다.VM-entry interruption-information field내valid비트가 1인 경우 전달 될 인터럽트는 논리 프로세서가Activity-state field내 상태 중 하나일 때 차단되는 인터럽트이면 안됩니다.- 아래 항목은 다양한
activity state에 대해 주입이 허용되는 인터럽트를 열거합니다.- Active(0) : 모든 인터럽션을 허용합니다.
- HLT(1) : 아래의 경우에만 허용합니다.
interruption type이external interrupt(0)이거나NMI Interrupt(2)인 경우hardware exception(3)이고Vector가 1(Debug exception) 또는 18(machine-check) 인 경우other event(7)이고Vector가 0(pending MTF VM exit)인 경우
- Shutdown(2) :
NMI interrupt(2)이고 Vector 18(machine-check) 인 경우에만 허용합니다. - Wait-for-SIPI(3) : 아무런 인터럽션도 허용하지 않습니다.
activity-state field는VMEntry_entry to SMM제어가 1인 경우wait-for-SIPI상태가 되면 안됩니다.
- Interruptibility State(32 bits)
- 예약된 bits 31:5 는 0이어야 합니다.
- bit 0(
Block STI), bit 1(Block MOV SS) 는 둘 다 1일 수 없습니다. - bit 0(
Block STI) 는RFLAGS.IF = 0인 경우 0 이어야 합니다. VM-entry interruption-information field내valid비트가 1이고interruption type이external interrupt(0)이거나NMI interrupt(2)인 경우 bit 0(Block STI) 와 bit 1(block MOV SS) 는 둘 다 0입니다.- bit 2(
Block SMI) 는 프로세서가SMM이 아니면 0 이어야 합니다. - bit 2(
Block SMI) 는VMEntry_entry to SMM제어가 1이면 1 이어야 합니다. - bit 3(
Block NMI) 는Pin_virtual NMIs제어가 1,VM-entry interruption-information field내valid비트가 1,interruption type이NMI interrupt(2)인 경우 0으로 설정되어야 합니다. - bit 4(
Enclave Interruption)가 1이면 bit 1(Block MOV SS) 는 0이어야 하고, 프로세서는CPUID를 이용하여SGX를 지원해야 합니다.
-
Pending Debug Exception(32 or 64 bits)

- bits 11:4, bit 13, bit 15, bits 63:17 은 예약된 영역으로 0이어야 합니다.
- 아래의 확인은 특정 조건에 따라 수행되며 해당 조건 중 하나라도 충족되면 검사를 수행합니다.
- bit 14(
BS) 는RFLAGS.TF = 1이고IA32_DEBUGCTL필드의 bit 1(BTF flag) 가 0인 경우 1 이어야 하며, 반대의 경우 0이어야 합니다. 조건은 아래와 같습니다.interruptibility-state field내 bit 0(Block STI) 가 1인 경우interruptibility-state field내 bit 1(Block MOV SS) 가 1인 경우activity-state field의 상태가HLT인 경우
- bit 14(
- bit 16(
RTM) 이 1인 경우 아래의 검사가 수행됩니다.- bits 11:0, bits 15:13, bits 63:17 은 0이어야 하며 bit 12(
Enable breakpoint) 는 1이어야 합니다. CPUID를 이용하여RTM을 지원해야 합니다.interruption-state field내 bit 1(Block MOV SS) 는 0이어야 합니다.
- bits 11:0, bits 15:13, bits 63:17 은 0이어야 하며 bit 12(
- VMCS Link Pointer(64 bits)
- 해당 필드의 값이
FFFFFFFF'FFFFFFFFh가 아니면 아래의 검사가 수행됩니다.- Bits 11:0 은 0이어야 하며 물리 주소 너비를 초과하는 비트는 0이어야 합니다.
- 필드 값(물리 주소)이 참조하는 메모리에 있는 4byte 는 다음을 충족해야 합니다.
- bits 30:0 에는
VMCS revision identifier값이 존재해야 합니다. - bit 31 에는
Second_VMCS shadowing이 포함됩니다. 이는 참조된VMCS가Second_VMCS shadowing제어가 1인 경우에만Shadow VMCS임을 의미합니다.
- bits 30:0 에는
- 프로세서가
SMM에 있지 않거나VMEntry_entry to SMM제어 비트가 1인 경우 해당 필드는 현재(current state)VMCS pointer를 포함하지 않아야 합니다. - 프로세서가
SMM에 있고,VMEntry_entry to SMM제어 비트가 0인 경우 필드는executive-VMCS Pointer와 달라야 합니다.(이는launched상태를 의미하는 것으로 이해했습니다.)
- 해당 필드의 값이
[+] Checks on Guest Page-Directory-Pointer-Table Entries
CR0.PG = 1, CR4.PAE = 1, IA32_EFER.LME = 0 인 경우 논리 프로세서는 PAE paging 을 사용합니다. PAE paging 이 사용 중일 때 CR3 의 물리 주소는 PDPTE 테이블을 참조합니다.
이 때 MOV to CR3 명령은 PDPTE 의 유효성 검사를 수행합니다.
PAE paging 을 사용하는 게스트의 VM Entry 는 아래와 같습니다.
- (게스트 상태 영역의)
CR0.PG = 1인 경우 CR4.PAE = 1인 경우VMEntry_IA-32e mode guest가 0인 경우
위와 같은 VM Entry 는 PDPTE 유효성을 검사합니다.
Second_Enable EPT제어 비트가 0이면VM Entry가 이전에PAE paging을 사용하지 않은 경우 게스트 상태 영역의CR3필드에서 참조되는PDPTE의 유효성을 검사합니다.Second_Enable EPT제어 비트가 0이면VM Entry의 결과로CR3값이 변경되는 경우 게스트 상태 영역의CR3필드에서 참조되는PDPTE의 유효성을 검사합니다.Second_Enable EPT제어 비트가 1이면VM Entry는 게스트 상태 영역의PDPTE필드의 유효성을 검사합니다.
PAE paging 을 사용하지 않는 게스트에 대한 VM Entry 는 PDPTE 의 유효성을 검사하지 않습니다.
[-] Loading Guest State
다음과 같은 방식으로 VM Entry 에서 프로세서 상태가 업데이트 됩니다.
- 일부 상태는 게스트 상태 영역에서 로드됩니다.
- 일부 상태는
VM-Entry Controls에 의해 결정됩니다. Page-Directory Pointer는 특정 제어 레지스터의 값을 기반으로 로드됩니다.
[+] Loading Guest Control Registers, Debug Registers, and MSRs
다음 항목들은 게스트 Control Register, Debug Register, MSR 이 VM Entry 에 어떻게 로드되는가에 대한 설명입니다.
CR0은VM Entry에서 수정되지 않는 bit 4(ET), bits 15:6, bit 17, bits 28:19(예약), bit 29(NW), bit 30(CD) 의 값을 제외하고 로드됩니다.CR3,CR4는 각 필드에서 로드됩니다.DR7은VMEntry_load debug controls제어가 1 일 때, bit 12, bits 15:14(예약)가 항상 0이고 bit 10 이 항상 1인 경우를 제외하고DR7필드에서 로드합니다.- 다음은 게스트 상태 영역의 필드를 사용하여 특정
MSR이 로드되는 방법을 설명합니다.VMEntry_load debug controls제어가 1인 경우IA32_DEBUGCTL MSR은IA32_DEBUGCTL필드에서 로드됩니다.IA32_SYSENTER_CS MSR은IA32_SYSENTER_CS필드에서 로드됩니다. 32bits 만 존재하므로 bits 63:32 는 0으로 설정됩니다.IA32_SYSENTER_ESP, EIP MSR은IA32_SYSENTER_ESP, EIP필드에서 로드됩니다.- 다음은
Intel 64아키텍처를 지원하는 프로세서에서만 수행됩니다.GS.base,FS.base는 각FS, GS의base-address fields에서 로드됩니다.VMEntry_load IA32_EFER제어가 0이면IA32_EFER MSR의 비트는 다음과 같이 수정됩니다.IA32_EFER.LMA는VMEntry_IA-32e mode guest제어 비트로 로드됩니다.CR0이 로드되어CR0.PG = 1이면IA32_EFER.LME도VMEntry_IA-32e mode guest제어 비트와 함께 로드됩니다.
VMEntry_load IA32_PERF_GLOBAL_CTRL제어가 1이면IA32_PERF_GLOBAL_CTRL_MSR이IA32_PERF_GLOBAL_CTRL필드에서 로드 됩니다.VMEntry_load IA32_PAT제어가 1이면IA32_PAT MSR이IA32_PAT필드에서 로드됩니다.VMEntry_load IA32_EFER제어가 1이면IA32_EFER MSR이IA32_EFER필드에서 로드됩니다.VMEntry_load IA32_BNDCFGS제어가 1이면IA32_BNDCFGS MSR이IA32_BNDCFGS필드에서 로드됩니다.VMEntry_load IA32_RTIT_CTL제어가 1이면IA32_RTIT_CTL MSR이IA32_RTIT_CTL필드에서 로드됩니다.VMEntry_load CET제어가 1이면IA32_S_CET, IA32_INTERRUPT_SSP_TABLE_ADDR MSR은 각각의 필드에서 로드됩니다.VMEntry_load guest IA_32_LBR_CTL제어가 1이면IA32_LBR_CTL MSR이IA32_LBR_CTL게스트 상태 필드에서 로드됩니다.VMEntry_load PKRS제어가 1이면IA32_PKRS MSR이IA32_PKRS필드에서 로드됩니다.FS.Base,GS.Base를 제외하고 이러한MSR이VM-Entry MSR-load area에 나타난 후에 덮어씁니다.
[+] Loading Guest Segment Registers and Descriptor-Table Registers
CS, SS, DS, ES, FS, GS, TR, LDTR 은 아래와 같이 게스트 상태 영역에서 필드가 로드됩니다.
- 다음 레지스터 중
Access-Rights Field에서unusable비트가 설정된 경우 아래와 같이 적용됩니다.CS, SS, DS, ES, FS, GS각각에 대해Null Selector를 이용하여 세그먼트를 로드하는 경우와 마찬가지로 세그먼트 사용 시 장애가 발생합니다.LDTR에 설정된 경우LDTR을 사용하면 모든 모드에서 #GP 가 발생합니다.
TR:Selector,Base-Address,Limit,Access-Right필드가 로드됩니다.CSSelector,Base-Address,Limit필드와Access-Right Field내 bit 13(L), bit 14(D), bit 15(G) 비트가 로드됩니다.Access-Rights Fields내unusable비트가 0이면 모든 필드가 로드됩니다. 1인 경우에는 정의되어 있지 않습니다.
SS, DS, ES, FS, GS, LDTRSelector Fields가 로드됩니다.Access-Rights Fields내unusable비트에 따라 아래와 같이 로드됩니다.unusable비트가 0인 경우Base-Address,Limit,Access-Rights필드가 모두 로드됩니다.unusable비트가 1인 경우Base-Address,Limit,Access-Rights의 경우 다음의 예외를 제외하고VM Entry후에 정의되지 않습니다.SS의Base-Address의 bits 3:0은 0으로 지워집니다.SS.DPL은 항상 로드됩니다. 이것은VM Entry가 완료된 후의CPL이 됩니다.SS.B는 항상 1로 설정됩니다.FS, GS의Base-Address는 해당하는Base-Address필드에서 로드됩니다.Intel 64아키텍처를 지원하는 프로세서에서LDTR의Base-Address는 정의되지 않았지만 정규 주소로 설정됩니다.Intel 64아키텍처를 지원하는 프로세서에서SS, DS, ES에 대한Base-Address의 bits 63:32 는 0으로 지워집니다.
GDTR,IDTR은Base-Address,Limit필드에서 로드됩니다.
[+] Loading Guest RIP, RSP, RFLAGS and SSP
RSP, RIP, RFLAGS 는 각각의 필드에서 로드됩니다.
VMEntry_load CET 제어 비트가 1이면 SSP 필드에서 SSP 를 로드합니다.
아래는 64-bit mode 가 아닌 VM Entry 에서 이러한 필드의 상위 32bit에 대해 설명합니다.
RSP의 bits 63:32 는 정의되지 않습니다. 따라서 논리 프로세서는 64-bit 모드가 아닌VM Entry에서RSP필드의 bits 63:32 값을 무시할 수 있습니다.RIP, RFLAGS필드의 bits 63:32 는 64-bit mode가 아닌VM Entry에서 0이어야 합니다.
[+] Loading Page-Directory-Pointer-Table Entries
논리 프로세서는 CR0.PG = 1, CR4.PAE = 1, IA32_EFER.LME = 0 인 경우 PAE paging 을 사용한다고 언급했었습니다. PAE paging 을 사용하는 게스트에 대한 VM Entry 는 Second_enable EPT 제어 비트의 설정에 따라 PDPTE 를 내부의 non-architectural register 에 로드합니다.
Second_enable EPT제어가 0이면PDPTE는VM Entry에 의해 로드되는CR3값의 물리 주소가 참조하는Page-Directory-Pointer Table에서 로드됩니다. 로드된 값은VMX non-root operation에서 물리 주소로 처리됩니다.Second_enable EPT제어가 1이면 게스트 상태 영역의 해당 필드에서PDPTE가 로드됩니다. 로드된 값은VMX non-root operation에서 물리 주소로 처리됩니다.
[+] Updating Non-Register State
VMX 아키텍처에서 논리 프로세서가 TLB 및 paging-structure 캐시 정보를 관리하는 방법에 대해 추후에 자세하게 설명됩니다.
다음 항목에서는 VM Entry 가 캐시된 매핑을 어떻게 무효화하는지에 대한 설명입니다.
Second_enable VPID제어가 0인 경우, 논리 프로세서는VPID0000h(모든PCID)와 관련된 선형 매핑 및 결합된 매핑을 무효화 합니다.VPID0000h 에 대한 결합된 매핑은 모든EP4TA값에 대해 무효화 합니다.(EP4TA는EPTP필드의 bits 51:12 입니다.)VM Entry는 게스트-물리 매핑을 무효화하는 데 필요하지 않으며,Second_enable VPID제어가 1인 경우 선형 매핑 또는 결합된 매핑을 무효화할 필요도 없습니다.
Second_virtual-interrupt delivery 제어가 1인 경우 VM Entry 는 VMCS 의 geust nterrupt-status field 에서 RVI , SVI 값을 로드합니다.
로드한 후에 논리 프로세서는 먼저 PPR 가상화를 진행한 다음 보류 중인 가상 인터럽트를 평가합니다.
가상 인터럽트가 인식되면 VM Entry(지정된 이벤트 주입 포함)가 완료된 직후 VMX non-root operation 으로 전달될 수 있습니다.
[+] Clearing Address-Range Monitoring
VMM 은 MONITOR 및 MWAIT 명령을 이용하여 지정된 주소 범위를 모니터링 할 수 있습니다. VM Entry 는 적용될 수 있는 모든 Address-range monitoring 을 지웁니다.
[0x04] Conclusion
이 프로젝트를 진행하면서 가장 깨달음이 컸던 챕터였습니다.
VM Entry 에서 어떤 것들에 대해 검사하는지를 알게 되었으니 이를 통해 구현에 가까워진 것 같습니다.
실제로 구현할 때는 해당 챕터의 내용을 다시 확인할 것으로 예상됩니다.
[0x05] Reference
- Intel 64 and IA-32 Architectures Software Developer’s Manual