mirror of
https://github.com/reactos/reactos.git
synced 2024-08-28 06:08:23 +00:00
* Call KeBugcheck in MmDeletePageTable/MmFreePageTable if the
address points to the kernel address space. * Check if an other process has inserted a kernel page directory entry while waiting for a page (MmGetPageEntry/MmGetPageEntry2). * Check the kernel page directory only for an entry if the address points to the kernel address space (MmGetPageEntry1/2, MmDeleteVirtualMapping and MmDeletePageFileMapping). * Disabled MmEnableVirtualMapping/MmDisableVirtualMapping. There is no difference between an entry with disabled mapping and a swap entry. svn path=/trunk/; revision=3700
This commit is contained in:
parent
a4b5d8a978
commit
3d3d96c5d6
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: page.c,v 1.45 2002/10/01 19:27:25 chorns Exp $
|
/* $Id: page.c,v 1.46 2002/11/05 20:39:03 hbirr Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/mm/i386/page.c
|
* FILE: ntoskrnl/mm/i386/page.c
|
||||||
|
@ -161,7 +161,7 @@ NTSTATUS MmCopyMmInfo(PEPROCESS Src, PEPROCESS Dest)
|
||||||
}
|
}
|
||||||
DPRINT("Addr %x\n",PAGETABLE_MAP / (4*1024*1024));
|
DPRINT("Addr %x\n",PAGETABLE_MAP / (4*1024*1024));
|
||||||
PageDirectory[PAGETABLE_MAP / (4*1024*1024)] =
|
PageDirectory[PAGETABLE_MAP / (4*1024*1024)] =
|
||||||
(ULONG)PhysPageDirectory.QuadPart | 0x7;
|
PhysPageDirectory.u.LowPart | PA_PRESENT | PA_READWRITE;
|
||||||
|
|
||||||
ExUnmapPage(PageDirectory);
|
ExUnmapPage(PageDirectory);
|
||||||
|
|
||||||
|
@ -180,7 +180,8 @@ VOID MmDeletePageTable(PEPROCESS Process, PVOID Address)
|
||||||
*(ADDR_TO_PDE(Address)) = 0;
|
*(ADDR_TO_PDE(Address)) = 0;
|
||||||
if (Address >= (PVOID)KERNEL_BASE)
|
if (Address >= (PVOID)KERNEL_BASE)
|
||||||
{
|
{
|
||||||
MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] = 0;
|
KeBugCheck(0);
|
||||||
|
// MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] = 0;
|
||||||
}
|
}
|
||||||
FLUSH_TLB;
|
FLUSH_TLB;
|
||||||
if (Process != NULL && Process != CurrentProcess)
|
if (Process != NULL && Process != CurrentProcess)
|
||||||
|
@ -200,6 +201,7 @@ VOID MmFreePageTable(PEPROCESS Process, PVOID Address)
|
||||||
{
|
{
|
||||||
KeAttachProcess(Process);
|
KeAttachProcess(Process);
|
||||||
}
|
}
|
||||||
|
|
||||||
PageTable = (PULONG)PAGE_ROUND_DOWN((PVOID)ADDR_TO_PTE(Address));
|
PageTable = (PULONG)PAGE_ROUND_DOWN((PVOID)ADDR_TO_PTE(Address));
|
||||||
for (i = 0; i < 1024; i++)
|
for (i = 0; i < 1024; i++)
|
||||||
{
|
{
|
||||||
|
@ -212,12 +214,17 @@ VOID MmFreePageTable(PEPROCESS Process, PVOID Address)
|
||||||
}
|
}
|
||||||
npage = *(ADDR_TO_PDE(Address));
|
npage = *(ADDR_TO_PDE(Address));
|
||||||
*(ADDR_TO_PDE(Address)) = 0;
|
*(ADDR_TO_PDE(Address)) = 0;
|
||||||
|
FLUSH_TLB;
|
||||||
|
|
||||||
if (Address >= (PVOID)KERNEL_BASE)
|
if (Address >= (PVOID)KERNEL_BASE)
|
||||||
{
|
{
|
||||||
MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] = 0;
|
// MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] = 0;
|
||||||
|
KeBugCheck(0);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
MmReleasePageMemoryConsumer(MC_NPPOOL, PTE_TO_PAGE(npage));
|
MmReleasePageMemoryConsumer(MC_NPPOOL, PTE_TO_PAGE(npage));
|
||||||
FLUSH_TLB;
|
}
|
||||||
if (Process != NULL && Process != CurrentProcess)
|
if (Process != NULL && Process != CurrentProcess)
|
||||||
{
|
{
|
||||||
KeDetachProcess();
|
KeDetachProcess();
|
||||||
|
@ -229,41 +236,66 @@ NTSTATUS MmGetPageEntry2(PVOID PAddress, PULONG* Pte, BOOLEAN MayWait)
|
||||||
* FUNCTION: Get a pointer to the page table entry for a virtual address
|
* FUNCTION: Get a pointer to the page table entry for a virtual address
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PULONG Pde;
|
PULONG Pde, kePde;
|
||||||
ULONG Address = (ULONG)PAddress;
|
|
||||||
PHYSICAL_ADDRESS npage;
|
PHYSICAL_ADDRESS npage;
|
||||||
|
BOOLEAN Free = FALSE;
|
||||||
|
NTSTATUS Status;
|
||||||
|
KIRQL oldIrql;
|
||||||
|
|
||||||
DPRINT("MmGetPageEntry(Address %x)\n", Address);
|
DPRINT("MmGetPageEntry(Address %x)\n", PAddress);
|
||||||
|
|
||||||
Pde = ADDR_TO_PDE(Address);
|
Pde = ADDR_TO_PDE(PAddress);
|
||||||
if ((*Pde) == 0)
|
if (*Pde == 0)
|
||||||
{
|
{
|
||||||
if (Address >= KERNEL_BASE &&
|
if (PAddress >= (PVOID)KERNEL_BASE)
|
||||||
MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] != 0)
|
|
||||||
{
|
{
|
||||||
(*Pde) = MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)];
|
kePde = MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(PAddress);
|
||||||
|
oldIrql = KeRaiseIrqlToSynchLevel();
|
||||||
|
if (*kePde != 0)
|
||||||
|
{
|
||||||
|
*Pde = *kePde;
|
||||||
FLUSH_TLB;
|
FLUSH_TLB;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
KeLowerIrql(oldIrql);
|
||||||
|
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, MayWait, &npage);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
oldIrql = KeRaiseIrqlToSynchLevel();
|
||||||
|
/* An other thread can set this pde entry, we must check again */
|
||||||
|
if (*kePde == 0)
|
||||||
|
{
|
||||||
|
*kePde = npage.u.LowPart | PA_PRESENT | PA_READWRITE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Free = TRUE;
|
||||||
|
}
|
||||||
|
*Pde = *kePde;
|
||||||
|
FLUSH_TLB;
|
||||||
|
}
|
||||||
|
KeLowerIrql(oldIrql);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, MayWait, &npage);
|
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, MayWait, &npage);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
(*Pde) = npage.QuadPart | 0x7;
|
*Pde = npage.u.LowPart | PA_PRESENT | PA_READWRITE | PA_USER;
|
||||||
if (Address >= KERNEL_BASE)
|
|
||||||
{
|
|
||||||
MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] =
|
|
||||||
*Pde;
|
|
||||||
}
|
|
||||||
memset((PVOID)PAGE_ROUND_DOWN(ADDR_TO_PTE(Address)), 0, PAGE_SIZE);
|
|
||||||
FLUSH_TLB;
|
FLUSH_TLB;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*Pte = ADDR_TO_PTE(Address);
|
*Pte = (PULONG)ADDR_TO_PTE(PAddress);
|
||||||
return(STATUS_SUCCESS);
|
if (Free)
|
||||||
|
{
|
||||||
|
MmReleasePageMemoryConsumer(MC_NPPOOL, npage);
|
||||||
|
}
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG MmGetPageEntryForProcess(PEPROCESS Process, PVOID Address)
|
ULONG MmGetPageEntryForProcess(PEPROCESS Process, PVOID Address)
|
||||||
|
@ -288,27 +320,30 @@ ULONG MmGetPageEntry1(PVOID PAddress)
|
||||||
* FUNCTION: Get a pointer to the page table entry for a virtual address
|
* FUNCTION: Get a pointer to the page table entry for a virtual address
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PULONG page_tlb;
|
PULONG Pde, kePde;
|
||||||
PULONG page_dir;
|
ULONG Entry = 0;
|
||||||
ULONG Address = (ULONG)PAddress;
|
|
||||||
|
|
||||||
DPRINT("MmGetPageEntry(Address %x)\n", Address);
|
DPRINT("MmGetPageEntry(Address %x)\n", PAddress);
|
||||||
|
|
||||||
page_dir = ADDR_TO_PDE(Address);
|
Pde = ADDR_TO_PDE(PAddress);
|
||||||
if ((*page_dir) == 0 &&
|
if (*Pde == 0)
|
||||||
MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] != 0)
|
|
||||||
{
|
{
|
||||||
(*page_dir) = MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)];
|
if (PAddress >= (PVOID)KERNEL_BASE)
|
||||||
|
{
|
||||||
|
kePde = MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(PAddress);
|
||||||
|
if (*kePde != 0)
|
||||||
|
{
|
||||||
|
*Pde = *kePde;
|
||||||
FLUSH_TLB;
|
FLUSH_TLB;
|
||||||
|
Entry = *(PULONG)ADDR_TO_PTE(PAddress);
|
||||||
}
|
}
|
||||||
DPRINT("page_dir %x *page_dir %x\n",page_dir,*page_dir);
|
}
|
||||||
if ((*page_dir) == 0)
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
return(0);
|
Entry = *(PULONG)ADDR_TO_PTE(PAddress);
|
||||||
}
|
}
|
||||||
page_tlb = ADDR_TO_PTE(Address);
|
return Entry;
|
||||||
DPRINT("page_tlb %x\n",page_tlb);
|
|
||||||
return(*page_tlb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG MmGetPageEntryForProcess1(PEPROCESS Process, PVOID Address)
|
ULONG MmGetPageEntryForProcess1(PEPROCESS Process, PVOID Address)
|
||||||
|
@ -343,7 +378,7 @@ MmGetPhysicalAddressForProcess(PEPROCESS Process,
|
||||||
}
|
}
|
||||||
return(PTE_TO_PAGE(PageEntry));
|
return(PTE_TO_PAGE(PageEntry));
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
VOID
|
VOID
|
||||||
MmDisableVirtualMapping(PEPROCESS Process, PVOID Address, BOOL* WasDirty, PHYSICAL_ADDRESS* PhysicalAddr)
|
MmDisableVirtualMapping(PEPROCESS Process, PVOID Address, BOOL* WasDirty, PHYSICAL_ADDRESS* PhysicalAddr)
|
||||||
/*
|
/*
|
||||||
|
@ -413,7 +448,7 @@ MmDisableVirtualMapping(PEPROCESS Process, PVOID Address, BOOL* WasDirty, PHYSIC
|
||||||
PhysicalAddr->u.LowPart = PAGE_MASK(Pte);
|
PhysicalAddr->u.LowPart = PAGE_MASK(Pte);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
VOID
|
VOID
|
||||||
MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage,
|
MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage,
|
||||||
BOOL* WasDirty, PHYSICAL_ADDRESS* PhysicalAddr)
|
BOOL* WasDirty, PHYSICAL_ADDRESS* PhysicalAddr)
|
||||||
|
@ -422,7 +457,7 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage,
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
ULONG Pte;
|
ULONG Pte;
|
||||||
PULONG Pde;
|
PULONG Pde, kePde;
|
||||||
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
||||||
BOOLEAN WasValid;
|
BOOLEAN WasValid;
|
||||||
|
|
||||||
|
@ -440,13 +475,17 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage,
|
||||||
* the global page directory.
|
* the global page directory.
|
||||||
*/
|
*/
|
||||||
Pde = ADDR_TO_PDE(Address);
|
Pde = ADDR_TO_PDE(Address);
|
||||||
if ((*Pde) == 0 &&
|
if (*Pde == 0 && Address >= (PVOID)KERNEL_BASE)
|
||||||
MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] != 0)
|
|
||||||
{
|
{
|
||||||
(*Pde) = MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)];
|
kePde = MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(Address);
|
||||||
|
if (*kePde != 0)
|
||||||
|
{
|
||||||
|
*Pde = *kePde;
|
||||||
FLUSH_TLB;
|
FLUSH_TLB;
|
||||||
}
|
}
|
||||||
if ((*Pde) == 0)
|
}
|
||||||
|
|
||||||
|
if (*Pde == 0)
|
||||||
{
|
{
|
||||||
if (Process != NULL && Process != CurrentProcess)
|
if (Process != NULL && Process != CurrentProcess)
|
||||||
{
|
{
|
||||||
|
@ -483,7 +522,7 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage,
|
||||||
*/
|
*/
|
||||||
if (Process != NULL && WasValid &&
|
if (Process != NULL && WasValid &&
|
||||||
Process->AddressSpace.PageTableRefCountTable != NULL &&
|
Process->AddressSpace.PageTableRefCountTable != NULL &&
|
||||||
ADDR_TO_PAGE_TABLE(Address) < 768)
|
Address < (PVOID)KERNEL_BASE)
|
||||||
{
|
{
|
||||||
PUSHORT Ptrc;
|
PUSHORT Ptrc;
|
||||||
|
|
||||||
|
@ -532,7 +571,7 @@ MmDeletePageFileMapping(PEPROCESS Process, PVOID Address,
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
ULONG Pte;
|
ULONG Pte;
|
||||||
PULONG Pde;
|
PULONG Pde, kePde;
|
||||||
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
||||||
BOOLEAN WasValid = FALSE;
|
BOOLEAN WasValid = FALSE;
|
||||||
|
|
||||||
|
@ -550,13 +589,19 @@ MmDeletePageFileMapping(PEPROCESS Process, PVOID Address,
|
||||||
* the global page directory.
|
* the global page directory.
|
||||||
*/
|
*/
|
||||||
Pde = ADDR_TO_PDE(Address);
|
Pde = ADDR_TO_PDE(Address);
|
||||||
if ((*Pde) == 0 &&
|
if (*Pde == 0)
|
||||||
MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] != 0)
|
|
||||||
{
|
{
|
||||||
(*Pde) = MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)];
|
if (Address >= (PVOID)KERNEL_BASE)
|
||||||
|
{
|
||||||
|
kePde = MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(Address);
|
||||||
|
if (*kePde != 0)
|
||||||
|
{
|
||||||
|
*Pde = *kePde;
|
||||||
FLUSH_TLB;
|
FLUSH_TLB;
|
||||||
}
|
}
|
||||||
if ((*Pde) == 0)
|
}
|
||||||
|
}
|
||||||
|
if (*Pde == 0)
|
||||||
{
|
{
|
||||||
if (Process != NULL && Process != CurrentProcess)
|
if (Process != NULL && Process != CurrentProcess)
|
||||||
{
|
{
|
||||||
|
@ -572,12 +617,14 @@ MmDeletePageFileMapping(PEPROCESS Process, PVOID Address,
|
||||||
Pte = (ULONG)InterlockedExchange((PLONG)ADDR_TO_PTE(Address), 0);
|
Pte = (ULONG)InterlockedExchange((PLONG)ADDR_TO_PTE(Address), 0);
|
||||||
FLUSH_TLB;
|
FLUSH_TLB;
|
||||||
|
|
||||||
|
WasValid = PAGE_MASK(Pte) == 0 ? FALSE : TRUE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Decrement the reference count for this page table.
|
* Decrement the reference count for this page table.
|
||||||
*/
|
*/
|
||||||
if (Process != NULL && WasValid &&
|
if (Process != NULL && WasValid &&
|
||||||
Process->AddressSpace.PageTableRefCountTable != NULL &&
|
Process->AddressSpace.PageTableRefCountTable != NULL &&
|
||||||
ADDR_TO_PAGE_TABLE(Address) < 768)
|
Address < (PVOID)KERNEL_BASE)
|
||||||
{
|
{
|
||||||
PUSHORT Ptrc;
|
PUSHORT Ptrc;
|
||||||
|
|
||||||
|
@ -607,61 +654,73 @@ MmDeletePageFileMapping(PEPROCESS Process, PVOID Address,
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
Mmi386MakeKernelPageTableGlobal(PVOID PAddress)
|
Mmi386MakeKernelPageTableGlobal(PVOID PAddress)
|
||||||
{
|
{
|
||||||
PULONG page_dir;
|
PULONG kePde, Pde;
|
||||||
ULONG Address = (ULONG)PAddress;
|
|
||||||
|
|
||||||
page_dir = ADDR_TO_PDE(Address);
|
Pde = ADDR_TO_PDE(PAddress);
|
||||||
if ((*page_dir) == 0 &&
|
if (*Pde == 0)
|
||||||
MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] != 0)
|
|
||||||
{
|
{
|
||||||
(*page_dir) = MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)];
|
kePde = MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(PAddress);
|
||||||
|
if (*kePde != 0)
|
||||||
|
{
|
||||||
|
*Pde = *kePde;
|
||||||
FLUSH_TLB;
|
FLUSH_TLB;
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN MmIsPageTablePresent(PVOID PAddress)
|
BOOLEAN MmIsPageTablePresent(PVOID PAddress)
|
||||||
{
|
{
|
||||||
PULONG page_dir;
|
PULONG Pde, kePde;
|
||||||
ULONG Address = (ULONG)PAddress;
|
|
||||||
|
|
||||||
page_dir = ADDR_TO_PDE(Address);
|
Pde = ADDR_TO_PDE(PAddress);
|
||||||
if ((*page_dir) == 0 &&
|
if (*Pde == 0)
|
||||||
MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] != 0)
|
|
||||||
{
|
{
|
||||||
(*page_dir) = MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)];
|
kePde = MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(PAddress);
|
||||||
|
if (*kePde != 0)
|
||||||
|
{
|
||||||
|
*Pde = *kePde;
|
||||||
FLUSH_TLB;
|
FLUSH_TLB;
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
return((*page_dir) == 0);
|
}
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS MmCreatePageTable(PVOID PAddress)
|
NTSTATUS MmCreatePageTable(PVOID PAddress)
|
||||||
{
|
{
|
||||||
PULONG page_dir;
|
PULONG Pde, kePde;
|
||||||
ULONG Address = (ULONG)PAddress;
|
|
||||||
PHYSICAL_ADDRESS npage;
|
PHYSICAL_ADDRESS npage;
|
||||||
|
|
||||||
DPRINT("MmGetPageEntry(Address %x)\n", Address);
|
|
||||||
|
|
||||||
page_dir = ADDR_TO_PDE(Address);
|
|
||||||
DPRINT("page_dir %x *page_dir %x\n",page_dir,*page_dir);
|
|
||||||
if ((*page_dir) == 0 &&
|
|
||||||
MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] != 0)
|
|
||||||
{
|
|
||||||
(*page_dir) = MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)];
|
|
||||||
FLUSH_TLB;
|
|
||||||
}
|
|
||||||
if ((*page_dir) == 0)
|
|
||||||
{
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
DPRINT("MmGetPageEntry(Address %x)\n", PAddress);
|
||||||
|
|
||||||
|
Pde = ADDR_TO_PDE(PAddress);
|
||||||
|
DPRINT("page_dir %x *page_dir %x\n", Pde, *Pde);
|
||||||
|
if (*Pde == 0 && PAddress >= (PVOID)KERNEL_BASE)
|
||||||
|
{
|
||||||
|
kePde = MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(PAddress);
|
||||||
|
if (*kePde != 0)
|
||||||
|
{
|
||||||
|
*Pde = *kePde;
|
||||||
|
FLUSH_TLB;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
/* Should we create a kernel page table? */
|
||||||
|
DPRINT1("!!!!!!!!!!!!!!!!!!\n");
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*Pde == 0)
|
||||||
|
{
|
||||||
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &npage);
|
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &npage);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
(*page_dir) = npage.QuadPart | 0x7;
|
MiZeroPage(npage);
|
||||||
memset((PVOID)PAGE_ROUND_DOWN(ADDR_TO_PTE(Address)), 0, PAGE_SIZE);
|
*Pde = npage.u.LowPart | PA_PRESENT | PA_READWRITE | PA_USER;
|
||||||
FLUSH_TLB;
|
FLUSH_TLB;
|
||||||
}
|
}
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
|
@ -672,36 +731,69 @@ PULONG MmGetPageEntry(PVOID PAddress)
|
||||||
* FUNCTION: Get a pointer to the page table entry for a virtual address
|
* FUNCTION: Get a pointer to the page table entry for a virtual address
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PULONG page_tlb;
|
PULONG Pde, kePde;
|
||||||
PULONG page_dir;
|
|
||||||
ULONG Address = (ULONG)PAddress;
|
|
||||||
PHYSICAL_ADDRESS npage;
|
PHYSICAL_ADDRESS npage;
|
||||||
|
KIRQL oldIrql;
|
||||||
|
BOOLEAN Free = FALSE;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("MmGetPageEntry(Address %x)\n", Address);
|
DPRINT("MmGetPageEntry(Address %x)\n", PAddress);
|
||||||
|
|
||||||
page_dir = ADDR_TO_PDE(Address);
|
Pde = ADDR_TO_PDE(PAddress);
|
||||||
DPRINT("page_dir %x *page_dir %x\n",page_dir,*page_dir);
|
DPRINT("page_dir %x *page_dir %x\n",Pde,*Pde);
|
||||||
if ((*page_dir) == 0 &&
|
if (*Pde == 0)
|
||||||
MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] != 0)
|
|
||||||
{
|
{
|
||||||
(*page_dir) = MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)];
|
if (PAddress >= (PVOID)KERNEL_BASE)
|
||||||
|
{
|
||||||
|
oldIrql = KeRaiseIrqlToSynchLevel();
|
||||||
|
kePde = MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(PAddress);
|
||||||
|
if (*kePde != 0)
|
||||||
|
{
|
||||||
|
*Pde = *kePde;
|
||||||
FLUSH_TLB;
|
FLUSH_TLB;
|
||||||
}
|
}
|
||||||
if ((*page_dir) == 0)
|
else
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
KeLowerIrql(oldIrql);
|
||||||
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &npage);
|
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &npage);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
}
|
}
|
||||||
(*page_dir) = npage.QuadPart | 0x7;
|
MiZeroPage(npage);
|
||||||
memset((PVOID)PAGE_ROUND_DOWN(ADDR_TO_PTE(Address)), 0, PAGE_SIZE);
|
oldIrql = KeRaiseIrqlToSynchLevel();
|
||||||
|
if (*kePde != 0)
|
||||||
|
{
|
||||||
|
*Pde = *kePde;
|
||||||
|
FLUSH_TLB;
|
||||||
|
Free = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*Pde = *kePde = npage.u.LowPart | PA_PRESENT | PA_READWRITE;
|
||||||
FLUSH_TLB;
|
FLUSH_TLB;
|
||||||
}
|
}
|
||||||
page_tlb = ADDR_TO_PTE(Address);
|
}
|
||||||
DPRINT("page_tlb %x\n",page_tlb);
|
KeLowerIrql(oldIrql);
|
||||||
return(page_tlb);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &npage);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
MiZeroPage(npage);
|
||||||
|
*Pde = npage.u.LowPart | PA_PRESENT | PA_READWRITE | PA_USER;
|
||||||
|
FLUSH_TLB;
|
||||||
|
}
|
||||||
|
if (Free)
|
||||||
|
{
|
||||||
|
MmReleasePageMemoryConsumer(MC_NPPOOL, npage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ADDR_TO_PTE(PAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN MmIsDirtyPage(PEPROCESS Process, PVOID Address)
|
BOOLEAN MmIsDirtyPage(PEPROCESS Process, PVOID Address)
|
||||||
|
@ -770,7 +862,7 @@ VOID MmSetDirtyPage(PEPROCESS Process, PVOID Address)
|
||||||
KeDetachProcess();
|
KeDetachProcess();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
VOID MmEnableVirtualMapping(PEPROCESS Process, PVOID Address)
|
VOID MmEnableVirtualMapping(PEPROCESS Process, PVOID Address)
|
||||||
{
|
{
|
||||||
PULONG PageEntry;
|
PULONG PageEntry;
|
||||||
|
@ -788,7 +880,7 @@ VOID MmEnableVirtualMapping(PEPROCESS Process, PVOID Address)
|
||||||
KeDetachProcess();
|
KeDetachProcess();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
BOOLEAN MmIsPagePresent(PEPROCESS Process, PVOID Address)
|
BOOLEAN MmIsPagePresent(PEPROCESS Process, PVOID Address)
|
||||||
{
|
{
|
||||||
return((MmGetPageEntryForProcess1(Process, Address)) & PA_PRESENT);
|
return((MmGetPageEntryForProcess1(Process, Address)) & PA_PRESENT);
|
||||||
|
|
Loading…
Reference in a new issue