MCPcopy Create free account
hub / github.com/HoShiMin/Kernel-Bridge / EptViolationHandler

Function EptViolationHandler

Kernel-Bridge/API/Hypervisor.cpp:2196–2290  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2194 _IRQL_requires_same_
2195 _IRQL_requires_min_(DISPATCH_LEVEL)
2196 static VMM_STATUS EptViolationHandler(__inout PRIVATE_VM_DATA* Private, __inout GUEST_CONTEXT* Context, unsigned long long Rip, __inout_opt bool& RepeatInstruction)
2197 {
2198 UNREFERENCED_PARAMETER(Context);
2199 UNREFERENCED_PARAMETER(RepeatInstruction);
2200
2201 VMX::EXIT_QUALIFICATION Info = { vmread(VMX::VMCS_FIELD_EXIT_QUALIFICATION) };
2202 unsigned long long AccessedPa = vmread(VMX::VMCS_FIELD_GUEST_PHYSICAL_ADDRESS_FULL);
2203
2204 if (!(Info.EptViolations.GuestPhysicalReadable || Info.EptViolations.GuestPhysicalExecutable))
2205 {
2206 // The page is neither readable nor executable (acts as not present):
2207 InjectEvent(VMX::INTERRUPTION_TYPE::HardwareException, INTERRUPT_VECTOR::GeneralProtection, true, 0);
2208 return VMM_STATUS::VMM_CONTINUE;
2209 }
2210
2211 bool Handled = false;
2212
2213 if (Info.EptViolations.AccessedRead)
2214 {
2215 unsigned long long RipPa;
2216 if (AddressRange::IsUserAddress(reinterpret_cast<void*>(Rip)))
2217 {
2218 __writecr3(vmread(VMX::VMCS_FIELD_GUEST_CR3));
2219 RipPa = Supplementation::FastPhys::GetPhysAddressFast4KbUnsafe(Rip);
2220 __writecr3(g_Shared.KernelCr3);
2221 }
2222 else
2223 {
2224 RipPa = Supplementation::FastPhys::GetPhysAddressFast4KbUnsafe(Rip);
2225 }
2226
2227 if (ALIGN_DOWN_BY(AccessedPa, PAGE_SIZE) == ALIGN_DOWN_BY(RipPa, PAGE_SIZE))
2228 {
2229 unsigned long long InstructionLength = vmread(VMX::VMCS_FIELD_VMEXIT_INSTRUCTION_LENGTH);
2230 Handled = Private->EptInterceptor->HandleExecuteRead(AccessedPa, reinterpret_cast<void*>(Rip + InstructionLength));
2231 if (Handled)
2232 {
2233 // Perform a single step:
2234 EnableMonitorTrapFlag();
2235 DisableGuestInterrupts();
2236 }
2237 }
2238 else
2239 {
2240 Handled = Private->EptInterceptor->HandleRead(AccessedPa);
2241 }
2242 }
2243 else if (Info.EptViolations.AccessedWrite)
2244 {
2245 unsigned long long InstructionLength = vmread(VMX::VMCS_FIELD_VMEXIT_INSTRUCTION_LENGTH);
2246
2247 unsigned long long RipPa;
2248 if (AddressRange::IsUserAddress(reinterpret_cast<void*>(Rip)))
2249 {
2250 __writecr3(vmread(VMX::VMCS_FIELD_GUEST_CR3));
2251 RipPa = Supplementation::FastPhys::GetPhysAddressFast4KbUnsafe(Rip);
2252 __writecr3(g_Shared.KernelCr3);
2253 }

Callers

nothing calls this directly

Calls 11

vmreadFunction · 0.85
InjectEventFunction · 0.85
EnableMonitorTrapFlagFunction · 0.85
DisableGuestInterruptsFunction · 0.85
HandleExecuteReadMethod · 0.80
HandleReadMethod · 0.80
HandleExecuteWriteMethod · 0.80
HandleWriteMethod · 0.80
HandleExecuteMethod · 0.80
IsUserAddressFunction · 0.70

Tested by

no test coverage detected