| 2101 | _IRQL_requires_same_ |
| 2102 | _IRQL_requires_min_(DISPATCH_LEVEL) |
| 2103 | static VMM_STATUS CpuidHandler(__inout PRIVATE_VM_DATA* Private, __inout GUEST_CONTEXT* Context, unsigned long long Rip, __inout_opt bool& RepeatInstruction) |
| 2104 | { |
| 2105 | UNREFERENCED_PARAMETER(RepeatInstruction); |
| 2106 | |
| 2107 | CPUID_REGS Regs = {}; |
| 2108 | int Function = static_cast<int>(Context->Rax); |
| 2109 | if (Function == CPUID_VMM_SHUTDOWN) |
| 2110 | { |
| 2111 | Rip += vmread(VMX::VMCS_FIELD_VMEXIT_INSTRUCTION_LENGTH); |
| 2112 | |
| 2113 | size_t Rsp = vmread(VMX::VMCS_FIELD_GUEST_RSP); |
| 2114 | |
| 2115 | Context->Rax = reinterpret_cast<UINT64>(Private) & MAXUINT32; // Low part |
| 2116 | Context->Rbx = Rip; // Guest RIP |
| 2117 | Context->Rcx = Rsp; // Guest RSP |
| 2118 | Context->Rdx = reinterpret_cast<UINT64>(Private) >> 32; // High part |
| 2119 | |
| 2120 | _lgdt(&Private->Gdtr); |
| 2121 | __lidt(&Private->Idtr); |
| 2122 | |
| 2123 | CR3 Cr3 = {}; |
| 2124 | Cr3.Value = vmread(VMX::VMCS_FIELD_GUEST_CR3); |
| 2125 | __writecr3(Cr3.Value); |
| 2126 | |
| 2127 | RFLAGS Rflags = {}; |
| 2128 | Rflags.Value = vmread(VMX::VMCS_FIELD_GUEST_RFLAGS); |
| 2129 | __writeeflags(Rflags.Value); |
| 2130 | |
| 2131 | __vmx_off(); |
| 2132 | |
| 2133 | RepeatInstruction = true; |
| 2134 | return VMM_STATUS::VMM_SHUTDOWN; |
| 2135 | } |
| 2136 | |
| 2137 | int SubLeaf = static_cast<int>(Context->Rcx); |
| 2138 | __cpuidex(Regs.Raw, Function, SubLeaf); |
| 2139 | |
| 2140 | switch (Function) |
| 2141 | { |
| 2142 | case CPUID::Generic::CPUID_MAXIMUM_FUNCTION_NUMBER_AND_VENDOR_ID: |
| 2143 | { |
| 2144 | // Vendor = 'Hyper-Bridge' as RBX + RDX + RCX: |
| 2145 | Context->Rax = Regs.Regs.Eax; |
| 2146 | GetHvCpuName(Context->Rbx, Context->Rcx, Context->Rdx); |
| 2147 | break; |
| 2148 | } |
| 2149 | case 0x11223344: |
| 2150 | { |
| 2151 | // Example of events injection: |
| 2152 | InjectEvent(INTERRUPTION_TYPE::HardwareException, INTERRUPT_VECTOR::GeneralProtection, true, 0); |
| 2153 | break; |
| 2154 | } |
| 2155 | case static_cast<int>(HyperV::CPUID::MAX_LEAF_NUMBER_AND_VENDOR_ID) : |
| 2156 | { |
| 2157 | Context->Rax = static_cast<int>(HyperV::CPUID::INTERFACE_SIGNATURE); |
| 2158 | GetHvCpuName(Context->Rbx, Context->Rcx, Context->Rdx); |
| 2159 | break; |
| 2160 | } |
nothing calls this directly
no test coverage detected