[NTOS]: Add the tiny little bit of code required to correctly handle user-mode faults on ARM3 mapped sections in certain limited scenarios.

svn path=/trunk/; revision=48993
This commit is contained in:
Sir Richard 2010-10-05 08:14:02 +00:00
parent 121276a884
commit 04a028b58e

View file

@ -27,6 +27,7 @@ MiCheckVirtualAddress(IN PVOID VirtualAddress,
OUT PMMVAD *ProtoVad) OUT PMMVAD *ProtoVad)
{ {
PMMVAD Vad; PMMVAD Vad;
PMMPTE PointerPte;
/* No prototype/section support for now */ /* No prototype/section support for now */
*ProtoVad = NULL; *ProtoVad = NULL;
@ -51,15 +52,33 @@ MiCheckVirtualAddress(IN PVOID VirtualAddress,
return NULL; return NULL;
} }
/* This must be a TEB/PEB VAD */ /* This must be a VM VAD */
ASSERT(Vad->u.VadFlags.PrivateMemory == TRUE);
ASSERT(Vad->u.VadFlags.MemCommit == TRUE);
ASSERT(Vad->u.VadFlags.VadType == VadNone); ASSERT(Vad->u.VadFlags.VadType == VadNone);
/* Return the protection on it */ /* Check if it's a section, or just an allocation */
if (Vad->u.VadFlags.PrivateMemory == TRUE)
{
/* This must be a TEB/PEB VAD */
ASSERT(Vad->u.VadFlags.MemCommit == TRUE);
*ProtectCode = Vad->u.VadFlags.Protection; *ProtectCode = Vad->u.VadFlags.Protection;
return NULL; return NULL;
} }
else
{
/* Return the proto VAD */
ASSERT(Vad->u2.VadFlags2.ExtendableFile == 0);
*ProtoVad = Vad;
/* Get the prototype PTE for this page */
PointerPte = (((ULONG_PTR)VirtualAddress >> PAGE_SHIFT) - Vad->StartingVpn) + Vad->FirstPrototypePte;
ASSERT(PointerPte <= Vad->LastContiguousPte);
ASSERT(PointerPte != NULL);
/* Return the Prototype PTE and the protection for the page mapping */
*ProtectCode = Vad->u.VadFlags.Protection;
return PointerPte;
}
}
NTSTATUS NTSTATUS
FASTCALL FASTCALL
@ -482,8 +501,8 @@ MiDispatchFault(IN BOOLEAN StoreInstruction,
} }
else else
{ {
ASSERT(PointerPte->u.Hard.Valid == 0);
/* Resolve the fault -- this will release the PFN lock */ /* Resolve the fault -- this will release the PFN lock */
ASSERT(PointerPte->u.Hard.Valid == 0);
Status = MiResolveProtoPteFault(StoreInstruction, Status = MiResolveProtoPteFault(StoreInstruction,
Address, Address,
PointerPte, PointerPte,
@ -505,15 +524,14 @@ MiDispatchFault(IN BOOLEAN StoreInstruction,
} }
else else
{ {
/* We currently only handle the shared user data PTE path */ /* We currently only handle very limited paths */
ASSERT(PointerPte->u.Soft.Prototype == 1); ASSERT(PointerPte->u.Soft.Prototype == 1);
ASSERT(PointerPte->u.Soft.PageFileHigh == MI_PTE_LOOKUP_NEEDED); ASSERT(PointerPte->u.Soft.PageFileHigh == MI_PTE_LOOKUP_NEEDED);
ASSERT(Vad == NULL);
/* Lock the PFN database */ /* Lock the PFN database */
LockIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); LockIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
/* For the shared data page, this should be true */ /* For our current usage, this should be true */
ASSERT(SuperProtoPte->u.Hard.Valid == 1); ASSERT(SuperProtoPte->u.Hard.Valid == 1);
ASSERT(TempPte.u.Hard.Valid == 0); ASSERT(TempPte.u.Hard.Valid == 0);
@ -972,8 +990,9 @@ MmArmAccessFault(IN BOOLEAN StoreInstruction,
} }
else else
{ {
/* The only "prototype PTE" we support is the shared user data path */ /* No guard page support yet */
ASSERT(ProtectionCode == MM_READONLY); ASSERT((ProtectionCode & MM_DECOMMIT) == 0);
ASSERT(ProtectionCode != 0x100);
/* Write the prototype PTE */ /* Write the prototype PTE */
TempPte = PrototypePte; TempPte = PrototypePte;
@ -991,7 +1010,7 @@ MmArmAccessFault(IN BOOLEAN StoreInstruction,
Vad); Vad);
ASSERT(Status == STATUS_PAGE_FAULT_TRANSITION); ASSERT(Status == STATUS_PAGE_FAULT_TRANSITION);
ASSERT(PointerPte->u.Hard.Valid == 1); ASSERT(PointerPte->u.Hard.Valid == 1);
ASSERT(PointerPte->u.Hard.PageFrameNumber == MmSharedUserDataPte->u.Hard.PageFrameNumber); ASSERT(PointerPte->u.Hard.PageFrameNumber != 0);
} }
/* Release the working set */ /* Release the working set */