mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 13:47:56 +00:00
hw: don't take the log backend's mutex in kernel
To prevent the kernel to deadlock, or call itself with a syscall when using a lock potentially hold by a core thread, the log console's backend for core (hw) gets replaced by a specific variant that checks whether it runs in the kernel context before using the mutex. Fix genodelabs/genode#3280
This commit is contained in:
parent
b59ec55d50
commit
8fe7fa5532
@ -10,3 +10,8 @@ include $(BASE_DIR)/lib/mk/base-common.inc
|
|||||||
SRC_CC += rpc_dispatch_loop.cc
|
SRC_CC += rpc_dispatch_loop.cc
|
||||||
SRC_CC += thread.cc thread_myself.cc thread_bootstrap.cc
|
SRC_CC += thread.cc thread_myself.cc thread_bootstrap.cc
|
||||||
SRC_CC += signal_transmitter.cc
|
SRC_CC += signal_transmitter.cc
|
||||||
|
|
||||||
|
# filter out log.cc from the generic base library
|
||||||
|
# in core and hw kernel we have to implement it differently
|
||||||
|
SRC_CC_WITH_LOG_CC := $(SRC_CC)
|
||||||
|
SRC_CC = $(filter-out log.cc,$(SRC_CC_WITH_LOG_CC))
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
include $(BASE_DIR)/lib/mk/base.inc
|
include $(BASE_DIR)/lib/mk/base.inc
|
||||||
|
|
||||||
|
SRC_CC += log.cc
|
||||||
SRC_CC += thread_start.cc
|
SRC_CC += thread_start.cc
|
||||||
SRC_CC += capability.cc
|
SRC_CC += capability.cc
|
||||||
SRC_CC += cache.cc
|
SRC_CC += cache.cc
|
||||||
|
@ -12,15 +12,22 @@
|
|||||||
* under the terms of the GNU Affero General Public License version 3.
|
* under the terms of the GNU Affero General Public License version 3.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <base/log.h>
|
||||||
|
#include <base/thread.h>
|
||||||
|
|
||||||
/* base-internal includes */
|
/* base-internal includes */
|
||||||
#include <base/internal/output.h>
|
#include <base/internal/output.h>
|
||||||
#include <base/internal/raw_write_string.h>
|
#include <base/internal/raw_write_string.h>
|
||||||
|
|
||||||
#include <core_log.h>
|
#include <core_log.h>
|
||||||
|
#include <kernel/cpu.h>
|
||||||
#include <kernel/log.h>
|
#include <kernel/log.h>
|
||||||
|
|
||||||
|
using namespace Genode;
|
||||||
|
|
||||||
void Genode::Core_log::out(char const c) { Kernel::log(c); }
|
|
||||||
|
void Core_log::out(char const c) { Kernel::log(c); }
|
||||||
|
|
||||||
|
|
||||||
void Genode::raw_write_string(char const *str)
|
void Genode::raw_write_string(char const *str)
|
||||||
@ -28,3 +35,75 @@ void Genode::raw_write_string(char const *str)
|
|||||||
while (char c = *str++)
|
while (char c = *str++)
|
||||||
Kernel::log(c);
|
Kernel::log(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************
|
||||||
|
** Utility to check whether kernel or core code is active **
|
||||||
|
************************************************************/
|
||||||
|
|
||||||
|
extern void const * const kernel_stack;
|
||||||
|
|
||||||
|
static inline bool running_in_kernel()
|
||||||
|
{
|
||||||
|
addr_t const stack_base = reinterpret_cast<addr_t>(&kernel_stack);
|
||||||
|
static constexpr size_t stack_size =
|
||||||
|
NR_OF_CPUS * Kernel::Cpu::KERNEL_STACK_SIZE;
|
||||||
|
|
||||||
|
/* check stack variable against kernel stack area */
|
||||||
|
return ((addr_t)&stack_base) >= stack_base &&
|
||||||
|
((addr_t)&stack_base) < (stack_base + stack_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************
|
||||||
|
** Implementation of src/lib/base/log.cc **
|
||||||
|
*******************************************/
|
||||||
|
|
||||||
|
void Log::_acquire(Type type)
|
||||||
|
{
|
||||||
|
if (!running_in_kernel()) _mutex.acquire();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mark warnings and errors via distinct colors.
|
||||||
|
*/
|
||||||
|
switch (type) {
|
||||||
|
case LOG: break;
|
||||||
|
case WARNING: _output.out_string("\033[34mWarning: "); break;
|
||||||
|
case ERROR: _output.out_string("\033[31mError: "); break;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Log::_release()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Reset color and add newline
|
||||||
|
*/
|
||||||
|
_output.out_string("\033[0m\n");
|
||||||
|
|
||||||
|
if (!running_in_kernel()) _mutex.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Raw::_acquire()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Mark raw output with distinct color
|
||||||
|
*/
|
||||||
|
_output().out_string("\033[32mKernel: ");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Raw::_release()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Reset color and add newline
|
||||||
|
*/
|
||||||
|
_output().out_string("\033[0m\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Trace_output::Write_trace_fn::operator () (char const *s)
|
||||||
|
{
|
||||||
|
Thread::trace(s);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user