https://git.reactos.org/?p=reactos.git;a=commitdiff;h=dd73d1b6d414660a42d07598ad040357fd40019d

commit dd73d1b6d414660a42d07598ad040357fd40019d
Author:     Timo Kreuzer <[email protected]>
AuthorDate: Sun Feb 4 13:30:47 2018 +0100
Commit:     Timo Kreuzer <[email protected]>
CommitDate: Thu Aug 16 16:52:02 2018 +0200

    [NTOS:MM] Make SLIST handling for kernel stacks portable
    
    Kernel stacks that re freed, can be placed on an SLIST for quick reuse. The 
old code was using a member of the PFN of the last stack page as the 
SLIST_ENTRY. This relies on the following (non-portable) assumptions:
    - A stack always has a PTE associated with it.
    - This PTE has a PFN associated with it.
    - The PFN has an empty field that can be re-used as an SLIST_ENTRY.
    - The PFN has another field that points back to the PTE, which then can be 
used to get the stack base.
    
    Specifically: On x64 the PFN field is not 16 bytes aligned, so it cannot be 
used as an SLIST_ENTRY. (In a "usermode kernel" the other assumptions are also 
invalid).
    
    The new code does what Windows does (and which seems absolutely obvious to 
do): Place the SLIST_ENTRY directly on the stack.
---
 ntoskrnl/mm/ARM3/procsup.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/ntoskrnl/mm/ARM3/procsup.c b/ntoskrnl/mm/ARM3/procsup.c
index 009168eba9..51502b9a5d 100644
--- a/ntoskrnl/mm/ARM3/procsup.c
+++ b/ntoskrnl/mm/ARM3/procsup.c
@@ -175,6 +175,7 @@ MmDeleteKernelStack(IN PVOID StackBase,
     PMMPFN Pfn1, Pfn2;
     ULONG i;
     KIRQL OldIrql;
+    PSLIST_ENTRY SListEntry;
 
     //
     // This should be the guard page, so decrement by one
@@ -189,9 +190,8 @@ MmDeleteKernelStack(IN PVOID StackBase,
     {
         if (ExQueryDepthSList(&MmDeadStackSListHead) < 
MmMaximumDeadKernelStacks)
         {
-            Pfn1 = MiGetPfnEntry(PointerPte->u.Hard.PageFrameNumber);
-            InterlockedPushEntrySList(&MmDeadStackSListHead,
-                                      (PSLIST_ENTRY)&Pfn1->u1.NextStackPfn);
+            SListEntry = ((PSLIST_ENTRY)StackBase) - 1;
+            InterlockedPushEntrySList(&MmDeadStackSListHead, SListEntry);
             return;
         }
     }
@@ -265,7 +265,7 @@ MmCreateKernelStack(IN BOOLEAN GuiStack,
     KIRQL OldIrql;
     PFN_NUMBER PageFrameIndex;
     ULONG i;
-    PMMPFN Pfn1;
+    PSLIST_ENTRY SListEntry;
 
     //
     // Calculate pages needed
@@ -286,11 +286,10 @@ MmCreateKernelStack(IN BOOLEAN GuiStack,
         //
         if (ExQueryDepthSList(&MmDeadStackSListHead))
         {
-            Pfn1 = (PMMPFN)InterlockedPopEntrySList(&MmDeadStackSListHead);
-            if (Pfn1)
+            SListEntry = InterlockedPopEntrySList(&MmDeadStackSListHead);
+            if (SListEntry != NULL)
             {
-                PointerPte = Pfn1->PteAddress;
-                BaseAddress = MiPteToAddress(++PointerPte);
+                BaseAddress = (SListEntry + 1);
                 return BaseAddress;
             }
         }

Reply via email to