VirtualBox

Changeset 8550

Show
Ignore:
Timestamp:
05/03/08 17:09:28 (8 months ago)
Author:
vboxsync
Message:

Corrected the KVM presence check

Files:

Legend:

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

    r8155 r8550  
    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 
    167223 
    168224                /* We need to check if VT-x has been properly initialized on all CPUs. Some BIOSes do a lousy job. */ 
     
    194250                        HWACCMR0Globals.vmx.msr.vmx_cr4_fixed1  = ASMRdMsr(MSR_IA32_VMX_CR4_FIXED1); 
    195251                        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 #endif 
    250252                    } 
    251253                    else 

© 2008 Sun Microsystems, Inc.
ContactPrivacy policy