VirtualBox

Changeset 74113 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Sep 6, 2018 11:49:14 AM (6 years ago)
Author:
vboxsync
Message:

VMM/CPUM, IEM: Nested VMX: bugref:9180 Fixes for allowing 32-bit nested-guest support.

Location:
trunk/src/VBox/VMM
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/CPUMAllMsrs.cpp

    r74102 r74113  
    13161316        uVmxMsr = RT_BF_MAKE(VMX_BF_BASIC_VMCS_ID,         VMX_V_VMCS_REVISION_ID        )
    13171317                | RT_BF_MAKE(VMX_BF_BASIC_VMCS_SIZE,       VMX_V_VMCS_SIZE               )
    1318                 | RT_BF_MAKE(VMX_BF_BASIC_PHYSADDR_WIDTH,  VMX_V_VMCS_PHYSADDR_4G_LIMIT  )
     1318                | RT_BF_MAKE(VMX_BF_BASIC_PHYSADDR_WIDTH,  !pGuestFeatures->fLongMode    )
    13191319                | RT_BF_MAKE(VMX_BF_BASIC_DUAL_MON,        0                             )
    13201320                | RT_BF_MAKE(VMX_BF_BASIC_VMCS_MEM_TYPE,   VMX_BASIC_MEM_TYPE_WB         )
  • trunk/src/VBox/VMM/VMMAll/HMVMXAll.cpp

    r74104 r74113  
    151151    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_HostEferMsr              , "HostEferMsr"             ),
    152152    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_HostGuestLongMode        , "HostGuestLongMode"       ),
     153    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_HostGuestLongModeNoCpu   , "HostGuestLongModeNoCpu"  ),
    153154    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_HostSysenterEspEip       , "HostSysenterEspEip"      ),
    154155    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_HostPatMsr               , "HostPatMsr"              ),
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h

    r74105 r74113  
    360360    } while (0)
    361361# endif /* !IEM_WITH_CODE_TLB */
     362
     363/** The maximum physical address width in bits. */
     364#define IEM_VMX_MAX_PHYSADDR_WIDTH(a_pVCpu)         (IEM_GET_GUEST_CPU_FEATURES(a_pVCpu)->cVmxMaxPhysAddrWidth)
    362365
    363366/** Whether a shadow VMCS is present for the given VCPU. */
     
    15351538
    15361539    /* VMCS physical-address width limits. */
    1537     Assert(!VMX_V_VMCS_PHYSADDR_4G_LIMIT);
    1538     if (GCPhysVmcs >> IEM_GET_GUEST_CPU_FEATURES(pVCpu)->cMaxPhysAddrWidth)
     1540    if (GCPhysVmcs >> IEM_VMX_MAX_PHYSADDR_WIDTH(pVCpu))
    15391541    {
    15401542        Log(("vmclear: VMCS pointer extends beyond physical-address width -> VMFail()\n"));
     
    16951697
    16961698    /* VMCS physical-address width limits. */
    1697     Assert(!VMX_V_VMCS_PHYSADDR_4G_LIMIT);
    1698     if (GCPhysVmcs >> IEM_GET_GUEST_CPU_FEATURES(pVCpu)->cMaxPhysAddrWidth)
     1699    if (GCPhysVmcs >> IEM_VMX_MAX_PHYSADDR_WIDTH(pVCpu))
    16991700    {
    17001701        Log(("vmptrld: VMCS pointer extends beyond physical-address width -> VMFail()\n"));
     
    18631864
    18641865        /* VMXON physical-address width limits. */
    1865         Assert(!VMX_V_VMCS_PHYSADDR_4G_LIMIT);
    1866         if (GCPhysVmxon >> IEM_GET_GUEST_CPU_FEATURES(pVCpu)->cMaxPhysAddrWidth)
     1866        if (GCPhysVmxon >> IEM_VMX_MAX_PHYSADDR_WIDTH(pVCpu))
    18671867        {
    18681868            Log(("vmxon: VMXON region pointer extends beyond physical-address width -> VMFailInvalid\n"));
     
    19591959
    19601960/**
    1961  * Clears the high 32-bits of all natural-width fields in the given VMCS.
    1962  *
    1963  * @param   pVmcs       Pointer to the virtual VMCS.
    1964  */
    1965 IEM_STATIC void iemVmxVmcsFixNaturalWidthFields(PVMXVVMCS pVmcs)
    1966 {
    1967     /* Natural-width Control fields. */
    1968     pVmcs->u64Cr0Mask.s.Hi = 0;
    1969     pVmcs->u64Cr4Mask.s.Hi = 0;
    1970     pVmcs->u64Cr0ReadShadow.s.Hi = 0;
    1971     pVmcs->u64Cr4ReadShadow.s.Hi = 0;
    1972     pVmcs->u64Cr3Target0.s.Hi = 0;
    1973     pVmcs->u64Cr3Target1.s.Hi = 0;
    1974     pVmcs->u64Cr3Target2.s.Hi = 0;
    1975     pVmcs->u64Cr3Target3.s.Hi = 0;
    1976 
    1977     /* Natural-width Read-only data fields. */
    1978     pVmcs->u64ExitQual.s.Hi = 0;
    1979     pVmcs->u64IoRcx.s.Hi = 0;
    1980     pVmcs->u64IoRsi.s.Hi = 0;
    1981     pVmcs->u64IoRdi.s.Hi = 0;
    1982     pVmcs->u64IoRip.s.Hi = 0;
    1983     pVmcs->u64GuestLinearAddr.s.Hi = 0;
    1984 
    1985     /* Natural-width Guest-state Fields. */
    1986     pVmcs->u64GuestCr0.s.Hi = 0;
    1987     pVmcs->u64GuestCr3.s.Hi = 0;
    1988     pVmcs->u64GuestCr4.s.Hi = 0;
    1989     pVmcs->u64GuestEsBase.s.Hi = 0;
    1990     pVmcs->u64GuestCsBase.s.Hi = 0;
    1991     pVmcs->u64GuestSsBase.s.Hi = 0;
    1992     pVmcs->u64GuestDsBase.s.Hi = 0;
    1993     pVmcs->u64GuestFsBase.s.Hi = 0;
    1994     pVmcs->u64GuestGsBase.s.Hi = 0;
    1995     pVmcs->u64GuestLdtrBase.s.Hi = 0;
    1996     pVmcs->u64GuestTrBase.s.Hi = 0;
    1997     pVmcs->u64GuestGdtrBase.s.Hi = 0;
    1998     pVmcs->u64GuestIdtrBase.s.Hi = 0;
    1999     pVmcs->u64GuestDr7.s.Hi = 0;
    2000     pVmcs->u64GuestRsp.s.Hi = 0;
    2001     pVmcs->u64GuestRip.s.Hi = 0;
    2002     pVmcs->u64GuestRFlags.s.Hi = 0;
    2003     pVmcs->u64GuestPendingDbgXcpt.s.Hi = 0;
    2004     pVmcs->u64GuestSysenterEsp.s.Hi = 0;
    2005     pVmcs->u64GuestSysenterEip.s.Hi = 0;
    2006 
    2007     /* Natural-width Host-state fields. */
    2008     pVmcs->u64HostCr0.s.Hi = 0;
    2009     pVmcs->u64HostCr3.s.Hi = 0;
    2010     pVmcs->u64HostCr4.s.Hi = 0;
    2011     pVmcs->u64HostFsBase.s.Hi = 0;
    2012     pVmcs->u64HostGsBase.s.Hi = 0;
    2013     pVmcs->u64HostTrBase.s.Hi = 0;
    2014     pVmcs->u64HostGdtrBase.s.Hi = 0;
    2015     pVmcs->u64HostIdtrBase.s.Hi = 0;
    2016     pVmcs->u64HostSysenterEsp.s.Hi = 0;
    2017     pVmcs->u64HostSysenterEip.s.Hi = 0;
    2018     pVmcs->u64HostRsp.s.Hi = 0;
    2019     pVmcs->u64HostRip.s.Hi = 0;
    2020 }
    2021 
    2022 
    2023 /**
    20241961 * Checks host state as part of VM-entry.
    20251962 *
     
    20812018    {
    20822019        /* CR3 reserved bits. */
    2083         uint8_t const cMaxPhysAddrWidth = IEM_GET_GUEST_CPU_FEATURES(pVCpu)->cMaxPhysAddrWidth;
    2084         if (pVmcs->u64HostCr3.u >> cMaxPhysAddrWidth)
     2020        if (pVmcs->u64HostCr3.u >> IEM_VMX_MAX_PHYSADDR_WIDTH(pVCpu))
    20852021        {
    20862022            Log(("%s: Invalid host CR3 %#RX64 -> VMFail\n", pszInstr, pVmcs->u64HostCr3));
     
    21222058        return VERR_VMX_VMENTRY_FAILED;
    21232059    }
    2124     bool const fVirtHostLongMode      = RT_BOOL(pVmcs->u32ExitCtls & VMX_EXIT_CTLS_HOST_ADDR_SPACE_SIZE);
     2060    bool const fVirtHostInLongMode    = RT_BOOL(pVmcs->u32ExitCtls & VMX_EXIT_CTLS_HOST_ADDR_SPACE_SIZE);
    21252061    bool const fNstGstLongModeActive  = RT_BOOL(pVmcs->u64GuestEferMsr.u & MSR_K6_EFER_BIT_LMA);
    21262062    bool const fNstGstLongModeEnabled = RT_BOOL(pVmcs->u64GuestEferMsr.u & MSR_K6_EFER_BIT_LME);
    2127     if (fVirtHostLongMode == fNstGstLongModeActive == fNstGstLongModeEnabled)
     2063    if (fVirtHostInLongMode == fNstGstLongModeActive == fNstGstLongModeEnabled)
    21282064    { /* likely */ }
    21292065    else
     
    21662102
    21672103    /* SS cannot be 0 if 32-bit host. */
    2168     if (   fVirtHostLongMode
     2104    if (   fVirtHostInLongMode
    21692105        || pVmcs->HostSs)
    21702106    { /* likely */ }
     
    21912127            return VERR_VMX_VMENTRY_FAILED;
    21922128        }
    2193 
    2194         /*
    2195          * Host address-space size for 64-bit CPUs.
    2196          * See Intel spec. 26.2.4 "Checks Related to Address-Space Size".
    2197          */
     2129    }
     2130
     2131    /*
     2132     * Host address-space size for 64-bit CPUs.
     2133     * See Intel spec. 26.2.4 "Checks Related to Address-Space Size".
     2134     */
     2135    if (IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fLongMode)
     2136    {
     2137        bool const fGstInLongMode    = CPUMIsGuestInLongMode(pVCpu);
     2138        bool const fNstGstInLongMode = RT_BOOL(pVmcs->u32EntryCtls & VMX_ENTRY_CTLS_IA32E_MODE_GUEST);
     2139
     2140        /* Logical processor in IA-32e mode. */
     2141        if (fGstInLongMode)
     2142        {
     2143            if (fVirtHostInLongMode)
     2144            {
     2145                /* PAE must be set. */
     2146                if (pVmcs->u64HostCr4.u & X86_CR4_PAE)
     2147                { /* likely */ }
     2148                else
     2149                {
     2150                    /* fail. */
     2151                }
     2152
     2153                /* RIP must be canonical. */
     2154                if (X86_IS_CANONICAL(pVmcs->u64HostRip.u))
     2155                { /* likely */ }
     2156                else
     2157                {
     2158                    /* fail. */
     2159                }
     2160            }
     2161            else
     2162            {
     2163                /* fail. */
     2164            }
     2165        }
     2166        else
     2167        {
     2168            /* Logical processor is outside IA-32e mode. */
     2169            if (   !fNstGstInLongMode
     2170                && !fVirtHostInLongMode)
     2171            {
     2172                /* PCIDE should not be set. */
     2173                if (!(pVmcs->u64HostCr4.u & X86_CR4_PCIDE))
     2174                { /* likely */ }
     2175                else
     2176                {
     2177                }
     2178
     2179                /* Bits 63:32 of RIP MBZ. */
     2180                if (!pVmcs->u64HostRip.s.Hi)
     2181                { /* likely */ }
     2182                else
     2183                {
     2184                    /* fail */
     2185                }
     2186            }
     2187            else
     2188            {
     2189                Log(("%s: Host/guest cannot be in long mode when logical processor is not in long mode\n", pszInstr));
     2190                pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_HostGuestLongMode;
     2191                return VERR_VMX_VMENTRY_FAILED;
     2192            }
     2193        }
    21982194    }
    21992195    else
    22002196    {
    22012197        /* Host address-space size for 32-bit CPUs. */
    2202         bool const fNstGstLongMode = RT_BOOL(pVmcs->u32EntryCtls & VMX_ENTRY_CTLS_IA32E_MODE_GUEST);
    2203         if (   !fNstGstLongMode
    2204             && !fVirtHostLongMode)
     2198        bool const fNstGstInLongMode = RT_BOOL(pVmcs->u32EntryCtls & VMX_ENTRY_CTLS_IA32E_MODE_GUEST);
     2199        if (   !fNstGstInLongMode
     2200            && !fVirtHostInLongMode)
    22052201        { /* likely */ }
    22062202        else
    22072203        {
    22082204            Log(("%s: Host/guest cannot be in long mode on 32-bit CPUs\n", pszInstr));
    2209             pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_HostGuestLongMode;
     2205            pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_HostGuestLongModeNoCpu;
    22102206            return VERR_VMX_VMENTRY_FAILED;
    22112207        }
     
    23292325
    23302326    /* VM-entry MSR-load count and VM-entry MSR-load area address. */
    2331     uint8_t const cMaxPhysAddrWidth = IEM_GET_GUEST_CPU_FEATURES(pVCpu)->cMaxPhysAddrWidth;
    23322327    if (pVmcs->u32EntryMsrLoadCount)
    23332328    {
    23342329        if (   (pVmcs->u64AddrEntryMsrLoad.u & VMX_AUTOMSR_OFFSET_MASK)
    2335             || (pVmcs->u64AddrEntryMsrLoad.u >> cMaxPhysAddrWidth)
     2330            || (pVmcs->u64AddrEntryMsrLoad.u >> IEM_VMX_MAX_PHYSADDR_WIDTH(pVCpu))
    23362331            || !PGMPhysIsGCPhysNormal(pVCpu->CTX_SUFF(pVM), pVmcs->u64AddrEntryMsrLoad.u))
    23372332        {
     
    23882383
    23892384    /* VM-exit MSR-store count and VM-exit MSR-store area address. */
    2390     uint8_t const cMaxPhysAddrWidth = IEM_GET_GUEST_CPU_FEATURES(pVCpu)->cMaxPhysAddrWidth;
    23912385    if (pVmcs->u32ExitMsrStoreCount)
    23922386    {
    23932387        if (   (pVmcs->u64AddrExitMsrStore.u & VMX_AUTOMSR_OFFSET_MASK)
    2394             || (pVmcs->u64AddrExitMsrStore.u >> cMaxPhysAddrWidth)
     2388            || (pVmcs->u64AddrExitMsrStore.u >> IEM_VMX_MAX_PHYSADDR_WIDTH(pVCpu))
    23952389            || !PGMPhysIsGCPhysNormal(pVCpu->CTX_SUFF(pVM), pVmcs->u64AddrExitMsrStore.u))
    23962390        {
     
    24052399    {
    24062400        if (   (pVmcs->u64AddrExitMsrLoad.u & VMX_AUTOMSR_OFFSET_MASK)
    2407             || (pVmcs->u64AddrExitMsrLoad.u >> cMaxPhysAddrWidth)
     2401            || (pVmcs->u64AddrExitMsrLoad.u >> IEM_VMX_MAX_PHYSADDR_WIDTH(pVCpu))
    24082402            || !PGMPhysIsGCPhysNormal(pVCpu->CTX_SUFF(pVM), pVmcs->u64AddrExitMsrLoad.u))
    24092403        {
     
    25072501
    25082502    /* IO bitmaps physical addresses. */
    2509     uint8_t const cMaxPhysAddrWidth = IEM_GET_GUEST_CPU_FEATURES(pVCpu)->cMaxPhysAddrWidth;
    2510     Assert(!VMX_V_VMCS_PHYSADDR_4G_LIMIT);
    25112503    if (pVmcs->u32ProcCtls & VMX_PROC_CTLS_USE_IO_BITMAPS)
    25122504    {
    25132505        if (   (pVmcs->u64AddrIoBitmapA.u & X86_PAGE_4K_OFFSET_MASK)
    2514             || (pVmcs->u64AddrIoBitmapA.u >> cMaxPhysAddrWidth)
     2506            || (pVmcs->u64AddrIoBitmapA.u >> IEM_VMX_MAX_PHYSADDR_WIDTH(pVCpu))
    25152507            || !PGMPhysIsGCPhysNormal(pVCpu->CTX_SUFF(pVM), pVmcs->u64AddrIoBitmapA.u))
    25162508        {
     
    25212513
    25222514        if (   (pVmcs->u64AddrIoBitmapB.u & X86_PAGE_4K_OFFSET_MASK)
    2523             || (pVmcs->u64AddrIoBitmapB.u >> cMaxPhysAddrWidth)
     2515            || (pVmcs->u64AddrIoBitmapB.u >> IEM_VMX_MAX_PHYSADDR_WIDTH(pVCpu))
    25242516            || !PGMPhysIsGCPhysNormal(pVCpu->CTX_SUFF(pVM), pVmcs->u64AddrIoBitmapB.u))
    25252517        {
     
    25342526    {
    25352527        if (   (pVmcs->u64AddrMsrBitmap.u & X86_PAGE_4K_OFFSET_MASK)
    2536             || (pVmcs->u64AddrMsrBitmap.u >> cMaxPhysAddrWidth)
     2528            || (pVmcs->u64AddrMsrBitmap.u >> IEM_VMX_MAX_PHYSADDR_WIDTH(pVCpu))
    25372529            || !PGMPhysIsGCPhysNormal(pVCpu->CTX_SUFF(pVM), pVmcs->u64AddrMsrBitmap.u))
    25382530        {
     
    25492541        RTGCPHYS GCPhysVirtApic = pVmcs->u64AddrVirtApic.u;
    25502542        if (   (GCPhysVirtApic & X86_PAGE_4K_OFFSET_MASK)
    2551             || (GCPhysVirtApic >> cMaxPhysAddrWidth)
     2543            || (GCPhysVirtApic >> IEM_VMX_MAX_PHYSADDR_WIDTH(pVCpu))
    25522544            || !PGMPhysIsGCPhysNormal(pVCpu->CTX_SUFF(pVM), GCPhysVirtApic))
    25532545        {
     
    26442636        RTGCPHYS GCPhysApicAccess = pVmcs->u64AddrApicAccess.u;
    26452637        if (   (GCPhysApicAccess & X86_PAGE_4K_OFFSET_MASK)
    2646             || (GCPhysApicAccess >> cMaxPhysAddrWidth)
     2638            || (GCPhysApicAccess >> IEM_VMX_MAX_PHYSADDR_WIDTH(pVCpu))
    26472639            || !PGMPhysIsGCPhysNormal(pVCpu->CTX_SUFF(pVM), GCPhysApicAccess))
    26482640        {
     
    26932685        RTGCPHYS GCPhysVmreadBitmap = pVmcs->u64AddrVmreadBitmap.u;
    26942686        if (   ( GCPhysVmreadBitmap & X86_PAGE_4K_OFFSET_MASK)
    2695             || ( GCPhysVmreadBitmap >> cMaxPhysAddrWidth)
     2687            || ( GCPhysVmreadBitmap >> IEM_VMX_MAX_PHYSADDR_WIDTH(pVCpu))
    26962688            || !PGMPhysIsGCPhysNormal(pVCpu->CTX_SUFF(pVM), GCPhysVmreadBitmap))
    26972689        {
     
    27042696        RTGCPHYS GCPhysVmwriteBitmap = pVmcs->u64AddrVmreadBitmap.u;
    27052697        if (   ( GCPhysVmwriteBitmap & X86_PAGE_4K_OFFSET_MASK)
    2706             || ( GCPhysVmwriteBitmap >> cMaxPhysAddrWidth)
     2698            || ( GCPhysVmwriteBitmap >> IEM_VMX_MAX_PHYSADDR_WIDTH(pVCpu))
    27072699            || !PGMPhysIsGCPhysNormal(pVCpu->CTX_SUFF(pVM), GCPhysVmwriteBitmap))
    27082700        {
     
    28332825        return rc;
    28342826    }
    2835 
    2836     /*
    2837      * Clear the high 32-bits of all natural-width fields in the VMCS if the guest
    2838      * does not support long mode.
    2839      */
    2840     if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fLongMode)
    2841         iemVmxVmcsFixNaturalWidthFields(pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs));
    28422827
    28432828    /*
  • trunk/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp

    r74097 r74113  
    17821782        }
    17831783
     1784        /* VMX (VMXON, VMCS region and related data structures') physical address width (depends on long-mode). */
     1785        pFeatures->cVmxMaxPhysAddrWidth = pFeatures->fLongMode ? pFeatures->cMaxPhysAddrWidth : 32;
     1786
    17841787        if (   pExtLeaf
    17851788            && pFeatures->enmCpuVendor == CPUMCPUVENDOR_AMD)
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