VirtualBox

Ignore:
Timestamp:
Sep 28, 2021 7:14:56 AM (3 years ago)
Author:
vboxsync
Message:

VMM/IEM: Nested VMX: bugref:10092 Check PAE PDPTEs when EPT is enabled.

File:
1 edited

Legend:

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

    r91386 r91419  
    56265626
    56275627/**
    5628  * Checks if the PDPTEs referenced by the nested-guest CR3 are valid as part of
    5629  * VM-entry.
    5630  *
    5631  * @returns @c true if all PDPTEs are valid, @c false otherwise.
     5628 * Checks guest PDPTEs as part of VM-entry.
     5629 *
    56325630 * @param   pVCpu       The cross context virtual CPU structure.
    56335631 * @param   pszInstr    The VMX instruction name (for logging purposes).
    5634  * @param   pVmcs       Pointer to the virtual VMCS.
    5635  */
    5636 IEM_STATIC int iemVmxVmentryCheckGuestPdptesForCr3(PVMCPUCC pVCpu, const char *pszInstr, PVMXVVMCS pVmcs)
    5637 {
    5638     /*
    5639      * Check PDPTEs.
    5640      * See Intel spec. 4.4.1 "PDPTE Registers".
    5641      */
    5642     uint64_t const uGuestCr3 = pVmcs->u64GuestCr3.u & X86_CR3_PAE_PAGE_MASK;
    5643     const char *const pszFailure = "VM-exit";
    5644 
    5645     X86PDPE aPdptes[X86_PG_PAE_PDPE_ENTRIES];
    5646     int rc = PGMPhysSimpleReadGCPhys(pVCpu->CTX_SUFF(pVM), (void *)&aPdptes[0], uGuestCr3, sizeof(aPdptes));
    5647     if (RT_SUCCESS(rc))
    5648     {
    5649         for (unsigned iPdpte = 0; iPdpte < RT_ELEMENTS(aPdptes); iPdpte++)
    5650         {
    5651             if (   !(aPdptes[iPdpte].u & X86_PDPE_P)
    5652                 || !(aPdptes[iPdpte].u & X86_PDPE_PAE_MBZ_MASK))
     5632 */
     5633IEM_STATIC int iemVmxVmentryCheckGuestPdptes(PVMCPUCC pVCpu, const char *pszInstr)
     5634{
     5635    /*
     5636     * Guest PDPTEs.
     5637     * See Intel spec. 26.3.1.5 "Checks on Guest Page-Directory-Pointer-Table Entries".
     5638     */
     5639    PVMXVVMCS const pVmcs = &pVCpu->cpum.GstCtx.hwvirt.vmx.Vmcs;
     5640    const char * const pszFailure = "VM-exit";
     5641
     5642    bool const fGstInLongMode = RT_BOOL(pVmcs->u32EntryCtls & VMX_ENTRY_CTLS_IA32E_MODE_GUEST);
     5643    if (   !fGstInLongMode
     5644        && (pVmcs->u64GuestCr4.u & X86_CR4_PAE)
     5645        && (pVmcs->u64GuestCr0.u & X86_CR0_PG))
     5646    {
     5647        /* Get the PDPTEs. */
     5648        X86PDPE aPdpes[X86_PG_PAE_PDPE_ENTRIES];
     5649#ifdef VBOX_WITH_NESTED_HWVIRT_VMX_EPT
     5650        if (pVmcs->u32ProcCtls2 & VMX_PROC_CTLS2_EPT)
     5651        {
     5652            aPdpes[0].u = pVmcs->u64GuestPdpte0.u;
     5653            aPdpes[1].u = pVmcs->u64GuestPdpte1.u;
     5654            aPdpes[2].u = pVmcs->u64GuestPdpte2.u;
     5655            aPdpes[3].u = pVmcs->u64GuestPdpte3.u;
     5656        }
     5657        else
     5658#endif
     5659        {
     5660            uint64_t const uGuestCr3 = pVmcs->u64GuestCr3.u & X86_CR3_PAE_PAGE_MASK;
     5661            int const rc = PGMPhysSimpleReadGCPhys(pVCpu->CTX_SUFF(pVM), (void *)&aPdpes[0], uGuestCr3, sizeof(aPdpes));
     5662            if (RT_FAILURE(rc))
     5663            {
     5664                iemVmxVmcsSetExitQual(pVCpu, VMX_ENTRY_FAIL_QUAL_PDPTE);
     5665                IEM_VMX_VMENTRY_FAILED_RET(pVCpu, pszInstr, pszFailure, kVmxVDiag_Vmentry_GuestPdpteCr3ReadPhys);
     5666            }
     5667        }
     5668
     5669        /* Check validity of the PDPTEs. */
     5670        for (unsigned idx = 0; idx < RT_ELEMENTS(aPdpes); idx++)
     5671        {
     5672            if (   !(aPdpes[idx].u & X86_PDPE_P)
     5673                || !(aPdpes[idx].u & X86_PDPE_PAE_MBZ_MASK))
    56535674            { /* likely */ }
    56545675            else
    56555676            {
     5677                VMXVDIAG const enmDiag = iemVmxGetDiagVmentryPdpteRsvd(idx);
    56565678                iemVmxVmcsSetExitQual(pVCpu, VMX_ENTRY_FAIL_QUAL_PDPTE);
    5657                 VMXVDIAG const enmDiag = iemVmxGetDiagVmentryPdpteRsvd(iPdpte);
    56585679                IEM_VMX_VMENTRY_FAILED_RET(pVCpu, pszInstr, pszFailure, enmDiag);
    56595680            }
    56605681        }
    56615682    }
    5662     else
    5663     {
    5664         iemVmxVmcsSetExitQual(pVCpu, VMX_ENTRY_FAIL_QUAL_PDPTE);
    5665         IEM_VMX_VMENTRY_FAILED_RET(pVCpu, pszInstr, pszFailure, kVmxVDiag_Vmentry_GuestPdpteCr3ReadPhys);
    5666     }
    5667 
     5683
     5684    NOREF(pszInstr);
    56685685    NOREF(pszFailure);
    5669     NOREF(pszInstr);
    5670     return rc;
    5671 }
    5672 
    5673 
    5674 /**
    5675  * Checks guest PDPTEs as part of VM-entry.
    5676  *
    5677  * @param   pVCpu       The cross context virtual CPU structure.
    5678  * @param   pszInstr    The VMX instruction name (for logging purposes).
    5679  */
    5680 DECLINLINE(int) iemVmxVmentryCheckGuestPdptes(PVMCPUCC pVCpu, const char *pszInstr)
    5681 {
    5682     /*
    5683      * Guest PDPTEs.
    5684      * See Intel spec. 26.3.1.5 "Checks on Guest Page-Directory-Pointer-Table Entries".
    5685      */
    5686     PVMXVVMCS const pVmcs = &pVCpu->cpum.GstCtx.hwvirt.vmx.Vmcs;
    5687     bool const fGstInLongMode = RT_BOOL(pVmcs->u32EntryCtls & VMX_ENTRY_CTLS_IA32E_MODE_GUEST);
    5688 
    5689     /* Check PDPTes if the VM-entry is to a guest using PAE paging. */
    5690     int rc;
    5691     if (   !fGstInLongMode
    5692         && (pVmcs->u64GuestCr4.u & X86_CR4_PAE)
    5693         && (pVmcs->u64GuestCr0.u & X86_CR0_PG))
    5694     {
    5695         /*
    5696          * We don't support nested-paging for nested-guests yet.
    5697          *
    5698          * Without nested-paging for nested-guests, PDPTEs in the VMCS are not used,
    5699          * rather we need to check the PDPTEs referenced by the guest CR3.
    5700          */
    5701         rc = iemVmxVmentryCheckGuestPdptesForCr3(pVCpu, pszInstr, pVmcs);
    5702     }
    5703     else
    5704         rc = VINF_SUCCESS;
    5705     return rc;
     5686    return VINF_SUCCESS;
    57065687}
    57075688
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