Skip to content

Commit 82ec928

Browse files
committed
[VIDEOPRT] Use a spinlock instead of mutex
1 parent 659be05 commit 82ec928

3 files changed

Lines changed: 45 additions & 50 deletions

File tree

win32ss/drivers/videoprt/resource.c

Lines changed: 31 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -993,9 +993,18 @@ VideoPortVerifyAccessRanges(
993993
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
994994
ULONG i;
995995
NTSTATUS Status;
996+
KIRQL OldIrql;
996997

997998
TRACE_(VIDEOPRT, "VideoPortVerifyAccessRanges\n");
998999

1000+
/* This function requires PASSIVE_LEVEL for IoReportResourceUsage and PagedPool allocations */
1001+
if (KeGetCurrentIrql() != PASSIVE_LEVEL)
1002+
{
1003+
ERR_(VIDEOPRT, "VideoPortVerifyAccessRanges called at IRQL %d (requires PASSIVE_LEVEL)\n",
1004+
KeGetCurrentIrql());
1005+
return ERROR_INVALID_PARAMETER;
1006+
}
1007+
9991008
/* Verify parameters */
10001009
if (NumAccessRanges && !AccessRanges)
10011010
return ERROR_INVALID_PARAMETER;
@@ -1009,25 +1018,15 @@ VideoPortVerifyAccessRanges(
10091018
/* If releasing VGA device resources, clear tracked ranges */
10101019
if (DeviceExtension->IsVgaDriver)
10111020
{
1012-
/* Mutexes can only be acquired at PASSIVE_LEVEL */
1013-
if (KeGetCurrentIrql() == PASSIVE_LEVEL)
1014-
{
1015-
KeWaitForMutexObject(&VgaSyncLock, Executive, KernelMode, FALSE, NULL);
1016-
if (VgaRanges)
1017-
{
1018-
ExFreePoolWithTag(VgaRanges, TAG_VIDEO_PORT);
1019-
VgaRanges = NULL;
1020-
}
1021-
NumOfVgaRanges = 0;
1022-
VgaDeviceExtension = NULL;
1023-
KeReleaseMutex(&VgaSyncLock, FALSE);
1024-
}
1025-
else
1021+
KeAcquireSpinLock(&VgaSyncLock, &OldIrql);
1022+
if (VgaRanges)
10261023
{
1027-
/* Can't acquire mutex at elevated IRQL; skip VGA tracking cleanup */
1028-
WARN_(VIDEOPRT, "VideoPortVerifyAccessRanges: Cannot release VGA resources at IRQL %d\n",
1029-
KeGetCurrentIrql());
1024+
ExFreePoolWithTag(VgaRanges, TAG_VIDEO_PORT);
1025+
VgaRanges = NULL;
10301026
}
1027+
NumOfVgaRanges = 0;
1028+
VgaDeviceExtension = NULL;
1029+
KeReleaseSpinLock(&VgaSyncLock, OldIrql);
10311030
}
10321031
return NO_ERROR;
10331032
}
@@ -1198,28 +1197,26 @@ VideoPortVerifyAccessRanges(
11981197
/* Track VGA access ranges on success for fallback handling */
11991198
if (DeviceExtension->IsVgaDriver)
12001199
{
1201-
if (KeGetCurrentIrql() == PASSIVE_LEVEL)
1200+
KeAcquireSpinLock(&VgaSyncLock, &OldIrql);
1201+
if (VgaRanges)
1202+
{
1203+
ExFreePoolWithTag(VgaRanges, TAG_VIDEO_PORT);
1204+
VgaRanges = NULL;
1205+
NumOfVgaRanges = 0;
1206+
}
1207+
if (NumAccessRanges)
12021208
{
1203-
KeWaitForMutexObject(&VgaSyncLock, Executive, KernelMode, FALSE, NULL);
1209+
SIZE_T sz = NumAccessRanges * sizeof(VIDEO_ACCESS_RANGE);
1210+
/* Note: We're at PASSIVE_LEVEL, so PagedPool allocation is safe */
1211+
VgaRanges = ExAllocatePoolWithTag(PagedPool, sz, TAG_VIDEO_PORT);
12041212
if (VgaRanges)
12051213
{
1206-
ExFreePoolWithTag(VgaRanges, TAG_VIDEO_PORT);
1207-
VgaRanges = NULL;
1208-
NumOfVgaRanges = 0;
1209-
}
1210-
if (NumAccessRanges)
1211-
{
1212-
SIZE_T sz = NumAccessRanges * sizeof(VIDEO_ACCESS_RANGE);
1213-
VgaRanges = ExAllocatePoolWithTag(PagedPool, sz, TAG_VIDEO_PORT);
1214-
if (VgaRanges)
1215-
{
1216-
RtlCopyMemory(VgaRanges, AccessRanges, sz);
1217-
NumOfVgaRanges = NumAccessRanges;
1218-
VgaDeviceExtension = DeviceExtension;
1219-
}
1214+
RtlCopyMemory(VgaRanges, AccessRanges, sz);
1215+
NumOfVgaRanges = NumAccessRanges;
1216+
VgaDeviceExtension = DeviceExtension;
12201217
}
1221-
KeReleaseMutex(&VgaSyncLock, FALSE);
12221218
}
1219+
KeReleaseSpinLock(&VgaSyncLock, OldIrql);
12231220
}
12241221
/* Leave VGA detect phase after first successful claim */
12251222
DeviceExtension->IsVgaDetect = FALSE;

win32ss/drivers/videoprt/videoprt.c

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ BOOLEAN VideoPortUseNewKey = FALSE;
4242

4343
KSPIN_LOCK HwResetAdaptersLock;
4444
RTL_STATIC_LIST_HEAD(HwResetAdaptersList);
45-
KMUTEX VgaSyncLock;
45+
KSPIN_LOCK VgaSyncLock;
4646
PVIDEO_PORT_DEVICE_EXTENSION VgaDeviceExtension = NULL;
4747
PVIDEO_ACCESS_RANGE VgaRanges = NULL;
4848
ULONG NumOfVgaRanges = 0;
@@ -435,6 +435,7 @@ IntVideoPortFindAdapter(
435435
UCHAR Again = FALSE;
436436
BOOL LegacyDetection = FALSE;
437437
BOOLEAN VgaResourcesReleased = FALSE;
438+
KIRQL OldIrql;
438439

439440
DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
440441
DeviceExtension->IsVgaDriver = IntIsVgaSaveDriverName(DriverObject);
@@ -489,14 +490,14 @@ IntVideoPortFindAdapter(
489490
/* If we already have a VGA miniport and are about to probe for additional adapters,
490491
* release its resources temporarily so conflicts are visible during detection.
491492
* We'll reclaim them later if no new adapter successfully claims them. */
492-
KeWaitForMutexObject(&VgaSyncLock, Executive, KernelMode, FALSE, NULL);
493+
KeAcquireSpinLock(&VgaSyncLock, &OldIrql);
493494
if (VgaDeviceExtension)
494495
{
495496
INFO_(VIDEOPRT, "Temporarily releasing VGA resources for adapter probing\n");
496497
IntVideoPortReleaseResources(VgaDeviceExtension);
497498
VgaResourcesReleased = TRUE;
498499
}
499-
KeReleaseMutex(&VgaSyncLock, FALSE);
500+
KeReleaseSpinLock(&VgaSyncLock, OldIrql);
500501

501502
if (LegacyDetection)
502503
{
@@ -616,12 +617,12 @@ IntVideoPortFindAdapter(
616617

617618
if (DeviceExtension->IsVgaDriver)
618619
{
619-
KeWaitForMutexObject(&VgaSyncLock, Executive, KernelMode, FALSE, NULL);
620+
KeAcquireSpinLock(&VgaSyncLock, &OldIrql);
620621
if (VgaDeviceExtension == NULL)
621622
{
622623
VgaDeviceExtension = DeviceExtension;
623624
}
624-
KeReleaseMutex(&VgaSyncLock, FALSE);
625+
KeReleaseSpinLock(&VgaSyncLock, OldIrql);
625626
}
626627

627628
DeviceExtension->IsVgaDetect = FALSE;
@@ -669,15 +670,12 @@ IntVideoPortFindAdapter(
669670
{
670671
/* Another driver has taken VGA resources; drop fallback state */
671672
WARN_(VIDEOPRT, "VGA reclaim failed (vpStatus=0x%X); releasing fallback state\n", vr);
672-
if (KeGetCurrentIrql() == PASSIVE_LEVEL)
673-
{
674-
KeWaitForMutexObject(&VgaSyncLock, Executive, KernelMode, FALSE, NULL);
675-
ExFreePoolWithTag(VgaRanges, TAG_VIDEO_PORT);
676-
VgaRanges = NULL;
677-
NumOfVgaRanges = 0;
678-
VgaDeviceExtension = NULL;
679-
KeReleaseMutex(&VgaSyncLock, FALSE);
680-
}
673+
KeAcquireSpinLock(&VgaSyncLock, &OldIrql);
674+
ExFreePoolWithTag(VgaRanges, TAG_VIDEO_PORT);
675+
VgaRanges = NULL;
676+
NumOfVgaRanges = 0;
677+
VgaDeviceExtension = NULL;
678+
KeReleaseSpinLock(&VgaSyncLock, OldIrql);
681679
}
682680
else
683681
{
@@ -943,7 +941,7 @@ VideoPortInitialize(
943941
{
944942
FirstInitialization = TRUE;
945943
KeInitializeMutex(&VideoPortInt10Mutex, 0);
946-
KeInitializeMutex(&VgaSyncLock, 0);
944+
KeInitializeSpinLock(&VgaSyncLock);
947945
KeInitializeSpinLock(&HwResetAdaptersLock);
948946
IntLoadRegistryParameters();
949947
}

win32ss/drivers/videoprt/videoprt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ extern BOOLEAN VideoPortUseNewKey;
262262

263263
extern KSPIN_LOCK HwResetAdaptersLock;
264264
extern LIST_ENTRY HwResetAdaptersList;
265-
extern KMUTEX VgaSyncLock;
265+
extern KSPIN_LOCK VgaSyncLock;
266266
extern PVIDEO_PORT_DEVICE_EXTENSION VgaDeviceExtension;
267267
extern PVIDEO_ACCESS_RANGE VgaRanges;
268268
extern ULONG NumOfVgaRanges;

0 commit comments

Comments
 (0)