VirtualBox

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


Ignore:
Timestamp:
Apr 30, 2013 12:14:47 AM (12 years ago)
Author:
vboxsync
Message:

PGM: Extended the WP0+RO+US hack to include big pages and adjusted some assertions to handle the hack.

Location:
trunk/src/VBox/VMM
Files:
3 edited

Legend:

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

    r45808 r45826  
    926926 * @param   pVCpu       Pointer to the VMCPU.
    927927 * @param   GCPtr       Virtual address of the first page in the range.
     928 * @param   fBigPage    Whether or not this is a big page. If it is, we have to
     929 *                      change the shadow PDE as well.  If it isn't, the caller
     930 *                      has checked that the shadow PDE doesn't need changing.
     931 *                      We ASSUME 4KB pages backing the big page here!
    928932 * @param   fOpFlags    A combination of the PGM_MK_PG_XXX flags.
    929933 */
    930 int pgmShwMakePageSupervisorAndWritable(PVMCPU pVCpu, RTGCPTR GCPtr, uint32_t fOpFlags)
    931 {
    932     return pdmShwModifyPage(pVCpu, GCPtr, X86_PTE_RW, ~(uint64_t)X86_PTE_US, fOpFlags);
     934int pgmShwMakePageSupervisorAndWritable(PVMCPU pVCpu, RTGCPTR GCPtr, bool fBigPage, uint32_t fOpFlags)
     935{
     936    int rc = pdmShwModifyPage(pVCpu, GCPtr, X86_PTE_RW, ~(uint64_t)X86_PTE_US, fOpFlags);
     937    if (rc == VINF_SUCCESS && fBigPage)
     938    {
     939        /* this is a bit ugly... */
     940        switch (pVCpu->pgm.s.enmShadowMode)
     941        {
     942            case PGMMODE_32_BIT:
     943            {
     944                PX86PDE pPde = pgmShwGet32BitPDEPtr(pVCpu, GCPtr);
     945                AssertReturn(pPde, VERR_INTERNAL_ERROR_3);
     946                Log(("pgmShwMakePageSupervisorAndWritable: PDE=%#llx", pPde->u));
     947                pPde->n.u1Write = 1;
     948                Log(("-> PDE=%#llx (32)\n", pPde->u));
     949                break;
     950            }
     951            case PGMMODE_PAE:
     952            case PGMMODE_PAE_NX:
     953            {
     954                PX86PDEPAE pPde = pgmShwGetPaePDEPtr(pVCpu, GCPtr);
     955                AssertReturn(pPde, VERR_INTERNAL_ERROR_3);
     956                Log(("pgmShwMakePageSupervisorAndWritable: PDE=%#llx", pPde->u));
     957                pPde->n.u1Write = 1;
     958                Log(("-> PDE=%#llx (PAE)\n", pPde->u));
     959                break;
     960            }
     961            default:
     962                AssertFailedReturn(VERR_INTERNAL_ERROR_4);
     963        }
     964    }
     965    return rc;
    933966}
    934967
  • trunk/src/VBox/VMM/VMMAll/PGMAllBth.h

    r45798 r45826  
    10001000                 * bit changes to 1 (see PGMCr0WpEnabled()).
    10011001                 */
     1002#    if (PGM_GST_TYPE == PGM_TYPE_32BIT || PGM_GST_TYPE == PGM_TYPE_PAE) && 1
    10021003                if (   GstWalk.Core.fEffectiveUS
    1003                     && !GstWalk.Core.fBigPage
     1004                    && !GstWalk.Core.fEffectiveRW
     1005                    && (GstWalk.Core.fBigPage || GstWalk.Pde.n.u1Write)
    10041006                    && pVM->cCpus == 1 /* Sorry, no go on SMP. Add CFGM option? */)
    10051007                {
    1006                     /* Temorarily change the page to a RW super visor page. We'll trap
    1007                        and switch it back when user mode tries to read from it again.
    1008                        (See further down.) */
    1009                     Log(("PGM #PF: Netware WP0+RO+US hack: pvFault=%RGp uErr=%#x\n", pvFault, uErr));
    1010                     rc = pgmShwMakePageSupervisorAndWritable(pVCpu, pvFault, PGM_MK_PG_IS_WRITE_FAULT);
     1008                    Log(("PGM #PF: Netware WP0+RO+US hack: pvFault=%RGp uErr=%#x (big=%d)\n", pvFault, uErr, GstWalk.Core.fBigPage));
     1009                    rc = pgmShwMakePageSupervisorAndWritable(pVCpu, pvFault, GstWalk.Core.fBigPage, PGM_MK_PG_IS_WRITE_FAULT);
    10111010                    if (rc == VINF_SUCCESS || rc == VINF_PGM_SYNC_CR3)
    10121011                    {
     
    10191018                    Log(("pgmShwMakePageSupervisorAndWritable(%RGv) failed with rc=%Rrc - ignored\n", pvFault, rc));
    10201019                }
     1020#    endif
    10211021
    10221022                /* Interpret the access. */
    10231023                rc = VBOXSTRICTRC_TODO(PGMInterpretInstruction(pVM, pVCpu, pRegFrame, pvFault));
    1024                 Log(("PGM #PF: WP0 emulation (pvFault=%RGp uErr=%#x)\n", pvFault, uErr));
     1024                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.fEffectiveUS));
    10251025                if (RT_SUCCESS(rc))
    10261026                    STAM_COUNTER_INC(&pVCpu->pgm.s.CTX_SUFF(pStats)->StatRZTrap0eWPEmulInRZ);
     
    10651065                {
    10661066                    rc = PGMGstGetPage(pVCpu, pvFault, &fPageGst, &GCPhys2);
    1067                     AssertMsg(RT_SUCCESS(rc) && (fPageGst & X86_PTE_RW), ("rc=%Rrc fPageGst=%RX64\n", rc, fPageGst));
     1067                    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));
    10681068                    LogFlow(("Obsolete physical monitor page out of sync %RGv - phys %RGp flags=%08llx\n", pvFault, GCPhys2, (uint64_t)fPageGst));
    10691069                }
     
    10821082         * mode accesses the page again.
    10831083         */
    1084         else if (    !GstWalk.Core.fEffectiveRW
    1085                  &&  GstWalk.Core.fEffectiveUS
    1086                  &&  GstWalk.Core.fBigPage
     1084        else if (    GstWalk.Core.fEffectiveUS
     1085                 && !GstWalk.Core.fEffectiveRW
     1086                 && (GstWalk.Core.fBigPage || GstWalk.Pde.n.u1Write)
    10871087                 &&  pVCpu->pgm.s.cNetwareWp0Hacks > 0
    10881088                 &&  (CPUMGetGuestCR0(pVCpu) & (X86_CR0_WP | X86_CR0_PG)) == X86_CR0_PG
     
    11241124                 * Note: we have AVL, A, D bits desynced.
    11251125                 */
    1126                 AssertMsg(   (fPageShw & ~(X86_PTE_A | X86_PTE_D | X86_PTE_AVL_MASK))
    1127                           == (fPageGst & ~(X86_PTE_A | X86_PTE_D | X86_PTE_AVL_MASK)),
     1126                AssertMsg(      (fPageShw & ~(X86_PTE_A | X86_PTE_D | X86_PTE_AVL_MASK))
     1127                             == (fPageGst & ~(X86_PTE_A | X86_PTE_D | X86_PTE_AVL_MASK))
     1128                          || (   pVCpu->pgm.s.cNetwareWp0Hacks > 0
     1129                              &&    (fPageShw & ~(X86_PTE_A | X86_PTE_D | X86_PTE_AVL_MASK | X86_PTE_RW | X86_PTE_US))
     1130                                 == (fPageGst & ~(X86_PTE_A | X86_PTE_D | X86_PTE_AVL_MASK | X86_PTE_RW | X86_PTE_US))
     1131                              && (fPageShw & (X86_PTE_RW | X86_PTE_US)) == X86_PTE_RW
     1132                              && (fPageGst & (X86_PTE_RW | X86_PTE_US)) == X86_PTE_US),
    11281133                          ("Page flags mismatch! pvFault=%RGv uErr=%x GCPhys=%RGp fPageShw=%RX64 fPageGst=%RX64\n",
    11291134                           pvFault, (uint32_t)uErr, GCPhys, fPageShw, fPageGst));
     
    13221327    {
    13231328        Assert(     PdeSrc.n.u1User == PdeDst.n.u1User
    1324                &&   (PdeSrc.n.u1Write || !PdeDst.n.u1Write));
     1329               &&   (PdeSrc.n.u1Write || !PdeDst.n.u1Write || pVCpu->pgm.s.cNetwareWp0Hacks > 0));
    13251330# ifndef PGM_WITHOUT_MAPPING
    13261331        if (PdeDst.u & PGM_PDFLAGS_MAPPING)
  • trunk/src/VBox/VMM/include/PGMInternal.h

    r45808 r45826  
    40274027int             pgmMapDeactivateCR3(PVM pVM, PPGMPOOLPAGE pShwPageCR3);
    40284028
    4029 int             pgmShwMakePageSupervisorAndWritable(PVMCPU pVCpu, RTGCPTR GCPtr, uint32_t fOpFlags);
     4029int             pgmShwMakePageSupervisorAndWritable(PVMCPU pVCpu, RTGCPTR GCPtr, bool fBigPage, uint32_t fOpFlags);
    40304030int             pgmShwSyncPaePDPtr(PVMCPU pVCpu, RTGCPTR GCPtr, X86PGPAEUINT uGstPdpe, PX86PDPAE *ppPD);
    40314031int             pgmShwSyncNestedPageLocked(PVMCPU pVCpu, RTGCPHYS GCPhysFault, uint32_t cPages, PGMMODE enmShwPagingMode);
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