fix: kernel concurrency, interrupt context, and user VA safety
This commit is contained in:
1 parent
f222bf1f04
commit
b1c55073c7
71 files changed
+2654
-1092
No files matched your search
@@ -7,18 +7,29 @@
|
||||
#include "Spinlock.hpp"
|
||||
|
||||
namespace kcp {
|
||||
void Spinlock::Acquire() {
|
||||
uint64_t Spinlock::AcquireIrqSave() {
|
||||
uint64_t flags;
|
||||
asm volatile("pushfq; pop %0; cli" : "=r"(flags) :: "memory");
|
||||
while (atomic_flag.test_and_set(std::memory_order_acquire)) {
|
||||
asm volatile("pause");
|
||||
}
|
||||
savedFlags = flags;
|
||||
return flags;
|
||||
}
|
||||
|
||||
void Spinlock::Release() {
|
||||
uint64_t flags = savedFlags;
|
||||
void Spinlock::ReleaseIrqRestore(uint64_t flags) {
|
||||
atomic_flag.clear(std::memory_order_release);
|
||||
asm volatile("push %0; popfq" :: "r"(flags) : "memory");
|
||||
}
|
||||
};
|
||||
|
||||
void Spinlock::ReleaseIrqNoRestore() {
|
||||
atomic_flag.clear(std::memory_order_release);
|
||||
}
|
||||
|
||||
void Spinlock::Acquire() {
|
||||
savedFlags = AcquireIrqSave();
|
||||
}
|
||||
|
||||
void Spinlock::Release() {
|
||||
ReleaseIrqRestore(savedFlags);
|
||||
}
|
||||
};
|
||||
@@ -14,6 +14,14 @@ namespace kcp {
|
||||
public:
|
||||
void Acquire();
|
||||
void Release();
|
||||
|
||||
// Explicit IRQ-save form for locks whose ownership is deliberately
|
||||
// handed across a context switch. The saved flags live on the caller's
|
||||
// stack (or in scheduler-owned per-context storage), not in the shared
|
||||
// lock object, so the resumed context restores its own interrupt state.
|
||||
uint64_t AcquireIrqSave();
|
||||
void ReleaseIrqRestore(uint64_t flags);
|
||||
void ReleaseIrqNoRestore();
|
||||
};
|
||||
|
||||
// Non-interrupt-disabling mutex for subsystems that are only called
|
||||
@@ -31,4 +39,4 @@ namespace kcp {
|
||||
flag.clear(std::memory_order_release);
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
Reference in new issue
Block a user