Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-9]: src/sys/dev/nvmm Pull up following revision(s) (requested by ...



details:   https://anonhg.NetBSD.org/src/rev/9a8735e04438
branches:  netbsd-9
changeset: 932646:9a8735e04438
user:      martin <martin%NetBSD.org@localhost>
date:      Wed May 13 12:21:56 2020 +0000

description:
Pull up following revision(s) (requested by maxv in ticket #898):

        sys/dev/nvmm/x86/nvmm_x86_svm.c: revision 1.59
        sys/dev/nvmm/nvmm_internal.h: revision 1.14
        sys/dev/nvmm/x86/nvmm_x86_vmx.c: revision 1.53
        sys/dev/nvmm/x86/nvmm_x86_vmx.c: revision 1.54
        sys/dev/nvmm/x86/nvmm_x86_vmx.c: revision 1.55
        sys/dev/nvmm/nvmm.c: revision 1.27
        sys/dev/nvmm/nvmm.c: revision 1.28

When the identification fails, print the reason.

If we were processing a software int/excp, and got a VMEXIT in the middle,
we must also reflect the instruction length, otherwise the next VMENTER
fails and Qemu shuts the guest down.

On Intel CPUs, CPUID leaf 0xB, too, provides topology information, so
filter it correctly, to avoid inconsistencies if the host has SMT.

This fixes HaikuOS which fetches SMT information from there and would
panic because of the inconsistencies.

diffstat:

 sys/dev/nvmm/nvmm.c             |  10 ++++-
 sys/dev/nvmm/nvmm_internal.h    |   3 +-
 sys/dev/nvmm/x86/nvmm_x86_svm.c |   9 ++++-
 sys/dev/nvmm/x86/nvmm_x86_vmx.c |  65 +++++++++++++++++++++++++++++++++++++---
 4 files changed, 75 insertions(+), 12 deletions(-)

diffs (truncated from 329 to 300 lines):

diff -r e715021acda5 -r 9a8735e04438 sys/dev/nvmm/nvmm.c
--- a/sys/dev/nvmm/nvmm.c       Sat May 09 08:21:36 2020 +0000
+++ b/sys/dev/nvmm/nvmm.c       Wed May 13 12:21:56 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nvmm.c,v 1.22.2.2 2020/04/27 14:56:22 martin Exp $     */
+/*     $NetBSD: nvmm.c,v 1.22.2.3 2020/05/13 12:21:56 martin Exp $     */
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.22.2.2 2020/04/27 14:56:22 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.22.2.3 2020/05/13 12:21:56 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -413,6 +413,8 @@
 
        nvmm_vcpu_put(vcpu);
 
+       atomic_inc_uint(&mach->ncpus);
+
 out:
        nvmm_machine_put(mach);
        return error;
@@ -437,6 +439,8 @@
        nvmm_vcpu_free(mach, vcpu);
        nvmm_vcpu_put(vcpu);
 
+       atomic_dec_uint(&mach->ncpus);
+
 out:
        nvmm_machine_put(mach);
        return error;
@@ -961,7 +965,7 @@
                break;
        }
        if (nvmm_impl == NULL) {
-               printf("[!] No implementation found\n");
+               printf("NVMM: CPU not supported\n");
                return ENOTSUP;
        }
 
diff -r e715021acda5 -r 9a8735e04438 sys/dev/nvmm/nvmm_internal.h
--- a/sys/dev/nvmm/nvmm_internal.h      Sat May 09 08:21:36 2020 +0000
+++ b/sys/dev/nvmm/nvmm_internal.h      Wed May 13 12:21:56 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nvmm_internal.h,v 1.12.2.1 2019/11/10 12:58:30 martin Exp $    */
+/*     $NetBSD: nvmm_internal.h,v 1.12.2.2 2020/05/13 12:21:56 martin Exp $    */
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -83,6 +83,7 @@
        struct nvmm_hmapping hmap[NVMM_MAX_HMAPPINGS];
 
        /* CPU */
+       volatile unsigned int ncpus;
        struct nvmm_cpu cpus[NVMM_MAX_VCPUS];
 
        /* Implementation-specific */
diff -r e715021acda5 -r 9a8735e04438 sys/dev/nvmm/x86/nvmm_x86_svm.c
--- a/sys/dev/nvmm/x86/nvmm_x86_svm.c   Sat May 09 08:21:36 2020 +0000
+++ b/sys/dev/nvmm/x86/nvmm_x86_svm.c   Wed May 13 12:21:56 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nvmm_x86_svm.c,v 1.46.4.3 2019/11/25 16:39:30 martin Exp $     */
+/*     $NetBSD: nvmm_x86_svm.c,v 1.46.4.4 2020/05/13 12:21:56 martin Exp $     */
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.46.4.3 2019/11/25 16:39:30 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.46.4.4 2020/05/13 12:21:56 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -2266,21 +2266,25 @@
                return false;
        }
        if (!(cpu_feature[3] & CPUID_SVM)) {
+               printf("NVMM: SVM not supported\n");
                return false;
        }
 
        if (curcpu()->ci_max_ext_cpuid < 0x8000000a) {
+               printf("NVMM: CPUID leaf not available\n");
                return false;
        }
        x86_cpuid(0x8000000a, descs);
 
        /* Want Nested Paging. */
        if (!(descs[3] & CPUID_AMD_SVM_NP)) {
+               printf("NVMM: SVM-NP not supported\n");
                return false;
        }
 
        /* Want nRIP. */
        if (!(descs[3] & CPUID_AMD_SVM_NRIPS)) {
+               printf("NVMM: SVM-NRIPS not supported\n");
                return false;
        }
 
