From d55811f160a3b6e8e8867d1149c10799b513a637 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sun, 4 Feb 2018 19:19:03 +0100 Subject: [PATCH] [NTOS:MM:X64] Fix session space initialization on x64 --- ntoskrnl/include/internal/amd64/mm.h | 21 ++++++------- ntoskrnl/mm/ARM3/session.c | 13 ++++++-- ntoskrnl/mm/amd64/init.c | 44 ++++++++++++++++++---------- 3 files changed, 51 insertions(+), 27 deletions(-) diff --git a/ntoskrnl/include/internal/amd64/mm.h b/ntoskrnl/include/internal/amd64/mm.h index bfc4a4b68d1..f6c96bdc7e9 100644 --- a/ntoskrnl/include/internal/amd64/mm.h +++ b/ntoskrnl/include/internal/amd64/mm.h @@ -21,8 +21,8 @@ #define MI_PAGED_POOL_START (PVOID)0xFFFFF8A000000000ULL // 128 GB paged pool [MiVaPagedPool] //#define MI_PAGED_POOL_END 0xFFFFF8BFFFFFFFFFULL //#define MI_SESSION_SPACE_START 0xFFFFF90000000000ULL // 512 GB session space [MiVaSessionSpace] -#define MI_SESSION_VIEW_END 0xFFFFF97FFF000000ULL -#define MI_SESSION_SPACE_END 0xFFFFF97FFFFFFFFFULL +//#define MI_SESSION_VIEW_END 0xFFFFF97FFF000000ULL +#define MI_SESSION_SPACE_END 0xFFFFF98000000000ULL #define MI_SYSTEM_CACHE_START 0xFFFFF98000000000ULL // 1 TB system cache (on Vista+ this is dynamic VA space) [MiVaSystemCache,MiVaSpecialPoolPaged,MiVaSpecialPoolNonPaged] #define MI_SYSTEM_CACHE_END 0xFFFFFA7FFFFFFFFFULL #define MI_PFN_DATABASE 0xFFFFFA8000000000ULL // up to 5.5 TB PFN database followed by non paged pool [MiVaPfnDatabase/MiVaNonPagedPool] @@ -58,11 +58,11 @@ #define MI_MIN_INIT_PAGED_POOLSIZE (32 * _1MB) #define MI_MAX_INIT_NONPAGED_POOL_SIZE (128ULL * 1024 * 1024 * 1024) #define MI_MAX_NONPAGED_POOL_SIZE (128ULL * 1024 * 1024 * 1024) -#define MI_SYSTEM_VIEW_SIZE (16 * _1MB) -#define MI_SESSION_VIEW_SIZE (20 * _1MB) -#define MI_SESSION_POOL_SIZE (16 * _1MB) -#define MI_SESSION_IMAGE_SIZE (8 * _1MB) -#define MI_SESSION_WORKING_SET_SIZE (4 * _1MB) +#define MI_SYSTEM_VIEW_SIZE (104 * _1MB) +#define MI_SESSION_VIEW_SIZE (104 * _1MB) +#define MI_SESSION_POOL_SIZE (64 * _1MB) +#define MI_SESSION_IMAGE_SIZE (16 * _1MB) +#define MI_SESSION_WORKING_SET_SIZE (16 * _1MB) #define MI_SESSION_SIZE (MI_SESSION_VIEW_SIZE + \ MI_SESSION_POOL_SIZE + \ MI_SESSION_IMAGE_SIZE + \ @@ -289,9 +289,10 @@ FORCEINLINE BOOLEAN MI_IS_MAPPED_PTE(PMMPTE PointerPte) { - /// FIXME - __debugbreak(); - return ((PointerPte->u.Long & 0xFFFFFC01) != 0); + return ((PointerPte->u.Hard.Valid != 0) || + (PointerPte->u.Proto.Prototype != 0) || + (PointerPte->u.Trans.Transition != 0) || + (PointerPte->u.Hard.PageFrameNumber != 0)); } INIT_FUNCTION diff --git a/ntoskrnl/mm/ARM3/session.c b/ntoskrnl/mm/ARM3/session.c index 87606239685..898dbbbaebc 100644 --- a/ntoskrnl/mm/ARM3/session.c +++ b/ntoskrnl/mm/ARM3/session.c @@ -603,10 +603,14 @@ NTAPI MiSessionCreateInternal(OUT PULONG SessionId) { PEPROCESS Process = PsGetCurrentProcess(); - ULONG NewFlags, Flags, Size, i, Color; + ULONG NewFlags, Flags, i, Color; +#if (_MI_PAGING_LEVELS < 3) + ULONG Size; +#endif // (_MI_PAGING_LEVELS < 3) + PMMPDE PageTables = NULL; KIRQL OldIrql; PMMPTE PointerPte, SessionPte; - PMMPDE PointerPde, PageTables; + PMMPDE PointerPde; PMM_SESSION_SPACE SessionGlobal; MMPTE TempPte; MMPDE TempPde; @@ -644,6 +648,7 @@ MiSessionCreateInternal(OUT PULONG SessionId) /* Now we should own the flag */ ASSERT(Process->Flags & PSF_SESSION_CREATION_UNDERWAY_BIT); +#if (_MI_PAGING_LEVELS < 3) /* * Session space covers everything from 0xA0000000 to 0xC0000000. * Allocate enough page tables to describe the entire region @@ -652,6 +657,7 @@ MiSessionCreateInternal(OUT PULONG SessionId) PageTables = ExAllocatePoolWithTag(NonPagedPool, Size, 'tHmM'); ASSERT(PageTables != NULL); RtlZeroMemory(PageTables, Size); +#endif // (_MI_PAGING_LEVELS < 3) /* Lock the session ID creation mutex */ KeAcquireGuardedMutex(&MiSessionIdMutex); @@ -662,7 +668,9 @@ MiSessionCreateInternal(OUT PULONG SessionId) { /* We ran out of session IDs, we should expand */ DPRINT1("Too many sessions created. Expansion not yet supported\n"); +#if (_MI_PAGING_LEVELS < 3) ExFreePoolWithTag(PageTables, 'tHmM'); +#endif // (_MI_PAGING_LEVELS < 3) return STATUS_NO_MEMORY; } @@ -786,6 +794,7 @@ MiSessionCreateInternal(OUT PULONG SessionId) MmSessionSpace->PageTables[PointerPde - MiAddressToPde(MmSessionBase)] = *PointerPde; #endif InitializeListHead(&MmSessionSpace->ImageList); + DPRINT1("Session %lu is ready to go: 0x%p 0x%p, %lx 0x%p\n", *SessionId, MmSessionSpace, SessionGlobal, SessionPageDirIndex, PageTables); diff --git a/ntoskrnl/mm/amd64/init.c b/ntoskrnl/mm/amd64/init.c index f56816c76e4..89aace7dc15 100644 --- a/ntoskrnl/mm/amd64/init.c +++ b/ntoskrnl/mm/amd64/init.c @@ -15,11 +15,11 @@ #include #include +#include extern PMMPTE MmDebugPte; /* Helper macros */ -#define IS_ALIGNED(addr, align) (((ULONG64)(addr) & (align - 1)) == 0) #define IS_PAGE_ALIGNED(addr) IS_ALIGNED(addr, PAGE_SIZE) /* GLOBALS *****************************************************************/ @@ -62,28 +62,31 @@ VOID NTAPI MiInitializeSessionSpaceLayout(VOID) { + /* This is the entire size */ MmSessionSize = MI_SESSION_SIZE; - MmSessionViewSize = MI_SESSION_VIEW_SIZE; - MmSessionPoolSize = MI_SESSION_POOL_SIZE; - MmSessionImageSize = MI_SESSION_IMAGE_SIZE; - MmSystemViewSize = MI_SYSTEM_VIEW_SIZE; - /* Set up session space */ + /* Start with session space end */ MiSessionSpaceEnd = (PVOID)MI_SESSION_SPACE_END; - /* This is where we will load Win32k.sys and the video driver */ + /* The highest range is the session image range */ + MmSessionImageSize = MI_SESSION_IMAGE_SIZE; MiSessionImageEnd = MiSessionSpaceEnd; - MiSessionImageStart = (PCHAR)MiSessionImageEnd - MmSessionImageSize; + MiSessionImageStart = (PUCHAR)MiSessionImageEnd - MmSessionImageSize; + ASSERT(IS_PAGE_ALIGNED(MiSessionImageStart)); - /* The view starts right below the session working set (itself below - * the image area) */ - MiSessionViewEnd = (PVOID)MI_SESSION_VIEW_END; - MiSessionViewStart = (PCHAR)MiSessionViewEnd - MmSessionViewSize; + /* Session working set is below the session image range */ + MiSessionSpaceWs = (PUCHAR)MiSessionImageStart - MI_SESSION_WORKING_SET_SIZE; + + /* Session view is below the session working set */ + MmSessionViewSize = MI_SESSION_VIEW_SIZE; + MiSessionViewEnd = MiSessionSpaceWs; + MiSessionViewStart = (PUCHAR)MiSessionViewEnd - MmSessionViewSize; ASSERT(IS_PAGE_ALIGNED(MiSessionViewStart)); - /* Session pool follows */ + /* Session pool is below session view */ + MmSessionPoolSize = MI_SESSION_POOL_SIZE; MiSessionPoolEnd = MiSessionViewStart; - MiSessionPoolStart = (PCHAR)MiSessionPoolEnd - MmSessionPoolSize; + MiSessionPoolStart = (PUCHAR)MiSessionPoolEnd - MmSessionPoolSize; ASSERT(IS_PAGE_ALIGNED(MiSessionPoolStart)); /* And it all begins here */ @@ -91,12 +94,23 @@ MiInitializeSessionSpaceLayout(VOID) /* System view space ends at session space, so now that we know where * this is, we can compute the base address of system view space itself. */ - MiSystemViewStart = (PCHAR)MmSessionBase - MmSystemViewSize; + MmSystemViewSize = MI_SYSTEM_VIEW_SIZE; + MiSystemViewStart = (PUCHAR)MmSessionBase - MmSystemViewSize; ASSERT(IS_PAGE_ALIGNED(MiSystemViewStart)); /* Sanity checks */ + ASSERT(Add2Ptr(MmSessionBase, MmSessionSize) == MiSessionSpaceEnd); ASSERT(MiSessionViewEnd <= MiSessionImageStart); ASSERT(MmSessionBase <= MiSessionPoolStart); + + /* Compute the PTE addresses for all the addresses we carved out */ + MiSessionImagePteStart = MiAddressToPte(MiSessionImageStart); + MiSessionImagePteEnd = MiAddressToPte(MiSessionImageEnd); + MiSessionBasePte = MiAddressToPte(MmSessionBase); + MiSessionLastPte = MiAddressToPte(MiSessionSpaceEnd); + + /* Initialize the pointer to the session space structure */ + MmSessionSpace = (PMM_SESSION_SPACE)Add2Ptr(MiSessionImageStart, 0x10000); } VOID