[NTOSKRNL] Drop the MmPagingFile spin lock in favor of a guarded mutex

This commit is contained in:
Pierre Schweitzer 2018-08-16 12:39:24 +02:00
parent 891a6eeeb9
commit 315867d4ff
No known key found for this signature in database
GPG key ID: 7545556C3D585B0B

View file

@ -44,7 +44,7 @@
PMMPAGING_FILE MmPagingFile[MAX_PAGING_FILES]; PMMPAGING_FILE MmPagingFile[MAX_PAGING_FILES];
/* Lock for examining the list of paging files */ /* Lock for examining the list of paging files */
static KSPIN_LOCK PagingFileListLock; KGUARDED_MUTEX MmPageFileCreationLock;
/* Number of paging files */ /* Number of paging files */
ULONG MmNumberOfPagingFiles; ULONG MmNumberOfPagingFiles;
@ -258,7 +258,7 @@ MmInitPagingFile(VOID)
{ {
ULONG i; ULONG i;
KeInitializeSpinLock(&PagingFileListLock); KeInitializeGuardedMutex(&MmPageFileCreationLock);
MiFreeSwapPages = 0; MiFreeSwapPages = 0;
MiUsedSwapPages = 0; MiUsedSwapPages = 0;
@ -277,13 +277,12 @@ MmFreeSwapPage(SWAPENTRY Entry)
{ {
ULONG i; ULONG i;
ULONG_PTR off; ULONG_PTR off;
KIRQL oldIrql;
PMMPAGING_FILE PagingFile; PMMPAGING_FILE PagingFile;
i = FILE_FROM_ENTRY(Entry); i = FILE_FROM_ENTRY(Entry);
off = OFFSET_FROM_ENTRY(Entry) - 1; off = OFFSET_FROM_ENTRY(Entry) - 1;
KeAcquireSpinLock(&PagingFileListLock, &oldIrql); KeAcquireGuardedMutex(&MmPageFileCreationLock);
PagingFile = MmPagingFile[i]; PagingFile = MmPagingFile[i];
if (PagingFile == NULL) if (PagingFile == NULL)
@ -299,23 +298,22 @@ MmFreeSwapPage(SWAPENTRY Entry)
MiFreeSwapPages++; MiFreeSwapPages++;
MiUsedSwapPages--; MiUsedSwapPages--;
KeReleaseSpinLock(&PagingFileListLock, oldIrql); KeReleaseGuardedMutex(&MmPageFileCreationLock);
} }
SWAPENTRY SWAPENTRY
NTAPI NTAPI
MmAllocSwapPage(VOID) MmAllocSwapPage(VOID)
{ {
KIRQL oldIrql;
ULONG i; ULONG i;
ULONG off; ULONG off;
SWAPENTRY entry; SWAPENTRY entry;
KeAcquireSpinLock(&PagingFileListLock, &oldIrql); KeAcquireGuardedMutex(&MmPageFileCreationLock);
if (MiFreeSwapPages == 0) if (MiFreeSwapPages == 0)
{ {
KeReleaseSpinLock(&PagingFileListLock, oldIrql); KeReleaseGuardedMutex(&MmPageFileCreationLock);
return(0); return(0);
} }
@ -328,19 +326,19 @@ MmAllocSwapPage(VOID)
if (off == 0xFFFFFFFF) if (off == 0xFFFFFFFF)
{ {
KeBugCheck(MEMORY_MANAGEMENT); KeBugCheck(MEMORY_MANAGEMENT);
KeReleaseSpinLock(&PagingFileListLock, oldIrql); KeReleaseGuardedMutex(&MmPageFileCreationLock);
return(STATUS_UNSUCCESSFUL); return(STATUS_UNSUCCESSFUL);
} }
MiUsedSwapPages++; MiUsedSwapPages++;
MiFreeSwapPages--; MiFreeSwapPages--;
KeReleaseSpinLock(&PagingFileListLock, oldIrql); KeReleaseGuardedMutex(&MmPageFileCreationLock);
entry = ENTRY_FROM_FILE_OFFSET(i, off + 1); entry = ENTRY_FROM_FILE_OFFSET(i, off + 1);
return(entry); return(entry);
} }
} }
KeReleaseSpinLock(&PagingFileListLock, oldIrql); KeReleaseGuardedMutex(&MmPageFileCreationLock);
KeBugCheck(MEMORY_MANAGEMENT); KeBugCheck(MEMORY_MANAGEMENT);
return(0); return(0);
} }
@ -357,7 +355,6 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
IO_STATUS_BLOCK IoStatus; IO_STATUS_BLOCK IoStatus;
PFILE_OBJECT FileObject; PFILE_OBJECT FileObject;
PMMPAGING_FILE PagingFile; PMMPAGING_FILE PagingFile;
KIRQL oldIrql;
ULONG AllocMapSize; ULONG AllocMapSize;
ULONG Count; ULONG Count;
KPROCESSOR_MODE PreviousMode; KPROCESSOR_MODE PreviousMode;
@ -371,6 +368,8 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
DPRINT("NtCreatePagingFile(FileName %wZ, InitialSize %I64d)\n", DPRINT("NtCreatePagingFile(FileName %wZ, InitialSize %I64d)\n",
FileName, InitialSize->QuadPart); FileName, InitialSize->QuadPart);
PAGED_CODE();
if (MmNumberOfPagingFiles >= MAX_PAGING_FILES) if (MmNumberOfPagingFiles >= MAX_PAGING_FILES)
{ {
return STATUS_TOO_MANY_PAGING_FILES; return STATUS_TOO_MANY_PAGING_FILES;
@ -602,6 +601,11 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
/* Find if it matches a previous page file */ /* Find if it matches a previous page file */
PagingFile = NULL; PagingFile = NULL;
/* FIXME: should be calling unsafe instead,
* we should already be in a guarded region
*/
KeAcquireGuardedMutex(&MmPageFileCreationLock);
if (MmNumberOfPagingFiles > 0) if (MmNumberOfPagingFiles > 0)
{ {
i = 0; i = 0;
@ -622,6 +626,7 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
/* If we didn't find the page file, fail */ /* If we didn't find the page file, fail */
if (PagingFile == NULL) if (PagingFile == NULL)
{ {
KeReleaseGuardedMutex(&MmPageFileCreationLock);
ObDereferenceObject(FileObject); ObDereferenceObject(FileObject);
ZwClose(FileHandle); ZwClose(FileHandle);
ExFreePoolWithTag(Dacl, 'lcaD'); ExFreePoolWithTag(Dacl, 'lcaD');
@ -632,6 +637,7 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
/* FIXME: implement parameters checking and page file extension */ /* FIXME: implement parameters checking and page file extension */
UNIMPLEMENTED; UNIMPLEMENTED;
KeReleaseGuardedMutex(&MmPageFileCreationLock);
ObDereferenceObject(FileObject); ObDereferenceObject(FileObject);
ZwClose(FileHandle); ZwClose(FileHandle);
ExFreePoolWithTag(Dacl, 'lcaD'); ExFreePoolWithTag(Dacl, 'lcaD');
@ -737,12 +743,15 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
(ULONG)(PagingFile->FreePages)); (ULONG)(PagingFile->FreePages));
RtlClearAllBits(PagingFile->AllocMap); RtlClearAllBits(PagingFile->AllocMap);
KeAcquireSpinLock(&PagingFileListLock, &oldIrql); /* FIXME: should be calling unsafe instead,
* we should already be in a guarded region
*/
KeAcquireGuardedMutex(&MmPageFileCreationLock);
ASSERT(MmPagingFile[MmNumberOfPagingFiles] == NULL); ASSERT(MmPagingFile[MmNumberOfPagingFiles] == NULL);
MmPagingFile[MmNumberOfPagingFiles] = PagingFile; MmPagingFile[MmNumberOfPagingFiles] = PagingFile;
MmNumberOfPagingFiles++; MmNumberOfPagingFiles++;
MiFreeSwapPages = MiFreeSwapPages + PagingFile->FreePages; MiFreeSwapPages = MiFreeSwapPages + PagingFile->FreePages;
KeReleaseSpinLock(&PagingFileListLock, oldIrql); KeReleaseGuardedMutex(&MmPageFileCreationLock);
MmSwapSpaceMessage = FALSE; MmSwapSpaceMessage = FALSE;