diff options
author | neel <neel@FreeBSD.org> | 2014-01-14 01:55:58 +0000 |
---|---|---|
committer | neel <neel@FreeBSD.org> | 2014-01-14 01:55:58 +0000 |
commit | 0bd53a85fbf7adb57099ce3d0a375a888f42f05e (patch) | |
tree | 16bc44da7679cb3df8f027a355a40bf77077480f /sys/amd64/vmm/intel/vmx.c | |
parent | 22c7ee83f61dc73c60942c528108e8b6220ed350 (diff) | |
download | FreeBSD-src-0bd53a85fbf7adb57099ce3d0a375a888f42f05e.zip FreeBSD-src-0bd53a85fbf7adb57099ce3d0a375a888f42f05e.tar.gz |
Add an API to rendezvous all active vcpus in a virtual machine. The rendezvous
can be initiated in the context of a vcpu thread or from the bhyve(8) control
process.
The first use of this functionality is to update the vlapic trigger-mode
register when the IOAPIC pin configuration is changed.
Prior to this change we would update the TMR in the virtual-APIC page at
the time of interrupt delivery. But this doesn't work with Posted Interrupts
because there is no way to program the EOI_exit_bitmap[] in the VMCS of
the target at the time of interrupt delivery.
Discussed with: grehan@
Diffstat (limited to 'sys/amd64/vmm/intel/vmx.c')
-rw-r--r-- | sys/amd64/vmm/intel/vmx.c | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c index 5809b8c..a4e0a85 100644 --- a/sys/amd64/vmm/intel/vmx.c +++ b/sys/amd64/vmm/intel/vmx.c @@ -1669,6 +1669,18 @@ vmx_exit_astpending(struct vmx *vmx, int vcpu, struct vm_exit *vmexit) } static __inline int +vmx_exit_rendezvous(struct vmx *vmx, int vcpu, struct vm_exit *vmexit) +{ + + vmexit->rip = vmcs_guest_rip(); + vmexit->inst_length = 0; + vmexit->exitcode = VM_EXITCODE_RENDEZVOUS; + vmm_stat_incr(vmx->vm, vcpu, VMEXIT_RENDEZVOUS, 1); + + return (UNHANDLED); +} + +static __inline int vmx_exit_inst_error(struct vmxctx *vmxctx, int rc, struct vm_exit *vmexit) { @@ -1697,10 +1709,12 @@ vmx_exit_inst_error(struct vmxctx *vmxctx, int rc, struct vm_exit *vmexit) } static int -vmx_run(void *arg, int vcpu, register_t startrip, pmap_t pmap) +vmx_run(void *arg, int vcpu, register_t startrip, pmap_t pmap, + void *rendezvous_cookie) { int rc, handled, launched; struct vmx *vmx; + struct vm *vm; struct vmxctx *vmxctx; struct vmcs *vmcs; struct vm_exit *vmexit; @@ -1709,10 +1723,11 @@ vmx_run(void *arg, int vcpu, register_t startrip, pmap_t pmap) uint32_t exit_reason; vmx = arg; + vm = vmx->vm; vmcs = &vmx->vmcs[vcpu]; vmxctx = &vmx->ctx[vcpu]; - vlapic = vm_lapic(vmx->vm, vcpu); - vmexit = vm_exitinfo(vmx->vm, vcpu); + vlapic = vm_lapic(vm, vcpu); + vmexit = vm_exitinfo(vm, vcpu); launched = 0; KASSERT(vmxctx->pmap == pmap, @@ -1760,6 +1775,12 @@ vmx_run(void *arg, int vcpu, register_t startrip, pmap_t pmap) break; } + if (vcpu_rendezvous_pending(rendezvous_cookie)) { + enable_intr(); + handled = vmx_exit_rendezvous(vmx, vcpu, vmexit); + break; + } + vmx_inject_interrupts(vmx, vcpu, vlapic); vmx_run_trace(vmx, vcpu); rc = vmx_enter_guest(vmxctx, launched); @@ -1793,9 +1814,9 @@ vmx_run(void *arg, int vcpu, register_t startrip, pmap_t pmap) } if (!handled) - vmm_stat_incr(vmx->vm, vcpu, VMEXIT_USERSPACE, 1); + vmm_stat_incr(vm, vcpu, VMEXIT_USERSPACE, 1); - VCPU_CTR1(vmx->vm, vcpu, "returning from vmx_run: exitcode %d", + VCPU_CTR1(vm, vcpu, "returning from vmx_run: exitcode %d", vmexit->exitcode); VMCLEAR(vmcs); |