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?re... ============================================================================== --- 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?rev... ============================================================================== --- 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); }
/*