VirtualBox

Changeset 92426 in vbox


Ignore:
Timestamp:
Nov 15, 2021 1:25:47 PM (3 years ago)
Author:
vboxsync
Message:

VMM: Nested VMX: bugref:10092 Refactor PGMGstGetPage and related API and functions to pass more info back to callers on page walk failures.

Location:
trunk
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/pgm.h

    r92409 r92426  
    3434#include <VBox/vmm/vmapi.h>
    3535#include <VBox/vmm/gmm.h>               /* for PGMMREGISTERSHAREDMODULEREQ */
     36#include <VBox/vmm/hm_vmx.h>
    3637#include <iprt/x86.h>
    3738#include <VBox/param.h>
     
    295296} PGMSLAT;
    296297
     298
     299/** @name PGMPTATTRS - PGM page-table attributes.
     300 *
     301 * This is VirtualBox's combined page table attributes. It combines regular page
     302 * table and Intel EPT attributes. It's 64-bit in size so there's ample room for
     303 * bits added in the future to EPT or regular page tables (for e.g. Protection Key).
     304 *
     305 * The following bits map 1:1 (shifted by PGM_PTATTRS_EPT_SHIFT) to the Intel EPT
     306 * attributes as these are unique to EPT and fit within 64-bits despite the shift:
     307 *   - EPT_R         : Read access.
     308 *   - EPT_W         : Write access.
     309 *   - EPT_X_SUPER   : Execute or execute for supervisor-mode linear addr access.
     310 *   - EPT_MEMTYPE   : EPT memory type.
     311 *   - EPT_IGNORE_PAT: Ignore PAT memory type.
     312 *   - EPT_X_USER    : Execute access for user-mode linear addresses.
     313 *
     314 * For regular page tables, the R bit is always 1 (same as P bit).
     315 * For Intel EPT, the EPT_R and EPT_W bits are copied to R and W bits respectively.
     316 *
     317 * The following EPT attributes are mapped to the following positions because they
     318 * exist in the regular page tables at these positions OR are exclusive to EPT and
     319 * have been mapped to arbitrarily chosen positions:
     320 *   - EPT_A               : Accessed                (EPT bit  8 maps to bit  5).
     321 *   - EPT_D               : Dirty                   (EPT bit  9 maps to bit  6).
     322 *   - EPT_SUPER_SHW_STACK : Supervisor Shadow Stack (EPT bit 60 maps to bit 24).
     323 *   - EPT_SUPPRESS_VE_XCPT: Suppress \#VE exception (EPT bit 63 maps to bit 25).
     324 *
     325 * Bits 12, 11:9 and 43 are deliberately kept unused (correspond to bit PS and bits
     326 * 11:9 in the regular page-table structures and to bit 11 in the EPT structures
     327 * respectively) as bit 12 is the page-size bit and bits 11:9 are reserved for
     328 * use by software and we may want to use/preserve them in the future.
     329 *
     330 * @{ */
     331typedef uint64_t PGMPTATTRS;
     332/** Pointer to a PGMPTATTRS type. */
     333typedef PGMPTATTRS *PPGMPTATTRS;
     334
     335/** Read bit (always 1 for regular PT, copy of EPT_R for EPT). */
     336#define PGM_PTATTRS_R_SHIFT                         0
     337#define PGM_PTATTRS_R_MASK                          RT_BIT_64(PGM_PTATTRS_R_SHIFT)
     338/** Write access bit (aka read/write bit for regular PT). */
     339#define PGM_PTATTRS_W_SHIFT                         1
     340#define PGM_PTATTRS_W_MASK                          RT_BIT_64(PGM_PTATTRS_W_SHIFT)
     341/** User-mode access bit. */
     342#define PGM_PTATTRS_US_SHIFT                        2
     343#define PGM_PTATTRS_US_MASK                         RT_BIT_64(PGM_PTATTRS_US_SHIFT)
     344/** Write through cache bit. */
     345#define PGM_PTATTRS_PWT_SHIFT                       3
     346#define PGM_PTATTRS_PWT_MASK                        RT_BIT_64(PGM_PTATTRS_PWT_SHIFT)
     347/** Cache disabled bit. */
     348#define PGM_PTATTRS_PCD_SHIFT                       4
     349#define PGM_PTATTRS_PCD_MASK                        RT_BIT_64(PGM_PTATTRS_PCD_SHIFT)
     350/** Accessed bit. */
     351#define PGM_PTATTRS_A_SHIFT                         5
     352#define PGM_PTATTRS_A_MASK                          RT_BIT_64(PGM_PTATTRS_A_SHIFT)
     353/** Dirty bit. */
     354#define PGM_PTATTRS_D_SHIFT                         6
     355#define PGM_PTATTRS_D_MASK                          RT_BIT_64(PGM_PTATTRS_D_SHIFT)
     356/** The PAT bit. */
     357#define PGM_PTATTRS_PAT_SHIFT                       7
     358#define PGM_PTATTRS_PAT_MASK                        RT_BIT_64(PGM_PTATTRS_PAT_SHIFT)
     359/** The global bit. */
     360#define PGM_PTATTRS_G_SHIFT                         8
     361#define PGM_PTATTRS_G_MASK                          RT_BIT_64(PGM_PTATTRS_G_SHIFT)
     362/** Reserved (bits 12:9) unused. */
     363#define PGM_PTATTRS_RSVD_12_9_SHIFT                 9
     364#define PGM_PTATTRS_RSVD_12_9_MASK                  UINT64_C(0x0000000000001e00)
     365/** Read access bit - EPT only. */
     366#define PGM_PTATTRS_EPT_R_SHIFT                     13
     367#define PGM_PTATTRS_EPT_R_MASK                      RT_BIT_64(PGM_PTATTRS_EPT_R_SHIFT)
     368/** Write access bit - EPT only. */
     369#define PGM_PTATTRS_EPT_W_SHIFT                     14
     370#define PGM_PTATTRS_EPT_W_MASK                      RT_BIT_64(PGM_PTATTRS_EPT_W_SHIFT)
     371/** Execute or execute access for supervisor-mode linear addresses - EPT only. */
     372#define PGM_PTATTRS_EPT_X_SUPER_SHIFT               15
     373#define PGM_PTATTRS_EPT_X_SUPER_MASK                RT_BIT_64(PGM_PTATTRS_EPT_X_SUPER_SHIFT)
     374/** EPT memory type - EPT only. */
     375#define PGM_PTATTRS_EPT_MEMTYPE_SHIFT               16
     376#define PGM_PTATTRS_EPT_MEMTYPE_MASK                UINT64_C(0x0000000000070000)
     377/** Ignore PAT memory type - EPT only. */
     378#define PGM_PTATTRS_EPT_IGNORE_PAT_SHIFT            19
     379#define PGM_PTATTRS_EPT_IGNORE_PAT_MASK             RT_BIT_64(PGM_PTATTRS_EPT_IGNORE_PAT_SHIFT)
     380/** Reserved (bits 22:20) unused. */
     381#define PGM_PTATTRS_RSVD_22_20_SHIFT                20
     382#define PGM_PTATTRS_RSVD_22_20_MASK                 UINT64_C(0x0000000000700000)
     383/** Execute access for user-mode linear addresses - EPT only. */
     384#define PGM_PTATTRS_EPT_X_USER_SHIFT                23
     385#define PGM_PTATTRS_EPT_X_USER_MASK                 RT_BIT_64(PGM_PTATTRS_EPT_X_USER_SHIFT)
     386/** Reserved (bit 23) - unused. */
     387#define PGM_PTATTRS_RSVD_23_SHIFT                   24
     388#define PGM_PTATTRS_RSVD_23_MASK                    UINT64_C(0x0000000001000000)
     389/** Supervisor shadow stack - EPT only. */
     390#define PGM_PTATTRS_EPT_SUPER_SHW_STACK_SHIFT       25
     391#define PGM_PTATTRS_EPT_SUPER_SHW_STACK_MASK        RT_BIT_64(PGM_PTATTRS_EPT_SUPER_SHW_STACK_SHIFT)
     392/** Suppress \#VE exception - EPT only. */
     393#define PGM_PTATTRS_EPT_SUPPRESS_VE_XCPT_SHIFT      26
     394#define PGM_PTATTRS_EPT_SUPPRESS_VE_XCPT_MASK       RT_BIT_64(PGM_PTATTRS_EPT_SUPPRESS_VE_XCPT_SHIFT)
     395/** Reserved (bits 62:27) - unused. */
     396#define PGM_PTATTRS_RSVD_62_27_SHIFT                27
     397#define PGM_PTATTRS_RSVD_62_27_MASK                 UINT64_C(0x7ffffffff8000000)
     398/** No-execute bit. */
     399#define PGM_PTATTRS_NX_SHIFT                        63
     400#define PGM_PTATTRS_NX_MASK                         RT_BIT_64(PGM_PTATTRS_NX_SHIFT)
     401
     402RT_BF_ASSERT_COMPILE_CHECKS(PGM_PTATTRS_, UINT64_C(0), UINT64_MAX,
     403                            (R, W, US, PWT, PCD, A, D, PAT, G, RSVD_12_9, EPT_R, EPT_W, EPT_X_SUPER, EPT_MEMTYPE, EPT_IGNORE_PAT,
     404                             RSVD_22_20, EPT_X_USER, RSVD_23, EPT_SUPER_SHW_STACK, EPT_SUPPRESS_VE_XCPT, RSVD_62_27, NX));
     405
     406/** The bit position where the EPT specific attributes begin. */
     407#define PGM_PTATTRS_EPT_SHIFT                       PGM_PTATTRS_EPT_R_SHIFT
     408/** The mask of EPT bits (bits 26:ATTR_SHIFT). In the future we might choose to
     409 *  use higher unused bits for something else, in that case adjust this mask. */
     410#define PGM_PTATTRS_EPT_MASK                        UINT64_C(0x0000000007ffe000)
     411
     412/** The mask of all PGM page attribute bits for regular page-tables. */
     413#define PGM_PTATTRS_PT_VALID_MASK                   (  PGM_PTATTRS_R_MASK \
     414                                                     | PGM_PTATTRS_W_MASK \
     415                                                     | PGM_PTATTRS_US_MASK \
     416                                                     | PGM_PTATTRS_PWT_MASK \
     417                                                     | PGM_PTATTRS_PCD_MASK \
     418                                                     | PGM_PTATTRS_A_MASK \
     419                                                     | PGM_PTATTRS_D_MASK \
     420                                                     | PGM_PTATTRS_PAT_MASK \
     421                                                     | PGM_PTATTRS_G_MASK \
     422                                                     | PGM_PTATTRS_NX_MASK)
     423
     424/** The mask of all PGM page attribute bits for EPT. */
     425#define PGM_PTATTRS_EPT_VALID_MASK                  (  PGM_PTATTRS_R_MASK \
     426                                                     | PGM_PTATTRS_W_MASK \
     427                                                     | PGM_PTATTRS_A_MASK \
     428                                                     | PGM_PTATTRS_D_MASK \
     429                                                     | PGM_PTATTRS_EPT_R_MASK \
     430                                                     | PGM_PTATTRS_EPT_W_MASK \
     431                                                     | PGM_PTATTRS_EPT_X_SUPER \
     432                                                     | PGM_PTATTRS_EPT_MEMTYPE \
     433                                                     | PGM_PTATTRS_EPT_IGNORE_PAT \
     434                                                     | PGM_PTATTRS_EPT_X_USER \
     435                                                     | PGM_PTATTRS_EPT_SUPER_SHW_STACK \
     436                                                     | PGM_PTATTRS_EPT_SUPPRESS_VE_XCPT)
     437
     438/* The mask of all PGM page attribute bits (combined). */
     439#define PGM_PTATTRS_VALID_MASK                      (PGM_PTATTRS_PT_VALID_MASK | PGM_PTATTRS_PT_VALID_MASK)
     440
     441/* Verify bits match the regular PT bits. */
     442AssertCompile(PGM_PTATTRS_W_SHIFT   == X86_PTE_BIT_RW);
     443AssertCompile(PGM_PTATTRS_US_SHIFT  == X86_PTE_BIT_US);
     444AssertCompile(PGM_PTATTRS_PWT_SHIFT == X86_PTE_BIT_PWT);
     445AssertCompile(PGM_PTATTRS_PCD_SHIFT == X86_PTE_BIT_PCD);
     446AssertCompile(PGM_PTATTRS_A_SHIFT   == X86_PTE_BIT_A);
     447AssertCompile(PGM_PTATTRS_D_SHIFT   == X86_PTE_BIT_D);
     448AssertCompile(PGM_PTATTRS_PAT_SHIFT == X86_PTE_BIT_PAT);
     449AssertCompile(PGM_PTATTRS_G_SHIFT   == X86_PTE_BIT_G);
     450AssertCompile(PGM_PTATTRS_W_MASK    == X86_PTE_RW);
     451AssertCompile(PGM_PTATTRS_US_MASK   == X86_PTE_US);
     452AssertCompile(PGM_PTATTRS_PWT_MASK  == X86_PTE_PWT);
     453AssertCompile(PGM_PTATTRS_PCD_MASK  == X86_PTE_PCD);
     454AssertCompile(PGM_PTATTRS_A_MASK    == X86_PTE_A);
     455AssertCompile(PGM_PTATTRS_D_MASK    == X86_PTE_D);
     456AssertCompile(PGM_PTATTRS_PAT_MASK  == X86_PTE_PAT);
     457AssertCompile(PGM_PTATTRS_G_MASK    == X86_PTE_G);
     458AssertCompile(PGM_PTATTRS_NX_MASK   == X86_PTE_PAE_NX);
     459
     460/* Verify those EPT bits that must map 1:1 (after shifting). */
     461AssertCompile(PGM_PTATTRS_EPT_R_SHIFT          - PGM_PTATTRS_EPT_SHIFT == EPT_E_BIT_READ);
     462AssertCompile(PGM_PTATTRS_EPT_W_SHIFT          - PGM_PTATTRS_EPT_SHIFT == EPT_E_BIT_WRITE);
     463AssertCompile(PGM_PTATTRS_EPT_X_SUPER_SHIFT    - PGM_PTATTRS_EPT_SHIFT == EPT_E_BIT_EXECUTE);
     464AssertCompile(PGM_PTATTRS_EPT_IGNORE_PAT_SHIFT - PGM_PTATTRS_EPT_SHIFT == EPT_E_BIT_IGNORE_PAT);
     465AssertCompile(PGM_PTATTRS_EPT_X_USER_SHIFT     - PGM_PTATTRS_EPT_SHIFT == EPT_E_BIT_USER_EXECUTE);
     466/** @} */
     467
     468
     469/**
     470 * Page table walk information.
     471 *
     472 * This provides extensive information regarding page faults (or EPT
     473 * violations/misconfigurations) while traversing page tables.
     474 */
     475typedef struct PGMPTWALK
     476{
     477    /** The linear address that is being resolved (input). */
     478    RTGCPTR         GCPtr;
     479
     480    /** The second-level physical address (input/output).
     481     *  @remarks only valid if fIsSlat is set. */
     482    RTGCPHYS        GCPhysNested;
     483
     484    /** The physical address that is the result of the walk (output).
     485     * @remarks This is page aligned and only valid if fSucceeded is set. */
     486    RTGCPHYS        GCPhys;
     487
     488    /** Set if the walk succeeded. */
     489    bool            fSucceeded;
     490    /** Whether this is a second-level address translation. */
     491    bool            fIsSlat;
     492    /** Whether the linear address (GCPtr) caused the second-level
     493     *  address translation. */
     494    bool            fIsLinearAddrValid;
     495    /** The level problem arrised at.
     496     * PTE is level 1, PDE is level 2, PDPE is level 3, PML4 is level 4, CR3 is
     497     * level 8.  This is 0 on success. */
     498    uint8_t         uLevel;
     499    /** Set if the page isn't present. */
     500    bool            fNotPresent;
     501    /** Encountered a bad physical address. */
     502    bool            fBadPhysAddr;
     503    /** Set if there was reserved bit violations. */
     504    bool            fRsvdError;
     505    /** Set if it involves a big page (2/4 MB). */
     506    bool            fBigPage;
     507    /** Set if it involves a gigantic page (1 GB). */
     508    bool            fGigantPage;
     509    /** Set if the second-level fault was caused by an EPT misconfiguration. */
     510    bool            fEptMisconfig;
     511    bool            afPadding[6];
     512
     513    /** The effective attributes, PGM_PTATTRS_XXX. */
     514    PGMPTATTRS      fEffective;
     515} PGMPTWALK;
     516/** Pointer to page walk information. */
     517typedef PGMPTWALK *PPGMPTWALK;
     518/** Pointer to const page walk information. */
     519typedef PGMPTWALK const *PCPGMPTWALK;
     520
     521
    297522/** Macro for checking if the guest is using paging.
    298523 * @param enmMode   PGMMODE_*.
     
    351576#define PGM_MK_PG_IS_MMIO2           RT_BIT(1)
    352577/** @}*/
    353 VMMDECL(int)        PGMGstGetPage(PVMCPUCC pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys);
    354 VMMDECL(bool)       PGMGstIsPagePresent(PVMCPUCC pVCpu, RTGCPTR GCPtr);
     578VMMDECL(int)        PGMGstGetPage(PVMCPUCC pVCpu, RTGCPTR GCPtr, PPGMPTWALK pWalk);
    355579VMMDECL(int)        PGMGstSetPage(PVMCPUCC pVCpu, RTGCPTR GCPtr, size_t cb, uint64_t fFlags);
    356580VMMDECL(int)        PGMGstModifyPage(PVMCPUCC pVCpu, RTGCPTR GCPtr, size_t cb, uint64_t fFlags, uint64_t fMask);
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r91580 r92426  
    14261426    }
    14271427
    1428     RTGCPHYS    GCPhys;
    1429     uint64_t    fFlags;
    1430     int rc = PGMGstGetPage(pVCpu, GCPtrPC, &fFlags, &GCPhys);
    1431     if (RT_SUCCESS(rc)) { /* probable */ }
     1428    PGMPTWALK Walk;
     1429    int rc = PGMGstGetPage(pVCpu, GCPtrPC, &Walk);
     1430    if (RT_SUCCESS(rc))
     1431        Assert(Walk.fSucceeded); /* probable. */
    14321432    else
    14331433    {
     
    14351435        return iemRaisePageFault(pVCpu, GCPtrPC, IEM_ACCESS_INSTRUCTION, rc);
    14361436    }
    1437     if ((fFlags & X86_PTE_US) || pVCpu->iem.s.uCpl != 3) { /* likely */ }
     1437    if ((Walk.fEffective & X86_PTE_US) || pVCpu->iem.s.uCpl != 3) { /* likely */ }
    14381438    else
    14391439    {
     
    14411441        return iemRaisePageFault(pVCpu, GCPtrPC, IEM_ACCESS_INSTRUCTION, VERR_ACCESS_DENIED);
    14421442    }
    1443     if (!(fFlags & X86_PTE_PAE_NX) || !(pVCpu->cpum.GstCtx.msrEFER & MSR_K6_EFER_NXE)) { /* likely */ }
     1443    if (!(Walk.fEffective & X86_PTE_PAE_NX) || !(pVCpu->cpum.GstCtx.msrEFER & MSR_K6_EFER_NXE)) { /* likely */ }
    14441444    else
    14451445    {
     
    14471447        return iemRaisePageFault(pVCpu, GCPtrPC, IEM_ACCESS_INSTRUCTION, VERR_ACCESS_DENIED);
    14481448    }
    1449     GCPhys |= GCPtrPC & PAGE_OFFSET_MASK;
     1449    RTGCPHYS const GCPhys = Walk.GCPhys | (GCPtrPC & PAGE_OFFSET_MASK);
    14501450    /** @todo Check reserved bits and such stuff. PGM is better at doing
    14511451     *        that, so do it when implementing the guest virtual address
     
    17441744        {
    17451745            pVCpu->iem.s.CodeTlb.cTlbMisses++;
    1746             RTGCPHYS    GCPhys;
    1747             uint64_t    fFlags;
    1748             int rc = PGMGstGetPage(pVCpu, GCPtrFirst, &fFlags, &GCPhys);
     1746            PGMPTWALK Walk;
     1747            int rc = PGMGstGetPage(pVCpu, GCPtrFirst, &Walk);
    17491748            if (RT_FAILURE(rc))
    17501749            {
     
    17541753
    17551754            AssertCompile(IEMTLBE_F_PT_NO_EXEC == 1);
     1755            Assert(Walk.fSucceeded);
    17561756            pTlbe->uTag             = uTag;
    1757             pTlbe->fFlagsAndPhysRev = (~fFlags & (X86_PTE_US | X86_PTE_RW | X86_PTE_D)) | (fFlags >> X86_PTE_PAE_BIT_NX);
    1758             pTlbe->GCPhys           = GCPhys;
     1757            pTlbe->fFlagsAndPhysRev = (~Walk.fEffective & (X86_PTE_US | X86_PTE_RW | X86_PTE_D))
     1758                                    | (Walk.fEffective >> X86_PTE_PAE_BIT_NX);
     1759            pTlbe->GCPhys           = Walk.GCPhys;
    17591760            pTlbe->pbMappingR3      = NULL;
    17601761        }
     
    19611962    Assert(cbToTryRead >= cbMin - cbLeft); /* ASSUMPTION based on iemInitDecoderAndPrefetchOpcodes. */
    19621963
    1963     RTGCPHYS    GCPhys;
    1964     uint64_t    fFlags;
    1965     int rc = PGMGstGetPage(pVCpu, GCPtrNext, &fFlags, &GCPhys);
     1964    PGMPTWALK Walk;
     1965    int rc = PGMGstGetPage(pVCpu, GCPtrNext, &Walk);
    19661966    if (RT_FAILURE(rc))
    19671967    {
     
    19691969        return iemRaisePageFault(pVCpu, GCPtrNext, IEM_ACCESS_INSTRUCTION, rc);
    19701970    }
    1971     if (!(fFlags & X86_PTE_US) && pVCpu->iem.s.uCpl == 3)
     1971    if (!(Walk.fEffective & X86_PTE_US) && pVCpu->iem.s.uCpl == 3)
    19721972    {
    19731973        Log(("iemOpcodeFetchMoreBytes: %RGv - supervisor page\n", GCPtrNext));
    19741974        return iemRaisePageFault(pVCpu, GCPtrNext, IEM_ACCESS_INSTRUCTION, VERR_ACCESS_DENIED);
    19751975    }
    1976     if ((fFlags & X86_PTE_PAE_NX) && (pVCpu->cpum.GstCtx.msrEFER & MSR_K6_EFER_NXE))
     1976    if ((Walk.fEffective & X86_PTE_PAE_NX) && (pVCpu->cpum.GstCtx.msrEFER & MSR_K6_EFER_NXE))
    19771977    {
    19781978        Log(("iemOpcodeFetchMoreBytes: %RGv - NX\n", GCPtrNext));
    19791979        return iemRaisePageFault(pVCpu, GCPtrNext, IEM_ACCESS_INSTRUCTION, VERR_ACCESS_DENIED);
    19801980    }
    1981     GCPhys |= GCPtrNext & PAGE_OFFSET_MASK;
     1981    RTGCPHYS const GCPhys = Walk.GCPhys | (GCPtrNext & PAGE_OFFSET_MASK);
    19821982    Log5(("GCPtrNext=%RGv GCPhys=%RGp cbOpcodes=%#x\n",  GCPtrNext,  GCPhys,  pVCpu->iem.s.cbOpcode));
    19831983    /** @todo Check reserved bits and such stuff. PGM is better at doing
     
    81378137     *        iemSvmWorldSwitch/iemVmxWorldSwitch to work around raising a page-fault
    81388138     *        here. */
    8139     RTGCPHYS    GCPhys;
    8140     uint64_t    fFlags;
    8141     int rc = PGMGstGetPage(pVCpu, GCPtrMem, &fFlags, &GCPhys);
     8139    PGMPTWALK Walk;
     8140    int rc = PGMGstGetPage(pVCpu, GCPtrMem, &Walk);
    81428141    if (RT_FAILURE(rc))
    81438142    {
     
    81518150    /* If the page is writable and does not have the no-exec bit set, all
    81528151       access is allowed.  Otherwise we'll have to check more carefully... */
    8153     if ((fFlags & (X86_PTE_RW | X86_PTE_US | X86_PTE_PAE_NX)) != (X86_PTE_RW | X86_PTE_US))
     8152    if ((Walk.fEffective & (X86_PTE_RW | X86_PTE_US | X86_PTE_PAE_NX)) != (X86_PTE_RW | X86_PTE_US))
    81548153    {
    81558154        /* Write to read only memory? */
    81568155        if (   (fAccess & IEM_ACCESS_TYPE_WRITE)
    8157             && !(fFlags & X86_PTE_RW)
     8156            && !(Walk.fEffective & X86_PTE_RW)
    81588157            && (   (    pVCpu->iem.s.uCpl == 3
    81598158                    && !(fAccess & IEM_ACCESS_WHAT_SYS))
     
    81668165
    81678166        /* Kernel memory accessed by userland? */
    8168         if (   !(fFlags & X86_PTE_US)
     8167        if (   !(Walk.fEffective & X86_PTE_US)
    81698168            && pVCpu->iem.s.uCpl == 3
    81708169            && !(fAccess & IEM_ACCESS_WHAT_SYS))
     
    81778176        /* Executing non-executable memory? */
    81788177        if (   (fAccess & IEM_ACCESS_TYPE_EXEC)
    8179             && (fFlags & X86_PTE_PAE_NX)
     8178            && (Walk.fEffective & X86_PTE_PAE_NX)
    81808179            && (pVCpu->cpum.GstCtx.msrEFER & MSR_K6_EFER_NXE) )
    81818180        {
     
    81938192    /** @todo testcase: check when A and D bits are actually set by the CPU.  */
    81948193    uint32_t fAccessedDirty = fAccess & IEM_ACCESS_TYPE_WRITE ? X86_PTE_D | X86_PTE_A : X86_PTE_A;
    8195     if ((fFlags & fAccessedDirty) != fAccessedDirty)
     8194    if ((Walk.fEffective & fAccessedDirty) != fAccessedDirty)
    81968195    {
    81978196        int rc2 = PGMGstModifyPage(pVCpu, GCPtrMem, 1, fAccessedDirty, ~(uint64_t)fAccessedDirty);
     
    81998198    }
    82008199
    8201     GCPhys |= GCPtrMem & PAGE_OFFSET_MASK;
     8200    RTGCPHYS const GCPhys = Walk.GCPhys | (GCPtrMem & PAGE_OFFSET_MASK);
    82028201    *pGCPhysMem = GCPhys;
    82038202    return VINF_SUCCESS;
  • trunk/src/VBox/VMM/VMMAll/PGMAll.cpp

    r92344 r92426  
    5151DECLINLINE(int) pgmShwGetPaePoolPagePD(PVMCPUCC pVCpu, RTGCPTR GCPtr, PPGMPOOLPAGE *ppShwPde);
    5252#ifdef VBOX_WITH_NESTED_HWVIRT_VMX_EPT
    53 static int pgmGstSlatWalk(PVMCPUCC pVCpu, RTGCPHYS GCPhysNested, bool fIsLinearAddrValid, RTGCPTR GCPtrNested, PPGMPTWALKGST pWalk);
     53static int pgmGstSlatWalk(PVMCPUCC pVCpu, RTGCPHYS GCPhysNested, bool fIsLinearAddrValid, RTGCPTR GCPtrNested, PPGMPTWALK pWalk,
     54                          PPGMPTWALKGST pGstWalk);
    5455#endif
    5556static int pgmShwSyncLongModePDPtr(PVMCPUCC pVCpu, RTGCPTR64 GCPtr, X86PGPAEUINT uGstPml4e, X86PGPAEUINT uGstPdpe, PX86PDPAE *ppPD);
     
    17231724 * @param   pVCpu       The cross context virtual CPU structure of the calling EMT.
    17241725 * @param   GCPtr       Guest Context virtual address of the page.
    1725  * @param   pfFlags     Where to store the flags. These are X86_PTE_*, even for big pages.
    1726  * @param   pGCPhys     Where to store the GC physical address of the page.
    1727  *                      This is page aligned. The fact that the
    1728  */
    1729 VMMDECL(int) PGMGstGetPage(PVMCPUCC pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys)
     1726 * @param   pWalk       Where to store the page walk information.
     1727 */
     1728VMMDECL(int) PGMGstGetPage(PVMCPUCC pVCpu, RTGCPTR GCPtr, PPGMPTWALK pWalk)
    17301729{
    17311730    VMCPU_ASSERT_EMT(pVCpu);
     1731    Assert(pWalk);
     1732    RT_BZERO(pWalk, sizeof(*pWalk));
    17321733    uintptr_t idx = pVCpu->pgm.s.idxGuestModeData;
    17331734    AssertReturn(idx < RT_ELEMENTS(g_aPgmGuestModeData), VERR_PGM_MODE_IPE);
    17341735    AssertReturn(g_aPgmGuestModeData[idx].pfnGetPage, VERR_PGM_MODE_IPE);
    1735     return g_aPgmGuestModeData[idx].pfnGetPage(pVCpu, GCPtr, pfFlags, pGCPhys);
     1736    return g_aPgmGuestModeData[idx].pfnGetPage(pVCpu, GCPtr, pWalk);
    17361737}
    17371738
     
    17531754 * @param   pWalk       Where to return the walk result. This is valid for some
    17541755 *                      error codes as well.
    1755  */
    1756 int pgmGstPtWalk(PVMCPUCC pVCpu, RTGCPTR GCPtr, PPGMPTWALKGST pWalk)
     1756 * @param   pGstWalk    The guest mode specific page walk information.
     1757 */
     1758int pgmGstPtWalk(PVMCPUCC pVCpu, RTGCPTR GCPtr, PPGMPTWALK pWalk, PPGMPTWALKGST pGstWalk)
    17571759{
    17581760    VMCPU_ASSERT_EMT(pVCpu);
     
    17601762    {
    17611763        case PGMMODE_32_BIT:
    1762             pWalk->enmType = PGMPTWALKGSTTYPE_32BIT;
    1763             return PGM_GST_NAME_32BIT(Walk)(pVCpu, GCPtr, &pWalk->u.Legacy);
     1764            pGstWalk->enmType = PGMPTWALKGSTTYPE_32BIT;
     1765            return PGM_GST_NAME_32BIT(Walk)(pVCpu, GCPtr, pWalk, &pGstWalk->u.Legacy);
    17641766
    17651767        case PGMMODE_PAE:
    17661768        case PGMMODE_PAE_NX:
    1767             pWalk->enmType = PGMPTWALKGSTTYPE_PAE;
    1768             return PGM_GST_NAME_PAE(Walk)(pVCpu, GCPtr, &pWalk->u.Pae);
     1769            pGstWalk->enmType = PGMPTWALKGSTTYPE_PAE;
     1770            return PGM_GST_NAME_PAE(Walk)(pVCpu, GCPtr, pWalk, &pGstWalk->u.Pae);
    17691771
    17701772        case PGMMODE_AMD64:
    17711773        case PGMMODE_AMD64_NX:
    1772             pWalk->enmType = PGMPTWALKGSTTYPE_AMD64;
    1773             return PGM_GST_NAME_AMD64(Walk)(pVCpu, GCPtr, &pWalk->u.Amd64);
     1774            pGstWalk->enmType = PGMPTWALKGSTTYPE_AMD64;
     1775            return PGM_GST_NAME_AMD64(Walk)(pVCpu, GCPtr, pWalk, &pGstWalk->u.Amd64);
    17741776
    17751777        case PGMMODE_REAL:
    17761778        case PGMMODE_PROTECTED:
    1777             pWalk->enmType = PGMPTWALKGSTTYPE_INVALID;
     1779            pGstWalk->enmType = PGMPTWALKGSTTYPE_INVALID;
    17781780            return VERR_PGM_NOT_USED_IN_MODE;
    17791781
     
    17841786        default:
    17851787            AssertFailed();
    1786             pWalk->enmType = PGMPTWALKGSTTYPE_INVALID;
     1788            pGstWalk->enmType = PGMPTWALKGSTTYPE_INVALID;
    17871789            return VERR_PGM_NOT_USED_IN_MODE;
    17881790    }
     
    18131815 * @param   pWalk               Where to return the walk result. This is valid for
    18141816 *                              some error codes as well.
     1817 * @param   pGstWalk            The second-level paging-mode specific walk
     1818 *                              information.
    18151819 */
    18161820static int pgmGstSlatWalk(PVMCPUCC pVCpu, RTGCPHYS GCPhysNested, bool fIsLinearAddrValid, RTGCPTR GCPtrNested,
    1817                           PPGMPTWALKGST pWalk)
    1818 {
    1819     Assert(pVCpu->pgm.s.enmGuestSlatMode != PGMSLAT_DIRECT);
     1821                          PPGMPTWALK pWalk, PPGMPTWALKGST pGstWalk)
     1822{
     1823    Assert(   pVCpu->pgm.s.enmGuestSlatMode != PGMSLAT_DIRECT
     1824           && pVCpu->pgm.s.enmGuestSlatMode != PGMSLAT_INVALID);
    18201825    switch (pVCpu->pgm.s.enmGuestSlatMode)
    18211826    {
    18221827        case PGMSLAT_EPT:
    1823             pWalk->enmType = PGMPTWALKGSTTYPE_EPT;
    1824             return PGM_GST_SLAT_NAME_EPT(Walk)(pVCpu, GCPhysNested, fIsLinearAddrValid, GCPtrNested, &pWalk->u.Ept);
     1828            pGstWalk->enmType = PGMPTWALKGSTTYPE_EPT;
     1829            return PGM_GST_SLAT_NAME_EPT(Walk)(pVCpu, GCPhysNested, fIsLinearAddrValid, GCPtrNested, pWalk, &pGstWalk->u.Ept);
    18251830
    18261831        default:
    18271832            AssertFailed();
    1828             pWalk->enmType = PGMPTWALKGSTTYPE_INVALID;
     1833            pGstWalk->enmType = PGMPTWALKGSTTYPE_INVALID;
    18291834            return VERR_PGM_NOT_USED_IN_MODE;
    18301835    }
     
    18511856 *                      the result of this walk.  This is valid for some error
    18521857 *                      codes as well.
    1853  */
    1854 int pgmGstPtWalkNext(PVMCPUCC pVCpu, RTGCPTR GCPtr, PPGMPTWALKGST pWalk)
     1858 * @param   pGstWalk    The guest-mode specific walk information.
     1859 */
     1860int pgmGstPtWalkNext(PVMCPUCC pVCpu, RTGCPTR GCPtr, PPGMPTWALK pWalk, PPGMPTWALKGST pGstWalk)
    18551861{
    18561862    /*
     
    18581864     * We also limit ourselves to the next page.
    18591865     */
    1860     if (   pWalk->u.Core.fSucceeded
    1861         && GCPtr - pWalk->u.Core.GCPtr == PAGE_SIZE)
    1862     {
    1863         Assert(pWalk->u.Core.uLevel == 0);
    1864         if (pWalk->enmType == PGMPTWALKGSTTYPE_AMD64)
     1866    if (   pWalk->fSucceeded
     1867        && GCPtr - pWalk->GCPtr == PAGE_SIZE)
     1868    {
     1869        Assert(pWalk->uLevel == 0);
     1870        if (pGstWalk->enmType == PGMPTWALKGSTTYPE_AMD64)
    18651871        {
    18661872            /*
    18671873             * AMD64
    18681874             */
    1869             if (!pWalk->u.Core.fGigantPage && !pWalk->u.Core.fBigPage)
     1875            if (!pWalk->fGigantPage && !pWalk->fBigPage)
    18701876            {
    18711877                /*
     
    18781884                                        | X86_PDE_PCD | X86_PDE_A  | X86_PDE_PAE_NX | X86_PDE_PS;
    18791885
    1880                 if ((GCPtr >> X86_PD_PAE_SHIFT) == (pWalk->u.Core.GCPtr >> X86_PD_PAE_SHIFT))
     1886                if ((GCPtr >> X86_PD_PAE_SHIFT) == (pWalk->GCPtr >> X86_PD_PAE_SHIFT))
    18811887                {
    1882                     if (pWalk->u.Amd64.pPte)
     1888                    if (pGstWalk->u.Amd64.pPte)
    18831889                    {
    18841890                        X86PTEPAE Pte;
    1885                         Pte.u = pWalk->u.Amd64.pPte[1].u;
    1886                         if (   (Pte.u & fPteSame) == (pWalk->u.Amd64.Pte.u & fPteSame)
     1891                        Pte.u = pGstWalk->u.Amd64.pPte[1].u;
     1892                        if (   (Pte.u & fPteSame) == (pGstWalk->u.Amd64.Pte.u & fPteSame)
    18871893                            && !(Pte.u & (pVCpu)->pgm.s.fGstAmd64MbzPteMask))
    18881894                        {
    1889 
    1890                             pWalk->u.Core.GCPtr  = GCPtr;
    1891                             pWalk->u.Core.GCPhys = Pte.u & X86_PTE_PAE_PG_MASK;
    1892                             pWalk->u.Amd64.Pte.u = Pte.u;
    1893                             pWalk->u.Amd64.pPte++;
     1895                            pWalk->GCPtr  = GCPtr;
     1896                            pWalk->GCPhys = Pte.u & X86_PTE_PAE_PG_MASK;
     1897                            pGstWalk->u.Amd64.Pte.u = Pte.u;
     1898                            pGstWalk->u.Amd64.pPte++;
    18941899                            return VINF_SUCCESS;
    18951900                        }
    18961901                    }
    18971902                }
    1898                 else if ((GCPtr >> X86_PDPT_SHIFT) == (pWalk->u.Core.GCPtr >> X86_PDPT_SHIFT))
     1903                else if ((GCPtr >> X86_PDPT_SHIFT) == (pWalk->GCPtr >> X86_PDPT_SHIFT))
    18991904                {
    19001905                    Assert(!((GCPtr >> X86_PT_PAE_SHIFT) & X86_PT_PAE_MASK)); /* Must be first PT entry. */
    1901                     if (pWalk->u.Amd64.pPde)
     1906                    if (pGstWalk->u.Amd64.pPde)
    19021907                    {
    19031908                        X86PDEPAE Pde;
    1904                         Pde.u = pWalk->u.Amd64.pPde[1].u;
    1905                         if (   (Pde.u & fPdeSame) == (pWalk->u.Amd64.Pde.u & fPdeSame)
     1909                        Pde.u = pGstWalk->u.Amd64.pPde[1].u;
     1910                        if (   (Pde.u & fPdeSame) == (pGstWalk->u.Amd64.Pde.u & fPdeSame)
    19061911                            && !(Pde.u & (pVCpu)->pgm.s.fGstAmd64MbzPdeMask))
    19071912                        {
    19081913                            /* Get the new PTE and check out the first entry. */
    19091914                            int rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, PGM_A20_APPLY(pVCpu, (Pde.u & X86_PDE_PAE_PG_MASK)),
    1910                                                                &pWalk->u.Amd64.pPt);
     1915                                                               &pGstWalk->u.Amd64.pPt);
    19111916                            if (RT_SUCCESS(rc))
    19121917                            {
    1913                                 pWalk->u.Amd64.pPte = &pWalk->u.Amd64.pPt->a[0];
     1918                                pGstWalk->u.Amd64.pPte = &pGstWalk->u.Amd64.pPt->a[0];
    19141919                                X86PTEPAE Pte;
    1915                                 Pte.u = pWalk->u.Amd64.pPte->u;
    1916                                 if (   (Pte.u & fPteSame) == (pWalk->u.Amd64.Pte.u & fPteSame)
     1920                                Pte.u = pGstWalk->u.Amd64.pPte->u;
     1921                                if (   (Pte.u & fPteSame) == (pGstWalk->u.Amd64.Pte.u & fPteSame)
    19171922                                    && !(Pte.u & (pVCpu)->pgm.s.fGstAmd64MbzPteMask))
    19181923                                {
    1919                                     pWalk->u.Core.GCPtr  = GCPtr;
    1920                                     pWalk->u.Core.GCPhys = Pte.u & X86_PTE_PAE_PG_MASK;
    1921                                     pWalk->u.Amd64.Pte.u = Pte.u;
    1922                                     pWalk->u.Amd64.Pde.u = Pde.u;
    1923                                     pWalk->u.Amd64.pPde++;
     1924                                    pWalk->GCPtr  = GCPtr;
     1925                                    pWalk->GCPhys = Pte.u & X86_PTE_PAE_PG_MASK;
     1926                                    pGstWalk->u.Amd64.Pte.u = Pte.u;
     1927                                    pGstWalk->u.Amd64.Pde.u = Pde.u;
     1928                                    pGstWalk->u.Amd64.pPde++;
    19241929                                    return VINF_SUCCESS;
    19251930                                }
     
    19291934                }
    19301935            }
    1931             else if (!pWalk->u.Core.fGigantPage)
     1936            else if (!pWalk->fGigantPage)
    19321937            {
    1933                 if ((GCPtr & X86_PAGE_2M_BASE_MASK) == (pWalk->u.Core.GCPtr & X86_PAGE_2M_BASE_MASK))
     1938                if ((GCPtr & X86_PAGE_2M_BASE_MASK) == (pWalk->GCPtr & X86_PAGE_2M_BASE_MASK))
    19341939                {
    1935                     pWalk->u.Core.GCPtr   = GCPtr;
    1936                     pWalk->u.Core.GCPhys += PAGE_SIZE;
     1940                    pWalk->GCPtr   = GCPtr;
     1941                    pWalk->GCPhys += PAGE_SIZE;
    19371942                    return VINF_SUCCESS;
    19381943                }
     
    19401945            else
    19411946            {
    1942                 if ((GCPtr & X86_PAGE_1G_BASE_MASK) == (pWalk->u.Core.GCPtr & X86_PAGE_1G_BASE_MASK))
     1947                if ((GCPtr & X86_PAGE_1G_BASE_MASK) == (pWalk->GCPtr & X86_PAGE_1G_BASE_MASK))
    19431948                {
    1944                     pWalk->u.Core.GCPtr   = GCPtr;
    1945                     pWalk->u.Core.GCPhys += PAGE_SIZE;
     1949                    pWalk->GCPtr   = GCPtr;
     1950                    pWalk->GCPhys += PAGE_SIZE;
    19461951                    return VINF_SUCCESS;
    19471952                }
     
    19501955    }
    19511956    /* Case we don't handle.  Do full walk. */
    1952     return pgmGstPtWalk(pVCpu, GCPtr, pWalk);
    1953 }
    1954 
    1955 
    1956 /**
    1957  * Checks if the page is present.
    1958  *
    1959  * @returns true if the page is present.
    1960  * @returns false if the page is not present.
    1961  * @param   pVCpu       The cross context virtual CPU structure.
    1962  * @param   GCPtr       Address within the page.
    1963  */
    1964 VMMDECL(bool) PGMGstIsPagePresent(PVMCPUCC pVCpu, RTGCPTR GCPtr)
    1965 {
    1966     VMCPU_ASSERT_EMT(pVCpu);
    1967     int rc = PGMGstGetPage(pVCpu, GCPtr, NULL, NULL);
    1968     return RT_SUCCESS(rc);
     1957    return pgmGstPtWalk(pVCpu, GCPtr, pWalk, pGstWalk);
    19691958}
    19701959
     
    31793168#ifdef VBOX_WITH_NESTED_HWVIRT_VMX_EPT
    31803169    /* Update the guest SLAT mode if it's a nested-guest. */
    3181     if (CPUMIsGuestVmxEptPagingEnabled(pVCpu))
    3182     {
    3183         if (PGMMODE_WITH_PAGING(enmGuestMode))
    3184             pVCpu->pgm.s.enmGuestSlatMode = PGMSLAT_EPT;
    3185         else
    3186             pVCpu->pgm.s.enmGuestSlatMode = PGMSLAT_DIRECT;
    3187     }
     3170    if (   CPUMIsGuestVmxEptPagingEnabled(pVCpu)
     3171        && PGMMODE_WITH_PAGING(enmGuestMode))
     3172        pVCpu->pgm.s.enmGuestSlatMode = PGMSLAT_EPT;
    31883173    else
    3189         Assert(pVCpu->pgm.s.enmGuestSlatMode == PGMSLAT_DIRECT);
     3174        pVCpu->pgm.s.enmGuestSlatMode = PGMSLAT_DIRECT;
    31903175#endif
    31913176
  • trunk/src/VBox/VMM/VMMAll/PGMAllBth.h

    r92381 r92426  
    170170 *
    171171 * @param   pVCpu           The cross context virtual CPU structure of the calling EMT.
    172  * @param   pGstWalk        The guest page table walk result.
     172 * @param   pWalk           The guest page table walk result.
    173173 * @param   uErr            The error code.
    174174 */
    175 PGM_BTH_DECL(VBOXSTRICTRC, Trap0eHandlerGuestFault)(PVMCPUCC pVCpu, PGSTPTWALK pGstWalk, RTGCUINT uErr)
     175PGM_BTH_DECL(VBOXSTRICTRC, Trap0eHandlerGuestFault)(PVMCPUCC pVCpu, PPGMPTWALK pWalk, RTGCUINT uErr)
    176176{
    177177    /*
     
    181181                     ? uErr & (X86_TRAP_PF_RW | X86_TRAP_PF_US | X86_TRAP_PF_ID)
    182182                     : uErr & (X86_TRAP_PF_RW | X86_TRAP_PF_US);
    183     if (   pGstWalk->Core.fRsvdError
    184         || pGstWalk->Core.fBadPhysAddr)
     183    if (   pWalk->fRsvdError
     184        || pWalk->fBadPhysAddr)
    185185    {
    186186        uNewErr |= X86_TRAP_PF_RSVD | X86_TRAP_PF_P;
    187         Assert(!pGstWalk->Core.fNotPresent);
    188     }
    189     else if (!pGstWalk->Core.fNotPresent)
     187        Assert(!pWalk->fNotPresent);
     188    }
     189    else if (!pWalk->fNotPresent)
    190190        uNewErr |= X86_TRAP_PF_P;
    191191    TRPMSetErrorCode(pVCpu, uNewErr);
    192192
    193     LogFlow(("Guest trap; cr2=%RGv uErr=%RGv lvl=%d\n", pGstWalk->Core.GCPtr, uErr, pGstWalk->Core.uLevel));
     193    LogFlow(("Guest trap; cr2=%RGv uErr=%RGv lvl=%d\n", pWalk->GCPtr, uErr, pWalk->uLevel));
    194194    STAM_STATS({ pVCpu->pgmr0.s.pStatTrap0eAttributionR0 = &pVCpu->pgm.s.Stats.StatRZTrap0eTime2GuestTrap; });
    195195    return VINF_EM_RAW_GUEST_TRAP;
     
    211211 * @param   pvFault         The fault address.
    212212 * @param   pPage           The guest page at @a pvFault.
    213  * @param   pGstWalk        The guest page table walk result.
     213 * @param   pWalk           The guest page table walk result.
     214 * @param   pGstWalk        The guest paging-mode specific walk information.
    214215 * @param   pfLockTaken     PGM lock taken here or not (out).  This is true
    215216 *                          when we're called.
     
    218219                                                                RTGCPTR pvFault, PPGMPAGE pPage, bool *pfLockTaken
    219220# if PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE) || defined(DOXYGEN_RUNNING)
     221                                                                , PPGMPTWALK pWalk
    220222                                                                , PGSTPTWALK pGstWalk
    221223# endif
     
    234236         */
    235237# if PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE)
    236         const RTGCPHYS  GCPhysFault = pGstWalk->Core.GCPhys;
     238        const RTGCPHYS  GCPhysFault = pWalk->GCPhys;
    237239# else
    238240        const RTGCPHYS  GCPhysFault = PGM_A20_APPLY(pVCpu, (RTGCPHYS)pvFault);
     
    277279                && pCurType->enmKind != PGMPHYSHANDLERKIND_WRITE
    278280#   if PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE)
    279                 && (pGstWalk->Core.fEffective & (PGM_PTATTRS_W_MASK | PGM_PTATTRS_US_MASK))
    280                                               == PGM_PTATTRS_W_MASK  /** @todo Remove pGstWalk->Core.fEffectiveUS and X86_PTE_US further down in the sync code. */
     281                && (pWalk->fEffective & (PGM_PTATTRS_W_MASK | PGM_PTATTRS_US_MASK))
     282                                      == PGM_PTATTRS_W_MASK  /** @todo Remove pGstWalk->Core.fEffectiveUS and X86_PTE_US further down in the sync code. */
    281283#   endif
    282284               )
     
    418420     * Walk the guest page translation tables and check if it's a guest fault.
    419421     */
     422    PGMPTWALK Walk;
    420423    GSTPTWALK GstWalk;
    421     rc = PGM_GST_NAME(Walk)(pVCpu, pvFault, &GstWalk);
     424    rc = PGM_GST_NAME(Walk)(pVCpu, pvFault, &Walk, &GstWalk);
    422425    if (RT_FAILURE_NP(rc))
    423         return VBOXSTRICTRC_TODO(PGM_BTH_NAME(Trap0eHandlerGuestFault)(pVCpu, &GstWalk, uErr));
     426        return VBOXSTRICTRC_TODO(PGM_BTH_NAME(Trap0eHandlerGuestFault)(pVCpu, &Walk, uErr));
    424427
    425428    /* assert some GstWalk sanity. */
     
    432435    /*AssertMsg(GstWalk.Pde.u == GstWalk.pPde->u, ("%RX64 %RX64\n", (uint64_t)GstWalk.Pde.u, (uint64_t)GstWalk.pPde->u)); - ditto */
    433436    /*AssertMsg(GstWalk.Core.fBigPage || GstWalk.Pte.u == GstWalk.pPte->u, ("%RX64 %RX64\n", (uint64_t)GstWalk.Pte.u, (uint64_t)GstWalk.pPte->u)); - ditto */
    434     Assert(GstWalk.Core.fSucceeded);
     437    Assert(Walk.fSucceeded);
    435438
    436439    if (uErr & (X86_TRAP_PF_RW | X86_TRAP_PF_US | X86_TRAP_PF_ID))
    437440    {
    438441        if (    (   (uErr & X86_TRAP_PF_RW)
    439                  && !(GstWalk.Core.fEffective & PGM_PTATTRS_W_MASK)
     442                 && !(Walk.fEffective & PGM_PTATTRS_W_MASK)
    440443                 && (   (uErr & X86_TRAP_PF_US)
    441444                     || CPUMIsGuestR0WriteProtEnabled(pVCpu)) )
    442             ||  ((uErr & X86_TRAP_PF_US) && !(GstWalk.Core.fEffective & PGM_PTATTRS_US_MASK))
    443             ||  ((uErr & X86_TRAP_PF_ID) && (GstWalk.Core.fEffective & PGM_PTATTRS_NX_MASK))
     445            ||  ((uErr & X86_TRAP_PF_US) && !(Walk.fEffective & PGM_PTATTRS_US_MASK))
     446            ||  ((uErr & X86_TRAP_PF_ID) &&  (Walk.fEffective & PGM_PTATTRS_NX_MASK))
    444447           )
    445             return VBOXSTRICTRC_TODO(PGM_BTH_NAME(Trap0eHandlerGuestFault)(pVCpu, &GstWalk, uErr));
     448            return VBOXSTRICTRC_TODO(PGM_BTH_NAME(Trap0eHandlerGuestFault)(pVCpu, &Walk, uErr));
    446449    }
    447450
     
    468471    }
    469472#   endif
    470     if (GstWalk.Core.fBigPage)
     473    if (Walk.fBigPage)
    471474    {
    472475        Assert(GstWalk.Pde.u & X86_PDE_PS);
     
    521524        Assert(GstWalk.Pte.u == GstWalk.pPte->u);
    522525    }
     526#if 0
     527    /* Disabling this since it's not reliable for SMP, see @bugref{10092#c22}. */
    523528    AssertMsg(GstWalk.Pde.u == GstWalk.pPde->u || GstWalk.pPte->u == GstWalk.pPde->u,
    524529              ("%RX64 %RX64 pPte=%p pPde=%p Pte=%RX64\n", (uint64_t)GstWalk.Pde.u, (uint64_t)GstWalk.pPde->u, GstWalk.pPte, GstWalk.pPde, (uint64_t)GstWalk.pPte->u));
     530#endif
     531
    525532#  else  /* !PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE) */
    526533    GSTPDE const PdeSrcDummy = { X86_PDE_P | X86_PDE_US | X86_PDE_RW | X86_PDE_A}; /** @todo eliminate this */
     
    541548        PPGMPAGE pPage;
    542549#   if PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE)
    543         rc = pgmPhysGetPageEx(pVM, GstWalk.Core.GCPhys, &pPage);
     550        rc = pgmPhysGetPageEx(pVM, Walk.GCPhys, &pPage);
    544551        if (RT_SUCCESS(rc) && PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(pPage))
    545552            return VBOXSTRICTRC_TODO(PGM_BTH_NAME(Trap0eHandlerDoAccessHandlers)(pVCpu, uErr, pRegFrame, pvFault, pPage,
    546                                                                                  pfLockTaken, &GstWalk));
     553                                                                                 pfLockTaken, &Walk, &GstWalk));
    547554        rc = PGM_BTH_NAME(SyncPage)(pVCpu, GstWalk.Pde, pvFault, 1, uErr);
    548555#   else
     
    618625#ifdef DEBUG_bird
    619626        AssertMsg(GstWalk.Pde.u == GstWalk.pPde->u || GstWalk.pPte->u == GstWalk.pPde->u || pVM->cCpus > 1, ("%RX64 %RX64\n", (uint64_t)GstWalk.Pde.u, (uint64_t)GstWalk.pPde->u)); // - triggers with smp w7 guests.
    620         AssertMsg(GstWalk.Core.fBigPage || GstWalk.Pte.u == GstWalk.pPte->u || pVM->cCpus > 1, ("%RX64 %RX64\n", (uint64_t)GstWalk.Pte.u, (uint64_t)GstWalk.pPte->u)); // - ditto.
     627        AssertMsg(Walk.fBigPage || GstWalk.Pte.u == GstWalk.pPte->u || pVM->cCpus > 1, ("%RX64 %RX64\n", (uint64_t)GstWalk.Pte.u, (uint64_t)GstWalk.pPte->u)); // - ditto.
    621628#endif
    622629    }
     
    669676     */
    670677#  if PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE)
    671     RTGCPHYS GCPhys = GstWalk.Core.GCPhys & ~(RTGCPHYS)PAGE_OFFSET_MASK;
     678    RTGCPHYS GCPhys = Walk.GCPhys & ~(RTGCPHYS)PAGE_OFFSET_MASK;
    672679#  else
    673680    RTGCPHYS GCPhys = PGM_A20_APPLY(pVCpu, (RTGCPHYS)pvFault & ~(RTGCPHYS)PAGE_OFFSET_MASK);
     
    694701# if PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE)
    695702        return VBOXSTRICTRC_TODO(PGM_BTH_NAME(Trap0eHandlerDoAccessHandlers)(pVCpu, uErr, pRegFrame, pvFault, pPage, pfLockTaken,
    696                                                                              &GstWalk));
     703                                                                             &Walk, &GstWalk));
    697704# else
    698705        return VBOXSTRICTRC_TODO(PGM_BTH_NAME(Trap0eHandlerDoAccessHandlers)(pVCpu, uErr, pRegFrame, pvFault, pPage, pfLockTaken));
     
    778785             * Check to see if we need to emulate the instruction if CR0.WP=0.
    779786             */
    780             if (    !(GstWalk.Core.fEffective & PGM_PTATTRS_W_MASK)
     787            if (    !(Walk.fEffective & PGM_PTATTRS_W_MASK)
    781788                &&  (CPUMGetGuestCR0(pVCpu) & (X86_CR0_WP | X86_CR0_PG)) == X86_CR0_PG
    782789                &&  CPUMGetGuestCPL(pVCpu) < 3)
     
    797804                 */
    798805#    if (PGM_GST_TYPE == PGM_TYPE_32BIT || PGM_GST_TYPE == PGM_TYPE_PAE) && 1
    799                 if (   (GstWalk.Core.fEffective & (PGM_PTATTRS_W_MASK | PGM_PTATTRS_US_MASK)) == PGM_PTATTRS_US_MASK
    800                     && (GstWalk.Core.fBigPage || (GstWalk.Pde.u & X86_PDE_RW))
     806                if (   (Walk.fEffective & (PGM_PTATTRS_W_MASK | PGM_PTATTRS_US_MASK)) == PGM_PTATTRS_US_MASK
     807                    && (Walk.fBigPage || (GstWalk.Pde.u & X86_PDE_RW))
    801808                    && pVM->cCpus == 1 /* Sorry, no go on SMP. Add CFGM option? */)
    802809                {
    803                     Log(("PGM #PF: Netware WP0+RO+US hack: pvFault=%RGp uErr=%#x (big=%d)\n", pvFault, uErr, GstWalk.Core.fBigPage));
    804                     rc = pgmShwMakePageSupervisorAndWritable(pVCpu, pvFault, GstWalk.Core.fBigPage, PGM_MK_PG_IS_WRITE_FAULT);
     810                    Log(("PGM #PF: Netware WP0+RO+US hack: pvFault=%RGp uErr=%#x (big=%d)\n", pvFault, uErr, Walk.fBigPage));
     811                    rc = pgmShwMakePageSupervisorAndWritable(pVCpu, pvFault, Walk.fBigPage, PGM_MK_PG_IS_WRITE_FAULT);
    805812                    if (rc == VINF_SUCCESS || rc == VINF_PGM_SYNC_CR3)
    806813                    {
     
    817824                /* Interpret the access. */
    818825                rc = VBOXSTRICTRC_TODO(PGMInterpretInstruction(pVM, pVCpu, pRegFrame, pvFault));
    819                 Log(("PGM #PF: WP0 emulation (pvFault=%RGp uErr=%#x cpl=%d fBig=%d fEffUs=%d)\n", pvFault, uErr, CPUMGetGuestCPL(pVCpu), GstWalk.Core.fBigPage, !!(GstWalk.Core.fEffective & PGM_PTATTRS_US_MASK)));
     826                Log(("PGM #PF: WP0 emulation (pvFault=%RGp uErr=%#x cpl=%d fBig=%d fEffUs=%d)\n", pvFault, uErr, CPUMGetGuestCPL(pVCpu), Walk.fBigPage, !!(Walk.fEffective & PGM_PTATTRS_US_MASK)));
    820827                if (RT_SUCCESS(rc))
    821828                    STAM_COUNTER_INC(&pVCpu->pgm.s.Stats.StatRZTrap0eWPEmulInRZ);
     
    855862#   endif
    856863#   ifdef VBOX_STRICT
    857                 RTGCPHYS GCPhys2 = RTGCPHYS_MAX;
    858                 uint64_t fPageGst = UINT64_MAX;
     864                PGMPTWALK GstPageWalk;
     865                GstPageWalk.GCPhys = RTGCPHYS_MAX;
    859866                if (!pVM->pgm.s.fNestedPaging)
    860867                {
    861                     rc = PGMGstGetPage(pVCpu, pvFault, &fPageGst, &GCPhys2);
    862                     AssertMsg(RT_SUCCESS(rc) && ((fPageGst & X86_PTE_RW) || ((CPUMGetGuestCR0(pVCpu) & (X86_CR0_WP | X86_CR0_PG)) == X86_CR0_PG && CPUMGetGuestCPL(pVCpu) < 3)), ("rc=%Rrc fPageGst=%RX64\n", rc, fPageGst));
    863                     LogFlow(("Obsolete physical monitor page out of sync %RGv - phys %RGp flags=%08llx\n", pvFault, GCPhys2, (uint64_t)fPageGst));
     868                    rc = PGMGstGetPage(pVCpu, pvFault, &GstPageWalk);
     869                    AssertMsg(RT_SUCCESS(rc) && ((GstPageWalk.fEffective & X86_PTE_RW) || ((CPUMGetGuestCR0(pVCpu) & (X86_CR0_WP | X86_CR0_PG)) == X86_CR0_PG && CPUMGetGuestCPL(pVCpu) < 3)), ("rc=%Rrc fPageGst=%RX64\n", rc, GstPageWalk.fEffective));
     870                    LogFlow(("Obsolete physical monitor page out of sync %RGv - phys %RGp flags=%08llx\n", pvFault, GstPageWalk.GCPhys, GstPageWalk.fEffective));
    864871                }
    865872#    if 0 /* Bogus! Triggers incorrectly with w7-64 and later for the SyncPage case: "Pde at %RGv changed behind our back?" */
     
    867874                rc = PGMShwGetPage(pVCpu, pvFault, &fPageShw, NULL);
    868875                AssertMsg((RT_SUCCESS(rc) && (fPageShw & X86_PTE_RW)) || pVM->cCpus > 1 /* new monitor can be installed/page table flushed between the trap exit and PGMTrap0eHandler */,
    869                           ("rc=%Rrc fPageShw=%RX64 GCPhys2=%RGp fPageGst=%RX64 pvFault=%RGv\n", rc, fPageShw, GCPhys2, fPageGst, pvFault));
     876                          ("rc=%Rrc fPageShw=%RX64 GCPhys2=%RGp fPageGst=%RX64 pvFault=%RGv\n", rc, fPageShw, GstPageWalk.GCPhys, fPageGst, pvFault));
    870877#    endif
    871878#   endif /* VBOX_STRICT */
     
    879886         * mode accesses the page again.
    880887         */
    881         else if (   (GstWalk.Core.fEffective & (PGM_PTATTRS_W_MASK | PGM_PTATTRS_US_MASK)) == PGM_PTATTRS_US_MASK
    882                  && (GstWalk.Core.fBigPage || (GstWalk.Pde.u & X86_PDE_RW))
     888        else if (   (Walk.fEffective & (PGM_PTATTRS_W_MASK | PGM_PTATTRS_US_MASK)) == PGM_PTATTRS_US_MASK
     889                 && (Walk.fBigPage || (GstWalk.Pde.u & X86_PDE_RW))
    883890                 &&  pVCpu->pgm.s.cNetwareWp0Hacks > 0
    884891                 &&  (CPUMGetGuestCR0(pVCpu) & (X86_CR0_WP | X86_CR0_PG)) == X86_CR0_PG
     
    909916        {
    910917            /* Get guest page flags. */
    911             uint64_t fPageGst;
    912             int rc2 = PGMGstGetPage(pVCpu, pvFault, &fPageGst, NULL);
     918            PGMPTWALK GstPageWalk;
     919            int rc2 = PGMGstGetPage(pVCpu, pvFault, &GstPageWalk);
    913920            if (RT_SUCCESS(rc2))
    914921            {
  • trunk/src/VBox/VMM/VMMAll/PGMAllGst.h

    r92336 r92426  
    2424 || PGM_GST_TYPE == PGM_TYPE_PAE \
    2525 || PGM_GST_TYPE == PGM_TYPE_AMD64
    26 DECLINLINE(int) PGM_GST_NAME(Walk)(PVMCPUCC pVCpu, RTGCPTR GCPtr, PGSTPTWALK pWalk);
    27 #endif
    28 PGM_GST_DECL(int,  GetPage)(PVMCPUCC pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys);
     26DECLINLINE(int) PGM_GST_NAME(Walk)(PVMCPUCC pVCpu, RTGCPTR GCPtr, PPGMPTWALK pWalk, PGSTPTWALK pGstWalk);
     27#endif
     28PGM_GST_DECL(int,  GetPage)(PVMCPUCC pVCpu, RTGCPTR GCPtr, PPGMPTWALK pWalk);
    2929PGM_GST_DECL(int,  ModifyPage)(PVMCPUCC pVCpu, RTGCPTR GCPtr, size_t cb, uint64_t fFlags, uint64_t fMask);
    3030
     
    7676
    7777
    78 DECLINLINE(int) PGM_GST_NAME(WalkReturnNotPresent)(PVMCPUCC pVCpu, PGSTPTWALK pWalk, int iLevel)
     78DECLINLINE(int) PGM_GST_NAME(WalkReturnNotPresent)(PVMCPUCC pVCpu, PPGMPTWALK pWalk, int iLevel)
    7979{
    8080    NOREF(iLevel); NOREF(pVCpu);
    81     pWalk->Core.fNotPresent     = true;
    82     pWalk->Core.uLevel          = (uint8_t)iLevel;
     81    pWalk->fNotPresent     = true;
     82    pWalk->uLevel          = (uint8_t)iLevel;
    8383    return VERR_PAGE_TABLE_NOT_PRESENT;
    8484}
    8585
    86 DECLINLINE(int) PGM_GST_NAME(WalkReturnBadPhysAddr)(PVMCPUCC pVCpu, PGSTPTWALK pWalk, int iLevel, int rc)
     86DECLINLINE(int) PGM_GST_NAME(WalkReturnBadPhysAddr)(PVMCPUCC pVCpu, PPGMPTWALK pWalk, int iLevel, int rc)
    8787{
    8888    AssertMsg(rc == VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS, ("%Rrc\n", rc)); NOREF(rc); NOREF(pVCpu);
    89     pWalk->Core.fBadPhysAddr    = true;
    90     pWalk->Core.uLevel          = (uint8_t)iLevel;
     89    pWalk->fBadPhysAddr    = true;
     90    pWalk->uLevel          = (uint8_t)iLevel;
    9191    return VERR_PAGE_TABLE_NOT_PRESENT;
    9292}
    9393
    94 DECLINLINE(int) PGM_GST_NAME(WalkReturnRsvdError)(PVMCPUCC pVCpu, PGSTPTWALK pWalk, int iLevel)
     94DECLINLINE(int) PGM_GST_NAME(WalkReturnRsvdError)(PVMCPUCC pVCpu, PPGMPTWALK pWalk, int iLevel)
    9595{
    9696    NOREF(pVCpu);
    97     pWalk->Core.fRsvdError      = true;
    98     pWalk->Core.uLevel          = (uint8_t)iLevel;
     97    pWalk->fRsvdError      = true;
     98    pWalk->uLevel          = (uint8_t)iLevel;
    9999    return VERR_PAGE_TABLE_NOT_PRESENT;
    100100}
     
    110110 * @param   pVCpu       The cross context virtual CPU structure of the calling EMT.
    111111 * @param   GCPtr       The guest virtual address to walk by.
    112  * @param   pWalk       Where to return the walk result. This is always set.
    113  */
    114 DECLINLINE(int) PGM_GST_NAME(Walk)(PVMCPUCC pVCpu, RTGCPTR GCPtr, PGSTPTWALK pWalk)
     112 * @param   pWalk       The common page walk information.
     113 * @param   pGstWalk    The guest mode specific page walk information.
     114 *
     115 * @warning Callers must initialize @a pWalk and @a pGstWalk before calling this
     116 *          function.
     117 */
     118DECLINLINE(int) PGM_GST_NAME(Walk)(PVMCPUCC pVCpu, RTGCPTR GCPtr, PPGMPTWALK pWalk, PGSTPTWALK pGstWalk)
    115119{
    116120    int rc;
    117121
    118122#ifdef VBOX_WITH_NESTED_HWVIRT_VMX_EPT
     123/** @def PGM_GST_SLAT_WALK
     124 * Macro to perform guest second-level address translation (EPT or Nested).
     125 *
     126 * @param   pVCpu           The cross context virtual CPU structure of the calling EMT.
     127 * @param   a_GCPtrNested   The nested-guest linear address that caused the
     128 *                          second-level translation.
     129 * @param   a_GCPhysNested  The nested-guest physical address to translate.
     130 * @param   a_GCPhysOut     Where to store the guest-physical address (result).
     131 */
    119132# define PGM_GST_SLAT_WALK(a_pVCpu, a_GCPtrNested, a_GCPhysNested, a_GCPhysOut, a_pWalk) \
    120133    do { \
    121134        if ((a_pVCpu)->pgm.s.enmGuestSlatMode != PGMSLAT_DIRECT) \
    122135        { \
    123             PGMPTWALKGST SlatWalk; \
    124             int const rcX = pgmGstSlatWalk(a_pVCpu, a_GCPhysNested, true /* fIsLinearAddrValid */, a_GCPtrNested, &SlatWalk); \
     136            PGMPTWALK    SlatWalk; \
     137            PGMPTWALKGST SlatGstWalk; \
     138            int const rcX = pgmGstSlatWalk(a_pVCpu, a_GCPhysNested, true /* fIsLinearAddrValid */, a_GCPtrNested, &SlatWalk, \
     139                                           &SlatGstWalk); \
    125140            if (RT_SUCCESS(rcX)) \
    126                 (a_GCPhysOut) = SlatWalk.u.Core.GCPhys; \
     141                (a_GCPhysOut) = SlatWalk.GCPhys; \
    127142            else \
    128143            { \
    129                 (a_pWalk)->Core = SlatWalk.u.Core; \
     144                *(a_pWalk) = SlatWalk; \
    130145                return rcX; \
    131146            } \
     
    135150
    136151    /*
    137      * Init the walking structure.
     152     * Init the walking structures.
    138153     */
    139154    RT_ZERO(*pWalk);
    140     pWalk->Core.GCPtr = GCPtr;
     155    RT_ZERO(*pGstWalk);
     156    pWalk->GCPtr = GCPtr;
    141157
    142158# if PGM_GST_TYPE == PGM_TYPE_32BIT \
     
    155171         * The PML4 table.
    156172         */
    157         rc = pgmGstGetLongModePML4PtrEx(pVCpu, &pWalk->pPml4);
     173        rc = pgmGstGetLongModePML4PtrEx(pVCpu, &pGstWalk->pPml4);
    158174        if (RT_SUCCESS(rc)) { /* probable */ }
    159175        else return PGM_GST_NAME(WalkReturnBadPhysAddr)(pVCpu, pWalk, 4, rc);
    160176
    161177        PX86PML4E pPml4e;
    162         pWalk->pPml4e  = pPml4e  = &pWalk->pPml4->a[(GCPtr >> X86_PML4_SHIFT) & X86_PML4_MASK];
     178        pGstWalk->pPml4e  = pPml4e  = &pGstWalk->pPml4->a[(GCPtr >> X86_PML4_SHIFT) & X86_PML4_MASK];
    163179        X86PML4E  Pml4e;
    164         pWalk->Pml4e.u = Pml4e.u = pPml4e->u;
     180        pGstWalk->Pml4e.u = Pml4e.u = pPml4e->u;
    165181
    166182        if (GST_IS_PGENTRY_PRESENT(pVCpu, Pml4e)) { /* probable */ }
     
    170186        else return PGM_GST_NAME(WalkReturnRsvdError)(pVCpu, pWalk, 4);
    171187
    172         pWalk->Core.fEffective = fEffective = Pml4e.u & (  X86_PML4E_P   | X86_PML4E_RW | X86_PML4E_US | X86_PML4E_PWT
    173                                                          | X86_PML4E_PCD | X86_PML4E_A  | X86_PML4E_NX);
     188        pWalk->fEffective = fEffective = Pml4e.u & (  X86_PML4E_P   | X86_PML4E_RW | X86_PML4E_US | X86_PML4E_PWT
     189                                                    | X86_PML4E_PCD | X86_PML4E_A  | X86_PML4E_NX);
    174190
    175191        /*
     
    180196        PGM_GST_SLAT_WALK(pVCpu, GCPtr, GCPhysPdpt, GCPhysPdpt, pWalk);
    181197#endif
    182         rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, GCPhysPdpt, &pWalk->pPdpt);
     198        rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, GCPhysPdpt, &pGstWalk->pPdpt);
    183199        if (RT_SUCCESS(rc)) { /* probable */ }
    184200        else return PGM_GST_NAME(WalkReturnBadPhysAddr)(pVCpu, pWalk, 3, rc);
    185201
    186202# elif PGM_GST_TYPE == PGM_TYPE_PAE
    187         rc = pgmGstGetPaePDPTPtrEx(pVCpu, &pWalk->pPdpt);
     203        rc = pgmGstGetPaePDPTPtrEx(pVCpu, &pGstWalk->pPdpt);
    188204        if (RT_SUCCESS(rc)) { /* probable */ }
    189205        else return PGM_GST_NAME(WalkReturnBadPhysAddr)(pVCpu, pWalk, 8, rc);
     
    193209# if PGM_GST_TYPE == PGM_TYPE_AMD64 || PGM_GST_TYPE == PGM_TYPE_PAE
    194210        PX86PDPE pPdpe;
    195         pWalk->pPdpe  = pPdpe  = &pWalk->pPdpt->a[(GCPtr >> GST_PDPT_SHIFT) & GST_PDPT_MASK];
     211        pGstWalk->pPdpe  = pPdpe  = &pGstWalk->pPdpt->a[(GCPtr >> GST_PDPT_SHIFT) & GST_PDPT_MASK];
    196212        X86PDPE  Pdpe;
    197         pWalk->Pdpe.u = Pdpe.u = pPdpe->u;
     213        pGstWalk->Pdpe.u = Pdpe.u = pPdpe->u;
    198214
    199215        if (GST_IS_PGENTRY_PRESENT(pVCpu, Pdpe)) { /* probable */ }
     
    204220
    205221# if PGM_GST_TYPE == PGM_TYPE_AMD64
    206         pWalk->Core.fEffective = fEffective &= (Pdpe.u & (  X86_PDPE_P   | X86_PDPE_RW  | X86_PDPE_US
    207                                                           | X86_PDPE_PWT | X86_PDPE_PCD | X86_PDPE_A))
    208                                              | (Pdpe.u & X86_PDPE_LM_NX);
     222        pWalk->fEffective = fEffective &= (Pdpe.u & (  X86_PDPE_P   | X86_PDPE_RW  | X86_PDPE_US
     223                                                     | X86_PDPE_PWT | X86_PDPE_PCD | X86_PDPE_A))
     224                                        | (Pdpe.u & X86_PDPE_LM_NX);
    209225# else
    210226        /* NX in the legacy-mode PAE PDPE is reserved. The valid check above ensures the NX bit is not set. */
    211         pWalk->Core.fEffective = fEffective  = X86_PDPE_P | X86_PDPE_RW  | X86_PDPE_US | X86_PDPE_A
    212                                              | (Pdpe.u & (X86_PDPE_PWT | X86_PDPE_PCD));
     227        pWalk->fEffective = fEffective  = X86_PDPE_P | X86_PDPE_RW  | X86_PDPE_US | X86_PDPE_A
     228                                        | (Pdpe.u & (X86_PDPE_PWT | X86_PDPE_PCD));
    213229# endif
    214230
     
    220236        PGM_GST_SLAT_WALK(pVCpu, GCPtr, GCPhysPd, GCPhysPd, pWalk);
    221237# endif
    222         rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, GCPhysPd, &pWalk->pPd);
     238        rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, GCPhysPd, &pGstWalk->pPd);
    223239        if (RT_SUCCESS(rc)) { /* probable */ }
    224240        else return PGM_GST_NAME(WalkReturnBadPhysAddr)(pVCpu, pWalk, 2, rc);
    225241
    226242# elif PGM_GST_TYPE == PGM_TYPE_32BIT
    227         rc = pgmGstGet32bitPDPtrEx(pVCpu, &pWalk->pPd);
     243        rc = pgmGstGet32bitPDPtrEx(pVCpu, &pGstWalk->pPd);
    228244        if (RT_SUCCESS(rc)) { /* probable */ }
    229245        else return PGM_GST_NAME(WalkReturnBadPhysAddr)(pVCpu, pWalk, 8, rc);
     
    232248    {
    233249        PGSTPDE pPde;
    234         pWalk->pPde  = pPde  = &pWalk->pPd->a[(GCPtr >> GST_PD_SHIFT) & GST_PD_MASK];
     250        pGstWalk->pPde  = pPde  = &pGstWalk->pPd->a[(GCPtr >> GST_PD_SHIFT) & GST_PD_MASK];
    235251        GSTPDE  Pde;
    236         pWalk->Pde.u = Pde.u = pPde->u;
     252        pGstWalk->Pde.u = Pde.u = pPde->u;
    237253        if (GST_IS_PGENTRY_PRESENT(pVCpu, Pde)) { /* probable */ }
    238254        else return PGM_GST_NAME(WalkReturnNotPresent)(pVCpu, pWalk, 2);
     
    253269            fEffective |= Pde.u & (X86_PDE4M_D | X86_PDE4M_G);
    254270            fEffective |= (Pde.u & X86_PDE4M_PAT) >> X86_PDE4M_PAT_SHIFT;
    255             pWalk->Core.fEffective = fEffective;
     271            pWalk->fEffective = fEffective;
    256272            Assert(GST_IS_NX_ACTIVE(pVCpu) || !(fEffective & PGM_PTATTRS_NX_MASK));
    257273            Assert(fEffective & PGM_PTATTRS_R_MASK);
    258274
    259             pWalk->Core.fBigPage   = true;
    260             pWalk->Core.fSucceeded = true;
     275            pWalk->fBigPage   = true;
     276            pWalk->fSucceeded = true;
    261277            RTGCPHYS GCPhysPde = GST_GET_BIG_PDE_GCPHYS(pVCpu->CTX_SUFF(pVM), Pde)
    262278                               | (GCPtr & GST_BIG_PAGE_OFFSET_MASK);
     
    264280            PGM_GST_SLAT_WALK(pVCpu, GCPtr, GCPhysPde, GCPhysPde, pWalk);
    265281# endif
    266             pWalk->Core.GCPhys     = GCPhysPde;
    267             PGM_A20_APPLY_TO_VAR(pVCpu, pWalk->Core.GCPhys);
     282            pWalk->GCPhys     = GCPhysPde;
     283            PGM_A20_APPLY_TO_VAR(pVCpu, pWalk->GCPhys);
    268284            return VINF_SUCCESS;
    269285        }
     
    272288            return PGM_GST_NAME(WalkReturnRsvdError)(pVCpu, pWalk, 2);
    273289# if PGM_GST_TYPE == PGM_TYPE_32BIT
    274         pWalk->Core.fEffective = fEffective  = Pde.u & (  X86_PDE_P   | X86_PDE_RW  | X86_PDE_US
    275                                                         | X86_PDE_PWT | X86_PDE_PCD | X86_PDE_A);
     290        pWalk->fEffective = fEffective  = Pde.u & (  X86_PDE_P   | X86_PDE_RW  | X86_PDE_US
     291                                                   | X86_PDE_PWT | X86_PDE_PCD | X86_PDE_A);
    276292# else
    277         pWalk->Core.fEffective = fEffective &= (Pde.u & (  X86_PDE_P   | X86_PDE_RW  | X86_PDE_US
    278                                                          | X86_PDE_PWT | X86_PDE_PCD | X86_PDE_A))
    279                                              | (Pde.u & X86_PDE_PAE_NX);
     293        pWalk->fEffective = fEffective &= (Pde.u & (  X86_PDE_P   | X86_PDE_RW  | X86_PDE_US
     294                                                    | X86_PDE_PWT | X86_PDE_PCD | X86_PDE_A))
     295                                        | (Pde.u & X86_PDE_PAE_NX);
    280296# endif
    281297
     
    287303        PGM_GST_SLAT_WALK(pVCpu, GCPtr, GCPhysPt, GCPhysPt, pWalk);
    288304# endif
    289         rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, GCPhysPt, &pWalk->pPt);
     305        rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, GCPhysPt, &pGstWalk->pPt);
    290306        if (RT_SUCCESS(rc)) { /* probable */ }
    291307        else return PGM_GST_NAME(WalkReturnBadPhysAddr)(pVCpu, pWalk, 1, rc);
     
    293309    {
    294310        PGSTPTE pPte;
    295         pWalk->pPte  = pPte  = &pWalk->pPt->a[(GCPtr >> GST_PT_SHIFT) & GST_PT_MASK];
     311        pGstWalk->pPte  = pPte  = &pGstWalk->pPt->a[(GCPtr >> GST_PT_SHIFT) & GST_PT_MASK];
    296312        GSTPTE  Pte;
    297         pWalk->Pte.u = Pte.u = pPte->u;
     313        pGstWalk->Pte.u = Pte.u = pPte->u;
    298314
    299315        if (GST_IS_PGENTRY_PRESENT(pVCpu, Pte)) { /* probable */ }
     
    313329# endif
    314330        fEffective |= Pte.u & (X86_PTE_D | X86_PTE_PAT | X86_PTE_G);
    315         pWalk->Core.fEffective = fEffective;
     331        pWalk->fEffective = fEffective;
    316332        Assert(GST_IS_NX_ACTIVE(pVCpu) || !(fEffective & PGM_PTATTRS_NX_MASK));
    317333        Assert(fEffective & PGM_PTATTRS_R_MASK);
    318334
    319         pWalk->Core.fSucceeded = true;
     335        pWalk->fSucceeded = true;
    320336        RTGCPHYS GCPhysPte = GST_GET_PTE_GCPHYS(Pte)
    321337                           | (GCPtr & PAGE_OFFSET_MASK);
     
    323339        PGM_GST_SLAT_WALK(pVCpu, GCPtr, GCPhysPte, GCPhysPte, pWalk);
    324340# endif
    325         pWalk->Core.GCPhys     = GCPhysPte;
     341        pWalk->GCPhys     = GCPhysPte;
    326342        return VINF_SUCCESS;
    327343    }
     
    341357 * @param   pVCpu       The cross context virtual CPU structure.
    342358 * @param   GCPtr       Guest Context virtual address of the page.
    343  * @param   pfFlags     Where to store the flags. These are X86_PTE_*, even for big pages.
    344  * @param   pGCPhys     Where to store the GC physical address of the page.
    345  *                      This is page aligned!
    346  */
    347 PGM_GST_DECL(int, GetPage)(PVMCPUCC pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys)
     359 * @param   pWalk       Where to store the page walk info.
     360 */
     361PGM_GST_DECL(int, GetPage)(PVMCPUCC pVCpu, RTGCPTR GCPtr, PPGMPTWALK pWalk)
    348362{
    349363#if PGM_GST_TYPE == PGM_TYPE_REAL \
     
    352366     * Fake it.
    353367     */
    354     if (pfFlags)
    355         *pfFlags = X86_PTE_P | X86_PTE_RW | X86_PTE_US;
    356     if (pGCPhys)
    357         *pGCPhys = GCPtr & PAGE_BASE_GC_MASK;
     368    RT_ZERO(*pWalk);
     369    pWalk->fSucceeded = true;
     370    pWalk->GCPtr      = GCPtr;
     371    pWalk->GCPhys     = GCPtr & PAGE_BASE_GC_MASK;
     372    pWalk->fEffective = X86_PTE_P | X86_PTE_RW | X86_PTE_US;
     373    pWalk->GCPhys     = GCPtr & PAGE_BASE_GC_MASK;
    358374    NOREF(pVCpu);
    359375    return VINF_SUCCESS;
     
    363379   || PGM_GST_TYPE == PGM_TYPE_AMD64
    364380
    365     GSTPTWALK Walk;
    366     int rc = PGM_GST_NAME(Walk)(pVCpu, GCPtr, &Walk);
     381    PGMPTWALK Walk;
     382    GSTPTWALK GstWalk;
     383    RT_ZERO(Walk);
     384    RT_ZERO(GstWalk);
     385    int rc = PGM_GST_NAME(Walk)(pVCpu, GCPtr, &Walk, &GstWalk);
    367386    if (RT_FAILURE(rc))
    368387        return rc;
    369388
    370     if (pGCPhys)
    371         *pGCPhys = Walk.Core.GCPhys & ~(RTGCPHYS)PAGE_OFFSET_MASK;
    372 
    373     if (pfFlags)
     389    uint64_t fFlags;
     390    if (!Walk.fBigPage)
     391        fFlags = (GstWalk.Pte.u & ~(GST_PTE_PG_MASK | X86_PTE_RW | X86_PTE_US))                      /* NX not needed */
     392               | (Walk.fEffective & (PGM_PTATTRS_W_MASK | PGM_PTATTRS_US_MASK))
     393# if PGM_WITH_NX(PGM_GST_TYPE, PGM_GST_TYPE)
     394               | (Walk.fEffective & PGM_PTATTRS_NX_MASK)
     395# endif
     396                 ;
     397    else
    374398    {
    375         if (!Walk.Core.fBigPage)
    376             *pfFlags = (Walk.Pte.u & ~(GST_PTE_PG_MASK | X86_PTE_RW | X86_PTE_US))                      /* NX not needed */
    377                      | (Walk.Core.fEffective & (  PGM_PTATTRS_W_MASK
    378                                                 | PGM_PTATTRS_US_MASK))
     399        fFlags = (GstWalk.Pde.u & ~(GST_PTE_PG_MASK | X86_PDE4M_RW | X86_PDE4M_US | X86_PDE4M_PS))   /* NX not needed */
     400               | (Walk.fEffective & (PGM_PTATTRS_W_MASK | PGM_PTATTRS_US_MASK | PGM_PTATTRS_PAT_MASK))
    379401# if PGM_WITH_NX(PGM_GST_TYPE, PGM_GST_TYPE)
    380                      | (Walk.Core.fEffective & PGM_PTATTRS_NX_MASK)
    381 # endif
    382                      ;
    383         else
    384         {
    385             *pfFlags = (Walk.Pde.u & ~(GST_PTE_PG_MASK | X86_PDE4M_RW | X86_PDE4M_US | X86_PDE4M_PS))   /* NX not needed */
    386                      | (Walk.Core.fEffective & (  PGM_PTATTRS_W_MASK
    387                                                 | PGM_PTATTRS_US_MASK
    388                                                 | PGM_PTATTRS_PAT_MASK))
    389 # if PGM_WITH_NX(PGM_GST_TYPE, PGM_GST_TYPE)
    390                      | (Walk.Core.fEffective & PGM_PTATTRS_NX_MASK)
    391 # endif
    392                      ;
    393         }
     402               | (Walk.fEffective & PGM_PTATTRS_NX_MASK)
     403# endif
     404               ;
    394405    }
    395406
     407    pWalk->fSucceeded = true;
     408    pWalk->GCPtr      = GCPtr;
     409    pWalk->GCPhys     = Walk.GCPhys & ~(RTGCPHYS)PAGE_OFFSET_MASK;
     410    pWalk->fEffective = fFlags;
    396411    return VINF_SUCCESS;
    397412
     
    425440    for (;;)
    426441    {
    427         GSTPTWALK Walk;
    428         int rc = PGM_GST_NAME(Walk)(pVCpu, GCPtr, &Walk);
     442        PGMPTWALK Walk;
     443        GSTPTWALK GstWalk;
     444        int rc = PGM_GST_NAME(Walk)(pVCpu, GCPtr, &Walk, &GstWalk);
    429445        if (RT_FAILURE(rc))
    430446            return rc;
    431447
    432         if (!Walk.Core.fBigPage)
     448        if (!Walk.fBigPage)
    433449        {
    434450            /*
     
    438454             */
    439455            unsigned iPTE = (GCPtr >> GST_PT_SHIFT) & GST_PT_MASK;
    440             while (iPTE < RT_ELEMENTS(Walk.pPt->a))
     456            while (iPTE < RT_ELEMENTS(GstWalk.pPt->a))
    441457            {
    442                 GSTPTE Pte = Walk.pPt->a[iPTE];
     458                GSTPTE Pte = GstWalk.pPt->a[iPTE];
    443459                Pte.u = (Pte.u & (fMask | X86_PTE_PAE_PG_MASK))
    444460                      | (fFlags & ~GST_PTE_PG_MASK);
    445                 Walk.pPt->a[iPTE] = Pte;
     461                GstWalk.pPt->a[iPTE] = Pte;
    446462
    447463                /* next page */
     
    460476            GSTPDE PdeNew;
    461477# if PGM_GST_TYPE == PGM_TYPE_32BIT
    462             PdeNew.u = (Walk.Pde.u & (fMask | ((fMask & X86_PTE_PAT) << X86_PDE4M_PAT_SHIFT) | GST_PDE_BIG_PG_MASK | X86_PDE4M_PG_HIGH_MASK | X86_PDE4M_PS))
     478            PdeNew.u = (GstWalk.Pde.u & (fMask | ((fMask & X86_PTE_PAT) << X86_PDE4M_PAT_SHIFT) | GST_PDE_BIG_PG_MASK | X86_PDE4M_PG_HIGH_MASK | X86_PDE4M_PS))
    463479# else
    464             PdeNew.u = (Walk.Pde.u & (fMask | ((fMask & X86_PTE_PAT) << X86_PDE4M_PAT_SHIFT) | GST_PDE_BIG_PG_MASK | X86_PDE4M_PS))
     480            PdeNew.u = (GstWalk.Pde.u & (fMask | ((fMask & X86_PTE_PAT) << X86_PDE4M_PAT_SHIFT) | GST_PDE_BIG_PG_MASK | X86_PDE4M_PS))
    465481# endif
    466482                     | (fFlags & ~GST_PTE_PG_MASK)
    467483                     | ((fFlags & X86_PTE_PAT) << X86_PDE4M_PAT_SHIFT);
    468             *Walk.pPde = PdeNew;
     484            *GstWalk.pPde = PdeNew;
    469485
    470486            /* advance */
  • trunk/src/VBox/VMM/VMMAll/PGMAllGstSlatEpt.cpp.h

    r92336 r92426  
    1717
    1818#if PGM_GST_TYPE == PGM_TYPE_EPT
    19 DECLINLINE(int) PGM_GST_SLAT_NAME_EPT(WalkReturnNotPresent)(PVMCPUCC pVCpu, PGSTPTWALK pWalk, int iLevel)
     19DECLINLINE(int) PGM_GST_SLAT_NAME_EPT(WalkReturnNotPresent)(PVMCPUCC pVCpu, PPGMPTWALK pWalk, int iLevel)
    2020{
    2121    NOREF(pVCpu);
    22     pWalk->Core.fNotPresent     = true;
    23     pWalk->Core.uLevel          = (uint8_t)iLevel;
     22    pWalk->fNotPresent     = true;
     23    pWalk->uLevel          = (uint8_t)iLevel;
    2424    return VERR_PAGE_TABLE_NOT_PRESENT;
    2525}
    2626
    2727
    28 DECLINLINE(int) PGM_GST_SLAT_NAME_EPT(WalkReturnBadPhysAddr)(PVMCPUCC pVCpu, PGSTPTWALK pWalk, int iLevel, int rc)
     28DECLINLINE(int) PGM_GST_SLAT_NAME_EPT(WalkReturnBadPhysAddr)(PVMCPUCC pVCpu, PPGMPTWALK pWalk, int iLevel, int rc)
    2929{
    3030    AssertMsg(rc == VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS, ("%Rrc\n", rc)); NOREF(rc); NOREF(pVCpu);
    31     pWalk->Core.fBadPhysAddr    = true;
    32     pWalk->Core.uLevel          = (uint8_t)iLevel;
     31    pWalk->fBadPhysAddr    = true;
     32    pWalk->uLevel          = (uint8_t)iLevel;
    3333    return VERR_PAGE_TABLE_NOT_PRESENT;
    3434}
    3535
    3636
    37 DECLINLINE(int) PGM_GST_SLAT_NAME_EPT(WalkReturnRsvdError)(PVMCPUCC pVCpu, PGSTPTWALK pWalk, int iLevel)
     37DECLINLINE(int) PGM_GST_SLAT_NAME_EPT(WalkReturnRsvdError)(PVMCPUCC pVCpu, PPGMPTWALK pWalk, int iLevel)
    3838{
    3939    NOREF(pVCpu);
    40     pWalk->Core.fRsvdError      = true;
    41     pWalk->Core.uLevel          = (uint8_t)iLevel;
     40    pWalk->fRsvdError      = true;
     41    pWalk->uLevel          = (uint8_t)iLevel;
    4242    return VERR_PAGE_TABLE_NOT_PRESENT;
    4343}
     
    4545
    4646DECLINLINE(int) PGM_GST_SLAT_NAME_EPT(Walk)(PVMCPUCC pVCpu, RTGCPHYS GCPhysNested, bool fIsLinearAddrValid, RTGCPTR GCPtrNested,
    47                                             PGSTPTWALK pWalk)
    48 {
     47                                            PPGMPTWALK pWalk, PGSTPTWALK pGstWalk)
     48{
     49    /** @todo implement figuring out fEptMisconfig. */
    4950    /*
    50      * Init walk structure.
     51     * Init walk structures.
    5152     */
    52     int rc;
    5353    RT_ZERO(*pWalk);
    54     pWalk->Core.GCPtr              = GCPtrNested;
    55     pWalk->Core.GCPhysNested       = GCPhysNested;
    56     pWalk->Core.fIsSlat            = true;
    57     pWalk->Core.fIsLinearAddrValid = fIsLinearAddrValid;
     54    RT_ZERO(*pGstWalk);
     55
     56    pWalk->GCPtr              = GCPtrNested;
     57    pWalk->GCPhysNested       = GCPhysNested;
     58    pWalk->fIsLinearAddrValid = fIsLinearAddrValid;
     59    pWalk->fIsSlat            = true;
    5860
    5961    /*
     
    8284    uint64_t fEffective;
    8385    {
    84         rc = pgmGstGetEptPML4PtrEx(pVCpu, &pWalk->pPml4);
     86        int rc = pgmGstGetEptPML4PtrEx(pVCpu, &pGstWalk->pPml4);
    8587        if (RT_SUCCESS(rc)) { /* probable */ }
    8688        else return PGM_GST_SLAT_NAME_EPT(WalkReturnBadPhysAddr)(pVCpu, pWalk, 4, rc);
    8789
    8890        PEPTPML4E pPml4e;
    89         pWalk->pPml4e = pPml4e = &pWalk->pPml4->a[(GCPhysNested >> EPT_PML4_SHIFT) & EPT_PML4_MASK];
     91        pGstWalk->pPml4e = pPml4e = &pGstWalk->pPml4->a[(GCPhysNested >> EPT_PML4_SHIFT) & EPT_PML4_MASK];
    9092        EPTPML4E  Pml4e;
    91         pWalk->Pml4e.u = Pml4e.u = pPml4e->u;
     93        pGstWalk->Pml4e.u = Pml4e.u = pPml4e->u;
    9294
    9395        if (GST_IS_PGENTRY_PRESENT(pVCpu, Pml4e)) { /* probable */ }
     
    107109                   | RT_BF_MAKE(PGM_PTATTRS_A, fAccessed)
    108110                   | fEffectiveEpt;
    109         pWalk->Core.fEffective = fEffective;
    110 
    111         rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, Pml4e.u & EPT_PML4E_PG_MASK, &pWalk->pPdpt);
     111        pWalk->fEffective = fEffective;
     112
     113        rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, Pml4e.u & EPT_PML4E_PG_MASK, &pGstWalk->pPdpt);
    112114        if (RT_SUCCESS(rc)) { /* probable */ }
    113115        else return PGM_GST_SLAT_NAME_EPT(WalkReturnBadPhysAddr)(pVCpu, pWalk, 3, rc);
     
    115117    {
    116118        PEPTPDPTE pPdpte;
    117         pWalk->pPdpte = pPdpte = &pWalk->pPdpt->a[(GCPhysNested >> GST_PDPT_SHIFT) & GST_PDPT_MASK];
     119        pGstWalk->pPdpte = pPdpte = &pGstWalk->pPdpt->a[(GCPhysNested >> GST_PDPT_SHIFT) & GST_PDPT_MASK];
    118120        EPTPDPTE  Pdpte;
    119         pWalk->Pdpte.u = Pdpte.u = pPdpte->u;
     121        pGstWalk->Pdpte.u = Pdpte.u = pPdpte->u;
    120122
    121123        if (GST_IS_PGENTRY_PRESENT(pVCpu, Pdpte)) { /* probable */ }
     
    134136                        | RT_BF_MAKE(PGM_PTATTRS_A, fAccessed)
    135137                        | (fEffectiveEpt & fCumulativeEpt);
    136             pWalk->Core.fEffective = fEffective;
     138            pWalk->fEffective = fEffective;
    137139        }
    138140        else if (GST_IS_BIG_PDPE_VALID(pVCpu, Pdpte))
     
    151153            fEffective |= RT_BF_MAKE(PGM_PTATTRS_D,           fDirty)
    152154                        | RT_BF_MAKE(PGM_PTATTRS_EPT_MEMTYPE, fMemType);
    153             pWalk->Core.fEffective = fEffective;
    154 
    155             pWalk->Core.fGigantPage  = true;
    156             pWalk->Core.fSucceeded   = true;
    157             pWalk->Core.GCPhys       = GST_GET_BIG_PDPE_GCPHYS(pVCpu->CTX_SUFF(pVM), Pdpte)
     155            pWalk->fEffective = fEffective;
     156
     157            pWalk->fGigantPage  = true;
     158            pWalk->fSucceeded   = true;
     159            pWalk->GCPhys       = GST_GET_BIG_PDPE_GCPHYS(pVCpu->CTX_SUFF(pVM), Pdpte)
    158160                                     | (GCPhysNested & GST_GIGANT_PAGE_OFFSET_MASK);
    159             PGM_A20_APPLY_TO_VAR(pVCpu, pWalk->Core.GCPhys);
     161            PGM_A20_APPLY_TO_VAR(pVCpu, pWalk->GCPhys);
    160162            return VINF_SUCCESS;
    161163        }
     
    164166    {
    165167        PGSTPDE pPde;
    166         pWalk->pPde  = pPde  = &pWalk->pPd->a[(GCPhysNested >> GST_PD_SHIFT) & GST_PD_MASK];
     168        pGstWalk->pPde  = pPde  = &pGstWalk->pPd->a[(GCPhysNested >> GST_PD_SHIFT) & GST_PD_MASK];
    167169        GSTPDE  Pde;
    168         pWalk->Pde.u = Pde.u = pPde->u;
     170        pGstWalk->Pde.u = Pde.u = pPde->u;
     171
    169172        if (GST_IS_PGENTRY_PRESENT(pVCpu, Pde)) { /* probable */ }
    170173        else return PGM_GST_SLAT_NAME_EPT(WalkReturnNotPresent)(pVCpu, pWalk, 2);
     174
    171175        if ((Pde.u & X86_PDE_PS) && GST_IS_PSE_ACTIVE(pVCpu))
    172176        {
     
    187191            fEffective |= RT_BF_MAKE(PGM_PTATTRS_D,           fDirty)
    188192                        | RT_BF_MAKE(PGM_PTATTRS_EPT_MEMTYPE, fMemType);
    189             pWalk->Core.fEffective = fEffective;
    190 
    191             pWalk->Core.fBigPage     = true;
    192             pWalk->Core.fSucceeded   = true;
    193             pWalk->Core.GCPhys       = GST_GET_BIG_PDE_GCPHYS(pVCpu->CTX_SUFF(pVM), Pde)
     193            pWalk->fEffective = fEffective;
     194
     195            pWalk->fBigPage     = true;
     196            pWalk->fSucceeded   = true;
     197            pWalk->GCPhys       = GST_GET_BIG_PDE_GCPHYS(pVCpu->CTX_SUFF(pVM), Pde)
    194198                                     | (GCPhysNested & GST_BIG_PAGE_OFFSET_MASK);
    195             PGM_A20_APPLY_TO_VAR(pVCpu, pWalk->Core.GCPhys);
     199            PGM_A20_APPLY_TO_VAR(pVCpu, pWalk->GCPhys);
    196200            return VINF_SUCCESS;
    197201        }
     
    209213                    | RT_BF_MAKE(PGM_PTATTRS_A, fAccessed)
    210214                    | (fEffectiveEpt & fCumulativeEpt);
    211         pWalk->Core.fEffective = fEffective;
    212 
    213         rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, GST_GET_PDE_GCPHYS(Pde), &pWalk->pPt);
     215        pWalk->fEffective = fEffective;
     216
     217        int const rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, GST_GET_PDE_GCPHYS(Pde), &pGstWalk->pPt);
    214218        if (RT_SUCCESS(rc)) { /* probable */ }
    215219        else return PGM_GST_SLAT_NAME_EPT(WalkReturnBadPhysAddr)(pVCpu, pWalk, 1, rc);
     
    217221    {
    218222        PGSTPTE pPte;
    219         pWalk->pPte  = pPte  = &pWalk->pPt->a[(GCPhysNested >> GST_PT_SHIFT) & GST_PT_MASK];
     223        pGstWalk->pPte  = pPte  = &pGstWalk->pPt->a[(GCPhysNested >> GST_PT_SHIFT) & GST_PT_MASK];
    220224        GSTPTE  Pte;
    221         pWalk->Pte.u = Pte.u = pPte->u;
     225        pGstWalk->Pte.u = Pte.u = pPte->u;
    222226
    223227        if (GST_IS_PGENTRY_PRESENT(pVCpu, Pte)) { /* probable */ }
     
    240244        fEffective |= RT_BF_MAKE(PGM_PTATTRS_D,           fDirty)
    241245                    | RT_BF_MAKE(PGM_PTATTRS_EPT_MEMTYPE, fMemType);
    242         pWalk->Core.fEffective = fEffective;
    243 
    244         pWalk->Core.fSucceeded   = true;
    245         pWalk->Core.GCPhys       = GST_GET_PTE_GCPHYS(Pte)
    246                                  | (GCPhysNested & PAGE_OFFSET_MASK);
     246        pWalk->fEffective = fEffective;
     247
     248        pWalk->fSucceeded   = true;
     249        pWalk->GCPhys       = GST_GET_PTE_GCPHYS(Pte) | (GCPhysNested & PAGE_OFFSET_MASK);
    247250        return VINF_SUCCESS;
    248251    }
  • trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp

    r92391 r92426  
    23082308VMMDECL(int) PGMPhysGCPtr2GCPhys(PVMCPUCC pVCpu, RTGCPTR GCPtr, PRTGCPHYS pGCPhys)
    23092309{
    2310     int rc = PGMGstGetPage(pVCpu, (RTGCUINTPTR)GCPtr, NULL, pGCPhys);
     2310    PGMPTWALK Walk;
     2311    int rc = PGMGstGetPage(pVCpu, (RTGCUINTPTR)GCPtr, &Walk);
    23112312    if (pGCPhys && RT_SUCCESS(rc))
    2312         *pGCPhys |= (RTGCUINTPTR)GCPtr & PAGE_OFFSET_MASK;
     2313        *pGCPhys = Walk.GCPhys | ((RTGCUINTPTR)GCPtr & PAGE_OFFSET_MASK);
    23132314    return rc;
    23142315}
     
    23272328VMM_INT_DECL(int) PGMPhysGCPtr2HCPhys(PVMCPUCC pVCpu, RTGCPTR GCPtr, PRTHCPHYS pHCPhys)
    23282329{
    2329     PVMCC pVM = pVCpu->CTX_SUFF(pVM);
    2330     RTGCPHYS GCPhys;
    2331     int rc = PGMGstGetPage(pVCpu, (RTGCUINTPTR)GCPtr, NULL, &GCPhys);
     2330    PVMCC     pVM = pVCpu->CTX_SUFF(pVM);
     2331    PGMPTWALK Walk;
     2332    int rc = PGMGstGetPage(pVCpu, (RTGCUINTPTR)GCPtr, &Walk);
    23322333    if (RT_SUCCESS(rc))
    2333         rc = PGMPhysGCPhys2HCPhys(pVM, GCPhys | ((RTGCUINTPTR)GCPtr & PAGE_OFFSET_MASK), pHCPhys);
     2334        rc = PGMPhysGCPhys2HCPhys(pVM, Walk.GCPhys | ((RTGCUINTPTR)GCPtr & PAGE_OFFSET_MASK), pHCPhys);
    23342335    return rc;
    23352336}
     
    34293430VMMDECL(VBOXSTRICTRC) PGMPhysReadGCPtr(PVMCPUCC pVCpu, void *pvDst, RTGCPTR GCPtrSrc, size_t cb, PGMACCESSORIGIN enmOrigin)
    34303431{
    3431     RTGCPHYS    GCPhys;
    3432     uint64_t    fFlags;
    34333432    int         rc;
    34343433    PVMCC       pVM = pVCpu->CTX_SUFF(pVM);
     
    34493448    {
    34503449        /* Convert virtual to physical address + flags */
    3451         rc = PGMGstGetPage(pVCpu, (RTGCUINTPTR)GCPtrSrc, &fFlags, &GCPhys);
     3450        PGMPTWALK Walk;
     3451        rc = PGMGstGetPage(pVCpu, (RTGCUINTPTR)GCPtrSrc, &Walk);
    34523452        AssertMsgRCReturn(rc, ("GetPage failed with %Rrc for %RGv\n", rc, GCPtrSrc), rc);
    3453         GCPhys |= (RTGCUINTPTR)GCPtrSrc & PAGE_OFFSET_MASK;
     3453        RTGCPHYS const GCPhys = Walk.GCPhys | ((RTGCUINTPTR)GCPtrSrc & PAGE_OFFSET_MASK);
    34543454
    34553455        /* mark the guest page as accessed. */
    3456         if (!(fFlags & X86_PTE_A))
     3456        if (!(Walk.fEffective & X86_PTE_A))
    34573457        {
    34583458            rc = PGMGstModifyPage(pVCpu, GCPtrSrc, 1, X86_PTE_A, ~(uint64_t)(X86_PTE_A));
     
    34693469    {
    34703470        /* Convert virtual to physical address + flags */
    3471         rc = PGMGstGetPage(pVCpu, (RTGCUINTPTR)GCPtrSrc, &fFlags, &GCPhys);
     3471        PGMPTWALK Walk;
     3472        rc = PGMGstGetPage(pVCpu, (RTGCUINTPTR)GCPtrSrc, &Walk);
    34723473        AssertMsgRCReturn(rc, ("GetPage failed with %Rrc for %RGv\n", rc, GCPtrSrc), rc);
    3473         GCPhys |= (RTGCUINTPTR)GCPtrSrc & PAGE_OFFSET_MASK;
     3474        RTGCPHYS const GCPhys = Walk.GCPhys | ((RTGCUINTPTR)GCPtrSrc & PAGE_OFFSET_MASK);
    34743475
    34753476        /* mark the guest page as accessed. */
    3476         if (!(fFlags & X86_PTE_A))
     3477        if (!(Walk.fEffective & X86_PTE_A))
    34773478        {
    34783479            rc = PGMGstModifyPage(pVCpu, GCPtrSrc, 1, X86_PTE_A, ~(uint64_t)(X86_PTE_A));
     
    35203521VMMDECL(VBOXSTRICTRC) PGMPhysWriteGCPtr(PVMCPUCC pVCpu, RTGCPTR GCPtrDst, const void *pvSrc, size_t cb, PGMACCESSORIGIN enmOrigin)
    35213522{
    3522     RTGCPHYS    GCPhys;
    3523     uint64_t    fFlags;
    35243523    int         rc;
    35253524    PVMCC       pVM = pVCpu->CTX_SUFF(pVM);
     
    35403539    {
    35413540        /* Convert virtual to physical address + flags */
    3542         rc = PGMGstGetPage(pVCpu, (RTGCUINTPTR)GCPtrDst, &fFlags, &GCPhys);
     3541        PGMPTWALK Walk;
     3542        rc = PGMGstGetPage(pVCpu, (RTGCUINTPTR)GCPtrDst, &Walk);
    35433543        AssertMsgRCReturn(rc, ("GetPage failed with %Rrc for %RGv\n", rc, GCPtrDst), rc);
    3544         GCPhys |= (RTGCUINTPTR)GCPtrDst & PAGE_OFFSET_MASK;
     3544        RTGCPHYS const GCPhys = Walk.GCPhys | ((RTGCUINTPTR)GCPtrDst & PAGE_OFFSET_MASK);
    35453545
    35463546        /* Mention when we ignore X86_PTE_RW... */
    3547         if (!(fFlags & X86_PTE_RW))
     3547        if (!(Walk.fEffective & X86_PTE_RW))
    35483548            Log(("PGMPhysWriteGCPtr: Writing to RO page %RGv %#x\n", GCPtrDst, cb));
    35493549
    35503550        /* Mark the guest page as accessed and dirty if necessary. */
    3551         if ((fFlags & (X86_PTE_A | X86_PTE_D)) != (X86_PTE_A | X86_PTE_D))
     3551        if ((Walk.fEffective & (X86_PTE_A | X86_PTE_D)) != (X86_PTE_A | X86_PTE_D))
    35523552        {
    35533553            rc = PGMGstModifyPage(pVCpu, GCPtrDst, 1, X86_PTE_A | X86_PTE_D, ~(uint64_t)(X86_PTE_A | X86_PTE_D));
     
    35643564    {
    35653565        /* Convert virtual to physical address + flags */
    3566         rc = PGMGstGetPage(pVCpu, (RTGCUINTPTR)GCPtrDst, &fFlags, &GCPhys);
     3566        PGMPTWALK Walk;
     3567        rc = PGMGstGetPage(pVCpu, (RTGCUINTPTR)GCPtrDst, &Walk);
    35673568        AssertMsgRCReturn(rc, ("GetPage failed with %Rrc for %RGv\n", rc, GCPtrDst), rc);
    3568         GCPhys |= (RTGCUINTPTR)GCPtrDst & PAGE_OFFSET_MASK;
     3569        RTGCPHYS const GCPhys = Walk.GCPhys | ((RTGCUINTPTR)GCPtrDst & PAGE_OFFSET_MASK);
    35693570
    35703571        /* Mention when we ignore X86_PTE_RW... */
    3571         if (!(fFlags & X86_PTE_RW))
     3572        if (!(Walk.fEffective & X86_PTE_RW))
    35723573            Log(("PGMPhysWriteGCPtr: Writing to RO page %RGv %#x\n", GCPtrDst, cb));
    35733574
    35743575        /* Mark the guest page as accessed and dirty if necessary. */
    3575         if ((fFlags & (X86_PTE_A | X86_PTE_D)) != (X86_PTE_A | X86_PTE_D))
     3576        if ((Walk.fEffective & (X86_PTE_A | X86_PTE_D)) != (X86_PTE_A | X86_PTE_D))
    35763577        {
    35773578            rc = PGMGstModifyPage(pVCpu, GCPtrDst, 1, X86_PTE_A | X86_PTE_D, ~(uint64_t)(X86_PTE_A | X86_PTE_D));
  • trunk/src/VBox/VMM/VMMAll/PGMAllShw.h

    r91854 r92426  
    569569                     *        set instead of resolving the guest physical
    570570                     *        address yet again. */
    571                     RTGCPHYS GCPhys;
    572                     uint64_t fGstPte;
    573                     rc = PGMGstGetPage(pVCpu, GCPtr, &fGstPte, &GCPhys);
     571                    PGMPTWALK GstWalk;
     572                    rc = PGMGstGetPage(pVCpu, GCPtr, &GstWalk);
    574573                    AssertRC(rc);
    575574                    if (RT_SUCCESS(rc))
    576575                    {
    577                         Assert((fGstPte & X86_PTE_RW) || !(CPUMGetGuestCR0(pVCpu) & X86_CR0_WP /* allow netware hack */));
    578                         PPGMPAGE pPage = pgmPhysGetPage(pVM, GCPhys);
     576                        Assert((GstWalk.fEffective & X86_PTE_RW) || !(CPUMGetGuestCR0(pVCpu) & X86_CR0_WP /* allow netware hack */));
     577                        PPGMPAGE pPage = pgmPhysGetPage(pVM, GstWalk.GCPhys);
    579578                        Assert(pPage);
    580579                        if (pPage)
    581580                        {
    582                             rc = pgmPhysPageMakeWritable(pVM, pPage, GCPhys);
     581                            rc = pgmPhysPageMakeWritable(pVM, pPage, GstWalk.GCPhys);
    583582                            AssertRCReturn(rc, rc);
    584                             Log(("%s: pgmPhysPageMakeWritable on %RGv / %RGp %R[pgmpage]\n", __PRETTY_FUNCTION__, GCPtr, GCPhys, pPage));
     583                            Log(("%s: pgmPhysPageMakeWritable on %RGv / %RGp %R[pgmpage]\n", __PRETTY_FUNCTION__, GCPtr, GstWalk.GCPhys, pPage));
    585584                        }
    586585                    }
  • trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp

    r92392 r92426  
    71937193
    71947194        /* Check if the page at the fault-address is the APIC base. */
    7195         RTGCPHYS GCPhysPage;
    7196         int rc2 = PGMGstGetPage(pVCpu, (RTGCPTR)uFaultAddress, NULL /* pfFlags */, &GCPhysPage);
     7195        PGMPTWALK Walk;
     7196        int rc2 = PGMGstGetPage(pVCpu, (RTGCPTR)uFaultAddress, &Walk);
    71977197        if (   rc2 == VINF_SUCCESS
    7198             && GCPhysPage == GCPhysApicBase)
     7198            && Walk.GCPhys == GCPhysApicBase)
    71997199        {
    72007200            /* Only attempt to patch the instruction once. */
  • trunk/src/VBox/VMM/VMMR0/PGMR0SharedPage.cpp

    r86473 r92426  
    7474        {
    7575            /** @todo inefficient to fetch each guest page like this... */
    76             RTGCPHYS GCPhys;
    77             uint64_t fFlags;
    78             rc = PGMGstGetPage(pVCpu, GCPtrPage, &fFlags, &GCPhys);
     76            PGMPTWALK Walk;
     77            rc = PGMGstGetPage(pVCpu, GCPtrPage, &Walk);
    7978            if (    rc == VINF_SUCCESS
    80                 &&  !(fFlags & X86_PTE_RW)) /* important as we make assumptions about this below! */
     79                &&  !(Walk.fEffective & X86_PTE_RW)) /* important as we make assumptions about this below! */
    8180            {
    82                 PPGMPAGE pPage = pgmPhysGetPage(pVM, GCPhys);
     81                PPGMPAGE pPage = pgmPhysGetPage(pVM, Walk.GCPhys);
    8382                Assert(!pPage || !PGM_PAGE_IS_BALLOONED(pPage));
    8483                if (    pPage
     
    8988                    PageDesc.idPage = PGM_PAGE_GET_PAGEID(pPage);
    9089                    PageDesc.HCPhys = PGM_PAGE_GET_HCPHYS(pPage);
    91                     PageDesc.GCPhys = GCPhys;
     90                    PageDesc.GCPhys = Walk.GCPhys;
    9291
    9392                    rc = GMMR0SharedModuleCheckPage(pGVM, pModule, idxRegion, idxPage, &PageDesc);
  • trunk/src/VBox/VMM/VMMR3/DBGFAddr.cpp

    r90784 r92426  
    231231    VMCPU_ASSERT_EMT(pVCpu);
    232232    /* This is just a wrapper because we cannot pass FlatPtr thru VMR3ReqCall directly. */
    233     return PGMGstGetPage(pVCpu, pAddress->FlatPtr, NULL, pGCPhys);
     233    PGMPTWALK Walk;
     234    int const rc = PGMGstGetPage(pVCpu, pAddress->FlatPtr, &Walk);
     235    *pGCPhys = Walk.GCPhys;
     236    return rc;
    234237}
    235238
  • trunk/src/VBox/VMM/VMMR3/PGMDbg.cpp

    r91904 r92426  
    869869    RTGCPHYS        GCPhysPrev              = NIL_RTGCPHYS;
    870870    bool            fFullWalk               = true;
    871     PGMPTWALKGST    Walk;
    872     RT_ZERO(Walk);
     871    PGMPTWALK       Walk;
     872    PGMPTWALKGST    WalkGst;
    873873
    874874    PGM_LOCK_VOID(pVM);
     
    877877        int rc;
    878878        if (fFullWalk)
    879             rc = pgmGstPtWalk(pVCpu, GCPtr, &Walk);
     879            rc = pgmGstPtWalk(pVCpu, GCPtr, &Walk, &WalkGst);
    880880        else
    881             rc = pgmGstPtWalkNext(pVCpu, GCPtr, &Walk);
    882         if (RT_SUCCESS(rc) && Walk.u.Core.fSucceeded)
     881            rc = pgmGstPtWalkNext(pVCpu, GCPtr, &Walk, &WalkGst);
     882        if (RT_SUCCESS(rc) && Walk.fSucceeded)
    883883        {
    884884            fFullWalk = false;
    885885
    886886            /* Skip if same page as previous one (W10 optimization). */
    887             if (   Walk.u.Core.GCPhys != GCPhysPrev
     887            if (   Walk.GCPhys != GCPhysPrev
    888888                || cbPrev != 0)
    889889            {
    890                 PPGMPAGE pPage = pgmPhysGetPage(pVM, Walk.u.Core.GCPhys);
     890                PPGMPAGE pPage = pgmPhysGetPage(pVM, Walk.GCPhys);
    891891                if (   pPage
    892892                    && (   !PGM_PAGE_IS_ZERO(pPage)
     
    895895                    && !PGM_PAGE_IS_BALLOONED(pPage))
    896896                {
    897                     GCPhysPrev = Walk.u.Core.GCPhys;
     897                    GCPhysPrev = Walk.GCPhys;
    898898                    void const *pvPage;
    899899                    PGMPAGEMAPLOCK Lock;
    900                     rc = PGMPhysGCPhys2CCPtrReadOnly(pVM, Walk.u.Core.GCPhys, &pvPage, &Lock);
     900                    rc = PGMPhysGCPhys2CCPtrReadOnly(pVM, Walk.GCPhys, &pvPage, &Lock);
    901901                    if (RT_SUCCESS(rc))
    902902                    {
     
    933933        else
    934934        {
    935             Assert(Walk.enmType != PGMPTWALKGSTTYPE_INVALID);
    936             Assert(!Walk.u.Core.fSucceeded);
     935            Assert(WalkGst.enmType != PGMPTWALKGSTTYPE_INVALID);
     936            Assert(!Walk.fSucceeded);
    937937            cbPrev = 0; /* ignore error. */
    938938
     
    942942             */
    943943            uint64_t cPagesCanSkip;
    944             switch (Walk.u.Core.uLevel)
     944            switch (Walk.uLevel)
    945945            {
    946946                case 1:
     
    949949                    break;
    950950                case 2:
    951                     if (Walk.enmType == PGMPTWALKGSTTYPE_32BIT)
     951                    if (WalkGst.enmType == PGMPTWALKGSTTYPE_32BIT)
    952952                    {
    953953                        cPagesCanSkip = X86_PG_ENTRIES     - ((GCPtr >> X86_PT_SHIFT)     & X86_PT_MASK);
     
    977977                    break;
    978978                default:
    979                     AssertMsgFailed(("%d\n", Walk.u.Core.uLevel));
     979                    AssertMsgFailed(("%d\n", Walk.uLevel));
    980980                    cPagesCanSkip = 0;
    981981                    break;
  • trunk/src/VBox/VMM/VMMR3/PGMSharedPage.cpp

    r90439 r92426  
    288288{
    289289    /* Debug only API for the page fusion testcase. */
    290     RTGCPHYS GCPhys;
    291     uint64_t fFlags;
     290    PGMPTWALK Walk;
    292291
    293292    PGM_LOCK_VOID(pVM);
    294293
    295     int rc = PGMGstGetPage(VMMGetCpu(pVM), GCPtrPage, &fFlags, &GCPhys);
     294    int rc = PGMGstGetPage(VMMGetCpu(pVM), GCPtrPage, &Walk);
    296295    switch (rc)
    297296    {
    298297        case VINF_SUCCESS:
    299298        {
    300             PPGMPAGE pPage = pgmPhysGetPage(pVM, GCPhys);
     299            PPGMPAGE pPage = pgmPhysGetPage(pVM, Walk.GCPhys);
    301300            if (pPage)
    302301            {
    303302                *pfShared    = PGM_PAGE_IS_SHARED(pPage);
    304                 *pfPageFlags = fFlags;
     303                *pfPageFlags = Walk.fEffective;
    305304            }
    306305            else
  • trunk/src/VBox/VMM/include/PGMInternal.h

    r92420 r92426  
    3737#include <VBox/vmm/gmm.h>
    3838#include <VBox/vmm/hm.h>
    39 #include <VBox/vmm/hm_vmx.h>
    4039#include <iprt/asm.h>
    4140#include <iprt/assert.h>
     
    23312330
    23322331
    2333 /** @name PGMPTATTRS
    2334  *
    2335  * PGM page-table attributes.
    2336  *
    2337  * This is VirtualBox's combined page table attributes. It combines regular page
    2338  * table and Intel EPT attributes. It's 64-bit in size so there's ample room for
    2339  * bits added in the future to EPT or regular page tables (for e.g. Protection Key).
    2340  *
    2341  * The following bits map 1:1 (shifted by PGM_PTATTRS_EPT_SHIFT) to the Intel EPT
    2342  * attributes as these are unique to EPT and fit within 64-bits despite the shift:
    2343  *   - EPT_R         : Read access.
    2344  *   - EPT_W         : Write access.
    2345  *   - EPT_X_SUPER   : Execute or execute for supervisor-mode linear addr access.
    2346  *   - EPT_MEMTYPE   : EPT memory type.
    2347  *   - EPT_IGNORE_PAT: Ignore PAT memory type.
    2348  *   - EPT_X_USER    : Execute access for user-mode linear addresses.
    2349  *
    2350  * For regular page tables, the R bit is always 1 (same as P bit).
    2351  * For Intel EPT, the EPT_R and EPT_W bits are copied to R and W bits respectively.
    2352  *
    2353  * The following EPT attributes are mapped to the following positions because they
    2354  * exist in the regular page tables at these positions OR are exclusive to EPT and
    2355  * have been mapped to arbitrarily chosen positions:
    2356  *   - EPT_A               : Accessed                (EPT bit  8 maps to bit  5).
    2357  *   - EPT_D               : Dirty                   (EPT bit  9 maps to bit  6).
    2358  *   - EPT_SUPER_SHW_STACK : Supervisor Shadow Stack (EPT bit 60 maps to bit 24).
    2359  *   - EPT_SUPPRESS_VE_XCPT: Suppress \#VE exception (EPT bit 63 maps to bit 25).
    2360  *
    2361  * Bits 12, 11:9 and 43 are deliberately kept unused (correspond to bit PS and bits
    2362  * 11:9 in the regular page-table structures and to bit 11 in the EPT structures
    2363  * respectively) as bit 12 is the page-size bit and bits 11:9 are reserved for
    2364  * use by software and we may want to use/preserve them in the future.
    2365  *
    2366  * @{ */
    2367 typedef uint64_t PGMPTATTRS;
    2368 /** Pointer to a PGMPTATTRS type. */
    2369 typedef PGMPTATTRS *PPGMPTATTRS;
    2370 
    2371 /** Read bit (always 1 for regular PT, copy of EPT_R for EPT). */
    2372 #define PGM_PTATTRS_R_SHIFT                         0
    2373 #define PGM_PTATTRS_R_MASK                          RT_BIT_64(PGM_PTATTRS_R_SHIFT)
    2374 /** Write access bit (aka read/write bit for regular PT). */
    2375 #define PGM_PTATTRS_W_SHIFT                         1
    2376 #define PGM_PTATTRS_W_MASK                          RT_BIT_64(PGM_PTATTRS_W_SHIFT)
    2377 /** User-mode access bit. */
    2378 #define PGM_PTATTRS_US_SHIFT                        2
    2379 #define PGM_PTATTRS_US_MASK                         RT_BIT_64(PGM_PTATTRS_US_SHIFT)
    2380 /** Write through cache bit. */
    2381 #define PGM_PTATTRS_PWT_SHIFT                       3
    2382 #define PGM_PTATTRS_PWT_MASK                        RT_BIT_64(PGM_PTATTRS_PWT_SHIFT)
    2383 /** Cache disabled bit. */
    2384 #define PGM_PTATTRS_PCD_SHIFT                       4
    2385 #define PGM_PTATTRS_PCD_MASK                        RT_BIT_64(PGM_PTATTRS_PCD_SHIFT)
    2386 /** Accessed bit. */
    2387 #define PGM_PTATTRS_A_SHIFT                         5
    2388 #define PGM_PTATTRS_A_MASK                          RT_BIT_64(PGM_PTATTRS_A_SHIFT)
    2389 /** Dirty bit. */
    2390 #define PGM_PTATTRS_D_SHIFT                         6
    2391 #define PGM_PTATTRS_D_MASK                          RT_BIT_64(PGM_PTATTRS_D_SHIFT)
    2392 /** The PAT bit. */
    2393 #define PGM_PTATTRS_PAT_SHIFT                       7
    2394 #define PGM_PTATTRS_PAT_MASK                        RT_BIT_64(PGM_PTATTRS_PAT_SHIFT)
    2395 /** The global bit. */
    2396 #define PGM_PTATTRS_G_SHIFT                         8
    2397 #define PGM_PTATTRS_G_MASK                          RT_BIT_64(PGM_PTATTRS_G_SHIFT)
    2398 /** Reserved (bits 12:9) unused. */
    2399 #define PGM_PTATTRS_RSVD_12_9_SHIFT                 9
    2400 #define PGM_PTATTRS_RSVD_12_9_MASK                  UINT64_C(0x0000000000001e00)
    2401 /** Read access bit - EPT only. */
    2402 #define PGM_PTATTRS_EPT_R_SHIFT                     13
    2403 #define PGM_PTATTRS_EPT_R_MASK                      RT_BIT_64(PGM_PTATTRS_EPT_R_SHIFT)
    2404 /** Write access bit - EPT only. */
    2405 #define PGM_PTATTRS_EPT_W_SHIFT                     14
    2406 #define PGM_PTATTRS_EPT_W_MASK                      RT_BIT_64(PGM_PTATTRS_EPT_W_SHIFT)
    2407 /** Execute or execute access for supervisor-mode linear addresses - EPT only. */
    2408 #define PGM_PTATTRS_EPT_X_SUPER_SHIFT               15
    2409 #define PGM_PTATTRS_EPT_X_SUPER_MASK                RT_BIT_64(PGM_PTATTRS_EPT_X_SUPER_SHIFT)
    2410 /** EPT memory type - EPT only. */
    2411 #define PGM_PTATTRS_EPT_MEMTYPE_SHIFT               16
    2412 #define PGM_PTATTRS_EPT_MEMTYPE_MASK                UINT64_C(0x0000000000070000)
    2413 /** Ignore PAT memory type - EPT only. */
    2414 #define PGM_PTATTRS_EPT_IGNORE_PAT_SHIFT            19
    2415 #define PGM_PTATTRS_EPT_IGNORE_PAT_MASK             RT_BIT_64(PGM_PTATTRS_EPT_IGNORE_PAT_SHIFT)
    2416 /** Reserved (bits 22:20) unused. */
    2417 #define PGM_PTATTRS_RSVD_22_20_SHIFT                20
    2418 #define PGM_PTATTRS_RSVD_22_20_MASK                 UINT64_C(0x0000000000700000)
    2419 /** Execute access for user-mode linear addresses - EPT only. */
    2420 #define PGM_PTATTRS_EPT_X_USER_SHIFT                23
    2421 #define PGM_PTATTRS_EPT_X_USER_MASK                 RT_BIT_64(PGM_PTATTRS_EPT_X_USER_SHIFT)
    2422 /** Reserved (bit 23) - unused. */
    2423 #define PGM_PTATTRS_RSVD_23_SHIFT                   24
    2424 #define PGM_PTATTRS_RSVD_23_MASK                    UINT64_C(0x0000000001000000)
    2425 /** Supervisor shadow stack - EPT only. */
    2426 #define PGM_PTATTRS_EPT_SUPER_SHW_STACK_SHIFT       25
    2427 #define PGM_PTATTRS_EPT_SUPER_SHW_STACK_MASK        RT_BIT_64(PGM_PTATTRS_EPT_SUPER_SHW_STACK_SHIFT)
    2428 /** Suppress \#VE exception - EPT only. */
    2429 #define PGM_PTATTRS_EPT_SUPPRESS_VE_XCPT_SHIFT      26
    2430 #define PGM_PTATTRS_EPT_SUPPRESS_VE_XCPT_MASK       RT_BIT_64(PGM_PTATTRS_EPT_SUPPRESS_VE_XCPT_SHIFT)
    2431 /** Reserved (bits 62:27) - unused. */
    2432 #define PGM_PTATTRS_RSVD_62_27_SHIFT                27
    2433 #define PGM_PTATTRS_RSVD_62_27_MASK                 UINT64_C(0x7ffffffff8000000)
    2434 /** No-execute bit. */
    2435 #define PGM_PTATTRS_NX_SHIFT                        63
    2436 #define PGM_PTATTRS_NX_MASK                         RT_BIT_64(PGM_PTATTRS_NX_SHIFT)
    2437 
    2438 RT_BF_ASSERT_COMPILE_CHECKS(PGM_PTATTRS_, UINT64_C(0), UINT64_MAX,
    2439                             (R, W, US, PWT, PCD, A, D, PAT, G, RSVD_12_9, EPT_R, EPT_W, EPT_X_SUPER, EPT_MEMTYPE, EPT_IGNORE_PAT,
    2440                              RSVD_22_20, EPT_X_USER, RSVD_23, EPT_SUPER_SHW_STACK, EPT_SUPPRESS_VE_XCPT, RSVD_62_27, NX));
    2441 
    2442 /** The bit position where the EPT specific attributes begin. */
    2443 #define PGM_PTATTRS_EPT_SHIFT                       PGM_PTATTRS_EPT_R_SHIFT
    2444 /** The mask of EPT bits (bits 26:ATTR_SHIFT). In the future we might choose to
    2445  *  use higher unused bits for something else, in that case adjust this mask. */
    2446 #define PGM_PTATTRS_EPT_MASK                        UINT64_C(0x0000000007ffe000)
    2447 
    2448 /** The mask of all PGM page attribute bits for regular page-tables. */
    2449 #define PGM_PTATTRS_PT_VALID_MASK                   (  PGM_PTATTRS_R_MASK \
    2450                                                      | PGM_PTATTRS_W_MASK \
    2451                                                      | PGM_PTATTRS_US_MASK \
    2452                                                      | PGM_PTATTRS_PWT_MASK \
    2453                                                      | PGM_PTATTRS_PCD_MASK \
    2454                                                      | PGM_PTATTRS_A_MASK \
    2455                                                      | PGM_PTATTRS_D_MASK \
    2456                                                      | PGM_PTATTRS_PAT_MASK \
    2457                                                      | PGM_PTATTRS_G_MASK \
    2458                                                      | PGM_PTATTRS_NX_MASK)
    2459 
    2460 /** The mask of all PGM page attribute bits for EPT. */
    2461 #define PGM_PTATTRS_EPT_VALID_MASK                  (  PGM_PTATTRS_R_MASK \
    2462                                                      | PGM_PTATTRS_W_MASK \
    2463                                                      | PGM_PTATTRS_A_MASK \
    2464                                                      | PGM_PTATTRS_D_MASK \
    2465                                                      | PGM_PTATTRS_EPT_R_MASK \
    2466                                                      | PGM_PTATTRS_EPT_W_MASK \
    2467                                                      | PGM_PTATTRS_EPT_X_SUPER \
    2468                                                      | PGM_PTATTRS_EPT_MEMTYPE \
    2469                                                      | PGM_PTATTRS_EPT_IGNORE_PAT \
    2470                                                      | PGM_PTATTRS_EPT_X_USER \
    2471                                                      | PGM_PTATTRS_EPT_SUPER_SHW_STACK \
    2472                                                      | PGM_PTATTRS_EPT_SUPPRESS_VE_XCPT)
    2473 
    2474 /* The mask of all PGM page attribute bits (combined). */
    2475 #define PGM_PTATTRS_VALID_MASK                      (PGM_PTATTRS_PT_VALID_MASK | PGM_PTATTRS_PT_VALID_MASK)
    2476 
    2477 /* Verify bits match the regular PT bits. */
    2478 AssertCompile(PGM_PTATTRS_W_SHIFT   == X86_PTE_BIT_RW);
    2479 AssertCompile(PGM_PTATTRS_US_SHIFT  == X86_PTE_BIT_US);
    2480 AssertCompile(PGM_PTATTRS_PWT_SHIFT == X86_PTE_BIT_PWT);
    2481 AssertCompile(PGM_PTATTRS_PCD_SHIFT == X86_PTE_BIT_PCD);
    2482 AssertCompile(PGM_PTATTRS_A_SHIFT   == X86_PTE_BIT_A);
    2483 AssertCompile(PGM_PTATTRS_D_SHIFT   == X86_PTE_BIT_D);
    2484 AssertCompile(PGM_PTATTRS_PAT_SHIFT == X86_PTE_BIT_PAT);
    2485 AssertCompile(PGM_PTATTRS_G_SHIFT   == X86_PTE_BIT_G);
    2486 AssertCompile(PGM_PTATTRS_W_MASK    == X86_PTE_RW);
    2487 AssertCompile(PGM_PTATTRS_US_MASK   == X86_PTE_US);
    2488 AssertCompile(PGM_PTATTRS_PWT_MASK  == X86_PTE_PWT);
    2489 AssertCompile(PGM_PTATTRS_PCD_MASK  == X86_PTE_PCD);
    2490 AssertCompile(PGM_PTATTRS_A_MASK    == X86_PTE_A);
    2491 AssertCompile(PGM_PTATTRS_D_MASK    == X86_PTE_D);
    2492 AssertCompile(PGM_PTATTRS_PAT_MASK  == X86_PTE_PAT);
    2493 AssertCompile(PGM_PTATTRS_G_MASK    == X86_PTE_G);
    2494 
    2495 /* Verify those EPT bits that must map 1:1 (after shifting). */
    2496 AssertCompile(PGM_PTATTRS_EPT_R_SHIFT          - PGM_PTATTRS_EPT_SHIFT == EPT_E_BIT_READ);
    2497 AssertCompile(PGM_PTATTRS_EPT_W_SHIFT          - PGM_PTATTRS_EPT_SHIFT == EPT_E_BIT_WRITE);
    2498 AssertCompile(PGM_PTATTRS_EPT_X_SUPER_SHIFT    - PGM_PTATTRS_EPT_SHIFT == EPT_E_BIT_EXECUTE);
    2499 AssertCompile(PGM_PTATTRS_EPT_IGNORE_PAT_SHIFT - PGM_PTATTRS_EPT_SHIFT == EPT_E_BIT_IGNORE_PAT);
    2500 AssertCompile(PGM_PTATTRS_EPT_X_USER_SHIFT     - PGM_PTATTRS_EPT_SHIFT == EPT_E_BIT_USER_EXECUTE);
    2501 /** @} */
    2502 
    2503 
    2504 /**
    2505  * Page fault guest state for the AMD64 paging mode.
    2506  */
    2507 typedef struct PGMPTWALKCORE
    2508 {
    2509     /** The guest virtual address that is being resolved by the walk
    2510      *  (input). */
    2511     RTGCPTR         GCPtr;
    2512 
    2513     /** The nested-guest physical address that is being resolved if this is a
    2514      *  second-level walk (input).
    2515      *  @remarks only valid if fIsSlat is set. */
    2516     RTGCPHYS        GCPhysNested;
    2517 
    2518     /** The guest physical address that is the result of the walk.
    2519      * @remarks only valid if fSucceeded is set. */
    2520     RTGCPHYS        GCPhys;
    2521 
    2522     /** Set if the walk succeeded, i.d. GCPhys is valid. */
    2523     bool            fSucceeded;
    2524     /** Whether this is a second-level translation. */
    2525     bool            fIsSlat;
    2526     /** Whether the linear address (GCPtr) is valid and thus the cause for the
    2527      *  second-level translation. */
    2528     bool            fIsLinearAddrValid;
    2529     /** The level problem arrised at.
    2530      * PTE is level 1, PDE is level 2, PDPE is level 3, PML4 is level 4, CR3 is
    2531      * level 8.  This is 0 on success. */
    2532     uint8_t         uLevel;
    2533     /** Set if the page isn't present. */
    2534     bool            fNotPresent;
    2535     /** Encountered a bad physical address. */
    2536     bool            fBadPhysAddr;
    2537     /** Set if there was reserved bit violations. */
    2538     bool            fRsvdError;
    2539     /** Set if it involves a big page (2/4 MB). */
    2540     bool            fBigPage;
    2541     /** Set if it involves a gigantic page (1 GB). */
    2542     bool            fGigantPage;
    2543     bool            afPadding[7];
    2544     /** The effective attributes, PGM_PTATTRS_XXX. */
    2545     PGMPTATTRS      fEffective;
    2546 } PGMPTWALKCORE;
    2547 
    25482332/**
    25492333 * Guest page table walk for the AMD64 mode.
     
    25512335typedef struct PGMPTWALKGSTAMD64
    25522336{
    2553     /** The common core. */
    2554     PGMPTWALKCORE   Core;
    2555 
    25562337    PX86PML4        pPml4;
    25572338    PX86PML4E       pPml4e;
     
    25802361typedef struct PGMPTWALKGSTEPT
    25812362{
    2582     /** The common core. */
    2583     PGMPTWALKCORE   Core;
    2584 
    25852363    PEPTPML4        pPml4;
    25862364    PEPTPML4E       pPml4e;
     
    26092387typedef struct PGMPTWALKGSTPAE
    26102388{
    2611     /** The common core. */
    2612     PGMPTWALKCORE   Core;
    2613 
    26142389    PX86PDPT        pPdpt;
    26152390    PX86PDPE        pPdpe;
     
    26342409typedef struct PGMPTWALKGST32BIT
    26352410{
    2636     /** The common core. */
    2637     PGMPTWALKCORE   Core;
    2638 
    26392411    PX86PD          pPd;
    26402412    PX86PDE         pPde;
     
    26762448    union
    26772449    {
    2678         /** The page walker core - always valid. */
    2679         PGMPTWALKCORE       Core;
    26802450        /** The page walker for AMD64. */
    26812451        PGMPTWALKGSTAMD64   Amd64;
     
    28662636    /** The guest mode type. */
    28672637    uint32_t                        uType;
    2868     DECLCALLBACKMEMBER(int, pfnGetPage,(PVMCPUCC pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys));
     2638    DECLCALLBACKMEMBER(int, pfnGetPage,(PVMCPUCC pVCpu, RTGCPTR GCPtr, PPGMPTWALK pWalk));
    28692639    DECLCALLBACKMEMBER(int, pfnModifyPage,(PVMCPUCC pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
    28702640    DECLCALLBACKMEMBER(int, pfnEnter,(PVMCPUCC pVCpu, RTGCPHYS GCPhysCR3));
     
    39153685int             pgmGstLazyMapEptPml4(PVMCPUCC pVCpu, PEPTPML4 *ppPml4);
    39163686#endif
    3917 int             pgmGstPtWalk(PVMCPUCC pVCpu, RTGCPTR GCPtr, PPGMPTWALKGST pWalk);
    3918 int             pgmGstPtWalkNext(PVMCPUCC pVCpu, RTGCPTR GCPtr, PPGMPTWALKGST pWalk);
     3687int             pgmGstPtWalk(PVMCPUCC pVCpu, RTGCPTR GCPtr, PPGMPTWALK pWalk, PPGMPTWALKGST pGstWalk);
     3688int             pgmGstPtWalkNext(PVMCPUCC pVCpu, RTGCPTR GCPtr, PPGMPTWALK pWalk, PPGMPTWALKGST pGstWalk);
    39193689
    39203690# if defined(VBOX_STRICT) && HC_ARCH_BITS == 64 && defined(IN_RING3)
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