VirtualBox

Changeset 8553

Show
Ignore:
Timestamp:
05/05/08 10:01:48 (8 months ago)
Author:
vboxsync
Message:

Moved VMX root mode check around.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • 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 

© 2008 Sun Microsystems, Inc.
ContactPrivacy policy