mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 16:51:39 +00:00
- 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. svn path=/trunk/; revision=32405
This commit is contained in:
parent
aa6f9c2d05
commit
750bf31ad3
2 changed files with 9 additions and 198 deletions
|
@ -21,8 +21,6 @@
|
||||||
#define KERNEL_DESCRIPTOR_PAGE(x) (((ULONG_PTR)x &~ KSEG0_BASE) >> PAGE_SHIFT)
|
#define KERNEL_DESCRIPTOR_PAGE(x) (((ULONG_PTR)x &~ KSEG0_BASE) >> PAGE_SHIFT)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ULONG MmFreeLdrPageDirectoryEnd;
|
|
||||||
|
|
||||||
typedef struct _BIOS_MEMORY_DESCRIPTOR
|
typedef struct _BIOS_MEMORY_DESCRIPTOR
|
||||||
{
|
{
|
||||||
ULONG BlockBase;
|
ULONG BlockBase;
|
||||||
|
@ -922,8 +920,6 @@ KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock,
|
||||||
|
|
||||||
/* First get some kernel-loader globals */
|
/* First get some kernel-loader globals */
|
||||||
AcpiTableDetected = (RosLoaderBlock->Flags & MB_FLAGS_ACPI_TABLE) ? TRUE : FALSE;
|
AcpiTableDetected = (RosLoaderBlock->Flags & MB_FLAGS_ACPI_TABLE) ? TRUE : FALSE;
|
||||||
MmFreeLdrPageDirectoryEnd = RosLoaderBlock->PageDirectoryEnd;
|
|
||||||
if (!MmFreeLdrPageDirectoryEnd) MmFreeLdrPageDirectoryEnd = 0x40000;
|
|
||||||
|
|
||||||
/* Set the NT Loader block and initialize it */
|
/* Set the NT Loader block and initialize it */
|
||||||
*NtLoaderBlock = KeLoaderBlock = LoaderBlock = &BldrLoaderBlock;
|
*NtLoaderBlock = KeLoaderBlock = LoaderBlock = &BldrLoaderBlock;
|
||||||
|
|
|
@ -251,7 +251,6 @@ MmAllocEarlyPage(VOID)
|
||||||
return Pfn;
|
return Pfn;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
MmInitializePageList(VOID)
|
MmInitializePageList(VOID)
|
||||||
|
@ -375,7 +374,15 @@ MmInitializePageList(VOID)
|
||||||
i <= MmPageArraySize;
|
i <= MmPageArraySize;
|
||||||
i++)
|
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;
|
MmPageArray[i] = UsedPage;
|
||||||
MmStats.NrSystemPages++;
|
MmStats.NrSystemPages++;
|
||||||
}
|
}
|
||||||
|
@ -386,198 +393,6 @@ MmInitializePageList(VOID)
|
||||||
MmStats.NrTotalPages = MmStats.NrFreePages + MmStats.NrSystemPages + MmStats.NrUserPages;
|
MmStats.NrTotalPages = MmStats.NrFreePages + MmStats.NrSystemPages + MmStats.NrUserPages;
|
||||||
MmInitializeBalancer(MmStats.NrFreePages, MmStats.NrSystemPages);
|
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
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue