mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +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
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
static KSPIN_LOCK ExpGlobalListLock = { 0, };
|
|
||||||
|
|
||||||
/* FUNCTIONS *************************************************************/
|
/* FUNCTIONS *************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -446,8 +444,31 @@ PSLIST_ENTRY
|
||||||
FASTCALL
|
FASTCALL
|
||||||
InterlockedPopEntrySList(IN PSLIST_HEADER ListHead)
|
InterlockedPopEntrySList(IN PSLIST_HEADER ListHead)
|
||||||
{
|
{
|
||||||
return (PSLIST_ENTRY) ExInterlockedPopEntrySList(ListHead,
|
SLIST_HEADER newslh, oldslh;
|
||||||
&ExpGlobalListLock);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -459,9 +480,21 @@ FASTCALL
|
||||||
InterlockedPushEntrySList(IN PSLIST_HEADER ListHead,
|
InterlockedPushEntrySList(IN PSLIST_HEADER ListHead,
|
||||||
IN PSLIST_ENTRY ListEntry)
|
IN PSLIST_ENTRY ListEntry)
|
||||||
{
|
{
|
||||||
return (PSLIST_ENTRY) ExInterlockedPushEntrySList(ListHead,
|
SLIST_HEADER newslh, oldslh;
|
||||||
ListEntry,
|
|
||||||
&ExpGlobalListLock);
|
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 */
|
/* EOF */
|
||||||
|
|
|
@ -563,6 +563,8 @@ NTSTATUS MmSafeCopyFromUser(PVOID Dest, const VOID *Src, ULONG Count);
|
||||||
|
|
||||||
NTSTATUS MmSafeCopyToUser(PVOID Dest, const VOID *Src, ULONG Count);
|
NTSTATUS MmSafeCopyToUser(PVOID Dest, const VOID *Src, ULONG Count);
|
||||||
|
|
||||||
|
PVOID FASTCALL MmSafeReadPtr(PVOID Source);
|
||||||
|
|
||||||
/* pageop.c ******************************************************************/
|
/* pageop.c ******************************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
|
|
@ -4,6 +4,9 @@
|
||||||
.globl _MmSafeCopyToUser
|
.globl _MmSafeCopyToUser
|
||||||
.globl _MmSafeCopyToUserUnsafeStart
|
.globl _MmSafeCopyToUserUnsafeStart
|
||||||
.globl _MmSafeCopyToUserRestart
|
.globl _MmSafeCopyToUserRestart
|
||||||
|
.globl @MmSafeReadPtr@4
|
||||||
|
.globl _MmSafeReadPtrStart
|
||||||
|
.globl _MmSafeReadPtrEnd
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NTSTATUS MmSafeCopyFromUser(PVOID Dest, PVOID Src,
|
* NTSTATUS MmSafeCopyFromUser(PVOID Dest, PVOID Src,
|
||||||
|
@ -83,3 +86,16 @@ _MmSafeCopyToUserRestart:
|
||||||
popl %ebp
|
popl %ebp
|
||||||
ret
|
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 MmSafeCopyFromUserRestart(VOID);
|
||||||
extern VOID MmSafeCopyToUserUnsafeStart(VOID);
|
extern VOID MmSafeCopyToUserUnsafeStart(VOID);
|
||||||
extern VOID MmSafeCopyToUserRestart(VOID);
|
extern VOID MmSafeCopyToUserRestart(VOID);
|
||||||
|
extern VOID MmSafeReadPtrStart(VOID);
|
||||||
|
extern VOID MmSafeReadPtrEnd(VOID);
|
||||||
|
|
||||||
extern ULONG MmGlobalKernelPageDirectory[1024];
|
extern ULONG MmGlobalKernelPageDirectory[1024];
|
||||||
|
|
||||||
|
@ -90,5 +92,14 @@ NTSTATUS MmPageFault(ULONG Cs,
|
||||||
(*Eax) = STATUS_ACCESS_VIOLATION;
|
(*Eax) = STATUS_ACCESS_VIOLATION;
|
||||||
return(STATUS_SUCCESS);
|
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);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue