| 2337 | _IRQL_requires_same_ |
| 2338 | _IRQL_requires_min_(DISPATCH_LEVEL) |
| 2339 | static VMM_STATUS VmcallHandler(__inout PRIVATE_VM_DATA* Private, __inout GUEST_CONTEXT* Context, unsigned long long Rip, __inout_opt bool& RepeatInstruction) |
| 2340 | { |
| 2341 | UNREFERENCED_PARAMETER(Private); |
| 2342 | UNREFERENCED_PARAMETER(Rip); |
| 2343 | UNREFERENCED_PARAMETER(RepeatInstruction); |
| 2344 | |
| 2345 | if (Context->R10 == HYPER_BRIDGE_SIGNATURE) |
| 2346 | { |
| 2347 | switch (static_cast<VMCALLS::VMCALL_INDEX>(Context->Rcx)) |
| 2348 | { |
| 2349 | case VMCALLS::VMCALL_INDEX::VmmCall: |
| 2350 | { |
| 2351 | unsigned long long(*Fn)(void* Arg) = reinterpret_cast<decltype(Fn)>(Context->Rdx); |
| 2352 | void* Arg = reinterpret_cast<void*>(Context->R8); |
| 2353 | bool SwitchToCallerAddressSpace = Context->R9 != 0; |
| 2354 | |
| 2355 | unsigned long long Cr3 = 0; |
| 2356 | if (SwitchToCallerAddressSpace) |
| 2357 | { |
| 2358 | Cr3 = __readcr3(); |
| 2359 | __writecr3(vmread(VMX::VMCS_FIELD_GUEST_CR3)); |
| 2360 | } |
| 2361 | |
| 2362 | Context->Rax = Fn(Arg); |
| 2363 | |
| 2364 | if (SwitchToCallerAddressSpace) |
| 2365 | { |
| 2366 | __writecr3(Cr3); |
| 2367 | } |
| 2368 | break; |
| 2369 | } |
| 2370 | default: |
| 2371 | { |
| 2372 | Context->Rax = HYPER_BRIDGE_SIGNATURE; |
| 2373 | } |
| 2374 | } |
| 2375 | } |
| 2376 | else |
| 2377 | { |
| 2378 | HyperV::HYPERCALL_INPUT_VALUE InputValue = { Context->Rcx }; |
| 2379 | switch (static_cast<HyperV::HYPERCALL_CODE>(InputValue.Bitmap.CallCode)) |
| 2380 | { |
| 2381 | case HyperV::HYPERCALL_CODE::HvSwitchVirtualAddressSpace: |
| 2382 | case HyperV::HYPERCALL_CODE::HvFlushVirtualAddressSpace: |
| 2383 | case HyperV::HYPERCALL_CODE::HvFlushVirtualAddressList: |
| 2384 | case HyperV::HYPERCALL_CODE::HvCallFlushVirtualAddressSpaceEx: |
| 2385 | case HyperV::HYPERCALL_CODE::HvCallFlushVirtualAddressListEx: |
| 2386 | { |
| 2387 | VMX::INVVPID_DESCRIPTOR InvvpidDesc = {}; |
| 2388 | __invvpid(VMX::INVVPID_TYPE::AllContextsInvalidation, &InvvpidDesc); |
| 2389 | break; |
| 2390 | } |
| 2391 | case HyperV::HYPERCALL_CODE::HvCallFlushGuestPhysicalAddressSpace: |
| 2392 | case HyperV::HYPERCALL_CODE::HvCallFlushGuestPhysicalAddressList: |
| 2393 | { |
| 2394 | // Acts as __invept(): |
| 2395 | INVEPT_DESCRIPTOR Desc = {}; |
| 2396 | Desc.Eptp = vmread(VMCS_FIELD_EPT_POINTER_FULL); |