Author: ion Date: Fri Aug 24 06:08:20 2012 New Revision: 57148
URL: http://svn.reactos.org/svn/reactos?rev=57148&view=rev Log: [NTOSKRNL]: Fix broken way we were creating prototype PTEs, which was only supporting 256MB worth of prototype PTE area instead of 1GB. [NTOSKRNL]: Add support (macros) for subsection PTEs.
Modified: trunk/reactos/ntoskrnl/mm/ARM3/miarm.h trunk/reactos/ntoskrnl/mm/ARM3/mminit.c trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/miarm.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/miarm.h?re... ============================================================================== --- trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] Fri Aug 24 06:08:20 2012 @@ -266,7 +266,19 @@ // #define MiProtoPteToPte(x) \ (PMMPTE)((ULONG_PTR)MmPagedPoolStart + \ - (((x)->u.Proto.ProtoAddressHigh << 7) | (x)->u.Proto.ProtoAddressLow)) + (((x)->u.Proto.ProtoAddressHigh << 9) | (x)->u.Proto.ProtoAddressLow << 2)) + +// +// Decodes a Prototype PTE into the underlying PTE +// +#define MiSubsectionPteToSubsection(x) \ + ((x)->u.Subsect.WhichPool == PagedPool) ? \ + (PMMPTE)((ULONG_PTR)MmSubsectionBase + \ + (((x)->u.Subsect.SubsectionAddressHigh << 7) | \ + (x)->u.Subsect.SubsectionAddressLow << 3)) : \ + (PMMPTE)((ULONG_PTR)MmNonPagedPoolEnd - \ + (((x)->u.Subsect.SubsectionAddressHigh << 7) | \ + (x)->u.Subsect.SubsectionAddressLow << 3)) #endif
// @@ -631,7 +643,6 @@ extern PVOID MmSystemCacheEnd; extern MMSUPPORT MmSystemCacheWs; extern SIZE_T MmAllocatedNonPagedPool; -extern ULONG_PTR MmSubsectionBase; extern ULONG MmSpecialPoolTag; extern PVOID MmHyperSpaceEnd; extern PMMWSL MmSystemCacheWorkingSetList; @@ -694,6 +705,7 @@ extern KGUARDED_MUTEX MmSectionBasedMutex; extern PVOID MmHighSectionBase; extern SIZE_T MmSystemLockPagesCount; +extern ULONG_PTR MmSubsectionBase;
BOOLEAN FORCEINLINE @@ -875,15 +887,58 @@
/* * Prototype PTEs are only valid in paged pool by design, this little trick - * lets us only use 28 bits for the adress of the PTE + * lets us only use 30 bits for the adress of the PTE, as long as the area + * stays 1024MB At most. */ Offset = (ULONG_PTR)PointerPte - (ULONG_PTR)MmPagedPoolStart;
- /* 7 bits go in the "low", and the other 21 bits go in the "high" */ - NewPte->u.Proto.ProtoAddressLow = Offset & 0x7F; - NewPte->u.Proto.ProtoAddressHigh = (Offset & 0xFFFFFF80) >> 7; - ASSERT(MiProtoPteToPte(NewPte) == PointerPte); -} + /* + * 7 bits go in the "low" (but we assume the bottom 2 are zero) + * and the other 21 bits go in the "high" + */ + NewPte->u.Proto.ProtoAddressLow = (Offset & 0x1FC) >> 2; + NewPte->u.Proto.ProtoAddressHigh = (Offset & 0x3FFFFE00) >> 9; +} + +// +// Builds a Subsection PTE for the address of the Segment +// +FORCEINLINE +VOID +MI_MAKE_SUBSECTION_PTE(IN PMMPTE NewPte, + IN PVOID Segment) +{ + ULONG_PTR Offset; + + /* Mark this as a prototype */ + NewPte->u.Long = 0; + NewPte->u.Subsect.Prototype = 1; + + /* + * Segments are only valid either in nonpaged pool. We store the 20 bit + * difference either from the top or bottom of nonpaged pool, giving a + * maximum of 128MB to each delta, meaning nonpaged pool cannot exceed + * 256MB. + */ + if ((ULONG_PTR)Segment < ((ULONG_PTR)MmSubsectionBase + (128 * _1MB))) + { + Offset = (ULONG_PTR)Segment - (ULONG_PTR)MmSubsectionBase; + NewPte->u.Subsect.WhichPool = PagedPool; + } + else + { + Offset = (ULONG_PTR)MmNonPagedPoolEnd - (ULONG_PTR)Segment; + NewPte->u.Subsect.WhichPool = NonPagedPool; + } + + /* + * 4 bits go in the "low" (but we assume the bottom 3 are zero) + * and the other 20 bits go in the "high" + */ + NewPte->u.Subsect.SubsectionAddressLow = (Offset & 0x78) >> 3; + NewPte->u.Subsect.SubsectionAddressHigh = (Offset & 0xFFFFF80) >> 7; +} + #endif
//
Modified: trunk/reactos/ntoskrnl/mm/ARM3/mminit.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/mminit.c?r... ============================================================================== --- trunk/reactos/ntoskrnl/mm/ARM3/mminit.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/ARM3/mminit.c [iso-8859-1] Fri Aug 24 06:08:20 2012 @@ -2004,6 +2004,11 @@ PVOID Bitmap; PPHYSICAL_MEMORY_RUN Run; PFN_NUMBER PageCount; +#if DBG + ULONG j; + PMMPTE PointerPte, TestPte; + MMPTE TempPte; +#endif
/* Dump memory descriptors */ if (MiDbgEnableMdDump) MiDbgDumpMemoryDescriptors(); @@ -2063,9 +2068,43 @@
/* Initialize session space address layout */ MiInitializeSessionSpaceLayout(); - + /* Set the based section highest address */ MmHighSectionBase = (PVOID)((ULONG_PTR)MmHighestUserAddress - 0x800000); + +#if DBG + /* The subection PTE format depends on things being 8-byte aligned */ + ASSERT((sizeof(CONTROL_AREA) % 8) == 0); + ASSERT((sizeof(SUBSECTION) % 8) == 0); + + /* Prototype PTEs are assumed to be in paged pool, so check if the math works */ + PointerPte = (PMMPTE)MmPagedPoolStart; + MI_MAKE_PROTOTYPE_PTE(&TempPte, PointerPte); + TestPte = MiProtoPteToPte(&TempPte); + ASSERT(PointerPte == TestPte); + + /* Try the last nonpaged pool address */ + PointerPte = (PMMPTE)MI_NONPAGED_POOL_END; + MI_MAKE_PROTOTYPE_PTE(&TempPte, PointerPte); + TestPte = MiProtoPteToPte(&TempPte); + ASSERT(PointerPte == TestPte); + + /* Try a bunch of random addresses near the end of the address space */ + PointerPte = (PMMPTE)0xFFFC8000; + for (j = 0; j < 20; j += 1) + { + MI_MAKE_PROTOTYPE_PTE(&TempPte, PointerPte); + TestPte = MiProtoPteToPte(&TempPte); + ASSERT(PointerPte == TestPte); + PointerPte++; + } + + /* Subsection PTEs are always in nonpaged pool, pick a random address to try */ + PointerPte = (PMMPTE)0xFFAACBB8; + MI_MAKE_SUBSECTION_PTE(&TempPte, PointerPte); + TestPte = MiSubsectionPteToSubsection(&TempPte); + ASSERT(PointerPte == TestPte); +#endif
/* Loop all 8 standby lists */ for (i = 0; i < 8; i++)
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] Fri Aug 24 06:08:20 2012 @@ -1742,18 +1742,15 @@ { /* Get the protection code and check if this is a proto PTE */ ProtectionCode = TempPte.u.Soft.Protection; - DPRINT1("Code: %lx\n", ProtectionCode); if (TempPte.u.Soft.Prototype) { /* Do we need to go find the real PTE? */ - DPRINT1("Soft: %lx\n", TempPte.u.Soft.PageFileHigh); if (TempPte.u.Soft.PageFileHigh == MI_PTE_LOOKUP_NEEDED) { /* Get the prototype pte and VAD for it */ ProtoPte = MiCheckVirtualAddress(Address, &ProtectionCode, &Vad); - DPRINT1("Address: %p ProtoP %p Code: %lx Vad: %p\n", Address, ProtoPte, ProtectionCode, Vad); if (!ProtoPte) { ASSERT(KeGetCurrentIrql() <= APC_LEVEL);