VirtualBox

Changeset 8550 in vbox for trunk/src/VBox/VMM/VMMR0


Ignore:
Timestamp:
May 3, 2008 3:09:28 PM (17 years ago)
Author:
vboxsync
Message:

Corrected the KVM presence check

File:
1 edited

Legend:

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