diff --git a/gbhv/ept.c b/gbhv/ept.c index 693cd88..6059ce9 100644 --- a/gbhv/ept.c +++ b/gbhv/ept.c @@ -173,7 +173,7 @@ PVMM_EPT_PAGE_TABLE HvEptAllocateAndCreateIdentityPageTable(PVMM_CONTEXT GlobalC SIZE_T EntryIndex; /* Allocate all paging structures as 4KB aligned pages */ - PageTable = OsAllocateContiguousAlignedPages(sizeof(VMM_EPT_PAGE_TABLE) / PAGE_SIZE); + PageTable = OsAllocateContiguousAlignedPages(ALIGN_UP_BY(sizeof(VMM_EPT_PAGE_TABLE), PAGE_SIZE) / PAGE_SIZE); if(PageTable == NULL) { @@ -393,7 +393,7 @@ BOOL HvEptSplitLargePage(PVMM_PROCESSOR_CONTEXT ProcessorContext, SIZE_T Physica * alternative was to use the contiguous aligned pages allocator because, in my testing, it resulted in only 4KB virtual * allocations. This allocator also utilizes nonpaged pool frames, so it is more-or-less the same as the other allocator. */ - NewSplit = (PVMM_EPT_DYNAMIC_SPLIT) OsAllocateContiguousAlignedPages(sizeof(VMM_EPT_DYNAMIC_SPLIT)/PAGE_SIZE); + NewSplit = (PVMM_EPT_DYNAMIC_SPLIT) OsAllocateContiguousAlignedPages(ALIGN_UP_BY(sizeof(VMM_EPT_DYNAMIC_SPLIT), PAGE_SIZE) / PAGE_SIZE); if(!NewSplit) { HvUtilLogError("HvEptSplitLargePage: Failed to allocate dynamic split memory.\n"); diff --git a/gbhv/os.h b/gbhv/os.h index 06632aa..f03494d 100644 --- a/gbhv/os.h +++ b/gbhv/os.h @@ -23,4 +23,4 @@ PVOID OsPhysicalToVirtual(PPHYSVOID PhysicalAddress); VOID OsZeroMemory(PVOID VirtualAddress, SIZE_T Length); -VOID OsCaptureContext(PREGISTER_CONTEXT ContextRecord); \ No newline at end of file +VOID OsCaptureContext(PREGISTER_CONTEXT ContextRecord); diff --git a/gbhv/os_nt.c b/gbhv/os_nt.c index bb1390e..061305d 100644 --- a/gbhv/os_nt.c +++ b/gbhv/os_nt.c @@ -25,6 +25,7 @@ SIZE_T OsGetCurrentProcessorNumber() /* * Allocate a number of page-aligned, contiguous pages of memory and return a pointer to the region. + * When your data size is divided by PAGE_SIZE, you should be sure that no remainder is discarded. * * Returns NULL if the pages could not be allocated. */ diff --git a/gbhv/vmm.h b/gbhv/vmm.h index cd4399d..2b90195 100644 --- a/gbhv/vmm.h +++ b/gbhv/vmm.h @@ -39,7 +39,10 @@ typedef struct _VMM_HOST_STACK_REGION /* * Top of the host stack must always have a pointer to the global context. * This allows the exit handler to access the global context after the host area is loaded. + * In order to follow the x64 calling convention, must ensure that the end of rsp is 8 after entering HOST. + * So we need a 16-byte aligned member in front of GlobalContext. */ + DECLSPEC_ALIGN(16) UINT64 Alignment; PVMM_CONTEXT GlobalContext; } VMM_HOST_STACK_REGION, *PVMM_HOST_STACK_REGION; diff --git a/gbhv/vmxdefs.asm b/gbhv/vmxdefs.asm index 975df26..816be6c 100644 --- a/gbhv/vmxdefs.asm +++ b/gbhv/vmxdefs.asm @@ -21,7 +21,7 @@ PushGeneralPurposeRegisterContext MACRO push rdi push rsi push rbp - sub rsp, 8 ; placeholder for rsp + push rbp ;rsp push rbx push rdx push rcx @@ -32,22 +32,22 @@ ENDM ; RSP is read from VMCS, so there's a placeholder. ; https://github.com/asamy/ksm/blob/e7e24931c9df26c33d6e2a0ea9a44c78d3ced7a6/vmx.asm#L62 PopGeneralPurposeRegisterContext MACRO - pop rax - pop rcx - pop rdx - pop rbx - add rsp, 8 - pop rbp - pop rsi - pop rdi - pop r8 - pop r9 - pop r10 - pop r11 - pop r12 - pop r13 - pop r14 - pop r15 + pop rax + pop rcx + pop rdx + pop rbx + pop rbp ;rsp + pop rbp + pop rsi + pop rdi + pop r8 + pop r9 + pop r10 + pop r11 + pop r12 + pop r13 + pop r14 + pop r15 ENDM __invept PROC @@ -111,6 +111,8 @@ HvBeginInitializeLogicalProcessor ENDP ; and we have to handle the VMRESUME failure. ; Interrupts are automatically disabled for us at this point. HvEnterFromGuest PROC + ; rsp == 0x...............8, qword[rsp] == PVMM_GLOBAL_CONTEXT + ; Macro to push all GP registers PushGeneralPurposeRegisterContext @@ -123,15 +125,10 @@ HvEnterFromGuest PROC ; Second argument (RDX) is stack pointer, which is also the location of the general purpose registers mov rdx, rsp - ; Save XMM registers. The stack must be 16-byte aligned - ; or a #GP exception is generated. - sub rsp, 68h - movaps xmmword ptr [rsp], xmm0 - movaps xmmword ptr [rsp+10h], xmm1 - movaps xmmword ptr [rsp+20h], xmm2 - movaps xmmword ptr [rsp+30h], xmm3 - movaps xmmword ptr [rsp+40h], xmm4 - movaps xmmword ptr [rsp+50h], xmm5 + ; Save the x87 FPU, MMX, XMM, and MXCSR register state to m512byte. + ; The stack must be 16-byte aligned, or a #GP exception is generated. + sub rsp, 208h + fxsave [rsp] ; Call HvHandleVmExit to actually handle the ; incoming exit @@ -139,14 +136,9 @@ HvEnterFromGuest PROC call HvHandleVmExit add rsp, 20h - ; Restore XMM registers - movaps xmm0, xmmword ptr [rsp] - movaps xmm1, xmmword ptr [rsp+10h] - movaps xmm2, xmmword ptr [rsp+20h] - movaps xmm3, xmmword ptr [rsp+30h] - movaps xmm4, xmmword ptr [rsp+40h] - movaps xmm5, xmmword ptr [rsp+50h] - add rsp, 68h + ; Restore the x87 FPU, MMX, XMM, and MXCSR register state from m512byte. + fxrstor [rsp] + add rsp, 208h ; If it's not successful, we need to stop and figure out why test al, al