diff options
author | Mike Larkin <mlarkin@cvs.openbsd.org> | 2017-03-02 02:57:36 +0000 |
---|---|---|
committer | Mike Larkin <mlarkin@cvs.openbsd.org> | 2017-03-02 02:57:36 +0000 |
commit | 4170538ba680b5e24389cd7462fffd3cc9101be8 (patch) | |
tree | 73ad9eda744323206d129c5119f9af4e28313441 | |
parent | 4f015a207c0842c11563fae5a46586f8ba4b16c2 (diff) |
reduce differences in vmm between amd64 and i386 (i386 picks up a handful
of recent fixes for SVM that were missed). No functional change on amd64
(just an added comment)
-rw-r--r-- | sys/arch/amd64/amd64/vmm.c | 3 | ||||
-rw-r--r-- | sys/arch/i386/i386/vmm.c | 55 |
2 files changed, 27 insertions, 31 deletions
diff --git a/sys/arch/amd64/amd64/vmm.c b/sys/arch/amd64/amd64/vmm.c index 6481f1a4cef..04a4d4fe7c0 100644 --- a/sys/arch/amd64/amd64/vmm.c +++ b/sys/arch/amd64/amd64/vmm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmm.c,v 1.116 2017/03/02 02:34:56 mlarkin Exp $ */ +/* $OpenBSD: vmm.c,v 1.117 2017/03/02 02:57:35 mlarkin Exp $ */ /* * Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org> * @@ -1292,6 +1292,7 @@ vcpu_reload_vmcs_vmx(uint64_t *vmcs) { uint64_t old; + /* Flush any old state */ if (!vmptrst(&old)) { if (old != 0xFFFFFFFFFFFFFFFFULL) { if (vmclear(&old)) diff --git a/sys/arch/i386/i386/vmm.c b/sys/arch/i386/i386/vmm.c index e6afcfe4fc9..c852deb05ee 100644 --- a/sys/arch/i386/i386/vmm.c +++ b/sys/arch/i386/i386/vmm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmm.c,v 1.21 2017/02/20 20:25:27 mlarkin Exp $ */ +/* $OpenBSD: vmm.c,v 1.22 2017/03/02 02:57:35 mlarkin Exp $ */ /* * Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org> * @@ -1338,8 +1338,7 @@ vcpu_readregs_vmx(struct vcpu *vcpu, uint64_t regmask, struct vcpu_reg_state *vrs) { int i, ret = 0; - uint32_t ar, sel; - uint32_t limit; + uint32_t sel, limit, ar; uint32_t *gprs = vrs->vrs_gprs; uint32_t *crs = vrs->vrs_crs; struct vcpu_segment_info *sregs = vrs->vrs_sregs; @@ -1542,6 +1541,7 @@ vcpu_writeregs_svm(struct vcpu *vcpu, uint64_t regmask, { uint32_t *gprs = vrs->vrs_gprs; uint32_t *crs = vrs->vrs_crs; + uint16_t attr; struct vcpu_segment_info *sregs = vrs->vrs_sregs; struct vmcb *vmcb = (struct vmcb *)vcpu->vc_control_va; @@ -1558,51 +1558,54 @@ vcpu_writeregs_svm(struct vcpu *vcpu, uint64_t regmask, vmcb->v_rip = gprs[VCPU_REGS_EIP]; vmcb->v_rsp = gprs[VCPU_REGS_ESP]; vmcb->v_rflags = gprs[VCPU_REGS_EFLAGS]; - DPRINTF("%s: set vcpu GPRs (eip=0x%llx esp=0x%llx)\n", - __func__, vmcb->v_rip, vmcb->v_rsp); } if (regmask & VM_RWREGS_SREGS) { vmcb->v_cs.vs_sel = sregs[VCPU_REGS_CS].vsi_sel; vmcb->v_cs.vs_lim = sregs[VCPU_REGS_CS].vsi_limit; - vmcb->v_cs.vs_attr = sregs[VCPU_REGS_CS].vsi_ar; + attr = sregs[VCPU_REGS_CS].vsi_ar; + vmcb->v_cs.vs_attr = (attr & 0xff) | ((attr >> 4) & 0xf00); vmcb->v_cs.vs_base = sregs[VCPU_REGS_CS].vsi_base; vmcb->v_ds.vs_sel = sregs[VCPU_REGS_DS].vsi_sel; vmcb->v_ds.vs_lim = sregs[VCPU_REGS_DS].vsi_limit; - vmcb->v_ds.vs_attr = sregs[VCPU_REGS_DS].vsi_ar; + attr = sregs[VCPU_REGS_DS].vsi_ar; + vmcb->v_ds.vs_attr = (attr & 0xff) | ((attr >> 4) & 0xf00); vmcb->v_ds.vs_base = sregs[VCPU_REGS_DS].vsi_base; vmcb->v_es.vs_sel = sregs[VCPU_REGS_ES].vsi_sel; vmcb->v_es.vs_lim = sregs[VCPU_REGS_ES].vsi_limit; - vmcb->v_es.vs_attr = sregs[VCPU_REGS_ES].vsi_ar; + attr = sregs[VCPU_REGS_ES].vsi_ar; + vmcb->v_es.vs_attr = (attr & 0xff) | ((attr >> 4) & 0xf00); vmcb->v_es.vs_base = sregs[VCPU_REGS_ES].vsi_base; vmcb->v_fs.vs_sel = sregs[VCPU_REGS_FS].vsi_sel; vmcb->v_fs.vs_lim = sregs[VCPU_REGS_FS].vsi_limit; - vmcb->v_fs.vs_attr = sregs[VCPU_REGS_FS].vsi_ar; + attr = sregs[VCPU_REGS_FS].vsi_ar; + vmcb->v_fs.vs_attr = (attr & 0xff) | ((attr >> 4) & 0xf00); vmcb->v_fs.vs_base = sregs[VCPU_REGS_FS].vsi_base; vmcb->v_gs.vs_sel = sregs[VCPU_REGS_GS].vsi_sel; vmcb->v_gs.vs_lim = sregs[VCPU_REGS_GS].vsi_limit; - vmcb->v_gs.vs_attr = sregs[VCPU_REGS_GS].vsi_ar; + attr = sregs[VCPU_REGS_GS].vsi_ar; + vmcb->v_gs.vs_attr = (attr & 0xff) | ((attr >> 4) & 0xf00); vmcb->v_gs.vs_base = sregs[VCPU_REGS_GS].vsi_base; vmcb->v_ss.vs_sel = sregs[VCPU_REGS_SS].vsi_sel; vmcb->v_ss.vs_lim = sregs[VCPU_REGS_SS].vsi_limit; - vmcb->v_ss.vs_attr = sregs[VCPU_REGS_SS].vsi_ar; + attr = sregs[VCPU_REGS_SS].vsi_ar; + vmcb->v_ss.vs_attr = (attr & 0xff) | ((attr >> 4) & 0xf00); vmcb->v_ss.vs_base = sregs[VCPU_REGS_SS].vsi_base; vmcb->v_ldtr.vs_sel = sregs[VCPU_REGS_LDTR].vsi_sel; vmcb->v_ldtr.vs_lim = sregs[VCPU_REGS_LDTR].vsi_limit; - vmcb->v_ldtr.vs_attr = sregs[VCPU_REGS_LDTR].vsi_ar; + attr = sregs[VCPU_REGS_LDTR].vsi_ar; + vmcb->v_ldtr.vs_attr = (attr & 0xff) | ((attr >> 4) & 0xf00); vmcb->v_ldtr.vs_base = sregs[VCPU_REGS_LDTR].vsi_base; vmcb->v_tr.vs_sel = sregs[VCPU_REGS_TR].vsi_sel; vmcb->v_tr.vs_lim = sregs[VCPU_REGS_TR].vsi_limit; + attr = sregs[VCPU_REGS_TR].vsi_ar; + vmcb->v_tr.vs_attr = (attr & 0xff) | ((attr >> 4) & 0xf00); vmcb->v_tr.vs_attr = sregs[VCPU_REGS_TR].vsi_ar; vmcb->v_tr.vs_base = sregs[VCPU_REGS_TR].vsi_base; vmcb->v_gdtr.vs_lim = vrs->vrs_gdtr.vsi_limit; vmcb->v_gdtr.vs_base = vrs->vrs_gdtr.vsi_base; vmcb->v_idtr.vs_lim = vrs->vrs_idtr.vsi_limit; vmcb->v_idtr.vs_base = vrs->vrs_idtr.vsi_base; - - DPRINTF("%s: set vcpu seg regs (gdt.base=0x%llx, " - "cs.sel=0x%llx)\n", __func__, vmcb->v_gdtr.vs_base, - (uint64_t)vmcb->v_cs.vs_sel); } if (regmask & VM_RWREGS_CRS) { @@ -1674,7 +1677,7 @@ vcpu_reset_regs_svm(struct vcpu *vcpu, struct vcpu_reg_state *vrs) /* Setup MSR bitmap */ memset((uint8_t *)vcpu->vc_msr_bitmap_va, 0xFF, 2 * PAGE_SIZE); - vmcb->v_iopm_pa = (uint64_t)(vcpu->vc_msr_bitmap_pa); + vmcb->v_msrpm_pa = (uint64_t)(vcpu->vc_msr_bitmap_pa); svm_setmsrbrw(vcpu, MSR_IA32_FEATURE_CONTROL); svm_setmsrbrw(vcpu, MSR_SYSENTER_CS); svm_setmsrbrw(vcpu, MSR_SYSENTER_ESP); @@ -1739,14 +1742,11 @@ svm_setmsrbr(struct vcpu *vcpu, uint32_t msr) msrs[idx] &= ~(SVM_MSRBIT_R(msr - 0xc0000000)); } else if (msr >= 0xc0010000 && msr <= 0xc0011fff) { idx = SVM_MSRIDX(msr - 0xc0010000) + 0x1000; - msrs[idx] &= ~(SVM_MSRBIT_R(msr - 0xc0000000)); + msrs[idx] &= ~(SVM_MSRBIT_R(msr - 0xc0010000)); } else { printf("%s: invalid msr 0x%x\n", __func__, msr); return; } - - DPRINTF("%s: set msr read bitmap, msr=0x%x, idx=0x%x, " - "msrs[0x%x]=0x%x\n", __func__, msr, idx, idx, msrs[idx]); } /* @@ -1782,15 +1782,12 @@ svm_setmsrbw(struct vcpu *vcpu, uint32_t msr) idx = SVM_MSRIDX(msr - 0xc0000000) + 0x800; msrs[idx] &= ~(SVM_MSRBIT_W(msr - 0xc0000000)); } else if (msr >= 0xc0010000 && msr <= 0xc0011fff) { - idx = SVM_MSRIDX(msr - 0xc0000000) + 0x1000; + idx = SVM_MSRIDX(msr - 0xc0010000) + 0x1000; msrs[idx] &= ~(SVM_MSRBIT_W(msr - 0xc0010000)); } else { printf("%s: invalid msr 0x%x\n", __func__, msr); return; } - - DPRINTF("%s: set msr write bitmap, msr=0x%x, idx=0x%x, " - "msrs[0x%x]=0x%x\n", __func__, msr, idx, idx, msrs[idx]); } /* @@ -2145,11 +2142,6 @@ vcpu_reset_regs_vmx(struct vcpu *vcpu, struct vcpu_reg_state *vrs) eptp |= IA32_EPT_PAGING_CACHE_TYPE_WB; } - if (msr & IA32_EPT_VPID_CAP_AD_BITS) { - /* EPT A/D bits supported */ - eptp |= IA32_EPT_AD_BITS_ENABLE; - } - DPRINTF("guest eptp = 0x%llx\n", eptp); if (vmwrite(VMCS_GUEST_IA32_EPTP, (uint32_t)(eptp & 0xFFFFFFFFUL))) { @@ -2547,6 +2539,9 @@ exit: if (vcpu->vc_vmx_msr_entry_load_va) km_free((void *)vcpu->vc_vmx_msr_entry_load_va, PAGE_SIZE, &kv_page, &kp_zero); + } else { + if (vmclear(&vcpu->vc_control_pa)) + ret = EINVAL; } return (ret); |