VirtualBox

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


Ignore:
Timestamp:
Sep 6, 2018 6:36:35 AM (6 years ago)
Author:
vboxsync
Message:

VMM/IEM, HM: Nested VMX: bugref:9180 vmlaunch/vmresume bits.

Location:
trunk/src/VBox/VMM/VMMAll
Files:
2 edited

Legend:

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

    r74103 r74104  
    142142    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_EntryCtlsAllowed1        , "EntryCtlsAllowed1"       ),
    143143    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_EntryCtlsDisallowed0     , "EntryCtlsDisallowed0"    ),
    144     VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_EntryHostCr0Fixed0       , "EntryHostCr0Fixed0"      ),
    145     VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_EntryHostCr0Fixed1       , "EntryHostCr0Fixed1"      ),
    146     VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_EntryHostCr3             , "EntryHostCr3"            ),
    147     VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_EntryHostCr4Fixed0       , "EntryHostCr4Fixed0"      ),
    148     VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_EntryHostCr4Fixed1       , "EntryHostCr4Fixed1"      ),
    149     VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_EntryHostSysenterEspEip  , "EntryHostSysenterEspEip" ),
    150     VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_EntryHostPatMsr          , "EntryHostPatMsr"         ),
     144    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_HostAddrSpace            , "HostAddrSpace"           ),
     145    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_HostCr0Fixed0            , "HostCr0Fixed0"           ),
     146    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_HostCr0Fixed1            , "HostCr0Fixed1"           ),
     147    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_HostCr3                  , "HostCr3"                 ),
     148    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_HostCr4Fixed0            , "HostCr4Fixed0"           ),
     149    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_HostCr4Fixed1            , "HostCr4Fixed1"           ),
     150    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_HostCsTr                 , "HostCsTr"                ),
     151    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_HostEferMsr              , "HostEferMsr"             ),
     152    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_HostGuestLongMode        , "HostGuestLongMode"       ),
     153    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_HostSysenterEspEip       , "HostSysenterEspEip"      ),
     154    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_HostPatMsr               , "HostPatMsr"              ),
     155    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_HostSel                  , "HostSel"                 ),
     156    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_HostSegBase              , "HostSegBase"             ),
     157    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_HostSs                   , "HostSs"                  ),
    151158    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_EntryInstrLen            , "EntryInstrLen"           ),
    152159    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_EntryInstrLenZero        , "EntryInstrLenZero"       ),
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h

    r74103 r74104  
    20322032    PCVMXVVMCS pVmcs = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs);
    20332033
     2034    /*
     2035     * Host Control Registers and MSRs.
     2036     * See Intel spec. 26.2.2 "Checks on Host Control Registers and MSRs".
     2037     */
    20342038    /* CR0 reserved bits. */
    20352039    {
     
    20392043        {
    20402044            Log(("%s: Invalid host CR0 %#RX32 (fixed0) -> VMFail\n", pszInstr, pVmcs->u64HostCr0));
    2041             pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_EntryHostCr0Fixed0;
     2045            pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_HostCr0Fixed0;
    20422046            return VERR_VMX_VMENTRY_FAILED;
    20432047        }
     
    20482052        {
    20492053            Log(("%s: Invalid host CR0 %#RX32 (fixed1) -> VMFail\n", pszInstr, pVmcs->u64HostCr0));
    2050             pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_EntryHostCr0Fixed1;
     2054            pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_HostCr0Fixed1;
    20512055            return VERR_VMX_VMENTRY_FAILED;
    20522056        }
     
    20602064        {
    20612065            Log(("%s: Invalid host CR4 %#RX64 (fixed0) -> VMFail\n", pszInstr, pVmcs->u64HostCr4));
    2062             pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_EntryHostCr4Fixed0;
     2066            pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_HostCr4Fixed0;
    20632067            return VERR_VMX_VMENTRY_FAILED;
    20642068        }
     
    20692073        {
    20702074            Log(("%s: Invalid host CR4 %#RX64 (fixed1) -> VMFail\n", pszInstr, pVmcs->u64HostCr4));
    2071             pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_EntryHostCr4Fixed1;
     2075            pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_HostCr4Fixed1;
    20722076            return VERR_VMX_VMENTRY_FAILED;
    20732077        }
     
    20812085        {
    20822086            Log(("%s: Invalid host CR3 %#RX64 -> VMFail\n", pszInstr, pVmcs->u64HostCr3));
    2083             pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_EntryHostCr3;
     2087            pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_HostCr3;
    20842088            return VERR_VMX_VMENTRY_FAILED;
    20852089        }
     
    20932097            Log(("%s: Host Sysenter ESP (%#RX64) / EIP (%#RX64) not canonical -> VMFail\n", pszInstr,
    20942098                 pVmcs->u64HostSysenterEsp.u, pVmcs->u64HostSysenterEip.u));
    2095             pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_EntryHostSysenterEspEip;
     2099            pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_HostSysenterEspEip;
    20962100            return VERR_VMX_VMENTRY_FAILED;
    20972101        }
    20982102    }
    20992103
     2104    Assert(!(pVmcs->u32ExitCtls & VMX_EXIT_CTLS_LOAD_PERF_MSR));   /* We don't support loading IA32_PERF_GLOBAL_CTRL MSR yet. */
     2105
    21002106    /* PAT MSR. */
    2101     if (   IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fVmxExitLoadPatMsr
     2107    if (   (pVmcs->u32ExitCtls & VMX_EXIT_CTLS_LOAD_PAT_MSR)
    21022108        && !CPUMIsPatMsrValid(pVmcs->u64HostPatMsr.u))
    21032109    {
    21042110        Log(("%s: Host PAT MSR (%#RX64) invalid\n", pszInstr, pVmcs->u64HostPatMsr.u));
    2105         pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_EntryHostPatMsr;
     2111        pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_HostPatMsr;
    21062112        return VERR_VMX_VMENTRY_FAILED;
    21072113    }
    21082114
    2109     /** @todo NSTVMX: EFER and others. */
    2110 
    2111     Assert(!(pVmcs->u32ExitCtls & VMX_EXIT_CTLS_LOAD_PERF_MSR));   /* We don't support loading IA32_PERF_GLOBAL_CTRL MSR yet. */
     2115    /* EFER MSR. */
     2116    uint64_t const uValidEferMask = CPUMGetGuestEferMsrValidMask(pVCpu->CTX_SUFF(pVM));
     2117    if (   (pVmcs->u32ExitCtls & VMX_EXIT_CTLS_LOAD_EFER_MSR)
     2118        && (pVmcs->u64GuestEferMsr.u & ~uValidEferMask))
     2119    {
     2120        Log(("%s: Host EFER MSR (%#RX64) reserved bits set\n", pszInstr, pVmcs->u64HostEferMsr.u));
     2121        pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_HostEferMsr;
     2122        return VERR_VMX_VMENTRY_FAILED;
     2123    }
     2124    bool const fHostLongMode        = RT_BOOL(pVmcs->u32ExitCtls & VMX_EXIT_CTLS_HOST_ADDR_SPACE_SIZE);
     2125    bool const fHostLongModeActive  = RT_BOOL(pVmcs->u64GuestEferMsr.u & MSR_K6_EFER_BIT_LMA);
     2126    bool const fHostLongModeEnabled = RT_BOOL(pVmcs->u64GuestEferMsr.u & MSR_K6_EFER_BIT_LME);
     2127    if (fHostLongModeEnabled == fHostLongModeActive == fHostLongMode)
     2128    { /* likely */ }
     2129    else
     2130    {
     2131        Log(("%s: Host EFER MSR (%#RX64) LMA, LME, host addr-space size mismatch\n", pszInstr, pVmcs->u64HostEferMsr.u));
     2132        pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_HostAddrSpace;
     2133        return VERR_VMX_VMENTRY_FAILED;
     2134    }
     2135
     2136    /*
     2137     * Host Segment and Descriptor-Table Registers.
     2138     * See Intel spec. 26.2.3 "Checks on Host Segment and Descriptor-Table Registers".
     2139     */
     2140    /* Selector RPL and TI. */
     2141    if (   !(pVmcs->HostCs & (X86_SEL_RPL | X86_SEL_LDT))
     2142        && !(pVmcs->HostSs & (X86_SEL_RPL | X86_SEL_LDT))
     2143        && !(pVmcs->HostDs & (X86_SEL_RPL | X86_SEL_LDT))
     2144        && !(pVmcs->HostEs & (X86_SEL_RPL | X86_SEL_LDT))
     2145        && !(pVmcs->HostFs & (X86_SEL_RPL | X86_SEL_LDT))
     2146        && !(pVmcs->HostGs & (X86_SEL_RPL | X86_SEL_LDT))
     2147        && !(pVmcs->HostTr & (X86_SEL_RPL | X86_SEL_LDT)))
     2148    { /* likely */ }
     2149    else
     2150    {
     2151        Log(("%s: One or more host selector registers invalid\n", pszInstr));
     2152        pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_HostSel;
     2153        return VERR_VMX_VMENTRY_FAILED;
     2154    }
     2155
     2156    /* CS and TR selectors cannot be 0. */
     2157    if (   pVmcs->HostCs
     2158        && pVmcs->HostTr)
     2159    { /* likely */ }
     2160    else
     2161    {
     2162        Log(("%s: Host CS/TR selector is invalid\n", pszInstr));
     2163        pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_HostCsTr;
     2164        return VERR_VMX_VMENTRY_FAILED;
     2165    }
     2166
     2167    /* SS cannot be 0 if 32-bit host. */
     2168    if (   fHostLongMode
     2169        || pVmcs->HostSs)
     2170    { /* likely */ }
     2171    else
     2172    {
     2173        Log(("%s: Host SS selector invalid for 32-bit host\n", pszInstr));
     2174        pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_HostSs;
     2175        return VERR_VMX_VMENTRY_FAILED;
     2176    }
     2177
     2178    if (IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fLongMode)
     2179    {
     2180        /* FS, GS, GDTR, IDTR, TR base address. */
     2181        if (   X86_IS_CANONICAL(pVmcs->u64HostFsBase.u)
     2182            && X86_IS_CANONICAL(pVmcs->u64HostFsBase.u)
     2183            && X86_IS_CANONICAL(pVmcs->u64HostGdtrBase.u)
     2184            && X86_IS_CANONICAL(pVmcs->u64HostIdtrBase.u)
     2185            && X86_IS_CANONICAL(pVmcs->u64HostTrBase.u))
     2186        { /* likely */ }
     2187        else
     2188        {
     2189            Log(("%s: Host segment register (FS/GS/GDTR/IDTR/TR) base address is not canonical\n", pszInstr));
     2190            pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_HostSegBase;
     2191            return VERR_VMX_VMENTRY_FAILED;
     2192        }
     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         */
     2198    }
     2199    else
     2200    {
     2201        /* Host address-space size for 32-bit CPUs. */
     2202        bool const fGuestLongMode = RT_BOOL(pVmcs->u32EntryCtls & VMX_ENTRY_CTLS_IA32E_MODE_GUEST);
     2203        if (   !fGuestLongMode
     2204            && !fHostLongMode)
     2205        { /* likely */ }
     2206        else
     2207        {
     2208            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;
     2210            return VERR_VMX_VMENTRY_FAILED;
     2211        }
     2212    }
    21122213
    21132214    NOREF(pszInstr);
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