VirtualBox

Changeset 8553 in vbox for trunk/src


Ignore:
Timestamp:
May 5, 2008 8:01:48 AM (17 years ago)
Author:
vboxsync
Message:

Moved VMX root mode check around.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp

    r8550 r8553  
    165165
    166166                HWACCMR0Globals.vmx.msr.feature_ctrl = ASMRdMsr(MSR_IA32_FEATURE_CONTROL);
    167                 HWACCMR0Globals.vmx.hostCR4          = ASMGetCR4();
    168 
    169 #if HC_ARCH_BITS == 64
    170                 RTR0MEMOBJ pScatchMemObj;
    171                 void      *pvScatchPage;
    172                 RTHCPHYS   pScatchPagePhys;
    173 
    174                 rc = RTR0MemObjAllocCont(&pScatchMemObj, 1 << PAGE_SHIFT, true /* executable R0 mapping */);
    175                 if (RT_FAILURE(rc))
    176                     return rc;
    177 
    178                 pvScatchPage    = RTR0MemObjAddress(pScatchMemObj);
    179                 pScatchPagePhys = RTR0MemObjGetPagePhysAddr(pScatchMemObj, 0);
    180                 memset(pvScatchPage, 0, PAGE_SIZE);
    181 
    182                 /* Set revision dword at the beginning of the structure. */
    183                 *(uint32_t *)pvScatchPage = MSR_IA32_VMX_BASIC_INFO_VMCS_ID(HWACCMR0Globals.vmx.msr.vmx_basic_info);
    184 
    185                 /* Make sure we don't get rescheduled to another cpu during this probe. */
    186                 RTCCUINTREG fFlags = ASMIntDisableFlags();
    187 
    188                 /*
    189                  * Check CR4.VMXE
    190                  */
    191                 if (!(HWACCMR0Globals.vmx.hostCR4 & X86_CR4_VMXE))
    192                 {
    193                     /* In theory this bit could be cleared behind our back. Which would cause #UD faults when we
    194                      * try to execute the VMX instructions...
    195                      */
    196                     ASMSetCR4(HWACCMR0Globals.vmx.hostCR4 | X86_CR4_VMXE);
    197                 }
    198 
    199                 /* Enter VMX Root Mode */
    200                 rc = VMXEnable(pScatchPagePhys);
    201                 if (VBOX_FAILURE(rc))
    202                 {
    203                     /* KVM leaves the CPU in VMX root mode. Not only is this not allowed, it will crash the host when we enter raw mode, because
    204                      * (a) clearing X86_CR4_VMXE in CR4 causes a #GP    (we no longer modify this bit)
    205                      * (b) turning off paging causes a #GP              (unavoidable when switching from long to 32 bits mode)
    206                      *
    207                      * They should fix their code, but until they do we simply refuse to run.
    208                      */
    209                     HWACCMR0Globals.lLastError = VERR_VMX_IN_VMX_ROOT_MODE;
    210                     HWACCMR0Globals.vmx.fSupported = false;
    211                 }
    212                 else
    213                     VMXDisable();
    214 
    215                 /* Restore CR4 again; don't leave the X86_CR4_VMXE flag set if it wasn't so before (some software could incorrectly think it's in VMX mode) */
    216                 ASMSetCR4(HWACCMR0Globals.vmx.hostCR4);
    217                 ASMSetFlags(fFlags);
    218 
    219                 RTR0MemObjFree(pScatchMemObj, false);
    220                 if (VBOX_FAILURE(HWACCMR0Globals.lLastError))
    221                     return HWACCMR0Globals.lLastError ;
    222 #endif
    223167
    224168                /* We need to check if VT-x has been properly initialized on all CPUs. Some BIOSes do a lousy job. */
     
    250194                        HWACCMR0Globals.vmx.msr.vmx_cr4_fixed1  = ASMRdMsr(MSR_IA32_VMX_CR4_FIXED1);
    251195                        HWACCMR0Globals.vmx.msr.vmx_vmcs_enum   = ASMRdMsr(MSR_IA32_VMX_VMCS_ENUM);
     196                        HWACCMR0Globals.vmx.hostCR4             = ASMGetCR4();
     197
     198#if HC_ARCH_BITS == 64
     199                        RTR0MEMOBJ pScatchMemObj;
     200                        void      *pvScatchPage;
     201                        RTHCPHYS   pScatchPagePhys;
     202
     203                        rc = RTR0MemObjAllocCont(&pScatchMemObj, 1 << PAGE_SHIFT, true /* executable R0 mapping */);
     204                        if (RT_FAILURE(rc))
     205                            return rc;
     206
     207                        pvScatchPage    = RTR0MemObjAddress(pScatchMemObj);
     208                        pScatchPagePhys = RTR0MemObjGetPagePhysAddr(pScatchMemObj, 0);
     209                        memset(pvScatchPage, 0, PAGE_SIZE);
     210
     211                        /* Set revision dword at the beginning of the structure. */
     212                        *(uint32_t *)pvScatchPage = MSR_IA32_VMX_BASIC_INFO_VMCS_ID(HWACCMR0Globals.vmx.msr.vmx_basic_info);
     213
     214                        /* Make sure we don't get rescheduled to another cpu during this probe. */
     215                        RTCCUINTREG fFlags = ASMIntDisableFlags();
     216
     217                        /*
     218                         * Check CR4.VMXE
     219                         */
     220                        if (!(HWACCMR0Globals.vmx.hostCR4 & X86_CR4_VMXE))
     221                        {
     222                            /* In theory this bit could be cleared behind our back. Which would cause #UD faults when we
     223                             * try to execute the VMX instructions...
     224                             */
     225                            ASMSetCR4(HWACCMR0Globals.vmx.hostCR4 | X86_CR4_VMXE);
     226                        }
     227
     228                        /* Enter VMX Root Mode */
     229                        rc = VMXEnable(pScatchPagePhys);
     230                        if (VBOX_FAILURE(rc))
     231                        {
     232                            /* KVM leaves the CPU in VMX root mode. Not only is this not allowed, it will crash the host when we enter raw mode, because
     233                             * (a) clearing X86_CR4_VMXE in CR4 causes a #GP    (we no longer modify this bit)
     234                             * (b) turning off paging causes a #GP              (unavoidable when switching from long to 32 bits mode)
     235                             *
     236                             * They should fix their code, but until they do we simply refuse to run.
     237                             */
     238                            HWACCMR0Globals.lLastError = VERR_VMX_IN_VMX_ROOT_MODE;
     239                            HWACCMR0Globals.vmx.fSupported = false;
     240                        }
     241                        else
     242                            VMXDisable();
     243
     244                        /* Restore CR4 again; don't leave the X86_CR4_VMXE flag set if it wasn't so before (some software could incorrectly think it's in VMX mode) */
     245                        ASMSetCR4(HWACCMR0Globals.vmx.hostCR4);
     246                        ASMSetFlags(fFlags);
     247
     248                        RTR0MemObjFree(pScatchMemObj, false);
     249                        if (VBOX_FAILURE(HWACCMR0Globals.lLastError))
     250                            return HWACCMR0Globals.lLastError ;
     251#endif
    252252                    }
    253253                    else
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