mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00
- Remove MiZeroPage, use MiZeroPhysicalPage instead. They work pretty much the same except the needless raise to DISPATCH_LEVEL.
- Get rid of the messed up MiMapPageToZeroInHyperSpace which was hacking into MiMapPagesToZeroInHyperSpace. Now MiMapPagesToZeroInHyperSpace is properly implemented to use chained PFNs, and the MmZeroPageThread code has been modified to correctly use the new mechanism. - Zero page mapping now happens at PASSIVE trough MiMapPAgesToZeroInHyperSpace, not DISPATCH anymore. - More fixes are coming to remove the remaining MiRemoveHeadList and rewrite the zero page loop. Should fix more possible corruptions. svn path=/trunk/; revision=48912
This commit is contained in:
parent
df34e334f0
commit
f269313793
6 changed files with 42 additions and 63 deletions
|
@ -29,6 +29,12 @@ ULONG CcFastReadResourceMiss;
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
MiZeroPhysicalPage(
|
||||||
|
IN PFN_NUMBER PageFrameIndex
|
||||||
|
);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
CcInitCacheZeroPage(VOID)
|
CcInitCacheZeroPage(VOID)
|
||||||
|
@ -41,12 +47,7 @@ CcInitCacheZeroPage(VOID)
|
||||||
DbgPrint("Can't allocate CcZeroPage.\n");
|
DbgPrint("Can't allocate CcZeroPage.\n");
|
||||||
KeBugCheck(CACHE_MANAGER);
|
KeBugCheck(CACHE_MANAGER);
|
||||||
}
|
}
|
||||||
Status = MiZeroPage(CcZeroPage);
|
MiZeroPhysicalPage(CcZeroPage);
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DbgPrint("Can't zero out CcZeroPage.\n");
|
|
||||||
KeBugCheck(CACHE_MANAGER);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
|
@ -1189,7 +1189,7 @@ MiUnmapPageInHyperSpace(IN PEPROCESS Process,
|
||||||
|
|
||||||
PVOID
|
PVOID
|
||||||
NTAPI
|
NTAPI
|
||||||
MiMapPagesToZeroInHyperSpace(IN PMMPFN *Pages,
|
MiMapPagesToZeroInHyperSpace(IN PMMPFN Pfn1,
|
||||||
IN PFN_NUMBER NumberOfPages);
|
IN PFN_NUMBER NumberOfPages);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -1208,14 +1208,6 @@ MmCreateHyperspaceMapping(IN PFN_NUMBER Page)
|
||||||
return MiMapPageInHyperSpace(HyperProcess, Page, &HyperIrql);
|
return MiMapPageInHyperSpace(HyperProcess, Page, &HyperIrql);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCEINLINE
|
|
||||||
PVOID
|
|
||||||
MiMapPageToZeroInHyperSpace(IN PFN_NUMBER Page)
|
|
||||||
{
|
|
||||||
PMMPFN Pfn1 = MiGetPfnEntry(Page);
|
|
||||||
return MiMapPagesToZeroInHyperSpace(&Pfn1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MmDeleteHyperspaceMapping(x) MiUnmapPageInHyperSpace(HyperProcess, x, HyperIrql);
|
#define MmDeleteHyperspaceMapping(x) MiUnmapPageInHyperSpace(HyperProcess, x, HyperIrql);
|
||||||
|
|
||||||
/* i386/page.c *********************************************************/
|
/* i386/page.c *********************************************************/
|
||||||
|
|
|
@ -112,18 +112,17 @@ MiUnmapPageInHyperSpace(IN PEPROCESS Process,
|
||||||
|
|
||||||
PVOID
|
PVOID
|
||||||
NTAPI
|
NTAPI
|
||||||
MiMapPagesToZeroInHyperSpace(IN PMMPFN *Pages,
|
MiMapPagesToZeroInHyperSpace(IN PMMPFN Pfn1,
|
||||||
IN PFN_NUMBER NumberOfPages)
|
IN PFN_NUMBER NumberOfPages)
|
||||||
{
|
{
|
||||||
MMPTE TempPte;
|
MMPTE TempPte;
|
||||||
PMMPTE PointerPte;
|
PMMPTE PointerPte;
|
||||||
PFN_NUMBER Offset, PageFrameIndex;
|
PFN_NUMBER Offset, PageFrameIndex;
|
||||||
PMMPFN Page;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Sanity checks
|
// Sanity checks
|
||||||
//
|
//
|
||||||
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
|
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
|
||||||
ASSERT(NumberOfPages != 0);
|
ASSERT(NumberOfPages != 0);
|
||||||
ASSERT(NumberOfPages <= (MI_ZERO_PTES - 1));
|
ASSERT(NumberOfPages <= (MI_ZERO_PTES - 1));
|
||||||
|
|
||||||
|
@ -151,19 +150,17 @@ MiMapPagesToZeroInHyperSpace(IN PMMPFN *Pages,
|
||||||
//
|
//
|
||||||
PointerPte->u.Hard.PageFrameNumber = Offset - NumberOfPages;
|
PointerPte->u.Hard.PageFrameNumber = Offset - NumberOfPages;
|
||||||
|
|
||||||
//
|
/* Choose the correct PTE to use, and which template */
|
||||||
// Write the current PTE
|
|
||||||
//
|
|
||||||
PointerPte += (Offset + 1);
|
PointerPte += (Offset + 1);
|
||||||
TempPte = ValidKernelPte;
|
TempPte = ValidKernelPte;
|
||||||
MI_MAKE_LOCAL_PAGE(&TempPte); // Hyperspace is local!
|
MI_MAKE_LOCAL_PAGE(&TempPte); // Hyperspace is local!
|
||||||
do
|
|
||||||
|
/* Make sure the list isn't empty and loop it */
|
||||||
|
ASSERT(Pfn1 != (PVOID)LIST_HEAD);
|
||||||
|
while (Pfn1 != (PVOID)LIST_HEAD)
|
||||||
{
|
{
|
||||||
//
|
/* Get the page index for this PFN */
|
||||||
// Get the first page entry and its PFN
|
PageFrameIndex = MiGetPfnEntryIndex(Pfn1);
|
||||||
//
|
|
||||||
Page = *Pages++;
|
|
||||||
PageFrameIndex = MiGetPfnEntryIndex(Page);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Write the PFN
|
// Write the PFN
|
||||||
|
@ -175,7 +172,10 @@ MiMapPagesToZeroInHyperSpace(IN PMMPFN *Pages,
|
||||||
//
|
//
|
||||||
PointerPte--;
|
PointerPte--;
|
||||||
MI_WRITE_VALID_PTE(PointerPte, TempPte);
|
MI_WRITE_VALID_PTE(PointerPte, TempPte);
|
||||||
} while (--NumberOfPages);
|
|
||||||
|
/* Move to the next PFN */
|
||||||
|
Pfn1 = (PMMPFN)Pfn1->u1.Flink;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Return the address
|
// Return the address
|
||||||
|
@ -193,7 +193,7 @@ MiUnmapPagesInZeroSpace(IN PVOID VirtualAddress,
|
||||||
//
|
//
|
||||||
// Sanity checks
|
// Sanity checks
|
||||||
//
|
//
|
||||||
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
|
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
|
||||||
ASSERT (NumberOfPages != 0);
|
ASSERT (NumberOfPages != 0);
|
||||||
ASSERT (NumberOfPages <= (MI_ZERO_PTES - 1));
|
ASSERT (NumberOfPages <= (MI_ZERO_PTES - 1));
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,7 @@ MiZeroPhysicalPage(IN PFN_NUMBER PageFrameIndex)
|
||||||
|
|
||||||
/* Map in hyperspace, then wipe it using XMMI or MEMSET */
|
/* Map in hyperspace, then wipe it using XMMI or MEMSET */
|
||||||
VirtualAddress = MiMapPageInHyperSpace(Process, PageFrameIndex, &OldIrql);
|
VirtualAddress = MiMapPageInHyperSpace(Process, PageFrameIndex, &OldIrql);
|
||||||
|
ASSERT(VirtualAddress);
|
||||||
KeZeroPages(VirtualAddress, PAGE_SIZE);
|
KeZeroPages(VirtualAddress, PAGE_SIZE);
|
||||||
MiUnmapPageInHyperSpace(Process, VirtualAddress, OldIrql);
|
MiUnmapPageInHyperSpace(Process, VirtualAddress, OldIrql);
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,6 +99,12 @@ MmInitializeMemoryConsumer(ULONG Consumer,
|
||||||
MiMemoryConsumers[Consumer].Trim = Trim;
|
MiMemoryConsumers[Consumer].Trim = Trim;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
MiZeroPhysicalPage(
|
||||||
|
IN PFN_NUMBER PageFrameIndex
|
||||||
|
);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
|
MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
|
||||||
|
@ -131,7 +137,7 @@ MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
|
||||||
Request = CONTAINING_RECORD(Entry, MM_ALLOCATION_REQUEST, ListEntry);
|
Request = CONTAINING_RECORD(Entry, MM_ALLOCATION_REQUEST, ListEntry);
|
||||||
KeReleaseSpinLock(&AllocationListLock, OldIrql);
|
KeReleaseSpinLock(&AllocationListLock, OldIrql);
|
||||||
if(Consumer == MC_USER) MmRemoveLRUUserPage(Page);
|
if(Consumer == MC_USER) MmRemoveLRUUserPage(Page);
|
||||||
MiZeroPage(Page);
|
MiZeroPhysicalPage(Page);
|
||||||
Request->Page = Page;
|
Request->Page = Page;
|
||||||
KeSetEvent(&Request->Event, IO_NO_INCREMENT, FALSE);
|
KeSetEvent(&Request->Event, IO_NO_INCREMENT, FALSE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -360,7 +360,7 @@ MiAllocatePagesForMdl(IN PHYSICAL_ADDRESS LowAddress,
|
||||||
//
|
//
|
||||||
Pfn1 = MiGetPfnEntry(Page);
|
Pfn1 = MiGetPfnEntry(Page);
|
||||||
ASSERT(Pfn1);
|
ASSERT(Pfn1);
|
||||||
if (Pfn1->u3.e1.PageLocation != ZeroedPageList) MiZeroPage(Page);
|
if (Pfn1->u3.e1.PageLocation != ZeroedPageList) MiZeroPhysicalPage(Page);
|
||||||
Pfn1->u3.e1.PageLocation = ActiveAndValid;
|
Pfn1->u3.e1.PageLocation = ActiveAndValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -625,25 +625,6 @@ MmAllocPage(ULONG Type)
|
||||||
return PfnOffset;
|
return PfnOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
NTAPI
|
|
||||||
MiZeroPage(PFN_NUMBER Page)
|
|
||||||
{
|
|
||||||
KIRQL Irql;
|
|
||||||
PVOID TempAddress;
|
|
||||||
|
|
||||||
Irql = KeRaiseIrqlToDpcLevel();
|
|
||||||
TempAddress = MiMapPageToZeroInHyperSpace(Page);
|
|
||||||
if (TempAddress == NULL)
|
|
||||||
{
|
|
||||||
return(STATUS_NO_MEMORY);
|
|
||||||
}
|
|
||||||
memset(TempAddress, 0, PAGE_SIZE);
|
|
||||||
MiUnmapPagesInZeroSpace(TempAddress, 1);
|
|
||||||
KeLowerIrql(Irql);
|
|
||||||
return(STATUS_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
MmZeroPageThreadMain(PVOID Ignored)
|
MmZeroPageThreadMain(PVOID Ignored)
|
||||||
|
@ -653,6 +634,7 @@ MmZeroPageThreadMain(PVOID Ignored)
|
||||||
PPHYSICAL_PAGE PageDescriptor;
|
PPHYSICAL_PAGE PageDescriptor;
|
||||||
PFN_NUMBER Pfn;
|
PFN_NUMBER Pfn;
|
||||||
ULONG Count;
|
ULONG Count;
|
||||||
|
PVOID ZeroAddress;
|
||||||
|
|
||||||
/* Free initial kernel memory */
|
/* Free initial kernel memory */
|
||||||
//MiFreeInitMemory();
|
//MiFreeInitMemory();
|
||||||
|
@ -679,22 +661,19 @@ MmZeroPageThreadMain(PVOID Ignored)
|
||||||
while (MmFreePageListHead.Total)
|
while (MmFreePageListHead.Total)
|
||||||
{
|
{
|
||||||
PageDescriptor = MiRemoveHeadList(&MmFreePageListHead);
|
PageDescriptor = MiRemoveHeadList(&MmFreePageListHead);
|
||||||
/* We set the page to used, because MmCreateVirtualMapping failed with unused pages */
|
|
||||||
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
|
|
||||||
Pfn = MiGetPfnEntryIndex(PageDescriptor);
|
Pfn = MiGetPfnEntryIndex(PageDescriptor);
|
||||||
Status = MiZeroPage(Pfn);
|
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
|
||||||
|
|
||||||
|
PageDescriptor->u1.Flink = LIST_HEAD;
|
||||||
|
ZeroAddress = MiMapPagesToZeroInHyperSpace(PageDescriptor, 1);
|
||||||
|
ASSERT(ZeroAddress);
|
||||||
|
RtlZeroMemory(ZeroAddress, PAGE_SIZE);
|
||||||
|
MiUnmapPagesInZeroSpace(ZeroAddress, 1);
|
||||||
|
|
||||||
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
|
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
MiInsertZeroListAtBack(Pfn);
|
||||||
MiInsertZeroListAtBack(Pfn);
|
Count++;
|
||||||
Count++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MiInsertInListTail(&MmFreePageListHead, PageDescriptor);
|
|
||||||
PageDescriptor->u3.e1.PageLocation = FreePageList;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
DPRINT("Zeroed %d pages.\n", Count);
|
DPRINT("Zeroed %d pages.\n", Count);
|
||||||
|
|
Loading…
Reference in a new issue