From 2cf4e5a6de176bc0c9fe6da46f06193a76c1d9cc Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Tue, 19 Feb 2019 15:18:02 +0100 Subject: [PATCH] hw: fix regression of smp kernel initialization In commit "hw: improve cross-cpu synchronization" the implicit safe initialization of the global kernel lock gets unsafe. It is a static object, which is protected by the cxx library regarding its initialization. But our cxx library uses a Genode::semaphore in the contention case of object construction, which implicitly leads to kernel syscalls for blocking the corresponding thread. This behaviour is unacceptable for the kernel code. Therefore, this fix guards the initialization of the kernel code with a simple static boolean value explicitely. Ref #3042 Ref #3043 --- repos/base-hw/src/core/kernel/init.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/repos/base-hw/src/core/kernel/init.cc b/repos/base-hw/src/core/kernel/init.cc index 3f027e4662..fa84e30de7 100644 --- a/repos/base-hw/src/core/kernel/init.cc +++ b/repos/base-hw/src/core/kernel/init.cc @@ -43,12 +43,24 @@ extern "C" void kernel_init(); */ extern "C" void kernel_init() { + static volatile bool lock_ready = false; static volatile bool pool_ready = false; static volatile bool kernel_ready = false; + /** + * It is essential to guard the initialization of the data_lock object + * in the SMP case, because otherwise the __cxa_guard_aquire of the cxx + * library contention path might get called, which ends up in + * calling a Semaphore, which will call Kernel::stop_thread() or + * Kernel::yield() system-calls in this code + */ + while (Cpu::executing_id() != Cpu::primary_id() && !lock_ready) { ; } + { Lock::Guard guard(data_lock()); + lock_ready = true; + /* initialize current cpu */ pool_ready = cpu_pool().initialize(pic()); };