-/* $OpenBSD: vmm.c,v 1.282 2021/05/12 04:00:46 mlarkin Exp $ */
+/* $OpenBSD: vmm.c,v 1.283 2021/05/17 23:36:40 dv Exp $ */
/*
* Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org>
*
int
vcpu_run_vmx(struct vcpu *vcpu, struct vm_run_params *vrp)
{
- int ret = 0, resume, locked, exitinfo;
+ int ret = 0, resume = 0, cleared = 1, locked, exitinfo;
struct region_descriptor gdt;
- struct cpu_info *ci;
+ struct cpu_info *ci = NULL;
uint64_t exit_reason, cr3, vmcs_ptr, insn_error;
struct schedstate_percpu *spc;
struct vmx_invvpid_descriptor vid;
u_long s;
struct region_descriptor gdtr, idtr;
- resume = 0;
irq = vrp->vrp_irq;
/*
while (ret == 0) {
vmm_update_pvclock(vcpu);
- if (!resume) {
+ if (cleared || ci != curcpu()) {
/*
- * We are launching for the first time, or we are
- * resuming from a different pcpu, so we need to
- * reset certain pcpu-specific values.
+ * We are launching for the first time, we yielded the
+ * pcpu, or we are resuming from a different pcpu, so we
+ * need to reset certain pcpu-specific values.
*/
+ resume = cleared = 0;
ci = curcpu();
setregion(&gdt, ci->ci_gdt, GDT_SIZE - 1);
/* Host TR base */
if (vmwrite(VMCS_HOST_IA32_TR_BASE,
- (uint64_t)curcpu()->ci_tss)) {
+ (uint64_t)ci->ci_tss)) {
ret = EINVAL;
break;
}
KERNEL_UNLOCK();
ret = vmx_enter_guest(&vcpu->vc_control_pa,
&vcpu->vc_gueststate, resume,
- curcpu()->ci_vmm_cap.vcc_vmx.vmx_has_l1_flush_msr);
+ ci->ci_vmm_cap.vcc_vmx.vmx_has_l1_flush_msr);
bare_lgdt(&gdtr);
lidt(&idtr);
/* Check if we should yield - don't hog the cpu */
spc = &ci->ci_schedstate;
if (spc->spc_schedflags & SPCF_SHOULDYIELD) {
- resume = 0;
if (vmclear(&vcpu->vc_control_pa)) {
ret = EINVAL;
break;
}
+ cleared = 1;
yield();
}
} else if (ret == VMX_FAIL_LAUNCH_INVALID_VMCS) {