@@ -2288,6 +2292,7 @@
 
        msr = rdmsr(MSR_VMCR);
        if ((msr & VMCR_SVMED) && (msr & VMCR_LOCK)) {
+               printf("NVMM: SVM disabled in BIOS\n");
                return false;
        }
 
diff -r e715021acda5 -r 9a8735e04438 sys/dev/nvmm/x86/nvmm_x86_vmx.c
--- a/sys/dev/nvmm/x86/nvmm_x86_vmx.c   Sat May 09 08:21:36 2020 +0000
+++ b/sys/dev/nvmm/x86/nvmm_x86_vmx.c   Wed May 13 12:21:56 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nvmm_x86_vmx.c,v 1.36.2.5 2020/02/10 19:05:05 martin Exp $     */
+/*     $NetBSD: nvmm_x86_vmx.c,v 1.36.2.6 2020/05/13 12:21:56 martin Exp $     */
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.36.2.5 2020/02/10 19:05:05 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.36.2.6 2020/05/13 12:21:56 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -39,6 +39,7 @@
 #include <sys/cpu.h>
 #include <sys/xcall.h>
 #include <sys/mman.h>
+#include <sys/bitops.h>
 
 #include <uvm/uvm.h>
 #include <uvm/uvm_page.h>
@@ -367,7 +368,7 @@
 #define                INTR_INFO_ERROR                 __BIT(11)
 #define                INTR_INFO_VALID                 __BIT(31)
 #define VMCS_ENTRY_EXCEPTION_ERROR             0x00004018
-#define VMCS_ENTRY_INST_LENGTH                 0x0000401A
+#define VMCS_ENTRY_INSTRUCTION_LENGTH          0x0000401A
 #define VMCS_TPR_THRESHOLD                     0x0000401C
 #define VMCS_PROCBASED_CTLS2                   0x0000401E
 #define                PROC_CTLS2_VIRT_APIC_ACCESSES   __BIT(0)
@@ -1137,9 +1138,11 @@
 }
 
 static void
