Author: ion
Date: Sun Jul 15 23:42:27 2012
New Revision: 56906
URL:
http://svn.reactos.org/svn/reactos?rev=56906&view=rev
Log:
[NTOSKRNL]: Implement support for session pool (not yet enabled) and session space
(implemented and enabled, but nobody is calling the APIs yet).
[NTOSKRNL]: Implement MmMapViewOInSessionSpace, MmUnmapViewInSessionSpace. Win32k needs to
use these to we can test them.
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c
trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c
trunk/reactos/ntoskrnl/mm/ARM3/pool.c
trunk/reactos/ntoskrnl/mm/ARM3/procsup.c
trunk/reactos/ntoskrnl/mm/ARM3/section.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/i386/init…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c [iso-8859-1] Sun Jul 15 23:42:27 2012
@@ -18,8 +18,13 @@
/* GLOBALS ********************************************************************/
/* Template PTE and PDE for a kernel page */
+ /* FIXME: These should be PTE_GLOBAL */
MMPTE ValidKernelPde = {{PTE_VALID|PTE_READWRITE|PTE_DIRTY|PTE_ACCESSED}};
MMPTE ValidKernelPte = {{PTE_VALID|PTE_READWRITE|PTE_DIRTY|PTE_ACCESSED}};
+
+/* The same, but for local pages */
+MMPTE ValidKernelPdeLocal = {{PTE_VALID|PTE_READWRITE|PTE_DIRTY|PTE_ACCESSED}};
+MMPTE ValidKernelPteLocal = {{PTE_VALID|PTE_READWRITE|PTE_DIRTY|PTE_ACCESSED}};
/* Template PDE for a demand-zero page */
MMPDE DemandZeroPde = {{MM_READWRITE << MM_PTE_SOFTWARE_PROTECTION_BITS}};
@@ -106,6 +111,18 @@
MiSessionImagePteEnd = MiAddressToPte(MiSessionImageEnd);
MiSessionBasePte = MiAddressToPte(MmSessionBase);
MiSessionLastPte = MiAddressToPte(MiSessionSpaceEnd);
+
+ /* Initialize session space */
+ MmSessionSpace = (PMM_SESSION_SPACE)((ULONG_PTR)MmSessionBase +
+ MmSessionSize -
+ MmSessionImageSize -
+ MM_ALLOCATION_GRANULARITY);
+
+ /* Setup all starting addresses */
+ DPRINT1("Session space: 0x%p\n", MmSessionSpace);
+ DPRINT1("Session Base: 0x%p, Session Image Size: 0x%lx, Session Image Start:
0x%p, Session ImageEnd: 0x%p\n",
+ MmSessionBase, MmSessionSize, MiSessionImageStart, MiSessionImageEnd);
+ DPRINT1("Session View start: 0x%p, Session View Size: 0x%lx\n",
MiSessionViewStart, MmSessionViewSize);
}
VOID
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] Sun Jul 15 23:42:27 2012
@@ -221,6 +221,11 @@
#define MM_SYSLDR_BOOT_LOADED (PVOID)0xFFFFFFFF
#define MM_SYSLDR_SINGLE_ENTRY 0x1
+//
+// Number of initial session IDs
+//
+#define MI_INITIAL_SESSION_IDS 64
+
#if defined(_M_IX86) || defined(_M_ARM)
//
// PFN List Sentinel
@@ -269,6 +274,24 @@
#else
#define MI_PTE_LOOKUP_NEEDED 0xFFFFF
#endif
+
+//
+// Number of session lists in the MM_SESSIONS_SPACE structure
+//
+#if defined(_M_AMD64)
+#define SESSION_POOL_LOOKASIDES 21
+#elif defined(_M_IX86)
+#define SESSION_POOL_LOOKASIDES 26
+#else
+#error Not Defined!
+#endif
+
+//
+// Number of session data and tag pages
+//
+#define MI_SESSION_DATA_PAGES_MAXIMUM (MM_ALLOCATION_GRANULARITY / PAGE_SIZE)
+#define MI_SESSION_TAG_PAGES_MAXIMUM (MM_ALLOCATION_GRANULARITY / PAGE_SIZE)
+
//
// System views are binned into 64K chunks
@@ -473,9 +496,70 @@
PRTL_BITMAP SystemSpaceBitMap;
} MMSESSION, *PMMSESSION;
+typedef struct _MM_SESSION_SPACE_FLAGS
+{
+ ULONG Initialized:1;
+ ULONG DeletePending:1;
+ ULONG Filler:30;
+} MM_SESSION_SPACE_FLAGS;
+
+typedef struct _MM_SESSION_SPACE
+{
+ struct _MM_SESSION_SPACE *GlobalVirtualAddress;
+ LONG ReferenceCount;
+ union
+ {
+ ULONG LongFlags;
+ MM_SESSION_SPACE_FLAGS Flags;
+ } u;
+ ULONG SessionId;
+ LIST_ENTRY ProcessList;
+ LARGE_INTEGER LastProcessSwappedOutTime;
+ PFN_NUMBER SessionPageDirectoryIndex;
+ SIZE_T NonPageablePages;
+ SIZE_T CommittedPages;
+ PVOID PagedPoolStart;
+ PVOID PagedPoolEnd;
+ PMMPTE PagedPoolBasePde;
+ ULONG Color;
+ LONG ResidentProcessCount;
+ ULONG SessionPoolAllocationFailures[4];
+ LIST_ENTRY ImageList;
+ LCID LocaleId;
+ ULONG AttachCount;
+ KEVENT AttachEvent;
+ PEPROCESS LastProcess;
+ LONG ProcessReferenceToSession;
+ LIST_ENTRY WsListEntry;
+ GENERAL_LOOKASIDE Lookaside[SESSION_POOL_LOOKASIDES];
+ MMSESSION Session;
+ KGUARDED_MUTEX PagedPoolMutex;
+ MM_PAGED_POOL_INFO PagedPoolInfo;
+ MMSUPPORT Vm;
+ PMMWSLE Wsle;
+ PDRIVER_UNLOAD Win32KDriverUnload;
+ POOL_DESCRIPTOR PagedPool;
+#if defined (_M_AMD64)
+ MMPTE PageDirectory;
+#else
+ PMMPTE PageTables;
+#endif
+#if defined (_M_AMD64)
+ PMMPTE SpecialPoolFirstPte;
+ PMMPTE SpecialPoolLastPte;
+ PMMPTE NextPdeForSpecialPoolExpansion;
+ PMMPTE LastPdeForSpecialPoolExpansion;
+ PFN_NUMBER SpecialPagesInUse;
+#endif
+ LONG ImageLoadingCount;
+} MM_SESSION_SPACE, *PMM_SESSION_SPACE;
+
+extern PMM_SESSION_SPACE MmSessionSpace;
extern MMPTE HyperTemplatePte;
extern MMPDE ValidKernelPde;
extern MMPTE ValidKernelPte;
+extern MMPDE ValidKernelPdeLocal;
+extern MMPTE ValidKernelPteLocal;
extern MMPDE DemandZeroPde;
extern MMPTE DemandZeroPte;
extern MMPTE PrototypePte;
@@ -1182,6 +1266,24 @@
IN ULONG Threshold //
); //
+// FIXFIX: THIS ONE TOO
+VOID
+NTAPI
+INIT_FUNCTION
+ExInitializePoolDescriptor(
+ IN PPOOL_DESCRIPTOR PoolDescriptor,
+ IN POOL_TYPE PoolType,
+ IN ULONG PoolIndex,
+ IN ULONG Threshold,
+ IN PVOID PoolLock
+);
+
+NTSTATUS
+NTAPI
+MiInitializeSessionPool(
+ VOID
+);
+
VOID
NTAPI
MiInitializeSystemPtes(
@@ -1289,6 +1391,15 @@
IN BOOLEAN Modified
);
+NTSTATUS
+NTAPI
+MiInitializeAndChargePfn(
+ OUT PPFN_NUMBER PageFrameIndex,
+ IN PMMPTE PointerPde,
+ IN PFN_NUMBER ContainingPageFrame,
+ IN BOOLEAN SessionAllocation
+);
+
VOID
NTAPI
MiInitializePfnAndMakePteValid(
@@ -1493,7 +1604,7 @@
BOOLEAN
NTAPI
MiInitializeSystemSpaceMap(
- IN PVOID InputSession OPTIONAL
+ IN PMMSESSION InputSession OPTIONAL
);
ULONG
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c [iso-8859-1] Sun Jul 15 23:42:27 2012
@@ -1123,6 +1123,45 @@
MI_WRITE_VALID_PTE(PointerPte, TempPte);
}
+NTSTATUS
+NTAPI
+MiInitializeAndChargePfn(OUT PPFN_NUMBER PageFrameIndex,
+ IN PMMPTE PointerPde,
+ IN PFN_NUMBER ContainingPageFrame,
+ IN BOOLEAN SessionAllocation)
+{
+ MMPTE TempPte;
+ KIRQL OldIrql;
+
+ /* Use either a global or local PDE */
+ TempPte = SessionAllocation ? ValidKernelPdeLocal : ValidKernelPde;
+
+ /* Lock the PFN database */
+ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+
+ /* Make sure nobody is racing us */
+ if (PointerPde->u.Hard.Valid == 1)
+ {
+ /* Return special error if that was the case */
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+ return STATUS_RETRY;
+ }
+
+ /* Grab a zero page and set the PFN, then make it valid */
+ *PageFrameIndex = MiRemoveZeroPage(MI_GET_NEXT_COLOR());
+ TempPte.u.Hard.PageFrameNumber = *PageFrameIndex;
+ MI_WRITE_VALID_PTE(PointerPde, TempPte);
+
+ /* Initialize the PFN */
+ MiInitializePfnForOtherProcess(*PageFrameIndex,
+ PointerPde,
+ ContainingPageFrame);
+ ASSERT(MI_PFN_ELEMENT(*PageFrameIndex)->u1.WsIndex == 0);
+
+ /* Release the lock and return success */
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+ return STATUS_SUCCESS;
+}
PFN_NUMBER
NTAPI
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pool.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pool.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/pool.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/pool.c [iso-8859-1] Sun Jul 15 23:42:27 2012
@@ -1261,6 +1261,107 @@
return TRUE;
}
+NTSTATUS
+NTAPI
+MiInitializeSessionPool(VOID)
+{
+ PMMPTE PointerPde, PointerPte, LastPte, LastPde;
+ PFN_NUMBER PageFrameIndex, PdeCount;
+ PPOOL_DESCRIPTOR PoolDescriptor;
+ PMM_SESSION_SPACE SessionGlobal;
+ PMM_PAGED_POOL_INFO PagedPoolInfo;
+ NTSTATUS Status;
+ ULONG Index, PoolSize, BitmapSize;
+ PAGED_CODE();
+
+ /* Lock session pool */
+ SessionGlobal = MmSessionSpace->GlobalVirtualAddress;
+ KeInitializeGuardedMutex(&SessionGlobal->PagedPoolMutex);
+
+ /* Setup a valid pool descriptor */
+ PoolDescriptor = &MmSessionSpace->PagedPool;
+ ExInitializePoolDescriptor(PoolDescriptor,
+ PagedPoolSession,
+ 0,
+ 0,
+ &SessionGlobal->PagedPoolMutex);
+
+ /* Setup the pool addresses */
+ MmSessionSpace->PagedPoolStart = (PVOID)MiSessionPoolStart;
+ MmSessionSpace->PagedPoolEnd = (PVOID)((ULONG_PTR)MiSessionPoolEnd - 1);
+ DPRINT1("Session Pool Start: 0x%p End: 0x%p\n",
+ MmSessionSpace->PagedPoolStart, MmSessionSpace->PagedPoolEnd);
+
+ /* Reset all the counters */
+ PagedPoolInfo = &MmSessionSpace->PagedPoolInfo;
+ PagedPoolInfo->PagedPoolCommit = 0;
+ PagedPoolInfo->PagedPoolHint = 0;
+ PagedPoolInfo->AllocatedPagedPool = 0;
+
+ /* Compute PDE and PTE addresses */
+ PointerPde = MiAddressToPde(MmSessionSpace->PagedPoolStart);
+ PointerPte = MiAddressToPte(MmSessionSpace->PagedPoolStart);
+ LastPde = MiAddressToPde(MmSessionSpace->PagedPoolEnd);
+ LastPte = MiAddressToPte(MmSessionSpace->PagedPoolEnd);
+
+ /* Write them down */
+ MmSessionSpace->PagedPoolBasePde = PointerPde;
+ PagedPoolInfo->FirstPteForPagedPool = PointerPte;
+ PagedPoolInfo->LastPteForPagedPool = LastPte;
+ PagedPoolInfo->NextPdeForPagedPoolExpansion = PointerPde + 1;
+
+ /* Zero the PDEs */
+ PdeCount = LastPde - PointerPde;
+ RtlZeroMemory(PointerPde, (PdeCount + 1) * sizeof(MMPTE));
+
+ /* Initialize the PFN for the PDE */
+ Status = MiInitializeAndChargePfn(&PageFrameIndex,
+ PointerPde,
+ MmSessionSpace->SessionPageDirectoryIndex,
+ TRUE);
+ ASSERT(NT_SUCCESS(Status) == TRUE);
+
+ /* Initialize the first page table */
+ Index = (ULONG_PTR)MmSessionSpace->PagedPoolStart - (ULONG_PTR)MmSessionBase;
+ Index >>= 22;
+ ASSERT(MmSessionSpace->PageTables[Index].u.Long == 0);
+ MmSessionSpace->PageTables[Index] = *PointerPde;
+
+ /* Bump up counters */
+ InterlockedIncrementSizeT(&MmSessionSpace->NonPageablePages);
+ InterlockedIncrementSizeT(&MmSessionSpace->CommittedPages);
+
+ /* Compute the size of the pool in pages, and of the bitmap for it */
+ PoolSize = MmSessionPoolSize >> PAGE_SHIFT;
+ BitmapSize = sizeof(RTL_BITMAP) + ((PoolSize + 31) / 32) * sizeof(ULONG);
+
+ /* Allocate and initialize the bitmap to track allocations */
+ PagedPoolInfo->PagedPoolAllocationMap = ExAllocatePoolWithTag(NonPagedPool,
+ BitmapSize,
+ ' mM');
+ ASSERT(PagedPoolInfo->PagedPoolAllocationMap != NULL);
+ RtlInitializeBitMap(PagedPoolInfo->PagedPoolAllocationMap,
+ (PULONG)(PagedPoolInfo->PagedPoolAllocationMap + 1),
+ PoolSize);
+
+ /* Set all bits, but clear the first page table's worth */
+ RtlSetAllBits(PagedPoolInfo->PagedPoolAllocationMap);
+ RtlClearBits(PagedPoolInfo->PagedPoolAllocationMap, 0, PTE_PER_PAGE);
+
+ /* Allocate and initialize the bitmap to track free space */
+ PagedPoolInfo->EndOfPagedPoolBitmap = ExAllocatePoolWithTag(NonPagedPool,
+ BitmapSize,
+ ' mM');
+ ASSERT(PagedPoolInfo->EndOfPagedPoolBitmap != NULL);
+ RtlInitializeBitMap(PagedPoolInfo->EndOfPagedPoolBitmap,
+ (PULONG)(PagedPoolInfo->EndOfPagedPoolBitmap + 1),
+ PoolSize);
+
+ /* Clear all the bits and return success */
+ RtlClearAllBits(PagedPoolInfo->EndOfPagedPoolBitmap);
+ return STATUS_SUCCESS;
+}
+
/* PUBLIC FUNCTIONS ***********************************************************/
/*
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] Sun Jul 15 23:42:27 2012
@@ -1457,7 +1457,11 @@
/* SESSION CODE TO MOVE TO SESSION.C ******************************************/
+PMM_SESSION_SPACE MmSessionSpace;
+PFN_NUMBER MiSessionDataPages, MiSessionTagPages, MiSessionTagSizePages;
+PFN_NUMBER MiSessionBigPoolPages, MiSessionCreateCharge;
KGUARDED_MUTEX MiSessionIdMutex;
+LONG MmSessionDataPages;
PRTL_BITMAP MiSessionIdBitmap;
volatile LONG MiSessionLeaderExists;
@@ -1465,19 +1469,40 @@
NTAPI
MiInitializeSessionIds(VOID)
{
- /* FIXME: Other stuff should go here */
+ ULONG Size, BitmapSize;
+ PFN_NUMBER TotalPages;
+
+ /* Setup the total number of data pages needed for the structure */
+ TotalPages = MI_SESSION_DATA_PAGES_MAXIMUM;
+ MiSessionDataPages = ROUND_TO_PAGES(sizeof(MM_SESSION_SPACE)) >> PAGE_SHIFT;
+ ASSERT(MiSessionDataPages <= MI_SESSION_DATA_PAGES_MAXIMUM - 3);
+ TotalPages -= MiSessionDataPages;
+
+ /* Setup the number of pages needed for session pool tags */
+ MiSessionTagSizePages = 2;
+ MiSessionBigPoolPages = 1;
+ MiSessionTagPages = MiSessionTagSizePages + MiSessionBigPoolPages;
+ ASSERT(MiSessionTagPages <= TotalPages);
+ ASSERT(MiSessionTagPages < MI_SESSION_TAG_PAGES_MAXIMUM);
+
+ /* Total pages needed for a session (FIXME: Probably different on PAE/x64) */
+ MiSessionCreateCharge = 1 + MiSessionDataPages + MiSessionTagPages;
/* Initialize the lock */
KeInitializeGuardedMutex(&MiSessionIdMutex);
/* Allocate the bitmap */
+ Size = MI_INITIAL_SESSION_IDS;
+ BitmapSize = ((Size + 31) / 32) * sizeof(ULONG);
MiSessionIdBitmap = ExAllocatePoolWithTag(PagedPool,
- sizeof(RTL_BITMAP) + ((64 + 31) / 32) * 4,
+ sizeof(RTL_BITMAP) + BitmapSize,
' mM');
if (MiSessionIdBitmap)
{
/* Free all the bits */
- RtlInitializeBitMap(MiSessionIdBitmap, (PVOID)(MiSessionIdBitmap + 1), 64);
+ RtlInitializeBitMap(MiSessionIdBitmap,
+ (PVOID)(MiSessionIdBitmap + 1),
+ Size);
RtlClearAllBits(MiSessionIdBitmap);
}
else
@@ -1508,7 +1533,20 @@
MiSessionCreateInternal(OUT PULONG SessionId)
{
PEPROCESS Process = PsGetCurrentProcess();
- ULONG NewFlags, Flags;
+ ULONG NewFlags, Flags, Size, i, Color;
+ KIRQL OldIrql;
+ PMMPTE PointerPte, PageTables, SessionPte;
+ PMMPDE PointerPde;
+ PMM_SESSION_SPACE SessionGlobal;
+ MMPTE TempPte;
+ NTSTATUS Status;
+ BOOLEAN Result;
+ PFN_NUMBER SessionPageDirIndex;
+ PFN_NUMBER TagPage[MI_SESSION_TAG_PAGES_MAXIMUM];
+ PFN_NUMBER DataPage[MI_SESSION_DATA_PAGES_MAXIMUM];
+
+ /* This should not exist yet */
+ ASSERT(MmIsAddressValid(MmSessionSpace) == FALSE);
/* Loop so we can set the session-is-creating flag */
Flags = Process->Flags;
@@ -1535,19 +1573,170 @@
/* Now we should own the flag */
ASSERT(Process->Flags & PSF_SESSION_CREATION_UNDERWAY_BIT);
+ /*
+ * Session space covers everything from 0xA0000000 to 0xC0000000.
+ * Allocate enough page tables to describe the entire region
+ */
+ Size = (0x20000000 / PDE_MAPPED_VA) * sizeof(MMPTE);
+ PageTables = ExAllocatePoolWithTag(NonPagedPool, Size, 'tHmM');
+ ASSERT(PageTables != NULL);
+ RtlZeroMemory(PageTables, Size);
+
+ /* Lock the session ID creation mutex */
+ KeAcquireGuardedMutex(&MiSessionIdMutex);
+
/* Allocate a new Session ID */
- KeAcquireGuardedMutex(&MiSessionIdMutex);
*SessionId = RtlFindClearBitsAndSet(MiSessionIdBitmap, 1, 0);
if (*SessionId == 0xFFFFFFFF)
{
+ /* We ran out of session IDs, we should expand */
DPRINT1("Too many sessions created. Expansion not yet supported\n");
return STATUS_NO_MEMORY;
}
+
+ /* Unlock the session ID creation mutex */
KeReleaseGuardedMutex(&MiSessionIdMutex);
+
+ /* Reserve the global PTEs */
+ SessionPte = MiReserveSystemPtes(MiSessionDataPages, SystemPteSpace);
+ ASSERT(SessionPte != NULL);
+
+ /* Acquire the PFN lock while we set everything up */
+ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+
+ /* Loop the global PTEs */
+ TempPte.u.Long = ValidKernelPte.u.Long;
+ for (i = 0; i < MiSessionDataPages; i++)
+ {
+ /* Get a zeroed colored zero page */
+ Color = MI_GET_NEXT_COLOR();
+ DataPage[i] = MiRemoveZeroPageSafe(Color);
+ if (!DataPage[i])
+ {
+ /* No zero pages, grab a free one */
+ DataPage[i] = MiRemoveAnyPage(Color);
+
+ /* Zero it outside the PFN lock */
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+ MiZeroPhysicalPage(DataPage[i]);
+ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+ }
+
+ /* Fill the PTE out */
+ TempPte.u.Hard.PageFrameNumber = DataPage[i];
+ MI_WRITE_VALID_PTE(SessionPte + i, TempPte);
+ }
+
+ /* Set the pointer to global space */
+ SessionGlobal = MiPteToAddress(SessionPte);
+
+ /* Get a zeroed colored zero page */
+ Color = MI_GET_NEXT_COLOR();
+ SessionPageDirIndex = MiRemoveZeroPageSafe(Color);
+ if (!SessionPageDirIndex)
+ {
+ /* No zero pages, grab a free one */
+ SessionPageDirIndex = MiRemoveAnyPage(Color);
+
+ /* Zero it outside the PFN lock */
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+ MiZeroPhysicalPage(SessionPageDirIndex);
+ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+ }
+
+ /* Fill the PTE out */
+ TempPte.u.Long = ValidKernelPdeLocal.u.Long;
+ TempPte.u.Hard.PageFrameNumber = SessionPageDirIndex;
+
+ /* Setup, allocate, fill out the MmSessionSpace PTE */
+ PointerPde = MiAddressToPde(MmSessionSpace);
+ ASSERT(PointerPde->u.Long == 0);
+ MI_WRITE_VALID_PTE(PointerPde, TempPte);
+ MiInitializePfnForOtherProcess(SessionPageDirIndex,
+ PointerPde,
+ SessionPageDirIndex);
+ ASSERT(MI_PFN_ELEMENT(SessionPageDirIndex)->u1.WsIndex == 0);
+
+ /* Loop all the local PTEs for it */
+ TempPte.u.Long = ValidKernelPteLocal.u.Long;
+ PointerPte = MiAddressToPte(MmSessionSpace);
+ for (i = 0; i < MiSessionDataPages; i++)
+ {
+ /* And fill them out */
+ TempPte.u.Hard.PageFrameNumber = DataPage[i];
+ MiInitializePfnAndMakePteValid(DataPage[i], PointerPte + i, TempPte);
+ ASSERT(MI_PFN_ELEMENT(DataPage[i])->u1.WsIndex == 0);
+ }
+
+ /* Finally loop all of the session pool tag pages */
+ for (i = 0; i < MiSessionTagPages; i++)
+ {
+ /* Grab a zeroed colored page */
+ Color = MI_GET_NEXT_COLOR();
+ TagPage[i] = MiRemoveZeroPageSafe(Color);
+ if (!TagPage[i])
+ {
+ /* No zero pages, grab a free one */
+ TagPage[i] = MiRemoveAnyPage(Color);
+
+ /* Zero it outside the PFN lock */
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+ MiZeroPhysicalPage(TagPage[i]);
+ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+ }
+
+ /* Fill the PTE out */
+ TempPte.u.Hard.PageFrameNumber = TagPage[i];
+ MiInitializePfnAndMakePteValid(TagPage[i],
+ PointerPte + MiSessionDataPages + i,
+ TempPte);
+ }
+
+ /* PTEs have been setup, release the PFN lock */
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+
+ /* Fill out the session space structure now */
+ MmSessionSpace->GlobalVirtualAddress = SessionGlobal;
+ MmSessionSpace->ReferenceCount = 1;
+ MmSessionSpace->ResidentProcessCount = 1;
+ MmSessionSpace->u.LongFlags = 0;
+ MmSessionSpace->SessionId = *SessionId;
+ MmSessionSpace->LocaleId = PsDefaultSystemLocaleId;
+ MmSessionSpace->SessionPageDirectoryIndex = SessionPageDirIndex;
+ MmSessionSpace->Color = Color;
+ MmSessionSpace->NonPageablePages = MiSessionCreateCharge;
+ MmSessionSpace->CommittedPages = MiSessionCreateCharge;
+ MmSessionSpace->PageTables = PageTables;
+ MmSessionSpace->PageTables[PointerPde - MiAddressToPde(MmSessionBase)] =
*PointerPde;
+ InitializeListHead(&MmSessionSpace->ImageList);
+ DPRINT1("Session %d is ready to go: 0x%p 0x%p, %lx 0x%p\n",
+ *SessionId, MmSessionSpace, SessionGlobal, SessionPageDirIndex, PageTables);
+
+ /* Initialize session pool */
+ //Status = MiInitializeSessionPool();
+ Status = STATUS_SUCCESS;
+ ASSERT(NT_SUCCESS(Status) == TRUE);
+
+ /* Initialize system space */
+ Result = MiInitializeSystemSpaceMap(&SessionGlobal->Session);
+ ASSERT(Result == TRUE);
+
+ /* Initialize the process list, make sure the workign set list is empty */
+ ASSERT(SessionGlobal->WsListEntry.Flink == NULL);
+ ASSERT(SessionGlobal->WsListEntry.Blink == NULL);
+ InitializeListHead(&SessionGlobal->ProcessList);
/* We're done, clear the flag */
ASSERT(Process->Flags & PSF_SESSION_CREATION_UNDERWAY_BIT);
PspClearProcessFlag(Process, PSF_SESSION_CREATION_UNDERWAY_BIT);
+
+ /* Insert the process into the session */
+ ASSERT(Process->Session == NULL);
+ ASSERT(SessionGlobal->ProcessReferenceToSession == 0);
+ SessionGlobal->ProcessReferenceToSession = 1;
+
+ /* We're done */
+ InterlockedIncrement(&MmSessionDataPages);
return STATUS_SUCCESS;
}
Modified: trunk/reactos/ntoskrnl/mm/ARM3/section.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/section.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/section.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/section.c [iso-8859-1] Sun Jul 15 23:42:27 2012
@@ -191,31 +191,44 @@
BOOLEAN
NTAPI
-MiInitializeSystemSpaceMap(IN PVOID InputSession OPTIONAL)
-{
- SIZE_T AllocSize, BitmapSize;
+MiInitializeSystemSpaceMap(IN PMMSESSION InputSession OPTIONAL)
+{
+ SIZE_T AllocSize, BitmapSize, Size;
+ PVOID ViewStart;
PMMSESSION Session;
- /* For now, always use the global session */
- ASSERT(InputSession == NULL);
- Session = &MmSession;
+ /* Check if this a session or system space */
+ if (InputSession)
+ {
+ /* Use the input session */
+ Session = InputSession;
+ ViewStart = MiSessionViewStart;
+ Size = MmSessionViewSize;
+ }
+ else
+ {
+ /* Use the system space "session" */
+ Session = &MmSession;
+ ViewStart = MiSystemViewStart;
+ Size = MmSystemViewSize;
+ }
/* Initialize the system space lock */
Session->SystemSpaceViewLockPointer = &Session->SystemSpaceViewLock;
KeInitializeGuardedMutex(Session->SystemSpaceViewLockPointer);
/* Set the start address */
- Session->SystemSpaceViewStart = MiSystemViewStart;
+ Session->SystemSpaceViewStart = ViewStart;
/* Create a bitmap to describe system space */
- BitmapSize = sizeof(RTL_BITMAP) + ((((MmSystemViewSize / MI_SYSTEM_VIEW_BUCKET_SIZE)
+ 31) / 32) * sizeof(ULONG));
+ BitmapSize = sizeof(RTL_BITMAP) + ((((Size / MI_SYSTEM_VIEW_BUCKET_SIZE) + 31) / 32)
* sizeof(ULONG));
Session->SystemSpaceBitMap = ExAllocatePoolWithTag(NonPagedPool,
BitmapSize,
TAG_MM);
ASSERT(Session->SystemSpaceBitMap);
RtlInitializeBitMap(Session->SystemSpaceBitMap,
(PULONG)(Session->SystemSpaceBitMap + 1),
- (ULONG)(MmSystemViewSize / MI_SYSTEM_VIEW_BUCKET_SIZE));
+ (ULONG)(Size / MI_SYSTEM_VIEW_BUCKET_SIZE));
/* Set system space fully empty to begin with */
RtlClearAllBits(Session->SystemSpaceBitMap);
@@ -2181,7 +2194,7 @@
}
/*
- * @unimplemented
+ * @implemented
*/
NTSTATUS
NTAPI
@@ -2189,19 +2202,43 @@
OUT PVOID *MappedBase,
IN OUT PSIZE_T ViewSize)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ PAGED_CODE();
+
+ /* Process must be in a session */
+ if (PsGetCurrentProcess()->ProcessInSession == FALSE)
+ {
+ DPRINT1("Process is not in session\n");
+ return STATUS_NOT_MAPPED_VIEW;
+ }
+
+ /* Use the system space API, but with the session view instead */
+ ASSERT(MmIsAddressValid(MmSessionSpace) == TRUE);
+ return MiMapViewInSystemSpace(Section,
+ &MmSessionSpace->Session,
+ MappedBase,
+ ViewSize);
}
/*
- * @unimplemented
+ * @implemented
*/
NTSTATUS
NTAPI
MmUnmapViewInSessionSpace(IN PVOID MappedBase)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ PAGED_CODE();
+
+ /* Process must be in a session */
+ if (PsGetCurrentProcess()->ProcessInSession == FALSE)
+ {
+ DPRINT1("Proess is not in session\n");
+ return STATUS_NOT_MAPPED_VIEW;
+ }
+
+ /* Use the system space API, but with the session view instead */
+ ASSERT(MmIsAddressValid(MmSessionSpace) == TRUE);
+ return MiUnmapViewInSystemSpace(&MmSessionSpace->Session,
+ MappedBase);
}
/*