Author: sir_richard
Date: Thu Jul 22 03:22:43 2010
New Revision: 48176
URL: http://svn.reactos.org/svn/reactos?rev=48176&view=rev
Log:
[NTOS]: MiRosTakeOverPebTebRanges now creates a small ~1MB ARM3 memory range on top of the ReactOS per-process VA. This does a couple of things: First of all, it changes the default PEB address to another static address. Still not dynamic like it will be soon, but at least it changes it a bit so we can test if anything breaks due to that. It also likewise changes the addresses of the TEBs (Shifted down by 1MB, basically). Finally, it blocks off that part of address space, which nobody should be using now, to see if anyone does indeed touch it.
[NTOS]: Knowing if this change causes issues will help later in determining regressions due to TEB/PEBs mapped as VADs by ARM3, and regressions simply due to the change in VA layout.
[NTOS]: When implemented, the VAD mapping for PEB/TEB will only use that ~1MB, which yes, will limit ReactOS processes to each have only 256 threads. That is obviously a temporary limitation, one I doubt we'll even hit, but I'm putting it out here so you know.
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/procsup.c
trunk/reactos/ntoskrnl/mm/procsup.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/procsup.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/procsup.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/procsup.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/procsup.c [iso-8859-1] Thu Jul 22 03:22:43 2010
@@ -24,6 +24,29 @@
PVOID BaseAddress);
/* PRIVATE FUNCTIONS **********************************************************/
+
+VOID
+NTAPI
+MiRosTakeOverPebTebRanges(IN PEPROCESS Process)
+{
+ NTSTATUS Status;
+ PMEMORY_AREA MemoryArea;
+ PHYSICAL_ADDRESS BoundaryAddressMultiple;
+ PVOID AllocatedBase = (PVOID)MI_LOWEST_VAD_ADDRESS;
+ BoundaryAddressMultiple.QuadPart = 0;
+
+ Status = MmCreateMemoryArea(&Process->Vm,
+ MEMORY_AREA_OWNED_BY_ARM3,
+ &AllocatedBase,
+ ((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS - 1) -
+ (ULONG_PTR)MI_LOWEST_VAD_ADDRESS,
+ PAGE_READWRITE,
+ &MemoryArea,
+ TRUE,
+ 0,
+ BoundaryAddressMultiple);
+ ASSERT(NT_SUCCESS(Status));
+}
VOID
NTAPI
@@ -394,8 +417,8 @@
//
Peb = MiCreatePebOrTeb(Process,
(PVOID)((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1));
- ASSERT(Peb == (PVOID)0x7FFDF000);
-
+ if (!Peb) return STATUS_INSUFFICIENT_RESOURCES;
+
//
// Map NLS Tables
//
Modified: trunk/reactos/ntoskrnl/mm/procsup.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/procsup.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/procsup.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/procsup.c [iso-8859-1] Thu Jul 22 03:22:43 2010
@@ -13,8 +13,10 @@
#define NDEBUG
#include <debug.h>
+VOID NTAPI MiRosTakeOverPebTebRanges(IN PEPROCESS Process);
+
/* FUNCTIONS *****************************************************************/
-
+
PVOID
NTAPI
MiCreatePebOrTeb(PEPROCESS Process,
@@ -111,6 +113,9 @@
FALSE,
0,
BoundaryAddressMultiple);
+
+ /* Lock the VAD, ARM3-owned ranges away */
+ MiRosTakeOverPebTebRanges(Process);
return Status;
}
@@ -192,7 +197,10 @@
{
DPRINT1("Failed to create Shared User Data\n");
goto exit;
- }
+ }
+
+ /* Lock the VAD, ARM3-owned ranges away */
+ MiRosTakeOverPebTebRanges(Process);
/* The process now has an address space */
Process->HasAddressSpace = TRUE;
@@ -319,6 +327,7 @@
case MEMORY_AREA_SHARED_DATA:
case MEMORY_AREA_NO_ACCESS:
+ case MEMORY_AREA_OWNED_BY_ARM3:
MmFreeMemoryArea(&Process->Vm,
MemoryArea,
NULL,
Author: sir_richard
Date: Thu Jul 22 02:20:27 2010
New Revision: 48175
URL: http://svn.reactos.org/svn/reactos?rev=48175&view=rev
Log:
[NTOS]: Learn to build User PTEs as well, with MI_MAKE_HARDWARE_PTE_USER.
[NTOS]: MI_MAKE_HARDWARE_PTE becomes MI_MAKE_HARDWARE_PTE_KERNEL, since it assumed this. MI_MAKE_HARDWARE_PTE is now a "generic" you can use when you don't know what the PTE should be. It uses MiDetermineUserGlobalMask to set the right bits.
[NTOS]: Add two more helpers: MI_IS_PAGE_TABLE_ADDRESS and MI_IS_SYSTEM_PAGE_TABLE_ADDDRESS. One is in the symbols, the other I made up to make things clearer.
[NTOS]: MiResolveDemandZeroFault now knnows how to resolve user-demand-zero-faults.
[NTOS]: Implement MiZeroPfn to do the actual zeroing during user-demand-zero-faults (also later for VAD faults).
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c
trunk/reactos/ntoskrnl/mm/ARM3/procsup.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/miarm.h?r…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] Thu Jul 22 02:20:27 2010
@@ -192,6 +192,12 @@
#define MI_IS_SESSION_PTE(Pte) \
((((PMMPTE)Pte) >= MiSessionBasePte) && (((PMMPTE)Pte) < MiSessionLastPte))
+
+#define MI_IS_PAGE_TABLE_ADDRESS(Address) \
+ (((PVOID)(Address) >= (PVOID)PTE_BASE) && ((PVOID)(Address) <= (PVOID)PTE_TOP))
+
+#define MI_IS_SYSTEM_PAGE_TABLE_ADDRESS(Address) \
+ (((Address) >= (PVOID)MiAddressToPte(MmSystemRangeStart)) && ((Address) <= (PVOID)PTE_TOP))
//
// Corresponds to MMPTE_SOFTWARE.Protection
@@ -470,7 +476,60 @@
#define MI_PFNENTRY_TO_PFN(x) (x - MmPfnDatabase[1])
//
+// Figures out the hardware bits for a PTE
+//
+ULONG
+FORCEINLINE
+MiDetermineUserGlobalPteMask(IN PMMPTE PointerPte)
+{
+ MMPTE TempPte;
+
+ /* Start fresh */
+ TempPte.u.Long = 0;
+
+ /* Make it valid and accessed */
+ TempPte.u.Hard.Valid = TRUE;
+ TempPte.u.Hard.Accessed = TRUE;
+
+ /* Is this for user-mode? */
+ if ((PointerPte <= MiHighestUserPte) ||
+ ((PointerPte >= MiAddressToPde(NULL)) && (PointerPte <= MiHighestUserPde)))
+ {
+ /* Set the owner bit */
+ TempPte.u.Hard.Owner = TRUE;
+ }
+
+ /* FIXME: We should also set the global bit */
+
+ /* Return the protection */
+ return TempPte.u.Long;
+}
+
+//
// Creates a valid kernel PTE with the given protection
+//
+FORCEINLINE
+VOID
+MI_MAKE_HARDWARE_PTE_KERNEL(IN PMMPTE NewPte,
+ IN PMMPTE MappingPte,
+ IN ULONG ProtectionMask,
+ IN PFN_NUMBER PageFrameNumber)
+{
+ /* Only valid for kernel, non-session PTEs */
+ ASSERT(MappingPte > MiHighestUserPte);
+ ASSERT(!MI_IS_SESSION_PTE(MappingPte));
+ ASSERT((MappingPte < (PMMPTE)PDE_BASE) || (MappingPte > (PMMPTE)PDE_TOP));
+
+ /* Start fresh */
+ *NewPte = ValidKernelPte;
+
+ /* Set the protection and page */
+ NewPte->u.Hard.PageFrameNumber = PageFrameNumber;
+ NewPte->u.Long |= MmProtectToPteMask[ProtectionMask];
+}
+
+//
+// Creates a valid PTE with the given protection
//
FORCEINLINE
VOID
@@ -479,15 +538,30 @@
IN ULONG ProtectionMask,
IN PFN_NUMBER PageFrameNumber)
{
+ /* Set the protection and page */
+ NewPte->u.Long = MiDetermineUserGlobalPteMask(MappingPte);
+ NewPte->u.Long |= MmProtectToPteMask[ProtectionMask];
+ NewPte->u.Hard.PageFrameNumber = PageFrameNumber;
+}
+
+//
+// Creates a valid user PTE with the given protection
+//
+FORCEINLINE
+VOID
+MI_MAKE_HARDWARE_PTE_USER(IN PMMPTE NewPte,
+ IN PMMPTE MappingPte,
+ IN ULONG ProtectionMask,
+ IN PFN_NUMBER PageFrameNumber)
+{
/* Only valid for kernel, non-session PTEs */
- ASSERT(MappingPte > MiHighestUserPte);
- ASSERT(!MI_IS_SESSION_PTE(MappingPte));
- ASSERT((MappingPte < (PMMPTE)PDE_BASE) || (MappingPte > (PMMPTE)PDE_TOP));
+ ASSERT(MappingPte <= MiHighestUserPte);
/* Start fresh */
*NewPte = ValidKernelPte;
/* Set the protection and page */
+ NewPte->u.Hard.Owner = TRUE;
NewPte->u.Hard.PageFrameNumber = PageFrameNumber;
NewPte->u.Long |= MmProtectToPteMask[ProtectionMask];
}
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pagfault.…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] Thu Jul 22 02:20:27 2010
@@ -34,8 +34,7 @@
//
// Check if this is a fault while trying to access the page table itself
//
- if ((Address >= (PVOID)MiAddressToPte(MmSystemRangeStart)) &&
- (Address < (PVOID)PTE_TOP))
+ if (MI_IS_SYSTEM_PAGE_TABLE_ADDRESS(Address))
{
//
// Send a hint to the page fault handler that this is only a valid fault
@@ -82,6 +81,52 @@
// Return status
//
return Status;
+}
+
+VOID
+NTAPI
+MiZeroPfn(IN PFN_NUMBER PageFrameNumber)
+{
+ PMMPTE ZeroPte;
+ MMPTE TempPte;
+ PMMPFN Pfn1;
+ PVOID ZeroAddress;
+
+ /* Get the PFN for this page */
+ Pfn1 = MiGetPfnEntry(PageFrameNumber);
+ ASSERT(Pfn1);
+
+ /* Grab a system PTE we can use to zero the page */
+ ZeroPte = MiReserveSystemPtes(1, SystemPteSpace);
+ ASSERT(ZeroPte);
+
+ /* Initialize the PTE for it */
+ TempPte = ValidKernelPte;
+ TempPte.u.Hard.PageFrameNumber = PageFrameNumber;
+
+ /* Setup caching */
+ if (Pfn1->u3.e1.CacheAttribute == MiWriteCombined)
+ {
+ /* Write combining, no caching */
+ MI_PAGE_DISABLE_CACHE(&TempPte);
+ MI_PAGE_WRITE_COMBINED(&TempPte);
+ }
+ else if (Pfn1->u3.e1.CacheAttribute == MiNonCached)
+ {
+ /* Write through, no caching */
+ MI_PAGE_DISABLE_CACHE(&TempPte);
+ MI_PAGE_WRITE_THROUGH(&TempPte);
+ }
+
+ /* Make the system PTE valid with our PFN */
+ MI_WRITE_VALID_PTE(ZeroPte, TempPte);
+
+ /* Get the address it maps to, and zero it out */
+ ZeroAddress = MiPteToAddress(ZeroPte);
+ KeZeroPages(ZeroAddress, PAGE_SIZE);
+
+ /* Now get rid of it */
+ MiReleaseSystemPtes(ZeroPte, 1, SystemPteSpace);
}
NTSTATUS
@@ -93,13 +138,24 @@
{
PFN_NUMBER PageFrameNumber;
MMPTE TempPte;
+ BOOLEAN NeedZero = FALSE;
DPRINT("ARM3 Demand Zero Page Fault Handler for address: %p in process: %p\n",
Address,
Process);
- /* Must currently only be called by paging path, for system addresses only */
+ /* Must currently only be called by paging path */
ASSERT(OldIrql == MM_NOIRQL);
- ASSERT(Process == NULL);
+ if (Process)
+ {
+ /* Sanity check */
+ ASSERT(MI_IS_PAGE_TABLE_ADDRESS(PointerPte));
+
+ /* No forking yet */
+ ASSERT(Process->ForkInProgress == NULL);
+
+ /* We'll need a zero page */
+ NeedZero = TRUE;
+ }
//
// Lock the PFN database
@@ -124,11 +180,31 @@
//
InterlockedIncrement(&KeGetCurrentPrcb()->MmDemandZeroCount);
- /* Shouldn't see faults for user PTEs yet */
- ASSERT(PointerPte > MiHighestUserPte);
+ /* Zero the page if need be */
+ if (NeedZero) MiZeroPfn(PageFrameNumber);
/* Build the PTE */
- MI_MAKE_HARDWARE_PTE(&TempPte, PointerPte, PointerPte->u.Soft.Protection, PageFrameNumber);
+ if (PointerPte <= MiHighestUserPte)
+ {
+ /* For user mode */
+ MI_MAKE_HARDWARE_PTE_USER(&TempPte,
+ PointerPte,
+ PointerPte->u.Soft.Protection,
+ PageFrameNumber);
+ }
+ else
+ {
+ /* For kernel mode */
+ MI_MAKE_HARDWARE_PTE(&TempPte,
+ PointerPte,
+ PointerPte->u.Soft.Protection,
+ PageFrameNumber);
+ }
+
+ /* Set it dirty if it's a writable page */
+ if (TempPte.u.Hard.Write) TempPte.u.Hard.Dirty = TRUE;
+
+ /* Write it */
MI_WRITE_VALID_PTE(PointerPte, TempPte);
//
Modified: trunk/reactos/ntoskrnl/mm/ARM3/procsup.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/procsup.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/procsup.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/procsup.c [iso-8859-1] Thu Jul 22 02:20:27 2010
@@ -156,7 +156,7 @@
MI_MAKE_SOFTWARE_PTE(&InvalidPte, MM_NOACCESS);
/* Setup the template stack PTE */
- MI_MAKE_HARDWARE_PTE(&TempPte, PointerPte + 1, MM_READWRITE, 0);
+ MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte, PointerPte + 1, MM_READWRITE, 0);
//
// Acquire the PFN DB lock
@@ -270,7 +270,7 @@
MiInitializePfn(PageFrameIndex, LimitPte, 1);
/* Setup the template stack PTE */
- MI_MAKE_HARDWARE_PTE(&TempPte, LimitPte, MM_READWRITE, PageFrameIndex);
+ MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte, LimitPte, MM_READWRITE, PageFrameIndex);
/* Write the valid PTE */
MI_WRITE_VALID_PTE(LimitPte--, TempPte);