[ros-diffs] [fireball] 32405: - 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.

fireball at svn.reactos.org fireball at svn.reactos.org
Sun Feb 17 17:24:24 CET 2008


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=32405&r1=32404&r2=32405&view=diff
==============================================================================
--- 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=32405&r1=32404&r2=32405&view=diff
==============================================================================
--- 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




More information about the Ros-diffs mailing list