mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 01:24:38 +00:00
InterlockedPushEntrySList() and InterlockedPopEntrySList() shouldn't serialize access to the list with semaphores
svn path=/trunk/; revision=13709
This commit is contained in:
parent
7e242c624b
commit
d2417ffe5a
4 changed files with 70 additions and 8 deletions
|
@ -16,8 +16,6 @@
|
|||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
static KSPIN_LOCK ExpGlobalListLock = { 0, };
|
||||
|
||||
/* FUNCTIONS *************************************************************/
|
||||
|
||||
/*
|
||||
|
@ -446,8 +444,31 @@ PSLIST_ENTRY
|
|||
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 @@ InterlockedPopEntrySList(IN PSLIST_HEADER ListHead)
|
|||
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 */
|
||||
|
|
|
@ -563,6 +563,8 @@ NTSTATUS MmSafeCopyFromUser(PVOID Dest, const VOID *Src, ULONG Count);
|
|||
|
||||
NTSTATUS MmSafeCopyToUser(PVOID Dest, const VOID *Src, ULONG Count);
|
||||
|
||||
PVOID FASTCALL MmSafeReadPtr(PVOID Source);
|
||||
|
||||
/* pageop.c ******************************************************************/
|
||||
|
||||
VOID
|
||||
|
|
|
@ -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 @@ _MmSafeCopyToUserRestart:
|
|||
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
|
||||
|
|
|
@ -20,6 +20,8 @@ extern VOID MmSafeCopyFromUserUnsafeStart(VOID);
|
|||
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 @@ NTSTATUS MmPageFault(ULONG Cs,
|
|||
(*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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue