VirtualBox

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


Ignore:
Timestamp:
Sep 6, 2018 4:57:57 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

    r74073 r74103  
    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"         ),
    144151    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_EntryInstrLen            , "EntryInstrLen"           ),
    145152    VMX_INSTR_DIAG_DESC(kVmxVInstrDiag_Vmentry_EntryInstrLenZero        , "EntryInstrLenZero"       ),
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h

    r74074 r74103  
    10041004
    10051005    /*
    1006      * Handle exceptions for certain instructions.
    1007      * (e.g. some instructions convey an instruction identity).
     1006     * Handle exceptions to the norm for certain instructions.
     1007     * (e.g. some instructions convey an instruction identity in place of iReg2).
    10081008     */
    10091009    switch (uExitReason)
     
    10921092    {
    10931093        iemVmxVmFailValid(pVCpu, enmInsErr);
    1094         /** @todo Set VM-instruction error field in the current virtual-VMCS.  */
     1094        /** @todo Set VM-instruction error field in the current virtual-VMCS. */
    10951095    }
    10961096    else
     
    15761576    if (IEM_VMX_GET_CURRENT_VMCS(pVCpu) == GCPhysVmcs)
    15771577    {
    1578         Assert(GCPhysVmcs != NIL_RTGCPHYS); /* Paranoia. */
     1578        Assert(GCPhysVmcs != NIL_RTGCPHYS);                     /* Paranoia. */
     1579        Assert(pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs));
    15791580        pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs)->fVmcsState = fVmcsStateClear;
    15801581        iemVmxCommitCurrentVmcsToMemory(pVCpu);
     
    19581959
    19591960/**
     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 */
     1965IEM_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/**
     2024 * Checks host state as part of VM-entry.
     2025 *
     2026 * @returns VBox status code.
     2027 * @param   pVCpu           The cross context virtual CPU structure.
     2028 * @param   pszInstr        The VMX instruction name (for logging purposes).
     2029 */
     2030IEM_STATIC VBOXSTRICTRC iemVmxVmentryCheckHostState(PVMCPU pVCpu, const char *pszInstr)
     2031{
     2032    PCVMXVVMCS pVmcs = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs);
     2033
     2034    /* CR0 reserved bits. */
     2035    {
     2036        /* CR0 MB1 bits. */
     2037        uint64_t const u64Cr0Fixed0 = CPUMGetGuestIa32VmxCr0Fixed0(pVCpu);
     2038        if (~pVmcs->u64HostCr0.u & u64Cr0Fixed0)
     2039        {
     2040            Log(("%s: Invalid host CR0 %#RX32 (fixed0) -> VMFail\n", pszInstr, pVmcs->u64HostCr0));
     2041            pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_EntryHostCr0Fixed0;
     2042            return VERR_VMX_VMENTRY_FAILED;
     2043        }
     2044
     2045        /* CR0 MBZ bits. */
     2046        uint64_t const u64Cr0Fixed1 = CPUMGetGuestIa32VmxCr0Fixed1(pVCpu);
     2047        if (pVmcs->u64HostCr0.u & ~u64Cr0Fixed1)
     2048        {
     2049            Log(("%s: Invalid host CR0 %#RX32 (fixed1) -> VMFail\n", pszInstr, pVmcs->u64HostCr0));
     2050            pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_EntryHostCr0Fixed1;
     2051            return VERR_VMX_VMENTRY_FAILED;
     2052        }
     2053    }
     2054
     2055    /* CR4 reserved bits. */
     2056    {
     2057        /* CR4 MB1 bits. */
     2058        uint64_t const u64Cr4Fixed0 = CPUMGetGuestIa32VmxCr4Fixed0(pVCpu);
     2059        if (~pVmcs->u64HostCr4.u & u64Cr4Fixed0)
     2060        {
     2061            Log(("%s: Invalid host CR4 %#RX64 (fixed0) -> VMFail\n", pszInstr, pVmcs->u64HostCr4));
     2062            pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_EntryHostCr4Fixed0;
     2063            return VERR_VMX_VMENTRY_FAILED;
     2064        }
     2065
     2066        /* CR4 MBZ bits. */
     2067        uint64_t const u64Cr4Fixed1 = CPUMGetGuestIa32VmxCr4Fixed1(pVCpu);
     2068        if (pVmcs->u64HostCr4.u & ~u64Cr4Fixed1)
     2069        {
     2070            Log(("%s: Invalid host CR4 %#RX64 (fixed1) -> VMFail\n", pszInstr, pVmcs->u64HostCr4));
     2071            pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_EntryHostCr4Fixed1;
     2072            return VERR_VMX_VMENTRY_FAILED;
     2073        }
     2074    }
     2075
     2076    if (IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fLongMode)
     2077    {
     2078        /* CR3 reserved bits. */
     2079        uint8_t const cMaxPhysAddrWidth = IEM_GET_GUEST_CPU_FEATURES(pVCpu)->cMaxPhysAddrWidth;
     2080        if (pVmcs->u64HostCr3.u >> cMaxPhysAddrWidth)
     2081        {
     2082            Log(("%s: Invalid host CR3 %#RX64 -> VMFail\n", pszInstr, pVmcs->u64HostCr3));
     2083            pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_EntryHostCr3;
     2084            return VERR_VMX_VMENTRY_FAILED;
     2085        }
     2086
     2087        /* SYSENTER ESP and SYSENTER EIP. */
     2088        if (   X86_IS_CANONICAL(pVmcs->u64HostSysenterEsp.u)
     2089            && X86_IS_CANONICAL(pVmcs->u64HostSysenterEip.u))
     2090        { /* likely */ }
     2091        else
     2092        {
     2093            Log(("%s: Host Sysenter ESP (%#RX64) / EIP (%#RX64) not canonical -> VMFail\n", pszInstr,
     2094                 pVmcs->u64HostSysenterEsp.u, pVmcs->u64HostSysenterEip.u));
     2095            pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_EntryHostSysenterEspEip;
     2096            return VERR_VMX_VMENTRY_FAILED;
     2097        }
     2098    }
     2099
     2100    /* PAT MSR. */
     2101    if (   IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fVmxExitLoadPatMsr
     2102        && !CPUMIsPatMsrValid(pVmcs->u64HostPatMsr.u))
     2103    {
     2104        Log(("%s: Host PAT MSR (%#RX64) invalid\n", pszInstr, pVmcs->u64HostPatMsr.u));
     2105        pVCpu->cpum.GstCtx.hwvirt.vmx.enmInstrDiag = kVmxVInstrDiag_Vmentry_EntryHostPatMsr;
     2106        return VERR_VMX_VMENTRY_FAILED;
     2107    }
     2108
     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. */
     2112
     2113    NOREF(pszInstr);
     2114    return VINF_SUCCESS;
     2115}
     2116
     2117
     2118/**
    19602119 * Checks VM-entry controls fields as part of VM-entry.
    19612120 * See Intel spec. 26.2.1.3 "VM-Entry Control Fields".
     
    20562215                }
    20572216
    2058                 /* Zero instruction length is only allowed when the CPU supports it explicitly. */
     2217                /* Zero instruction length is allowed only when the CPU supports it explicitly. */
    20592218                if (   pVmcs->u32EntryInstrLen == 0
    20602219                    && !IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fVmxEntryInjectSoftInt)
     
    21662325 * @param   pVCpu           The cross context virtual CPU structure.
    21672326 * @param   pszInstr        The VMX instruction name (for logging purposes).
     2327 *
     2328 * @remarks This may update secondary-processor based VM-execution control fields
     2329 *          in the current VMCS if necessary.
    21682330 */
    21692331IEM_STATIC VBOXSTRICTRC iemVmxVmentryCheckExecCtls(PVMCPU pVCpu, const char *pszInstr)
     
    22252387    }
    22262388    else
     2389    {
     2390        /*
     2391         * The guest is always capable of corrupting the VMCS by writing to the VMCS is guest
     2392         * memory directly rather than follow the rules. So we don't make any assumptions that
     2393         * u32ProcCtls2 will be 0 if no secondary-processor based VM-execution control support
     2394         * is reported to the guest.
     2395         */
    22272396        pVmcs->u32ProcCtls2 = 0;
     2397    }
    22282398
    22292399    /* CR3-target count. */
     
    22872457
    22882458        /* Read the Virtual-APIC page. */
     2459        Assert(pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pvVirtApicPage));
    22892460        int rc = PGMPhysSimpleReadGCPhys(pVCpu->CTX_SUFF(pVM), pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pvVirtApicPage),
    22902461                                         GCPhysVirtApic, VMX_V_VIRT_APIC_PAGES);
     
    24412612
    24422613        /* Read the VMREAD-bitmap. */
     2614        Assert(pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pvVmreadBitmap));
    24432615        int rc = PGMPhysSimpleReadGCPhys(pVCpu->CTX_SUFF(pVM), pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pvVmreadBitmap),
    24442616                                         GCPhysVmreadBitmap, VMX_V_VMREAD_VMWRITE_BITMAP_SIZE);
     
    24512623
    24522624        /* Read the VMWRITE-bitmap. */
     2625        Assert(pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pvVmwriteBitmap));
    24532626        rc = PGMPhysSimpleReadGCPhys(pVCpu->CTX_SUFF(pVM), pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pvVmwriteBitmap),
    24542627                                     GCPhysVmwriteBitmap, VMX_V_VMREAD_VMWRITE_BITMAP_SIZE);
     
    25502723     * Load the current VMCS.
    25512724     */
     2725    Assert(pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs));
    25522726    int rc = PGMPhysSimpleReadGCPhys(pVCpu->CTX_SUFF(pVM), pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs),
    25532727                                     IEM_VMX_GET_CURRENT_VMCS(pVCpu), VMX_V_VMCS_SIZE);
     
    25582732        return rc;
    25592733    }
     2734
     2735    /*
     2736     * Clear the high 32-bits of all natural-width fields in the VMCS if the guest
     2737     * does not support long mode.
     2738     */
     2739    if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fLongMode)
     2740        iemVmxVmcsFixNaturalWidthFields(pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs));
    25602741
    25612742    /*
     
    25942775    {
    25952776        iemVmxVmFail(pVCpu, VMXINSTRERR_VMENTRY_INVALID_CTLS);
     2777        iemRegAddToRipAndClearRF(pVCpu, cbInstr);
     2778        return VINF_SUCCESS;
     2779    }
     2780
     2781    /*
     2782     * Check host-state fields.
     2783     */
     2784    rc = iemVmxVmentryCheckHostState(pVCpu, pszInstr);
     2785    if (rc == VINF_SUCCESS)
     2786    { /* likely */ }
     2787    else
     2788    {
     2789        iemVmxVmFail(pVCpu, VMXINSTRERR_VMENTRY_INVALID_HOST_STATE);
    25962790        iemRegAddToRipAndClearRF(pVCpu, cbInstr);
    25972791        return VINF_SUCCESS;
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