-vmx_inkernel_handle_cpuid(struct nvmm_cpu *vcpu, uint64_t eax, uint64_t ecx)
+vmx_inkernel_handle_cpuid(struct nvmm_machine *mach, struct nvmm_cpu *vcpu,
+    uint64_t eax, uint64_t ecx)
 {
        struct vmx_cpudata *cpudata = vcpu->cpudata;
+       unsigned int ncpus;
        uint64_t cr4;
 
        switch (eax) {
@@ -1186,6 +1189,33 @@
                cpudata->gprs[NVMM_X64_GPR_RCX] = 0;
                cpudata->gprs[NVMM_X64_GPR_RDX] = 0;
                break;
+       case 0x0000000B:
+               switch (ecx) {
+               case 0: /* Threads */
+                       cpudata->gprs[NVMM_X64_GPR_RAX] = 0;
+                       cpudata->gprs[NVMM_X64_GPR_RBX] = 0;
+                       cpudata->gprs[NVMM_X64_GPR_RCX] =
+                           __SHIFTIN(ecx, CPUID_TOP_LVLNUM) |
+                           __SHIFTIN(CPUID_TOP_LVLTYPE_SMT, CPUID_TOP_LVLTYPE);
+                       cpudata->gprs[NVMM_X64_GPR_RDX] = vcpu->cpuid;
+                       break;
+               case 1: /* Cores */
+                       ncpus = atomic_load_relaxed(&mach->ncpus);
+                       cpudata->gprs[NVMM_X64_GPR_RAX] = ilog2(ncpus);
+                       cpudata->gprs[NVMM_X64_GPR_RBX] = ncpus;
+                       cpudata->gprs[NVMM_X64_GPR_RCX] =
+                           __SHIFTIN(ecx, CPUID_TOP_LVLNUM) |
+                           __SHIFTIN(CPUID_TOP_LVLTYPE_CORE, CPUID_TOP_LVLTYPE);
+                       cpudata->gprs[NVMM_X64_GPR_RDX] = vcpu->cpuid;
+                       break;
+               default:
+                       cpudata->gprs[NVMM_X64_GPR_RAX] = 0;
+                       cpudata->gprs[NVMM_X64_GPR_RBX] = 0;
+                       cpudata->gprs[NVMM_X64_GPR_RCX] = 0; /* LVLTYPE_INVAL */
+                       cpudata->gprs[NVMM_X64_GPR_RDX] = 0;
+                       break;
+               }
+               break;
        case 0x0000000D:
                if (vmx_xcr0_mask == 0) {
                        break;
@@ -1267,7 +1297,7 @@
        cpudata->gprs[NVMM_X64_GPR_RCX] = descs[2];
        cpudata->gprs[NVMM_X64_GPR_RDX] = descs[3];
 
-       vmx_inkernel_handle_cpuid(vcpu, eax, ecx);
+       vmx_inkernel_handle_cpuid(mach, vcpu, eax, ecx);
 
        for (i = 0; i < VMX_NCPUIDS; i++) {
                if (!cpudata->cpuidpresent[i]) {
@@ -1900,7 +1930,7 @@
 static inline void
 vmx_exit_evt(struct vmx_cpudata *cpudata)
 {
-       uint64_t info, err;
+       uint64_t info, err, inslen;
 
        cpudata->evt_pending = false;
 
@@ -1913,6 +1943,14 @@
        vmx_vmwrite(VMCS_ENTRY_INTR_INFO, info);
        vmx_vmwrite(VMCS_ENTRY_EXCEPTION_ERROR, err);
 
+       switch (__SHIFTOUT(info, INTR_INFO_TYPE)) {
+       case INTR_TYPE_SW_INT:
+       case INTR_TYPE_PRIV_SW_EXC:
+       case INTR_TYPE_SW_EXC:
+               inslen = vmx_vmread(VMCS_EXIT_INSTRUCTION_LENGTH);
+               vmx_vmwrite(VMCS_ENTRY_INSTRUCTION_LENGTH, inslen);
+       }
+
        cpudata->evt_pending = true;
 }
 
@@ -3008,17 +3046,21 @@
 
        msr = rdmsr(MSR_IA32_FEATURE_CONTROL);
        if ((msr & IA32_FEATURE_CONTROL_LOCK) == 0) {
+               printf("NVMM: VMX disabled in BIOS\n");
                return false;
        }
        if ((msr & IA32_FEATURE_CONTROL_OUT_SMX) == 0) {
+               printf("NVMM: VMX disabled in BIOS\n");
                return false;
        }
 
        msr = rdmsr(MSR_IA32_VMX_BASIC);
        if ((msr & IA32_VMX_BASIC_IO_REPORT) == 0) {
+               printf("NVMM: I/O reporting not supported\n");
                return false;
        }
        if (__SHIFTOUT(msr, IA32_VMX_BASIC_MEM_TYPE) != MEM_TYPE_WB) {
+               printf("NVMM: WB memory not supported\n");
                return false;
        }
 
@@ -3027,6 +3069,7 @@
        vmx_cr0_fixed1 = rdmsr(MSR_IA32_VMX_CR0_FIXED1) | (CR0_PG|CR0_PE);
        ret = vmx_check_cr(rcr0(), vmx_cr0_fixed0, vmx_cr0_fixed1);
        if (ret == -1) {
+               printf("NVMM: CR0 requirements not satisfied\n");
                return false;
        }
 
@@ -3034,6 +3077,7 @@
        vmx_cr4_fixed1 = rdmsr(MSR_IA32_VMX_CR4_FIXED1);
        ret = vmx_check_cr(rcr4() | CR4_VMXE, vmx_cr4_fixed0, vmx_cr4_fixed1);
        if (ret == -1) {
+               printf("NVMM: CR4 requirements not satisfied\n");
                return false;
        }
 
@@ -3043,6 +3087,7 @@
            VMX_PINBASED_CTLS_ONE, VMX_PINBASED_CTLS_ZERO,
            &vmx_pinbased_ctls);
        if (ret == -1) {
+               printf("NVMM: pin-based-ctls requirements not satisfied\n");
                return false;
        }
        ret = vmx_init_ctls(
@@ -3050,6 +3095,7 @@
            VMX_PROCBASED_CTLS_ONE, VMX_PROCBASED_CTLS_ZERO,
            &vmx_procbased_ctls);
        if (ret == -1) {
+               printf("NVMM: proc-based-ctls requirements not satisfied\n");
                return false;
        }
        ret = vmx_init_ctls(
@@ -3057,6 +3103,7 @@
            VMX_PROCBASED_CTLS2_ONE, VMX_PROCBASED_CTLS2_ZERO,
            &vmx_procbased_ctls2);
        if (ret == -1) {
+               printf("NVMM: proc-based-ctls2 requirements not satisfied\n");
                return false;
        }
        ret = vmx_check_ctls(
@@ -3070,6 +3117,7 @@
            VMX_ENTRY_CTLS_ONE, VMX_ENTRY_CTLS_ZERO,
            &vmx_entry_ctls);
        if (ret == -1) {
+               printf("NVMM: entry-ctls requirements not satisfied\n");
                return false;
        }
        ret = vmx_init_ctls(
@@ -3077,17 +3125,21 @@



Home | Main Index | Thread Index | Old Index