mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 01:15:43 +00:00
[NTOS]: Add support for user-mode VAD faults on page tables (just a couple lines of extra code).
[NTOS]: Add support for user-mode VAD demand zero faults. [NTOS]: Remove broken ASSERT. svn path=/trunk/; revision=49035
This commit is contained in:
parent
9dabd64349
commit
12e7ae649b
1 changed files with 45 additions and 17 deletions
|
@ -32,8 +32,25 @@ MiCheckVirtualAddress(IN PVOID VirtualAddress,
|
||||||
/* No prototype/section support for now */
|
/* No prototype/section support for now */
|
||||||
*ProtoVad = NULL;
|
*ProtoVad = NULL;
|
||||||
|
|
||||||
/* Only valid for user VADs for now */
|
/* Check if this is a page table address */
|
||||||
ASSERT(VirtualAddress <= MM_HIGHEST_USER_ADDRESS);
|
if (MI_IS_PAGE_TABLE_ADDRESS(VirtualAddress))
|
||||||
|
{
|
||||||
|
/* This should never happen, as these addresses are handled by the double-maping */
|
||||||
|
if (((PMMPTE)VirtualAddress >= MiAddressToPte(MmPagedPoolStart)) &&
|
||||||
|
((PMMPTE)VirtualAddress <= MmPagedPoolInfo.LastPteForPagedPool))
|
||||||
|
{
|
||||||
|
/* Fail such access */
|
||||||
|
*ProtectCode = MM_NOACCESS;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return full access rights */
|
||||||
|
*ProtectCode = MM_READWRITE;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Should not be a session address */
|
||||||
|
ASSERT(MI_IS_SESSION_ADDRESS(VirtualAddress) == FALSE);
|
||||||
|
|
||||||
/* Special case for shared data */
|
/* Special case for shared data */
|
||||||
if (PAGE_ALIGN(VirtualAddress) == (PVOID)USER_SHARED_DATA)
|
if (PAGE_ALIGN(VirtualAddress) == (PVOID)USER_SHARED_DATA)
|
||||||
|
@ -642,7 +659,7 @@ MmArmAccessFault(IN BOOLEAN StoreInstruction,
|
||||||
//
|
//
|
||||||
// Check for kernel fault
|
// Check for kernel fault
|
||||||
//
|
//
|
||||||
if (Address >= MmSystemRangeStart)
|
while (Address >= MmSystemRangeStart)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// What are you even DOING here?
|
// What are you even DOING here?
|
||||||
|
@ -718,25 +735,16 @@ MmArmAccessFault(IN BOOLEAN StoreInstruction,
|
||||||
//
|
//
|
||||||
if (MI_IS_PAGE_TABLE_OR_HYPER_ADDRESS(Address))
|
if (MI_IS_PAGE_TABLE_OR_HYPER_ADDRESS(Address))
|
||||||
{
|
{
|
||||||
//
|
|
||||||
// This might happen...not sure yet
|
|
||||||
//
|
|
||||||
DPRINT1("FAULT ON PAGE TABLES: %p %lx %lx!\n", Address, *PointerPte, *PointerPde);
|
|
||||||
#if (_MI_PAGING_LEVELS == 2)
|
#if (_MI_PAGING_LEVELS == 2)
|
||||||
//
|
/* Could be paged pool access from a new process -- synchronize the page directories */
|
||||||
// Map in the page table
|
|
||||||
//
|
|
||||||
if (MiCheckPdeForPagedPool(Address) == STATUS_WAIT_1)
|
if (MiCheckPdeForPagedPool(Address) == STATUS_WAIT_1)
|
||||||
{
|
{
|
||||||
DPRINT1("PAGE TABLES FAULTED IN!\n");
|
DPRINT1("PAGE TABLES FAULTED IN!\n");
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
//
|
/* Otherwise this could be a commit of a virtual address */
|
||||||
// Otherwise the page table doesn't actually exist
|
break;
|
||||||
//
|
|
||||||
DPRINT1("FAILING\n");
|
|
||||||
return STATUS_ACCESS_VIOLATION;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In this path, we are using the system working set */
|
/* In this path, we are using the system working set */
|
||||||
|
@ -866,7 +874,8 @@ MmArmAccessFault(IN BOOLEAN StoreInstruction,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* First things first, is the PDE valid? */
|
/* First things first, is the PDE valid? */
|
||||||
ASSERT(PointerPde != MiAddressToPde(PTE_BASE));
|
// DPRINT1("The PDE we faulted on: %lx %lx\n", PointerPde, MiAddressToPde(PTE_BASE));
|
||||||
|
//ASSERT(PointerPde != MiAddressToPde(PTE_BASE));
|
||||||
ASSERT(PointerPde->u.Hard.LargePage == 0);
|
ASSERT(PointerPde->u.Hard.LargePage == 0);
|
||||||
if (PointerPde->u.Hard.Valid == 0)
|
if (PointerPde->u.Hard.Valid == 0)
|
||||||
{
|
{
|
||||||
|
@ -901,8 +910,27 @@ MmArmAccessFault(IN BOOLEAN StoreInstruction,
|
||||||
ASSERT(PointerPde->u.Hard.Valid == 1);
|
ASSERT(PointerPde->u.Hard.Valid == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now capture the PTE. We only handle cases where it's totally empty */
|
/* Now capture the PTE. Ignore virtual faults for now */
|
||||||
TempPte = *PointerPte;
|
TempPte = *PointerPte;
|
||||||
|
ASSERT(TempPte.u.Hard.Valid == 0);
|
||||||
|
|
||||||
|
/* Quick check for demand-zero */
|
||||||
|
if (TempPte.u.Long == (MM_READWRITE << MM_PTE_SOFTWARE_PROTECTION_BITS))
|
||||||
|
{
|
||||||
|
/* Resolve the fault */
|
||||||
|
//DPRINT1("VAD demand-zero fault: %p\n", Address);
|
||||||
|
MiResolveDemandZeroFault(Address,
|
||||||
|
PointerPte,
|
||||||
|
CurrentProcess,
|
||||||
|
MM_NOIRQL);
|
||||||
|
|
||||||
|
/* Return the status */
|
||||||
|
MiUnlockProcessWorkingSet(CurrentProcess, CurrentThread);
|
||||||
|
return STATUS_PAGE_FAULT_DEMAND_ZERO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't handle prototype PTEs yet -- only kernel demand zero PTEs */
|
||||||
|
ASSERT(TempPte.u.Soft.Prototype == 0);
|
||||||
ASSERT(TempPte.u.Long == 0);
|
ASSERT(TempPte.u.Long == 0);
|
||||||
|
|
||||||
/* Check if this address range belongs to a valid allocation (VAD) */
|
/* Check if this address range belongs to a valid allocation (VAD) */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue