From 6830963321a4cfdd951e29ecb0f92a2cc3ddd166 Mon Sep 17 00:00:00 2001 From: Brian Gianforcaro Date: Tue, 25 May 2021 01:02:19 -0700 Subject: [PATCH] Kernel: Validate we don't hold s_mm_lock during context switch Since `s_mm_lock` is a RecursiveSpinlock, if a kernel thread gets preempted while accidentally hold the lock during switch_context, another thread running on the same processor could end up manipulating the state of the memory manager even though they should not be able to. It will just bump the recursion count and keep going. This appears to be the root cause of weird bugs like: #7359 Where page protection magically appears to be wrong during execution. To avoid these cases lets guard this specific unfortunate case and make sure it can never go unnoticed ever again. The assert was Tom's idea to help debug this, so I am going to tag him as co-author of this commit. Co-Authored-By: Tom --- Kernel/Scheduler.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Kernel/Scheduler.cpp b/Kernel/Scheduler.cpp index 13e714c7ae..3b62d69f1f 100644 --- a/Kernel/Scheduler.cpp +++ b/Kernel/Scheduler.cpp @@ -342,6 +342,10 @@ bool Scheduler::donate_to(RefPtr& beneficiary, const char* reason) bool Scheduler::context_switch(Thread* thread) { + if (s_mm_lock.own_lock()) { + PANIC("In context switch while holding s_mm_lock"); + } + thread->did_schedule(); auto from_thread = Thread::current();