From: dv Date: Tue, 11 May 2021 22:04:10 +0000 (+0000) Subject: vmm(4): fix flawed physical cpu tracking logic in svm_run_vcpu X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=97ad4f7f93830151ea04ac20ee6bfaaea2593cb4;p=openbsd vmm(4): fix flawed physical cpu tracking logic in svm_run_vcpu Replace the overly complicated logic used to track which CPU we are on in svm_run_vcpu. This fixes an issue where ltr causes a #GP on exit in certain conditions due to referencing the wrong GDT. This was primarily witnessed with NixOS guests that performed a heavy amount of disk io. Reported by Josh Rickmar. Tested by Josh & abieber@. OK mlarkin@. --- diff --git a/sys/arch/amd64/amd64/vmm.c b/sys/arch/amd64/amd64/vmm.c index ebf2bce6b36..b1c49b057d4 100644 --- a/sys/arch/amd64/amd64/vmm.c +++ b/sys/arch/amd64/amd64/vmm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmm.c,v 1.280 2021/04/06 00:19:58 dv Exp $ */ +/* $OpenBSD: vmm.c,v 1.281 2021/05/11 22:04:10 dv Exp $ */ /* * Copyright (c) 2014 Mike Larkin * @@ -6970,15 +6970,14 @@ vmm_handle_cpuid(struct vcpu *vcpu) int vcpu_run_svm(struct vcpu *vcpu, struct vm_run_params *vrp) { - int ret = 0, resume; + int ret = 0; struct region_descriptor gdt; - struct cpu_info *ci; + struct cpu_info *ci = NULL; uint64_t exit_reason; struct schedstate_percpu *spc; uint16_t irq; struct vmcb *vmcb = (struct vmcb *)vcpu->vc_control_va; - resume = 0; irq = vrp->vrp_irq; /* @@ -7000,7 +6999,7 @@ vcpu_run_svm(struct vcpu *vcpu, struct vm_run_params *vrp) while (ret == 0) { vmm_update_pvclock(vcpu); - if (!resume) { + if (ci != curcpu()) { /* * We are launching for the first time, or we are * resuming from a different pcpu, so we need to @@ -7106,8 +7105,6 @@ vcpu_run_svm(struct vcpu *vcpu, struct vm_run_params *vrp) /* If we exited successfully ... */ if (ret == 0) { - resume = 1; - vcpu->vc_gueststate.vg_rflags = vmcb->v_rflags; /* @@ -7149,7 +7146,6 @@ vcpu_run_svm(struct vcpu *vcpu, struct vm_run_params *vrp) /* Check if we should yield - don't hog the cpu */ spc = &ci->ci_schedstate; if (spc->spc_schedflags & SPCF_SHOULDYIELD) { - resume = 0; yield(); } }