InterlockedPushEntrySList() and InterlockedPopEntrySList() shouldn't serialize access to the list with semaphores Modified: trunk/reactos/ntoskrnl/ex/list.c Modified: trunk/reactos/ntoskrnl/include/internal/mm.h Modified: trunk/reactos/ntoskrnl/mm/i386/memsafe.s Modified: trunk/reactos/ntoskrnl/mm/i386/pfault.c _____
Modified: trunk/reactos/ntoskrnl/ex/list.c --- trunk/reactos/ntoskrnl/ex/list.c 2005-02-21 21:40:31 UTC (rev 13708) +++ trunk/reactos/ntoskrnl/ex/list.c 2005-02-22 01:07:41 UTC (rev 13709) @@ -16,8 +16,6 @@
#define NDEBUG #include <internal/debug.h>
-static KSPIN_LOCK ExpGlobalListLock = { 0, }; - /* FUNCTIONS *************************************************************/
/* @@ -446,8 +444,31 @@ FASTCALL InterlockedPopEntrySList(IN PSLIST_HEADER ListHead) { - return (PSLIST_ENTRY) ExInterlockedPopEntrySList(ListHead, - &ExpGlobalListLock); + SLIST_HEADER newslh, oldslh; + PSLIST_ENTRY le; + + do + { + oldslh = *ListHead; + le = oldslh.Next.Next; + if(le == NULL) + { + /* nothing to do */ + return NULL; + } + newslh.Sequence = oldslh.Sequence + 1; + newslh.Depth = oldslh.Depth - 1; + newslh.Next.Next = MmSafeReadPtr(&le->Next); + if(newslh.Next.Next == NULL) + { + /* try again */ + continue; + } + } while(ExfInterlockedCompareExchange64(&ListHead->Alignment, + &newslh.Alignment, + &oldslh.Alignment) != oldslh.Alignment); + + return le; }
@@ -457,11 +478,23 @@ PSLIST_ENTRY FASTCALL InterlockedPushEntrySList(IN PSLIST_HEADER ListHead, - IN PSLIST_ENTRY ListEntry) + IN PSLIST_ENTRY ListEntry) { - return (PSLIST_ENTRY) ExInterlockedPushEntrySList(ListHead, - ListEntry, - &ExpGlobalListLock); + SLIST_HEADER newslh, oldslh; + + newslh.Next.Next = ListEntry; + + do + { + oldslh = *ListHead; + newslh.Depth = oldslh.Depth + 1; + newslh.Sequence = oldslh.Sequence + 1; + ListEntry->Next = oldslh.Next.Next; + } while(ExfInterlockedCompareExchange64(&ListHead->Alignment, + &newslh.Alignment, + &oldslh.Alignment) != oldslh.Alignment); + + return oldslh.Next.Next; }
/* EOF */ _____
Modified: trunk/reactos/ntoskrnl/include/internal/mm.h --- trunk/reactos/ntoskrnl/include/internal/mm.h 2005-02-21 21:40:31 UTC (rev 13708) +++ trunk/reactos/ntoskrnl/include/internal/mm.h 2005-02-22 01:07:41 UTC (rev 13709) @@ -563,6 +563,8 @@
NTSTATUS MmSafeCopyToUser(PVOID Dest, const VOID *Src, ULONG Count);
+PVOID FASTCALL MmSafeReadPtr(PVOID Source); + /* pageop.c ******************************************************************/
VOID _____
Modified: trunk/reactos/ntoskrnl/mm/i386/memsafe.s --- trunk/reactos/ntoskrnl/mm/i386/memsafe.s 2005-02-21 21:40:31 UTC (rev 13708) +++ trunk/reactos/ntoskrnl/mm/i386/memsafe.s 2005-02-22 01:07:41 UTC (rev 13709) @@ -4,6 +4,9 @@
.globl _MmSafeCopyToUser .globl _MmSafeCopyToUserUnsafeStart .globl _MmSafeCopyToUserRestart +.globl @MmSafeReadPtr@4 +.globl _MmSafeReadPtrStart +.globl _MmSafeReadPtrEnd
/* * NTSTATUS MmSafeCopyFromUser(PVOID Dest, PVOID Src, @@ -83,3 +86,16 @@ popl %ebp ret
+/********************************************************************** *******/ + + /* + * PVOID FASTCALL MmSafeReadPtr(PVOID Source) + */ +@MmSafeReadPtr@4: +_MmSafeReadPtrStart: + /* + * If we incur a pagefault, eax will be set NULL + */ + movl (%ecx),%eax +_MmSafeReadPtrEnd: + ret _____
Modified: trunk/reactos/ntoskrnl/mm/i386/pfault.c --- trunk/reactos/ntoskrnl/mm/i386/pfault.c 2005-02-21 21:40:31 UTC (rev 13708) +++ trunk/reactos/ntoskrnl/mm/i386/pfault.c 2005-02-22 01:07:41 UTC (rev 13709) @@ -20,6 +20,8 @@
extern VOID MmSafeCopyFromUserRestart(VOID); extern VOID MmSafeCopyToUserUnsafeStart(VOID); extern VOID MmSafeCopyToUserRestart(VOID); +extern VOID MmSafeReadPtrStart(VOID); +extern VOID MmSafeReadPtrEnd(VOID);
extern ULONG MmGlobalKernelPageDirectory[1024];
@@ -90,5 +92,14 @@ (*Eax) = STATUS_ACCESS_VIOLATION; return(STATUS_SUCCESS); } + if (!NT_SUCCESS(Status) && (Mode == KernelMode) && + ((*Eip) >= (ULONG_PTR)MmSafeReadPtrStart) && + ((*Eip) <= (ULONG_PTR)MmSafeReadPtrEnd)) + { + (*Eip) = (ULONG_PTR)MmSafeReadPtrEnd; + (*Eax) = 0; + return(STATUS_SUCCESS); + } + return(Status); }