Skip to content
This repository was archived by the owner on Jan 28, 2023. It is now read-only.

Commit 6e2de31

Browse files
committed
Revert "windows: Use queued spin locks"
This reverts commit 5cfb841. The said patch is seriously flawed: 1. It calls the wrong Windows Driver Kit functions. E.g., KeAcquireInStackQueuedSpinLockAtDpcLevel() should only be called when IRQL = DISPATCH_LEVEL, but most of HAXM code runs below that level. The more general KeAcquireInStackQueuedSpinLock() should be used instead. 2. Unlike the release of a regular spin lock, which is a simple operation, the release of a queued spin lock needs to wait for a condition and thus may block. If called from a function that should never block, e.g. ept_tree_alloc_page(), a deadlock may occur. Fall back to regular spin locks which do not block on release.
1 parent 428a9da commit 6e2de31

File tree

2 files changed

+7
-7
lines changed

2 files changed

+7
-7
lines changed

include/windows/hax_types_windows.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,8 @@ typedef struct hax_kmap_phys {
102102

103103
typedef struct {
104104
KSPIN_LOCK lock;
105-
// According to MSDN:
106-
// https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/queued-spin-locks
107-
// "Drivers for Windows XP and later versions of Windows should use queued
108-
// spin locks instead of ordinary spin locks."
109-
KLOCK_QUEUE_HANDLE handle;
105+
uint32_t flags;
106+
KIRQL old_irq;
110107
} hax_spinlock;
111108

112109
typedef FAST_MUTEX *hax_mutex;

include/windows/hax_windows.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,17 @@ static inline hax_spinlock *hax_spinlock_alloc_init(void)
7575

7676
static inline void hax_spin_lock(hax_spinlock *lock)
7777
{
78+
KIRQL old_irq;
7879
ASSERT(lock);
79-
KeAcquireInStackQueuedSpinLockAtDpcLevel(&lock->lock, &lock->handle);
80+
KeAcquireSpinLock(&lock->lock, &old_irq);
81+
lock->old_irq = old_irq;
8082
}
8183

84+
/* Do we need a flag to track if old_irq is valid? */
8285
static inline void hax_spin_unlock(hax_spinlock *lock)
8386
{
8487
ASSERT(lock);
85-
KeReleaseInStackQueuedSpinLockFromDpcLevel(&lock->handle);
88+
KeReleaseSpinLock(&lock->lock, lock->old_irq);
8689
}
8790

8891
static inline hax_mutex hax_mutex_alloc_init(void)

0 commit comments

Comments
 (0)