Author: fireball
Date: Sun Feb 17 19:24:24 2008
New Revision: 32405
URL: http://svn.reactos.org/svn/reactos?rev=32405&view=rev
Log:
- Fix a bug, when the page first was marked as free and put into free pages list to zero out, and then was marked as used for PFN database, but *not* removed from that list! Certainly it was zeroed out later, introducing a corruption within the free list and a pagefault.
- This revision completely removes hacks introduced in 32386.
See issue #3076 for more details.
Modified:
trunk/reactos/ntoskrnl/ke/freeldr.c
trunk/reactos/ntoskrnl/mm/freelist.c
Modified: trunk/reactos/ntoskrnl/ke/freeldr.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/freeldr.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/freeldr.c (original)
+++ trunk/reactos/ntoskrnl/ke/freeldr.c Sun Feb 17 19:24:24 2008
@@ -20,8 +20,6 @@
#define KERNEL_RVA(x) RVA(x,KSEG0_BASE)
#define KERNEL_DESCRIPTOR_PAGE(x) (((ULONG_PTR)x &~ KSEG0_BASE) >> PAGE_SHIFT)
#endif
-
-ULONG MmFreeLdrPageDirectoryEnd;
typedef struct _BIOS_MEMORY_DESCRIPTOR
{
@@ -922,8 +920,6 @@
/* First get some kernel-loader globals */
AcpiTableDetected = (RosLoaderBlock->Flags & MB_FLAGS_ACPI_TABLE) ? TRUE : FALSE;
- MmFreeLdrPageDirectoryEnd = RosLoaderBlock->PageDirectoryEnd;
- if (!MmFreeLdrPageDirectoryEnd) MmFreeLdrPageDirectoryEnd = 0x40000;
/* Set the NT Loader block and initialize it */
*NtLoaderBlock = KeLoaderBlock = LoaderBlock = &BldrLoaderBlock;
Modified: trunk/reactos/ntoskrnl/mm/freelist.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/freelist.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/freelist.c (original)
+++ trunk/reactos/ntoskrnl/mm/freelist.c Sun Feb 17 19:24:24 2008
@@ -251,7 +251,6 @@
return Pfn;
}
-#if 0
VOID
NTAPI
MmInitializePageList(VOID)
@@ -375,7 +374,15 @@
i <= MmPageArraySize;
i++)
{
- /* Mark them as used kernel memory */
+ /* If this page was marked as free it should be removed from
+ the unzeroed free pages list */
+ if (MmPageArray[i].Flags.Type == MM_PHYSICAL_PAGE_FREE)
+ {
+ RemoveEntryList(&MmPageArray[i].ListEntry);
+ UnzeroedPageCount--;
+ }
+
+ /* Mark it as used kernel memory */
MmPageArray[i] = UsedPage;
MmStats.NrSystemPages++;
}
@@ -386,198 +393,6 @@
MmStats.NrTotalPages = MmStats.NrFreePages + MmStats.NrSystemPages + MmStats.NrUserPages;
MmInitializeBalancer(MmStats.NrFreePages, MmStats.NrSystemPages);
}
-#else
-VOID
-NTAPI
-MmInitializePageList()
-{
- ULONG i;
- ULONG Reserved;
- NTSTATUS Status;
- PFN_TYPE Pfn = 0;
- PHYSICAL_PAGE UsedPage;
- ULONG PdeStart = PsGetCurrentProcess()->Pcb.DirectoryTableBase.LowPart;
- ULONG PdePageStart, PdePageEnd;
- ULONG VideoPageStart, VideoPageEnd;
- ULONG KernelPageStart, KernelPageEnd;
- ULONG_PTR KernelStart, KernelEnd;
- extern ULONG MiKSeg0Start, MiKSeg0End, MmFreeLdrPageDirectoryEnd;
-
- /* Initialize the page lists */
- KeInitializeSpinLock(&PageListLock);
- InitializeListHead(&UserPageListHead);
- InitializeListHead(&FreeUnzeroedPageListHead);
- InitializeListHead(&FreeZeroedPageListHead);
-
- DPRINT1("HACK: Using old incorrect MmInitializePageList(). "
- "Please bugfix the new version and delete this one\n");
-
- /* Set the size and start of the PFN Database */
- MmPageArray = (PHYSICAL_PAGE *)MmPfnDatabase;
- MmPageArraySize = MmHighestPhysicalPage;
- Reserved = PAGE_ROUND_UP((MmPageArraySize * sizeof(PHYSICAL_PAGE))) / PAGE_SIZE;
-
- /* Loop every page required to hold the PFN database */
- for (i = 0; i < Reserved; i++)
- {
- PVOID Address = (char*)MmPageArray + (i * PAGE_SIZE);
-
- /* Check if FreeLDR has already allocated it for us */
- if (!MmIsPagePresent(NULL, Address))
- {
- /* Use one of our highest usable pages */
- Pfn = MmAllocEarlyPage();
-
- /* Set the PFN */
- Status = MmCreateVirtualMappingForKernel(Address,
- PAGE_READWRITE,
- &Pfn,
- 1);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Unable to create virtual mapping\n");
- KEBUGCHECK(0);
- }
- }
- else
- {
- /* Setting the page protection is necessary to set the global bit */
- MmSetPageProtect(NULL, Address, PAGE_READWRITE);
- }
- }
-
- /* Clear the PFN database */
- RtlZeroMemory(MmPageArray, (MmPageArraySize + 1) * sizeof(PHYSICAL_PAGE));
-
- /* This is what a used page looks like */
- RtlZeroMemory(&UsedPage, sizeof(UsedPage));
- UsedPage.Flags.Type = MM_PHYSICAL_PAGE_USED;
- UsedPage.Flags.Consumer = MC_NPPOOL;
- UsedPage.ReferenceCount = 2;
- UsedPage.MapCount = 1;
-
- /* We'll be applying a bunch of hacks -- precompute some static values */
- KernelStart = MiKSeg0Start - KSEG0_BASE;
- KernelEnd = MiKSeg0End - KSEG0_BASE;
- PdePageStart = PdeStart / PAGE_SIZE;
- PdePageEnd = MmFreeLdrPageDirectoryEnd / PAGE_SIZE;
- VideoPageStart = 0xA0000 / PAGE_SIZE;
- VideoPageEnd = 0x100000 / PAGE_SIZE;
- KernelPageStart = KernelStart / PAGE_SIZE;
- KernelPageEnd = KernelEnd / PAGE_SIZE;
-
- // Glorious Hack:
- // The kernel seems to crash if the region of memory that FreeLDR maps
- // (those evil 6MB) is not *entirely* marked "in use", even though only
- // 3 or 4MB of it may actually be in use.
- // This wasn't noticed before, because the PFN database pages which are
- // *VIRTUALLY* continous after the kernel end were also marked as
- // *PHYSICALLY* continous (even though they were allocated at the very far
- // end of physical memory).
- //
- // So we'll simply gobble up whatever is left of what FreeLDR mapped.
- //
- // PS. This is really sinister
- //
- KernelEnd += (KernelStart + 0x600000) - KernelEnd;
- KernelPageEnd = KernelEnd / PAGE_SIZE;
-
- /* Loop every page on the system */
- for (i = 0; i <= MmPageArraySize; i++)
- {
- /* Check if it's part of RAM */
- if (/*MiIsPfnRam(BIOSMemoryMap, AddressRangeCount, i)*/TRUE)
- {
- /* Apply assumptions that all computers are built the same way */
- if (i == 0)
- {
- /* Page 0 is reserved for the IVT */
- MmPageArray[i] = UsedPage;
- MmStats.NrSystemPages++;
- }
- else if (i == 1)
- {
- /* Page 1 is reserved for the PCR */
- MmPageArray[i] = UsedPage;
- MmStats.NrSystemPages++;
- }
- else if (i == 2)
- {
- /* Page 2 is reserved for the KUSER_SHARED_DATA */
- MmPageArray[i] = UsedPage;
- MmStats.NrSystemPages++;
- }
- else if ((i >= PdePageStart) && (i < PdePageEnd))
- {
- /* These pages contain the initial FreeLDR PDEs */
- MmPageArray[i] = UsedPage;
- MmStats.NrSystemPages++;
- }
- else if ((i >= VideoPageStart) && (i < VideoPageEnd))
- {
- /*
- * These pages are usually for the Video ROM BIOS.
- * Supposedly anyway. We'll simply ignore the fact that
- * many systems have this area somewhere else entirely
- * (which we'll assume to be "free" a couple of lines below)
- */
- MmPageArray[i].Flags.Type = MM_PHYSICAL_PAGE_BIOS;
- MmPageArray[i].Flags.Consumer = MC_NPPOOL;
- MmStats.NrSystemPages++;
- }
- else if ((i >= KernelPageStart) && (i < KernelPageEnd))
- {
- /* These are pages beloning to the kernel */
- MmPageArray[i] = UsedPage;
- MmStats.NrSystemPages++;
- }
- else if (i >= (MiFreeDescriptor->BasePage + MiFreeDescriptor->PageCount))
- {
- /* These are pages we allocated above to hold the PFN DB */
- MmPageArray[i] = UsedPage;
- MmStats.NrSystemPages++;
- }
- else
- {
- /*
- * These are supposedly free pages.
- * By the way, not all of them are, some contain vital
- * FreeLDR data, but since we choose to ignore the Memory
- * Descriptor List, why bother, right?
- */
- MmPageArray[i].Flags.Type = MM_PHYSICAL_PAGE_FREE;
- MmPageArray[i].ReferenceCount = 0;
- InsertTailList(&FreeUnzeroedPageListHead,
- &MmPageArray[i].ListEntry);
- UnzeroedPageCount++;
- MmStats.NrFreePages++;
- }
- }
- else
- {
- /* These are pages reserved by the BIOS/ROMs */
- MmPageArray[i].Flags.Type = MM_PHYSICAL_PAGE_BIOS;
- MmPageArray[i].Flags.Consumer = MC_NPPOOL;
- MmStats.NrSystemPages++;
- }
- }
-
- KeInitializeEvent(&ZeroPageThreadEvent, NotificationEvent, TRUE);
- DPRINT("Pages: %x %x\n", MmStats.NrFreePages, MmStats.NrSystemPages);
- /*
- DPRINT1("Unzeroed pages: %x\n", UnzeroedPageCount);
- {
- ULONG j = 0;
- for (j=0; j<=MmPageArraySize; j++)
- {
- if (j % 0x10 == 0) DbgPrint ("\n0x%x\t", j);
- DbgPrint("0x%x\t", MmPageArray[j].AllFlags);
- }
- }*/
- MmStats.NrTotalPages = MmStats.NrFreePages + MmStats.NrSystemPages + MmStats.NrUserPages;
- MmInitializeBalancer(MmStats.NrFreePages, MmStats.NrSystemPages);
-}
-#endif
VOID
NTAPI