mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-31 08:25:38 +00:00
NOVA: let thread die if SM cap is invalid
Patch prevents following bugs: * In sleep_forever the thread return from semaphore down if cap is revoked during destruction of a thread. This causes an endless loop consuming time not available for other threads. * In lock_helper and cap_sel_alloc the thread return from the lock() method even if the semaphore down call failed because of an revoked semaphore. This lead to the situation that a thread subject to de-construction returns from the lock method, but not holding the lock, entering the critical section and modifying state inside the critical section. Another thread in parallel already in the critical section or entering the critical section also modifies the state. This lead to curious bugs ... * thread_nova, thread_start, irq_session Detect early bugs if the SM is gone unexpectedly where it should never happen.
This commit is contained in:
parent
650a1d47f0
commit
4342d0d234
@ -20,6 +20,7 @@
|
||||
|
||||
/* NOVA includes */
|
||||
#include <nova/syscalls.h>
|
||||
#include <nova/util.h>
|
||||
|
||||
extern int main_thread_running_semaphore();
|
||||
|
||||
@ -32,7 +33,10 @@ namespace Genode {
|
||||
Thread_base *myself = Thread_base::myself();
|
||||
addr_t sem = myself ? myself->tid().exc_pt_sel + SM_SEL_EC :
|
||||
main_thread_running_semaphore();
|
||||
while (1) { Nova::sm_ctrl(sem, Nova::SEMAPHORE_DOWNZERO); }
|
||||
while (1) {
|
||||
if (Nova::sm_ctrl(sem, SEMAPHORE_DOWNZERO))
|
||||
nova_die();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,17 @@
|
||||
#include <base/printf.h>
|
||||
#include <base/thread.h>
|
||||
|
||||
__attribute__((always_inline))
|
||||
inline void nova_die(const char * text = 0)
|
||||
{
|
||||
/*
|
||||
* If thread is de-constructed the sessions are already gone.
|
||||
* Be careful when enabling printf here.
|
||||
*/
|
||||
while (1)
|
||||
asm volatile ("ud2a" : : "a"(text));
|
||||
}
|
||||
|
||||
inline void request_event_portal(Genode::Native_capability cap,
|
||||
Genode::addr_t exc_base, Genode::addr_t event)
|
||||
{
|
||||
@ -31,7 +42,7 @@ inline void request_event_portal(Genode::Native_capability cap,
|
||||
utcb->msg[0] = event;
|
||||
utcb->set_msg_word(1);
|
||||
|
||||
uint8_t res = call(pager_cap.local_name());
|
||||
uint8_t res = call(cap.local_name());
|
||||
if (res)
|
||||
PERR("request of event (%lu) capability selector failed",
|
||||
event);
|
||||
|
@ -21,11 +21,12 @@
|
||||
#ifndef _INCLUDE__SIGNAL_SESSION__SOURCE_CLIENT_H_
|
||||
#define _INCLUDE__SIGNAL_SESSION__SOURCE_CLIENT_H_
|
||||
|
||||
#include <nova/syscalls.h>
|
||||
#include <base/rpc_client.h>
|
||||
#include <signal_session/nova_source.h>
|
||||
|
||||
#include <base/nova_util.h>
|
||||
/* NOVA includes */
|
||||
#include <nova/syscalls.h>
|
||||
#include <nova/util.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
@ -34,7 +35,7 @@ namespace Genode {
|
||||
private:
|
||||
|
||||
/**
|
||||
* Capability with 'pt_sel' referring to a NOVA semaphore
|
||||
* Capability referring to a NOVA semaphore
|
||||
*/
|
||||
Native_capability _sem;
|
||||
|
||||
@ -78,7 +79,7 @@ namespace Genode {
|
||||
*/
|
||||
if (Nova::sm_ctrl(_sem.local_name(),
|
||||
Nova::SEMAPHORE_DOWN))
|
||||
nova_die(__FILE__, __LINE__);
|
||||
nova_die();
|
||||
|
||||
/*
|
||||
* Now that the server has unblocked the semaphore, we are sure
|
||||
|
13
base-nova/src/base/env/cap_sel_alloc.cc
vendored
13
base-nova/src/base/env/cap_sel_alloc.cc
vendored
@ -20,6 +20,7 @@
|
||||
|
||||
/* NOVA includes */
|
||||
#include <nova/syscalls.h>
|
||||
#include <nova/util.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
@ -52,9 +53,17 @@ class Alloc_lock
|
||||
*/
|
||||
Alloc_lock() : _sm_cap(Nova::PD_SEL_CAP_LOCK) { }
|
||||
|
||||
void lock() { Nova::sm_ctrl(_sm_cap, Nova::SEMAPHORE_DOWN); }
|
||||
void lock()
|
||||
{
|
||||
if (Nova::sm_ctrl(_sm_cap, Nova::SEMAPHORE_DOWN))
|
||||
nova_die();
|
||||
}
|
||||
|
||||
void unlock() { Nova::sm_ctrl(_sm_cap, Nova::SEMAPHORE_UP); }
|
||||
void unlock()
|
||||
{
|
||||
if (Nova::sm_ctrl(_sm_cap, Nova::SEMAPHORE_UP))
|
||||
nova_die();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
/* NOVA includes */
|
||||
#include <nova/syscalls.h>
|
||||
#include <nova/util.h>
|
||||
|
||||
|
||||
extern int main_thread_running_semaphore();
|
||||
@ -100,5 +101,6 @@ static inline void thread_stop_myself()
|
||||
else
|
||||
sem = main_thread_running_semaphore();
|
||||
|
||||
sm_ctrl(sem, SEMAPHORE_DOWNZERO);
|
||||
if (sm_ctrl(sem, SEMAPHORE_DOWNZERO))
|
||||
nova_die();
|
||||
}
|
||||
|
@ -21,9 +21,8 @@
|
||||
|
||||
/* NOVA includes */
|
||||
#include <nova/syscalls.h>
|
||||
#include <base/nova_util.h>
|
||||
#include <nova_cpu_session/connection.h>
|
||||
|
||||
#include <nova/util.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
/* NOVA includes */
|
||||
#include <nova/syscalls.h>
|
||||
#include <base/nova_util.h>
|
||||
#include <nova/util.h>
|
||||
#include <nova_cpu_session/connection.h>
|
||||
|
||||
using namespace Genode;
|
||||
@ -139,5 +139,8 @@ void Thread_base::start()
|
||||
|
||||
void Thread_base::cancel_blocking()
|
||||
{
|
||||
Nova::sm_ctrl(_tid.exc_pt_sel + Nova::SM_SEL_EC, Nova::SEMAPHORE_UP);
|
||||
using namespace Nova;
|
||||
|
||||
if (sm_ctrl(_tid.exc_pt_sel + SM_SEL_EC, SEMAPHORE_UP))
|
||||
nova_die();
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
/* NOVA includes */
|
||||
#include <nova/syscalls.h>
|
||||
#include <nova/util.h>
|
||||
#include <nova_util.h>
|
||||
|
||||
using namespace Genode;
|
||||
@ -28,7 +29,8 @@ using namespace Genode;
|
||||
|
||||
void Irq_session_component::wait_for_irq()
|
||||
{
|
||||
Nova::sm_ctrl(_irq_number, Nova::SEMAPHORE_DOWN);
|
||||
if (Nova::sm_ctrl(_irq_number, Nova::SEMAPHORE_DOWN))
|
||||
nova_die();
|
||||
}
|
||||
|
||||
|
||||
|
@ -92,5 +92,6 @@ void Thread_base::cancel_blocking()
|
||||
{
|
||||
using namespace Nova;
|
||||
|
||||
sm_ctrl(_tid.exc_pt_sel + SM_SEL_EC, SEMAPHORE_UP);
|
||||
if (sm_ctrl(_tid.exc_pt_sel + SM_SEL_EC, SEMAPHORE_UP))
|
||||
nova_die();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user