diff options
author | neel <neel@FreeBSD.org> | 2014-05-22 03:14:54 +0000 |
---|---|---|
committer | neel <neel@FreeBSD.org> | 2014-05-22 03:14:54 +0000 |
commit | 645d479a58a5eafe6f6c79b7f30b38ef8b865e60 (patch) | |
tree | b691b9b7b90a6c77cccd436ff24422fe17a9017e /sys/amd64/vmm/vmm.c | |
parent | 9e29b5f65069140228be54ba30dab6ace4548361 (diff) | |
download | FreeBSD-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.c | 21 |
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 = { |