Author: sir_richard
Date: Wed May 12 23:37:19 2010
New Revision: 47186
URL:
http://svn.reactos.org/svn/reactos?rev=47186&view=rev
Log:
[NTOS]: When grabbing physically contigous pages from the zero or free list, make sure to
re-initialize their PFN entries correctly, since their data might be stale. Fixes
potential weird memory corruption bugs.
[NTOS]: Physically contiguous memory allocations are not guaranteed to be zeroed, so do
not zero the pages.
[NTOS]: When allocating contigous memory, mark the PFN entries appropriately after mapping
the I/O ranges.
[NTOS]: When freeing contiguous memory, assert that all the freed pages correspond to PFN
entries that we expect to have allocated for this purpose. Detects (not neccessarily
fixes) memory corruption issues in contiguous memory allocations.
[NTOS]: These changes mostly affect certain network card and sound card systems/real
hardware, they fix possible bugs and detect corruption that was otherwise going by
unnoticed.
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/contmem.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/contmem.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/contmem.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/contmem.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/contmem.c [iso-8859-1] Wed May 12 23:37:19 2010
@@ -132,23 +132,14 @@
//
MiUnlinkFreeOrZeroedPage(Pfn1);
Pfn1->u3.e2.ReferenceCount = 1;
+ Pfn1->u2.ShareCount = 1;
+ Pfn1->u3.e1.PageLocation = ActiveAndValid;
+ Pfn1->u3.e1.StartOfAllocation = 0;
+ Pfn1->u3.e1.EndOfAllocation = 0;
+ Pfn1->u3.e1.PrototypePte = 0;
+ Pfn1->u4.VerifierAllocation = 0;
+ Pfn1->PteAddress = (PVOID)0xBAADF00D;
- //
- // Check if it was already zeroed
- //
- if (Pfn1->u3.e1.PageLocation != ZeroedPageList)
- {
- //
- // It wasn't, so zero it
- //
- MiZeroPage(MiGetPfnEntryIndex(Pfn1));
- }
-
- //
- // Mark it in use
- //
- Pfn1->u3.e1.PageLocation = ActiveAndValid;
-
//
// Check if this is the last PFN, otherwise go on
//
@@ -331,7 +322,10 @@
{
PFN_NUMBER Page;
PHYSICAL_ADDRESS PhysicalAddress;
- PAGED_CODE ();
+ PMMPFN Pfn1, EndPfn;
+ PMMPTE PointerPte;
+ PVOID BaseAddress;
+ PAGED_CODE();
ASSERT(SizeInPages != 0);
//
@@ -348,7 +342,22 @@
// We'll just piggyback on the I/O memory mapper
//
PhysicalAddress.QuadPart = Page << PAGE_SHIFT;
- return MmMapIoSpace(PhysicalAddress, SizeInPages << PAGE_SHIFT, CacheType);
+ BaseAddress = MmMapIoSpace(PhysicalAddress, SizeInPages << PAGE_SHIFT,
CacheType);
+ ASSERT(BaseAddress);
+
+ /* Loop the PFN entries */
+ Pfn1 = MiGetPfnEntry(Page);
+ EndPfn = Pfn1 + SizeInPages;
+ PointerPte = MiAddressToPte(BaseAddress);
+ do
+ {
+ /* Write the PTE address */
+ Pfn1->PteAddress = PointerPte++;
+ Pfn1->u4.PteFrame = PFN_FROM_PTE(MiAddressToPte(PointerPte));
+ } while (Pfn1++ < EndPfn);
+
+ /* Return the address */
+ return BaseAddress;
}
PVOID
@@ -437,6 +446,7 @@
KIRQL OldIrql;
PFN_NUMBER PageFrameIndex, LastPage, PageCount;
PMMPFN Pfn1, StartPfn;
+ PMMPTE PointerPte;
PAGED_CODE();
//
@@ -455,10 +465,9 @@
return;
}
- //
- // Otherwise, get the PTE and page number for the allocation
- //
- PageFrameIndex = PFN_FROM_PTE(MiAddressToPte(BaseAddress));
+ /* Get the PTE and frame number for the allocation*/
+ PointerPte = MiAddressToPte(BaseAddress);
+ PageFrameIndex = PFN_FROM_PTE(PointerPte);
//
// Now get the PFN entry for this, and make sure it's the correct one
@@ -469,11 +478,11 @@
//
// This probably means you did a free on an address that was in between
//
- KeBugCheckEx (BAD_POOL_CALLER,
- 0x60,
- (ULONG_PTR)BaseAddress,
- 0,
- 0);
+ KeBugCheckEx(BAD_POOL_CALLER,
+ 0x60,
+ (ULONG_PTR)BaseAddress,
+ 0,
+ 0);
}
//
@@ -482,16 +491,21 @@
StartPfn = Pfn1;
Pfn1->u3.e1.StartOfAllocation = 0;
- //
- // Look the PFNs
- //
+ /* Look the PFNs until we find the one that marks the end of the allocation */
do
{
- //
- // Until we find the one that marks the end of the allocation
- //
+ /* Make sure these are the pages we setup in the allocation routine */
+ ASSERT(Pfn1->u3.e2.ReferenceCount == 1);
+ ASSERT(Pfn1->u2.ShareCount == 1);
+ ASSERT(Pfn1->PteAddress == PointerPte);
+ ASSERT(Pfn1->u3.e1.PageLocation == ActiveAndValid);
+ ASSERT(Pfn1->u4.VerifierAllocation == 0);
+ ASSERT(Pfn1->u3.e1.PrototypePte == 0);
+
+ /* Keep going for assertions */
+ PointerPte++;
} while (Pfn1++->u3.e1.EndOfAllocation == 0);
-
+
//
// Found it, unmark it
//