From 11453cf565af07ba3d11f8d7994f117dcf1f880a Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Wed, 12 May 2010 20:48:15 +0000 Subject: [PATCH] [NTOS]: Add assertions to the paged pool and demand zero page faults, to catch possible errors and corruptions. These paths are not yet taken in today's builds, so they do not affect any runtime code. [NTOS]: Add assertions regarding the portability of certain code, which will need changes on ARM/x64. These should probably be C_ASSERT's but I don't want to break Timo's build. [NTOS]: Define MM_NOIRQL (found in assertions) instead of magical -1. [NTOS]: Add MI_IS_SESSION_PTE macro. [NTOS]: Export the MiXxxPte variables. [NTOS]: Fix some typos in comments. svn path=/trunk/; revision=47183 --- reactos/ntoskrnl/mm/ARM3/miarm.h | 36 +++++++++++++++++++++++------ reactos/ntoskrnl/mm/ARM3/pagfault.c | 22 +++++++++++++++++- reactos/ntoskrnl/mm/ARM3/pool.c | 8 ++++--- 3 files changed, 55 insertions(+), 11 deletions(-) diff --git a/reactos/ntoskrnl/mm/ARM3/miarm.h b/reactos/ntoskrnl/mm/ARM3/miarm.h index a6e87fe7b8b..6a84e4af354 100644 --- a/reactos/ntoskrnl/mm/ARM3/miarm.h +++ b/reactos/ntoskrnl/mm/ARM3/miarm.h @@ -42,7 +42,7 @@ #define _1KB (1024) #define _1MB (1024 * _1KB) -/* Are mapped by a PDE */ +/* Area mapped by a PDE */ #define PDE_MAPPED_VA (PTE_COUNT * PAGE_SIZE) /* Size of a PDE directory, and size of a page table */ @@ -89,6 +89,18 @@ #define MM_DECOMMIT 0x10 #define MM_NOACCESS (MM_DECOMMIT | MM_NOCACHE) +// +// Assertions for session images, addresses, and PTEs +// +#define MI_IS_SESSION_IMAGE_ADDRESS(Address) \ + (((Address) >= MiSessionImageStart) && ((Address) < MiSessionImageEnd)) + +#define MI_IS_SESSION_ADDRESS(Address) \ + (((Address) >= MmSessionBase) && ((Address) < MiSessionSpaceEnd)) + +#define MI_IS_SESSION_PTE(Pte) \ + ((((PMMPTE)Pte) >= MiSessionBasePte) && (((PMMPTE)Pte) < MiSessionLastPte)) + // // Corresponds to MMPTE_SOFTWARE.Protection // @@ -119,6 +131,11 @@ // #define LIST_HEAD 0xFFFFFFFF +// +// Special IRQL value (found in assertions) +// +#define MM_NOIRQL (KIRQL)0xFFFFFFFF + // // FIXFIX: These should go in ex.h after the pool merge // @@ -284,6 +301,10 @@ extern PVOID MiSystemViewStart; extern ULONG MmSystemViewSize; extern PVOID MmSessionBase; extern PVOID MiSessionSpaceEnd; +extern PMMPTE MiSessionImagePteStart; +extern PMMPTE MiSessionImagePteEnd; +extern PMMPTE MiSessionBasePte; +extern PMMPTE MiSessionLastPte; extern ULONG MmSizeOfPagedPoolInBytes; extern PMMPTE MmSystemPagePtes; extern PVOID MmSystemCacheStart; @@ -327,16 +348,17 @@ extern ULONG MmTotalFreeSystemPtes[MaximumPtePoolTypes]; extern PFN_NUMBER MmTotalSystemDriverPages; extern PVOID MiSessionImageStart; extern PVOID MiSessionImageEnd; +extern PMMPTE MiHighestUserPte; +extern PMMPDE MiHighestUserPde; +extern PFN_NUMBER MmSystemPageDirectory[PD_COUNT]; #define MI_PFN_TO_PFNENTRY(x) (&MmPfnDatabase[1][x]) #define MI_PFNENTRY_TO_PFN(x) (x - MmPfnDatabase[1]) -#define MI_IS_SESSION_IMAGE_ADDRESS(Address) \ - (((Address) >= MiSessionImageStart) && ((Address) < MiSessionImageEnd)) - -#define MI_IS_SESSION_ADDRESS(Address) \ - (((Address) >= MmSessionBase) && ((Address) < MiSessionSpaceEnd)) - +// +// Returns if the page is physically resident (ie: a large page) +// FIXFIX: CISC/x86 only? +// FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address) diff --git a/reactos/ntoskrnl/mm/ARM3/pagfault.c b/reactos/ntoskrnl/mm/ARM3/pagfault.c index dbed3005446..94363c0f670 100644 --- a/reactos/ntoskrnl/mm/ARM3/pagfault.c +++ b/reactos/ntoskrnl/mm/ARM3/pagfault.c @@ -27,6 +27,10 @@ MiCheckPdeForPagedPool(IN PVOID Address) PMMPDE PointerPde; NTSTATUS Status = STATUS_SUCCESS; + /* No session support in ReactOS yet */ + ASSERT(MI_IS_SESSION_ADDRESS(Address) == FALSE); + ASSERT(MI_IS_SESSION_PTE(Address) == FALSE); + // // Check if this is a fault while trying to access the page table itself // @@ -60,6 +64,9 @@ MiCheckPdeForPagedPool(IN PVOID Address) // if (PointerPde->u.Hard.Valid == 0) { + /* This seems to be making the assumption that one PDE is one page long */ + ASSERT(PAGE_SIZE == (PD_COUNT * (sizeof(MMPTE) * PDE_COUNT))); + // // Copy it from our double-mapped system page directory // @@ -88,6 +95,10 @@ MiResolveDemandZeroFault(IN PVOID Address, Address, Process); + /* Must currently only be called by paging path, for system addresses only */ + ASSERT(OldIrql == MM_NOIRQL); + ASSERT(Process == NULL); + // // Lock the PFN database // @@ -110,11 +121,16 @@ MiResolveDemandZeroFault(IN PVOID Address, // InterlockedIncrement(&KeGetCurrentPrcb()->MmDemandZeroCount); + /* Shouldn't see faults for user PTEs yet */ + ASSERT(PointerPte > MiHighestUserPte); + // // Build the PTE // TempPte = ValidKernelPte; TempPte.u.Hard.PageFrameNumber = PageFrameNumber; + ASSERT(TempPte.u.Hard.Valid == 1); + ASSERT(PointerPte->u.Hard.Valid == 0); *PointerPte = TempPte; ASSERT(PointerPte->u.Hard.Valid == 1); @@ -155,6 +171,9 @@ MiDispatchFault(IN BOOLEAN StoreInstruction, // TempPte = *PointerPte; + /* No prototype */ + ASSERT(PrototypePte == NULL); + // // The PTE must be invalid, but not totally blank // @@ -175,7 +194,8 @@ MiDispatchFault(IN BOOLEAN StoreInstruction, Status = MiResolveDemandZeroFault(Address, PointerPte, Process, - -1); + MM_NOIRQL); + ASSERT(KeAreAllApcsDisabled () == TRUE); if (NT_SUCCESS(Status)) { // diff --git a/reactos/ntoskrnl/mm/ARM3/pool.c b/reactos/ntoskrnl/mm/ARM3/pool.c index 10a585e8912..2ae4006a4a3 100644 --- a/reactos/ntoskrnl/mm/ARM3/pool.c +++ b/reactos/ntoskrnl/mm/ARM3/pool.c @@ -334,12 +334,13 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType, // // Save it into our double-buffered system page directory // + /* This seems to be making the assumption that one PDE is one page long */ + ASSERT(PAGE_SIZE == (PD_COUNT * (sizeof(MMPTE) * PDE_COUNT))); MmSystemPagePtes[(ULONG_PTR)PointerPte & (PAGE_SIZE - 1) / sizeof(MMPTE)] = TempPte; - // - // Write the actual PTE now - // + /* Write the actual PTE now */ + ASSERT(TempPte.u.Hard.Valid == 1); *PointerPte++ = TempPte; // @@ -432,6 +433,7 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType, // // Write the demand zero PTE and keep going // + ASSERT(PointerPte->u.Hard.Valid == 0); *PointerPte++ = TempPte; } while (PointerPte < StartPte); -- 2.17.1