summaryrefslogtreecommitdiffstats
path: root/sys/amd64/vmm/vmm.c
diff options
context:
space:
mode:
authorneel <neel@FreeBSD.org>2014-05-22 03:14:54 +0000
committerneel <neel@FreeBSD.org>2014-05-22 03:14:54 +0000
commit645d479a58a5eafe6f6c79b7f30b38ef8b865e60 (patch)
treeb691b9b7b90a6c77cccd436ff24422fe17a9017e /sys/amd64/vmm/vmm.c
parent9e29b5f65069140228be54ba30dab6ace4548361 (diff)
downloadFreeBSD-src-645d479a58a5eafe6f6c79b7f30b38ef8b865e60.zip
FreeBSD-src-645d479a58a5eafe6f6c79b7f30b38ef8b865e60.tar.gz
Inject page fault into the guest if the page table walker detects an invalid
translation for the guest linear address.
Diffstat (limited to 'sys/amd64/vmm/vmm.c')
-rw-r--r--sys/amd64/vmm/vmm.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c
index 7ab0b1e..b009905 100644
--- a/sys/amd64/vmm/vmm.c
+++ b/sys/amd64/vmm/vmm.c
@@ -1155,9 +1155,14 @@ vm_handle_inst_emul(struct vm *vm, int vcpuid, bool *retu)
vie_init(vie);
/* Fetch, decode and emulate the faulting instruction */
- if (vmm_fetch_instruction(vm, vcpuid, rip, inst_length, cr3,
- paging_mode, cpl, vie) != 0)
+ error = vmm_fetch_instruction(vm, vcpuid, rip, inst_length, cr3,
+ paging_mode, cpl, vie);
+ if (error == 1)
+ return (0); /* Resume guest to handle page fault */
+ else if (error == -1)
return (EFAULT);
+ else if (error != 0)
+ panic("%s: vmm_fetch_instruction error %d", __func__, error);
if (vmm_decode_instruction(vm, vcpuid, gla, cpu_mode, vie) != 0)
return (EFAULT);
@@ -1431,6 +1436,18 @@ vm_inject_fault(struct vm *vm, int vcpuid, struct vm_exception *exception)
}
void
+vm_inject_pf(struct vm *vm, int vcpuid, int error_code)
+{
+ struct vm_exception pf = {
+ .vector = IDT_PF,
+ .error_code_valid = 1,
+ .error_code = error_code
+ };
+
+ vm_inject_fault(vm, vcpuid, &pf);
+}
+
+void
vm_inject_gp(struct vm *vm, int vcpuid)
{
struct vm_exception gpf = {
OpenPOWER on IntegriCloud