summaryrefslogtreecommitdiffstats
path: root/sys/amd64/vmm/vmm.c
diff options
context:
space:
mode:
authorneel <neel@FreeBSD.org>2015-05-06 16:25:20 +0000
committerneel <neel@FreeBSD.org>2015-05-06 16:25:20 +0000
commit7776059e98331e0dd518aa210f210fce7b64c55b (patch)
tree0f6bdd72bb29ba16cf54715fc06dcea6d712040f /sys/amd64/vmm/vmm.c
parent54a32460dc6aa57316f66dfd3eb2bab0afa7263b (diff)
downloadFreeBSD-src-7776059e98331e0dd518aa210f210fce7b64c55b.zip
FreeBSD-src-7776059e98331e0dd518aa210f210fce7b64c55b.tar.gz
Deprecate the 3-way return values from vm_gla2gpa() and vm_copy_setup().
Prior to this change both functions returned 0 for success, -1 for failure and +1 to indicate that an exception was injected into the guest. The numerical value of ERESTART also happens to be -1 so when these functions returned -1 it had to be translated to a positive errno value to prevent the VM_RUN ioctl from being inadvertently restarted. This made it easy to introduce bugs when writing emulation code. Fix this by adding an 'int *guest_fault' parameter and setting it to '1' if an exception was delivered to the guest. The return value is 0 or EFAULT so no additional translation is needed. Reviewed by: tychon MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D2428
Diffstat (limited to 'sys/amd64/vmm/vmm.c')
-rw-r--r--sys/amd64/vmm/vmm.c23
1 files changed, 10 insertions, 13 deletions
diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c
index bca9b98..51c63f5 100644
--- a/sys/amd64/vmm/vmm.c
+++ b/sys/amd64/vmm/vmm.c
@@ -1256,7 +1256,7 @@ vm_handle_inst_emul(struct vm *vm, int vcpuid, bool *retu)
mem_region_read_t mread;
mem_region_write_t mwrite;
enum vm_cpu_mode cpu_mode;
- int cs_d, error, length;
+ int cs_d, error, fault, length;
vcpu = &vm->vcpu[vcpuid];
vme = &vcpu->exitinfo;
@@ -1279,19 +1279,15 @@ vm_handle_inst_emul(struct vm *vm, int vcpuid, bool *retu)
*/
length = vme->inst_length ? vme->inst_length : VIE_INST_SIZE;
error = vmm_fetch_instruction(vm, vcpuid, paging, vme->rip +
- cs_base, length, vie);
+ cs_base, length, vie, &fault);
} else {
/*
* The instruction bytes have already been copied into 'vie'
*/
- error = 0;
+ error = fault = 0;
}
- 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 (error || fault)
+ return (error);
if (vmm_decode_instruction(vm, vcpuid, gla, cpu_mode, cs_d, vie) != 0) {
VCPU_CTR1(vm, vcpuid, "Error decoding instruction at %#lx",
@@ -2323,7 +2319,7 @@ vm_copy_teardown(struct vm *vm, int vcpuid, struct vm_copyinfo *copyinfo,
int
vm_copy_setup(struct vm *vm, int vcpuid, struct vm_guest_paging *paging,
uint64_t gla, size_t len, int prot, struct vm_copyinfo *copyinfo,
- int num_copyinfo)
+ int num_copyinfo, int *fault)
{
int error, idx, nused;
size_t n, off, remaining;
@@ -2336,8 +2332,8 @@ vm_copy_setup(struct vm *vm, int vcpuid, struct vm_guest_paging *paging,
remaining = len;
while (remaining > 0) {
KASSERT(nused < num_copyinfo, ("insufficient vm_copyinfo"));
- error = vm_gla2gpa(vm, vcpuid, paging, gla, prot, &gpa);
- if (error)
+ error = vm_gla2gpa(vm, vcpuid, paging, gla, prot, &gpa, fault);
+ if (error || *fault)
return (error);
off = gpa & PAGE_MASK;
n = min(remaining, PAGE_SIZE - off);
@@ -2359,8 +2355,9 @@ vm_copy_setup(struct vm *vm, int vcpuid, struct vm_guest_paging *paging,
if (idx != nused) {
vm_copy_teardown(vm, vcpuid, copyinfo, num_copyinfo);
- return (-1);
+ return (EFAULT);
} else {
+ *fault = 0;
return (0);
}
}
OpenPOWER on IntegriCloud