VirtualBox

Changeset 91974 in vbox for trunk/src


Ignore:
Timestamp:
Oct 21, 2021 4:26:49 PM (3 years ago)
Author:
vboxsync
Message:

VMM/IEM: Nested VMX: bugref:10092 Peel out EPTP checking as a separate function, can be re-used when implementing EPTP switching/VMFUNC in the future.

File:
1 edited

Legend:

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

    r91971 r91974  
    58885888
    58895889
     5890#ifdef VBOX_WITH_NESTED_HWVIRT_VMX_EPT
     5891/**
     5892 * Checks the EPT pointer VMCS field as part of VM-entry.
     5893 *
     5894 * @returns VBox status code.
     5895 * @param   pVCpu           The cross context virtual CPU structure.
     5896 * @param   penmVmxDiag     Where to store the diagnostic reason on failure (not
     5897 *                          updated on success). Optional, can be NULL.
     5898 */
     5899IEM_STATIC int iemVmxVmentryCheckEptPtr(PVMCPUCC pVCpu, VMXVDIAG *penmVmxDiag)
     5900{
     5901    VMXVDIAG enmVmxDiag;
     5902    PCVMXVVMCS const pVmcs = &pVCpu->cpum.GstCtx.hwvirt.vmx.Vmcs;
     5903
     5904    /* Reserved bits. */
     5905    uint8_t const  cMaxPhysAddrWidth = IEM_GET_GUEST_CPU_FEATURES(pVCpu)->cMaxPhysAddrWidth;
     5906    uint64_t const fValidMask        = VMX_EPTP_VALID_MASK & ~(UINT64_MAX << cMaxPhysAddrWidth);
     5907    if (pVmcs->u64EptPtr.u & fValidMask)
     5908    {
     5909        /* Memory Type. */
     5910        uint64_t const fCaps    = pVCpu->cpum.GstCtx.hwvirt.vmx.Msrs.u64EptVpidCaps;
     5911        uint8_t const  fMemType = RT_BF_GET(pVmcs->u64EptPtr.u, VMX_BF_EPTP_MEMTYPE);
     5912        if (   (   fMemType == VMX_EPTP_MEMTYPE_WB
     5913                && RT_BF_GET(fCaps, VMX_BF_EPT_VPID_CAP_MEMTYPE_WB))
     5914            || (   fMemType == VMX_EPTP_MEMTYPE_UC
     5915                && RT_BF_GET(fCaps, VMX_BF_EPT_VPID_CAP_MEMTYPE_UC)))
     5916        {
     5917            /*
     5918             * Page walk length (PML4).
     5919             * Intel used to specify bit 7 of IA32_VMX_EPT_VPID_CAP as page walk length
     5920             * of 5 but that seems to be removed from the latest specs. leaving only PML4
     5921             * as the maximum supported page-walk level hence we hardcode it as 3 (1 less than 4)
     5922             */
     5923            Assert(RT_BF_GET(fCaps, VMX_BF_EPT_VPID_CAP_PAGE_WALK_LENGTH_4));
     5924            if (RT_BF_GET(pVmcs->u64EptPtr.u, VMX_BF_EPTP_PAGE_WALK_LENGTH) == 3)
     5925            {
     5926                /* Access and dirty bits support in EPT structures. */
     5927                if (   !RT_BF_GET(pVmcs->u64EptPtr.u, VMX_BF_EPTP_ACCESS_DIRTY)
     5928                    ||  RT_BF_GET(fCaps, VMX_BF_EPT_VPID_CAP_ACCESS_DIRTY))
     5929                    return VINF_SUCCESS;
     5930
     5931                enmVmxDiag = kVmxVDiag_Vmentry_EptpAccessDirty;
     5932            }
     5933            else
     5934                enmVmxDiag = kVmxVDiag_Vmentry_EptpPageWalkLength;
     5935        }
     5936        else
     5937            enmVmxDiag = kVmxVDiag_Vmentry_EptpMemType;
     5938    }
     5939    else
     5940        enmVmxDiag = kVmxVDiag_Vmentry_EptpRsvd;
     5941
     5942    if (penmVmxDiag)
     5943        *penmVmxDiag = enmVmxDiag;
     5944    return VERR_VMX_VMENTRY_FAILED;
     5945}
     5946#endif
     5947
     5948
    58905949/**
    58915950 * Checks VMCS controls fields as part of VM-entry.
     
    60976156        if (pVmcs->u32ProcCtls2 & VMX_PROC_CTLS2_EPT)
    60986157        {
    6099             /* Reserved bits. */
    6100             uint8_t const cMaxPhysAddrWidth = IEM_GET_GUEST_CPU_FEATURES(pVCpu)->cMaxPhysAddrWidth;
    6101             uint64_t const fValidMask       = VMX_EPTP_VALID_MASK & ~(UINT64_MAX << cMaxPhysAddrWidth);
    6102             if (pVmcs->u64EptPtr.u & fValidMask)
     6158            VMXVDIAG enmVmxDiag;
     6159            rc = iemVmxVmentryCheckEptPtr(pVCpu, &enmVmxDiag);
     6160            if (RT_SUCCESS(rc))
    61036161            { /* likely */ }
    61046162            else
    6105                 IEM_VMX_VMENTRY_FAILED_RET(pVCpu, pszInstr, pszFailure, kVmxVDiag_Vmentry_EptpRsvd);
    6106 
    6107             /* Memory Type. */
    6108             uint64_t const fCaps    = pVCpu->cpum.GstCtx.hwvirt.vmx.Msrs.u64EptVpidCaps;
    6109             uint8_t const  fMemType = RT_BF_GET(pVmcs->u64EptPtr.u, VMX_BF_EPTP_MEMTYPE);
    6110             if (   (   fMemType == VMX_EPTP_MEMTYPE_WB
    6111                     && RT_BF_GET(fCaps, VMX_BF_EPT_VPID_CAP_MEMTYPE_WB))
    6112                 || (   fMemType == VMX_EPTP_MEMTYPE_UC
    6113                     && RT_BF_GET(fCaps, VMX_BF_EPT_VPID_CAP_MEMTYPE_UC)))
    6114             { /* likely */ }
    6115             else
    6116                 IEM_VMX_VMENTRY_FAILED_RET(pVCpu, pszInstr, pszFailure, kVmxVDiag_Vmentry_EptpMemType);
    6117 
    6118             /*
    6119              * Page walk length (PML4).
    6120              * Intel used to specify bit 7 of IA32_VMX_EPT_VPID_CAP as page walk length
    6121              * of 5 but that seems to be removed from the latest specs. leaving only PML4
    6122              * as the maximum supported page-walk level hence we hardcode it as 3 (1 less than 4)
    6123              */
    6124             Assert(RT_BF_GET(fCaps, VMX_BF_EPT_VPID_CAP_PAGE_WALK_LENGTH_4));
    6125             if (RT_BF_GET(pVmcs->u64EptPtr.u, VMX_BF_EPTP_PAGE_WALK_LENGTH) == 3)
    6126             { /* likely */ }
    6127             else
    6128                 IEM_VMX_VMENTRY_FAILED_RET(pVCpu, pszInstr, pszFailure, kVmxVDiag_Vmentry_EptpPageWalkLength);
    6129 
    6130             /* Access and dirty bits support in EPT structures. */
    6131             if (   !RT_BF_GET(pVmcs->u64EptPtr.u, VMX_BF_EPTP_ACCESS_DIRTY)
    6132                 ||  RT_BF_GET(fCaps, VMX_BF_EPT_VPID_CAP_ACCESS_DIRTY))
    6133             { /* likely */ }
    6134             else
    6135                 IEM_VMX_VMENTRY_FAILED_RET(pVCpu, pszInstr, pszFailure, kVmxVDiag_Vmentry_EptpAccessDirty);
     6163                IEM_VMX_VMENTRY_FAILED_RET(pVCpu, pszInstr, pszFailure, enmVmxDiag);
    61366164        }
    61376165#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