Author: ion Date: Tue Jul 31 07:11:52 2012 New Revision: 57000
URL: http://svn.reactos.org/svn/reactos?rev=57000&view=rev Log: [NTOSKRNL]: Additional support for session space. A few more ASSERTs and paranoia. [NTOSKRNL]: Don't assume all prototype PTEs are cached, in fact none are in ReactOS at the moment! This resulted in the wrong hardware caching bits for the PEB/TEB and NLS Data which are using ARM3 section code. [NTOSKRNL]: Also implement dirty page bit for prototype PTEs.
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c... ============================================================================== --- trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] Tue Jul 31 07:11:52 2012 @@ -23,7 +23,7 @@ #endif
LONG MmSystemLockPagesCount; - + /* PRIVATE FUNCTIONS **********************************************************/
PMMPTE @@ -305,8 +305,18 @@ /* Check if we need a zero page */ NeedZero = (OldIrql != MM_NOIRQL);
- /* Get the next system page color */ - Color = MI_GET_NEXT_COLOR(); +#if 0 + /* Session-backed image views must be zeroed */ + if ((Process == HYDRA_PROCESS) && + ((MI_IS_SESSION_IMAGE_ADDRESS(Address)) || + ((Address >= (PVOID)MiSessionViewStart) && + (Address < (PVOID)MiSessionSpaceWs)))) + { + NeedZero = TRUE; + } +#endif + /* Hardcode unknown color */ + Color = 0xFFFFFFFF; }
/* Check if the PFN database should be acquired */ @@ -332,31 +342,31 @@ if (!Process) MI_SET_PROCESS2("Kernel Demand 0");
/* Do we need a zero page? */ - if ((NeedZero) && (Process)) + if (Color != 0xFFFFFFFF) { /* Try to get one, if we couldn't grab a free page and zero it */ PageFrameNumber = MiRemoveZeroPageSafe(Color); - if (PageFrameNumber) - { - /* We got a genuine zero page, stop worrying about it */ - NeedZero = FALSE; - } - else + if (!PageFrameNumber) { /* We'll need a free page and zero it manually */ PageFrameNumber = MiRemoveAnyPage(Color); - } - } - else if (!NeedZero) - { - /* Process or system doesn't want a zero page, grab anything */ - PageFrameNumber = MiRemoveAnyPage(Color); + NeedZero = TRUE; + } } else { - /* System wants a zero page, obtain one */ - PageFrameNumber = MiRemoveZeroPage(Color); - NeedZero = FALSE; + /* Get a color, and see if we should grab a zero or non-zero page */ + Color = MI_GET_NEXT_COLOR(); + if (!NeedZero) + { + /* Process or system doesn't want a zero page, grab anything */ + PageFrameNumber = MiRemoveAnyPage(Color); + } + else + { + /* System wants a zero page, obtain one */ + PageFrameNumber = MiRemoveZeroPage(Color); + } }
/* Initialize it */ @@ -434,6 +444,7 @@ ULONG_PTR Protection; PFN_NUMBER PageFrameIndex; PMMPFN Pfn1, Pfn2; + BOOLEAN OriginalProtection, DirtyPage;
/* Must be called with an valid prototype PTE, with the PFN lock held */ ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); @@ -458,13 +469,40 @@ { /* Get the protection from the PTE, there's no real Proto PTE data */ Protection = PointerPte->u.Soft.Protection; + + /* Remember that we did not use the proto protection */ + OriginalProtection = FALSE; } else { /* Get the protection from the original PTE link */ OriginalPte = &Pfn1->OriginalPte; Protection = OriginalPte->u.Soft.Protection; - } + + /* Remember that we used the original protection */ + OriginalProtection = TRUE; + + /* Check if this was a write on a read only proto */ + if ((StoreInstruction) && !(Protection & MM_READWRITE)) + { + /* Clear the flag */ + StoreInstruction = 0; + } + } + + /* Check if this was a write on a non-COW page */ + DirtyPage = FALSE; + if ((StoreInstruction) && ((Protection & MM_WRITECOPY) != MM_WRITECOPY)) + { + /* Then the page should be marked dirty */ + DirtyPage = TRUE; + + /* ReactOS check */ + ASSERT(Pfn1->OriginalPte.u.Soft.Prototype != 0); + } + + /* Not yet handled by ReactOS */ + ASSERT(LockedPfn == NULL);
/* Release the PFN lock */ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); @@ -472,6 +510,20 @@ /* Remove caching bits */ Protection &= ~(MM_NOCACHE | MM_NOACCESS);
+ /* Setup caching */ + if (Pfn1->u3.e1.CacheAttribute == MiWriteCombined) + { + /* Write combining, no caching */ + MI_PAGE_DISABLE_CACHE(&TempPte); + MI_PAGE_WRITE_COMBINED(&TempPte); + } + else if (Pfn1->u3.e1.CacheAttribute == MiNonCached) + { + /* Write through, no caching */ + MI_PAGE_DISABLE_CACHE(&TempPte); + MI_PAGE_WRITE_THROUGH(&TempPte); + } + /* Check if this is a kernel or user address */ if (Address < MmSystemRangeStart) { @@ -484,10 +536,17 @@ MI_MAKE_HARDWARE_PTE(&TempPte, PointerPte, Protection, PageFrameIndex); }
+ /* Set the dirty flag if needed */ + if (DirtyPage) TempPte.u.Hard.Dirty = TRUE; + /* Write the PTE */ MI_WRITE_VALID_PTE(PointerPte, TempPte);
+ /* Reset the protection if needed */ + if (OriginalProtection) Protection = MM_ZERO_ACCESS; + /* Return success */ + ASSERT(PointerPte == MiAddressToPte(Address)); return STATUS_SUCCESS; }
@@ -823,31 +882,31 @@ /* Has the PTE been made valid yet? */ if (!SuperProtoPte->u.Hard.Valid) { - UNIMPLEMENTED; - while (TRUE); - } - else - { - /* Resolve the fault -- this will release the PFN lock */ - ASSERT(PointerPte->u.Hard.Valid == 0); - Status = MiResolveProtoPteFault(StoreInstruction, - Address, - PointerPte, - PointerProtoPte, - NULL, - NULL, - NULL, - Process, - LockIrql, - TrapInformation); - ASSERT(Status == STATUS_SUCCESS); - - /* Complete this as a transition fault */ - ASSERT(OldIrql == KeGetCurrentIrql()); - ASSERT(OldIrql <= APC_LEVEL); - ASSERT(KeAreAllApcsDisabled() == TRUE); - return Status; - } + ASSERT(FALSE); + } + else if (PointerPte->u.Hard.Valid == 1) + { + ASSERT(FALSE); + } + + /* Resolve the fault -- this will release the PFN lock */ + Status = MiResolveProtoPteFault(StoreInstruction, + Address, + PointerPte, + PointerProtoPte, + NULL, + NULL, + NULL, + Process, + LockIrql, + TrapInformation); + ASSERT(Status == STATUS_SUCCESS); + + /* Complete this as a transition fault */ + ASSERT(OldIrql == KeGetCurrentIrql()); + ASSERT(OldIrql <= APC_LEVEL); + ASSERT(KeAreAllApcsDisabled() == TRUE); + return Status; } else {