VirtualBox

Changeset 48267 in vbox


Ignore:
Timestamp:
Sep 4, 2013 2:06:50 PM (11 years ago)
Author:
vboxsync
Message:

VMM: Allow VT-x to be used in SMX mode, more granular error checking.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/err.h

    r47789 r48267  
    19051905/** Somebody cleared X86_CR4_VMXE in the CR4 register. */
    19061906#define VERR_VMX_X86_CR4_VMXE_CLEARED               (-4012)
    1907 /** VT-x features locked or unavailable in MSR. */
    1908 #define VERR_VMX_MSR_LOCKED_OR_DISABLED             (-4013)
     1907/** Failed to enable and lock VT-x features. */
     1908#define VERR_VMX_MSR_LOCKING_FAILED                 (-4013)
    19091909/** Unable to switch due to invalid guest state. */
    19101910#define VERR_VMX_INVALID_GUEST_STATE                (-4014)
     
    19331933/** Internal VMX processing error no 1. */
    19341934#define VERR_HMVMX_IPE_5                            (-4027)
     1935/** VT-x features for SMX operation disabled by the BIOS. */
     1936#define VERR_VMX_MSR_SMX_VMXON_DISABLED             (-4028)
     1937/** VT-x features disabled by the BIOS. */
     1938#define VERR_VMX_MSR_VMXON_DISABLED                 (-4029)
    19351939/** @} */
    19361940
  • trunk/include/iprt/x86.h

    r48151 r48267  
    950950#define MSR_IA32_FEATURE_CONTROL            0x3A
    951951#define MSR_IA32_FEATURE_CONTROL_LOCK       RT_BIT(0)
     952#define MSR_IA32_FEATURE_CONTROL_SMX_VMXON  RT_BIT(1)
    952953#define MSR_IA32_FEATURE_CONTROL_VMXON      RT_BIT(2)
    953954
     
    11801181/** K8 FS.base - The 64-bit base FS register. */
    11811182#define MSR_K8_FS_BASE                      UINT32_C(0xc0000100)
    1182 /** K8 GS.base - The 64-bit base GS register. */     
     1183/** K8 GS.base - The 64-bit base GS register. */
    11831184#define MSR_K8_GS_BASE                      UINT32_C(0xc0000101)
    11841185/** K8 KernelGSbase - Used with SWAPGS. */
  • trunk/src/VBox/HostDrivers/Support/SUPDrv.c

    r48209 r48267  
    33943394        uint32_t fFeaturesECX, fFeaturesEDX, uDummy;
    33953395        uint32_t uMaxId, uVendorEBX, uVendorECX, uVendorEDX;
    3396         uint64_t u64Value;
     3396        uint64_t u64FeatMsr;
    33973397
    33983398        ASMCpuId(0, &uMaxId, &uVendorEBX, &uVendorECX, &uVendorEDX);
     
    34093409               )
    34103410            {
     3411                bool fInSmxMode;
     3412                bool fMsrLocked;
     3413                bool fSmxVmxAllowed;
     3414                bool fVmxAllowed;
     3415
    34113416                /*
    3412                  * Both the LOCK and VMXON bit must be set; otherwise VMXON will generate a #GP.
    3413                  * Once the lock bit is set, this MSR can no longer be modified.
     3417                 * We require the lock bit and the appropriate VMXON bit to be set otherwise VMXON will generate a #GP
     3418                 * This is a simplified check (assumes BIOS does it job and properly locks the control bit). For the more
     3419                 * extensive procedure see hmR0InitIntelCpu().
    34143420                 */
    3415                 u64Value = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
    3416                 if (      (u64Value & (MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK))
    3417                        ==             (MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK) /* enabled and locked */
    3418                     || !(u64Value & MSR_IA32_FEATURE_CONTROL_LOCK) /* not enabled, but not locked either */
    3419                    )
     3421                u64FeatMsr     = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
     3422                fInSmxMode     = !!(ASMGetCR4() & X86_CR4_SMXE);
     3423                fMsrLocked     = !!(u64FeatMsr & MSR_IA32_FEATURE_CONTROL_LOCK);
     3424                fSmxVmxAllowed = fMsrLocked && !!(u64FeatMsr & MSR_IA32_FEATURE_CONTROL_SMX_VMXON);
     3425                fVmxAllowed    = fMsrLocked && !!(u64FeatMsr & MSR_IA32_FEATURE_CONTROL_VMXON);
     3426                if (   (fInSmxMode && fSmxVmxAllowed)
     3427                    || fVmxAllowed)
    34203428                {
    34213429                    VMX_CAPABILITY vtCaps;
     
    34323440                    return VINF_SUCCESS;
    34333441                }
    3434                 return VERR_VMX_MSR_LOCKED_OR_DISABLED;
     3442                return fInSmxMode ? VERR_VMX_MSR_SMX_VMXON_DISABLED : VERR_VMX_MSR_VMXON_DISABLED;
    34353443            }
    34363444            return VERR_VMX_NO_VMX;
     
    34513459            {
    34523460                /* Check if SVM is disabled */
    3453                 u64Value = ASMRdMsr(MSR_K8_VM_CR);
    3454                 if (!(u64Value & MSR_K8_VM_CR_SVM_DISABLE))
     3461                u64FeatMsr = ASMRdMsr(MSR_K8_VM_CR);
     3462                if (!(u64FeatMsr & MSR_K8_VM_CR_SVM_DISABLE))
    34553463                {
    34563464                    uint32_t fSvmFeatures;
  • trunk/src/VBox/VMM/VMMR0/HMR0.cpp

    r48230 r48267  
    799799
    800800/**
    801  * Worker function used by hmR0PowerCallback  and HMR0Init to initalize
    802  * VT-x on a CPU.
     801 * Worker function used by hmR0PowerCallback() and HMR0Init() to initalize VT-x
     802 * on a CPU.
    803803 *
    804804 * @param   idCpu       The identifier for the CPU the function is called on.
     
    812812    NOREF(pvUser2);
    813813
    814     /*
    815      * Both the LOCK and VMXON bit must be set; otherwise VMXON will generate a #GP.
    816      * Once the lock bit is set, this MSR can no longer be modified.
    817      */
    818814    uint64_t fFC = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
    819     if (   !(fFC    & (MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK))
    820         || (   (fFC & (MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK))
    821             == MSR_IA32_FEATURE_CONTROL_VMXON ) /* Some BIOSes forget to set the locked bit. */
    822        )
    823     {
    824         /* MSR is not yet locked; we can change it ourselves here. */
    825         ASMWrMsr(MSR_IA32_FEATURE_CONTROL,
    826                  g_HvmR0.vmx.Msrs.u64FeatureCtrl | MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK);
     815    bool const fInSmxMode       = !!(ASMGetCR4() & X86_CR4_SMXE);
     816    bool       fMsrLocked       = !!(fFC & MSR_IA32_FEATURE_CONTROL_LOCK);
     817    bool       fSmxVmxAllowed   = !!(fFC & MSR_IA32_FEATURE_CONTROL_SMX_VMXON);
     818    bool       fVmxAllowed      = !!(fFC & MSR_IA32_FEATURE_CONTROL_VMXON);
     819
     820    /* Check if the LOCK bit is set but excludes the required VMXON bit. */
     821    int rc = VERR_HM_IPE_1;
     822    if (fMsrLocked)
     823    {
     824        if (fInSmxMode && !fSmxVmxAllowed)
     825            rc = VERR_VMX_MSR_SMX_VMXON_DISABLED;
     826        else if (!fVmxAllowed)
     827            rc = VERR_VMX_MSR_VMXON_DISABLED;
     828        else
     829            rc = VINF_SUCCESS;
     830    }
     831    else
     832    {
     833        /*
     834         * MSR is not yet locked; we can change it ourselves here.
     835         * Once the lock bit is set, this MSR can no longer be modified.
     836         */
     837        fFC |= MSR_IA32_FEATURE_CONTROL_LOCK;
     838        if (fInSmxMode)
     839            fFC |= MSR_IA32_FEATURE_CONTROL_SMX_VMXON;
     840        else
     841            fFC |= MSR_IA32_FEATURE_CONTROL_VMXON;
     842
     843        ASMWrMsr(MSR_IA32_FEATURE_CONTROL, fFC);
     844
     845        /* Verify. */
    827846        fFC = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
    828     }
    829 
    830     int rc;
    831     if ((fFC & (MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK))
    832         ==     (MSR_IA32_FEATURE_CONTROL_VMXON | MSR_IA32_FEATURE_CONTROL_LOCK))
    833     {
    834         rc = VINF_SUCCESS;
    835     }
    836     else
    837         rc = VERR_VMX_MSR_LOCKED_OR_DISABLED;
     847        fMsrLocked     = !!(fFC & MSR_IA32_FEATURE_CONTROL_LOCK);
     848        fSmxVmxAllowed = fMsrLocked && !!(fFC & MSR_IA32_FEATURE_CONTROL_SMX_VMXON);
     849        fVmxAllowed    = fMsrLocked && !!(fFC & MSR_IA32_FEATURE_CONTROL_VMXON);
     850
     851        if (   (fInSmxMode && fSmxVmxAllowed)
     852            || fVmxAllowed)
     853        {
     854            rc = VINF_SUCCESS;
     855        }
     856        else
     857            rc = VERR_VMX_MSR_LOCKING_FAILED;
     858    }
    838859
    839860    hmR0FirstRcSetStatus(pFirstRc, rc);
     
    929950
    930951/**
    931  * Worker function passed to RTMpOnAll, RTMpOnOthers and RTMpOnSpecific that
    932  * is to be called on the target cpus.
     952 * Worker function passed to RTMpOnAll() that is to be called on all CPUs.
    933953 *
    934954 * @param   idCpu       The identifier for the CPU the function is called on.
  • trunk/src/VBox/VMM/VMMR3/HM.cpp

    r48262 r48267  
    504504                    break;
    505505
    506                 case VERR_VMX_MSR_LOCKED_OR_DISABLED:
    507                     pszMsg = "VT-x is disabled in the BIOS (or by the host OS).";
     506                case VERR_VMX_MSR_VMXON_DISABLED:
     507                    pszMsg = "VT-x is disabled in the BIOS.";
     508                    break;
     509
     510                case VERR_VMX_MSR_SMX_VMXON_DISABLED:
     511                    pszMsg = "VT-x is disabled in the BIOS for Safer-Mode/Trusted Extensions.";
     512                    break;
     513
     514                case VERR_VMX_MSR_LOCKING_FAILED:
     515                    pszMsg = "Failed to enable and lock VT-x features.";
    508516                    break;
    509517
     
    906914            case VERR_VMX_NO_VMX:
    907915                return VM_SET_ERROR(pVM, VERR_VMX_NO_VMX, "VT-x is not available.");
    908             case VERR_VMX_MSR_LOCKED_OR_DISABLED:
    909                 return VM_SET_ERROR(pVM, VERR_VMX_NO_VMX, "VT-x is disabled in the BIOS (or by the host OS).");
     916            case VERR_VMX_MSR_VMXON_DISABLED:
     917                return VM_SET_ERROR(pVM, VERR_VMX_NO_VMX, "VT-x is disabled in the BIOS.");
     918            case VERR_VMX_MSR_SMX_VMXON_DISABLED:
     919                return VM_SET_ERROR(pVM, VERR_VMX_NO_VMX, "VT-x is disabled in the BIOS for Safer-Mode/Trusted Extensions.");
     920            case VERR_VMX_MSR_LOCKING_FAILED:
     921                return VM_SET_ERROR(pVM, VERR_VMX_NO_VMX, "Failed to enable and lock VT-x features.");
    910922
    911923            case VERR_SVM_IN_USE:
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette