_Use_decl_annotations_ bool __stdcall VmmVmExitHandler(VmmInitialStack *stack) { // Save guest's context and raise IRQL as quick as possible const auto guest_irql = KeGetCurrentIrql(); const auto guest_cr8 = IsX64() ? __readcr8() : 0; if (guest_irql < DISPATCH_LEVEL) { KeRaiseIrqlToDpcLevel(); } NT_ASSERT(stack->reserved == MAXULONG_PTR); // Capture the current guest state GuestContext guest_context = {stack, UtilVmRead(VmcsField::kGuestRflags), UtilVmRead(VmcsField::kGuestRip), guest_cr8, guest_irql, true}; guest_context.gp_regs->sp = UtilVmRead(VmcsField::kGuestRsp); // Dispatch the current VM-exit event VmmpHandleVmExit(&guest_context); // Restore guest's context if (guest_context.irql < DISPATCH_LEVEL) { KeLowerIrql(guest_context.irql); } // Apply possibly updated CR8 by the handler if (IsX64()) { __writecr8(guest_context.cr8); } return guest_context.vm_continue; }
FORCEINLINE KIRQL ApicGetCurrentIrql(VOID) { #ifdef _M_AMD64 return (KIRQL)__readcr8(); #elif defined(APIC_LAZY_IRQL) // HACK: some magic to Sync VBox's APIC registers ApicRead(APIC_VER); /* Return the field in the PCR */ return (KIRQL)__readfsbyte(FIELD_OFFSET(KPCR, Irql)); #else // HACK: some magic to Sync VBox's APIC registers ApicRead(APIC_VER); /* Read the TPR and convert it to an IRQL */ return TprToIrql(ApicRead(APIC_TPR)); #endif }