summaryrefslogtreecommitdiffstats
path: root/lib/libvmmapi/vmmapi.c
diff options
context:
space:
mode:
authorneel <neel@FreeBSD.org>2015-01-18 03:08:30 +0000
committerneel <neel@FreeBSD.org>2015-01-18 03:08:30 +0000
commitd9f07f98412532f2077e8a8503651536223931ca (patch)
tree059a656c08c5c81e9f08be1740cebcdf26e3df13 /lib/libvmmapi/vmmapi.c
parent359b23588446cd5af725d5a06bf6058c4ffa57b9 (diff)
downloadFreeBSD-src-d9f07f98412532f2077e8a8503651536223931ca.zip
FreeBSD-src-d9f07f98412532f2077e8a8503651536223931ca.tar.gz
Simplify instruction restart logic in bhyve.
Keep track of the next instruction to be executed by the vcpu as 'nextrip'. As a result the VM_RUN ioctl no longer takes the %rip where a vcpu should start execution. Also, instruction restart happens implicitly via 'vm_inject_exception()' or explicitly via 'vm_restart_instruction()'. The APIs behave identically in both kernel and userspace contexts. The main beneficiary is the instruction emulation code that executes in both contexts. bhyve(8) VM exit handlers now treat 'vmexit->rip' and 'vmexit->inst_length' as readonly: - Restarting an instruction is now done by calling 'vm_restart_instruction()' as opposed to setting 'vmexit->inst_length' to 0 (e.g. emulate_inout()) - Resuming vcpu at an arbitrary %rip is now done by setting VM_REG_GUEST_RIP as opposed to changing 'vmexit->rip' (e.g. vmexit_task_switch()) Differential Revision: https://reviews.freebsd.org/D1526 Reviewed by: grehan MFC after: 2 weeks
Diffstat (limited to 'lib/libvmmapi/vmmapi.c')
-rw-r--r--lib/libvmmapi/vmmapi.c37
1 files changed, 15 insertions, 22 deletions
diff --git a/lib/libvmmapi/vmmapi.c b/lib/libvmmapi/vmmapi.c
index bca1174..5660f3b 100644
--- a/lib/libvmmapi/vmmapi.c
+++ b/lib/libvmmapi/vmmapi.c
@@ -368,14 +368,13 @@ vm_get_register(struct vmctx *ctx, int vcpu, int reg, uint64_t *ret_val)
}
int
-vm_run(struct vmctx *ctx, int vcpu, uint64_t rip, struct vm_exit *vmexit)
+vm_run(struct vmctx *ctx, int vcpu, struct vm_exit *vmexit)
{
int error;
struct vm_run vmrun;
bzero(&vmrun, sizeof(vmrun));
vmrun.cpuid = vcpu;
- vmrun.rip = rip;
error = ioctl(ctx->fd, VM_RUN, &vmrun);
bcopy(&vmrun.vm_exit, vmexit, sizeof(struct vm_exit));
@@ -399,36 +398,22 @@ vm_reinit(struct vmctx *ctx)
return (ioctl(ctx->fd, VM_REINIT, 0));
}
-static int
-vm_inject_exception_real(struct vmctx *ctx, int vcpu, int vector,
- int error_code, int error_code_valid)
+int
+vm_inject_exception(struct vmctx *ctx, int vcpu, int vector, int errcode_valid,
+ uint32_t errcode, int restart_instruction)
{
struct vm_exception exc;
- bzero(&exc, sizeof(exc));
exc.cpuid = vcpu;
exc.vector = vector;
- exc.error_code = error_code;
- exc.error_code_valid = error_code_valid;
+ exc.error_code = errcode;
+ exc.error_code_valid = errcode_valid;
+ exc.restart_instruction = restart_instruction;
return (ioctl(ctx->fd, VM_INJECT_EXCEPTION, &exc));
}
int
-vm_inject_exception(struct vmctx *ctx, int vcpu, int vector)
-{
-
- return (vm_inject_exception_real(ctx, vcpu, vector, 0, 0));
-}
-
-int
-vm_inject_exception2(struct vmctx *ctx, int vcpu, int vector, int errcode)
-{
-
- return (vm_inject_exception_real(ctx, vcpu, vector, errcode, 1));
-}
-
-int
vm_apicid2vcpu(struct vmctx *ctx, int apicid)
{
/*
@@ -1198,3 +1183,11 @@ vm_rtc_gettime(struct vmctx *ctx, time_t *secs)
*secs = rtctime.secs;
return (error);
}
+
+int
+vm_restart_instruction(void *arg, int vcpu)
+{
+ struct vmctx *ctx = arg;
+
+ return (ioctl(ctx->fd, VM_RESTART_INSTRUCTION, &vcpu));
+}
OpenPOWER on IntegriCloud