untrusted comment: verify with openbsd-70-base.pub RWR3KL+gSr4QZxZ1V5QU74jakt+ULUtTYWYCLvTrY17yQMeZmvQuJu5m7DHQmszr1MAX60WrwCkWN2NfAzgta9QGs2xXEi0YTgE= OpenBSD 7.0 errata 010, January 19, 2022: Intel-based vmm(4) hosts may have vm processes die due to host-side state corruption. Apply by doing: signify -Vep /etc/signify/openbsd-70-base.pub -x 010_vmm.patch.sig \ -m - | (cd /usr/src && patch -p0) And then rebuild and install a new kernel: KK=`sysctl -n kern.osversion | cut -d# -f1` cd /usr/src/sys/arch/`machine`/compile/$KK make obj make config make make install Index: sys/arch/amd64/amd64/vmm.c =================================================================== RCS file: /cvs/src/sys/arch/amd64/amd64/vmm.c,v diff -u -p -r1.293 vmm.c --- sys/arch/amd64/amd64/vmm.c 13 Sep 2021 22:16:27 -0000 1.293 +++ sys/arch/amd64/amd64/vmm.c 17 Jan 2022 00:19:59 -0000 @@ -1368,7 +1368,7 @@ vmclear_on_cpu(struct cpu_info *ci) static int vmx_remote_vmclear(struct cpu_info *ci, struct vcpu *vcpu) { - int ret = 0, nticks = 100000; + int ret = 0, nticks = 200000000; rw_enter_write(&ci->ci_vmcs_lock); atomic_swap_ulong(&ci->ci_vmcs_pa, vcpu->vc_control_pa); @@ -3028,12 +3028,22 @@ vcpu_reset_regs_vmx(struct vcpu *vcpu, s IA32_VMX_ACTIVATE_SECONDARY_CONTROLS, 1)) { if (vcpu_vmx_check_cap(vcpu, IA32_VMX_PROCBASED2_CTLS, IA32_VMX_ENABLE_VPID, 1)) { - if (vmm_alloc_vpid(&vpid)) { + + /* We may sleep during allocation, so reload VMCS. */ + vcpu->vc_last_pcpu = curcpu(); + ret = vmm_alloc_vpid(&vpid); + if (vcpu_reload_vmcs_vmx(vcpu)) { + printf("%s: failed to reload vmcs\n", __func__); + ret = EINVAL; + goto exit; + } + if (ret) { DPRINTF("%s: could not allocate VPID\n", __func__); ret = EINVAL; goto exit; } + if (vmwrite(VMCS_GUEST_VPID, vpid)) { DPRINTF("%s: error setting guest VPID\n", __func__); @@ -5571,10 +5581,14 @@ vmx_fault_page(struct vcpu *vcpu, paddr_ return (EAGAIN); } - KERNEL_LOCK(); + /* We may sleep during uvm_fault(9), so reload VMCS. */ + vcpu->vc_last_pcpu = curcpu(); ret = uvm_fault(vcpu->vc_parent->vm_map, gpa, VM_FAULT_WIRE, PROT_READ | PROT_WRITE | PROT_EXEC); - KERNEL_UNLOCK(); + if (vcpu_reload_vmcs_vmx(vcpu)) { + printf("%s: failed to reload vmcs\n", __func__); + return (EINVAL); + } if (ret) printf("%s: uvm_fault returns %d, GPA=0x%llx, rip=0x%llx\n", @@ -5964,7 +5978,16 @@ vmx_load_pdptes(struct vcpu *vcpu) ret = 0; - cr3_host_virt = (vaddr_t)km_alloc(PAGE_SIZE, &kv_any, &kp_none, &kd_waitok); + /* We may sleep during km_alloc(9), so reload VMCS. */ + vcpu->vc_last_pcpu = curcpu(); + cr3_host_virt = (vaddr_t)km_alloc(PAGE_SIZE, &kv_any, &kp_none, + &kd_waitok); + if (vcpu_reload_vmcs_vmx(vcpu)) { + printf("%s: failed to reload vmcs\n", __func__); + ret = EINVAL; + goto exit; + } + if (!cr3_host_virt) { printf("%s: can't allocate address for guest CR3 mapping\n", __func__); @@ -6000,7 +6023,15 @@ vmx_load_pdptes(struct vcpu *vcpu) exit: pmap_kremove(cr3_host_virt, PAGE_SIZE); + + /* km_free(9) might sleep, so we need to reload VMCS. */ + vcpu->vc_last_pcpu = curcpu(); km_free((void *)cr3_host_virt, PAGE_SIZE, &kv_any, &kp_none); + if (vcpu_reload_vmcs_vmx(vcpu)) { + printf("%s: failed to reload vmcs after km_free\n", __func__); + ret = EINVAL; + } + return (ret); }