From 05f5999e719a432fcf69ba46ed4ef61b5da9d698 Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Mon, 12 Nov 2012 17:48:18 +0100 Subject: [PATCH] cpu_session: Access thread state by value --- .../src/core/include/platform_thread.h | 16 ++++--- base-codezero/src/core/platform_thread.cc | 13 ++++-- .../src/core/include/platform_thread.h | 16 ++++--- base-fiasco/src/core/platform_thread.cc | 18 ++++++-- base-foc/include/foc_cpu_session/client.h | 7 ++- base-foc/src/base/thread/thread_start.cc | 3 +- .../src/core/include/cpu_session_component.h | 3 +- base-foc/src/core/include/platform_thread.h | 16 ++++--- base-foc/src/core/platform_thread.cc | 21 ++++++--- base-host/src/core/include/platform_thread.h | 16 ++++--- base-host/src/core/platform_thread.cc | 14 ++++-- base-hw/src/core/include/platform_thread.h | 24 +++++----- base-linux/include/linux_cpu_session/client.h | 7 ++- .../src/core/include/cpu_session_component.h | 3 +- base-linux/src/core/include/platform_thread.h | 15 ++++++- base-mb/src/core/include/platform_thread.h | 16 ++++--- base-mb/src/core/platform_thread.cc | 14 ++++-- base-nova/include/base/thread_state.h | 7 +-- base-nova/include/cpu_session/client.h | 9 ++-- base-nova/src/base/server/server.cc | 7 +-- base-nova/src/base/thread/thread_nova.cc | 7 +-- .../src/core/include/cpu_session_component.h | 3 +- base-nova/src/core/include/platform_thread.h | 16 ++++--- base-nova/src/core/platform_thread.cc | 45 +++++++++---------- base-okl4/src/core/include/platform_thread.h | 14 +++--- base-okl4/src/core/x86/platform_thread_x86.cc | 34 ++++++++------ .../src/core/include/platform_thread.h | 14 +++--- base-pistachio/src/core/platform_thread.cc | 17 +++++-- base/include/cpu_session/client.h | 7 ++- base/include/cpu_session/cpu_session.h | 35 ++++++++++----- base/src/core/cpu_session_component.cc | 19 +++++--- base/src/core/include/cpu_session_component.h | 3 +- ports-foc/src/lib/l4lx/include/vcpu.h | 3 +- .../src/lib/oklx/genode/genode_threads.cc | 5 +-- .../app/gdb_monitor/cpu_session_component.cc | 12 +++-- .../app/gdb_monitor/cpu_session_component.h | 3 +- .../lib/gdbserver_platform/fiasco_x86_low.cc | 4 +- .../src/lib/gdbserver_platform/foc_arm_low.cc | 4 +- .../lib/gdbserver_platform/foc_x86_32_low.cc | 4 +- .../gdbserver_platform_helper.cc | 4 +- .../gdbserver_platform_helper.h | 5 ++- .../gdbserver_platform/linux_x86_32_low.cc | 4 +- .../lib/gdbserver_platform/nova_x86_32_low.cc | 4 +- .../lib/gdbserver_platform/okl4_x86_low.cc | 4 +- .../gdbserver_platform/pistachio_x86_low.cc | 4 +- ports/src/noux/cpu_session_component.h | 11 +++-- ports/src/vancouver/main.cc | 22 ++++----- 47 files changed, 353 insertions(+), 199 deletions(-) diff --git a/base-codezero/src/core/include/platform_thread.h b/base-codezero/src/core/include/platform_thread.h index 243882641..270f89c4a 100644 --- a/base-codezero/src/core/include/platform_thread.h +++ b/base-codezero/src/core/include/platform_thread.h @@ -87,14 +87,18 @@ namespace Genode { void cancel_blocking(); /** - * Request thread state + * Override thread state with 's' * - * \param state_dst destination state buffer - * - * \retval 0 successful - * \retval -1 thread state not accessible + * \throw Cpu_session::State_access_failed */ - int state(Genode::Thread_state *state_dst); + void state(Thread_state s); + + /** + * Read thread state + * + * \throw Cpu_session::State_access_failed + */ + Thread_state state(); /************************ diff --git a/base-codezero/src/core/platform_thread.cc b/base-codezero/src/core/platform_thread.cc index 0ff5d06a0..7f8ef069e 100644 --- a/base-codezero/src/core/platform_thread.cc +++ b/base-codezero/src/core/platform_thread.cc @@ -78,10 +78,17 @@ void Platform_thread::resume() } -int Platform_thread::state(Thread_state *state_dst) +void Platform_thread::state(Thread_state s) { - PDBG("not implemented"); - return -1; + PDBG("Not implemented"); + throw Cpu_session::State_access_failed(); +} + + +Thread_state Platform_thread::state() +{ + PDBG("Not implemented"); + throw Cpu_session::State_access_failed(); } diff --git a/base-fiasco/src/core/include/platform_thread.h b/base-fiasco/src/core/include/platform_thread.h index 7762afea8..cdb34dcc3 100644 --- a/base-fiasco/src/core/include/platform_thread.h +++ b/base-fiasco/src/core/include/platform_thread.h @@ -102,14 +102,18 @@ namespace Genode { void unbind(); /** - * Request thread state + * Override thread state with 's' * - * \param state_dst destination state buffer - * - * \retval 0 successful - * \retval -1 thread state not accessible + * \throw Cpu_session::State_access_failed */ - int state(Genode::Thread_state *state_dst); + void state(Thread_state s); + + /** + * Read thread state + * + * \throw Cpu_session::State_access_failed + */ + Thread_state state(); /** * Set the executing CPU for this thread diff --git a/base-fiasco/src/core/platform_thread.cc b/base-fiasco/src/core/platform_thread.cc index b5b8c4c03..e4dc279a2 100644 --- a/base-fiasco/src/core/platform_thread.cc +++ b/base-fiasco/src/core/platform_thread.cc @@ -17,6 +17,7 @@ /* Genode includes */ #include #include +#include /* core includes */ #include @@ -101,8 +102,17 @@ void Platform_thread::unbind() } -int Platform_thread::state(Thread_state *state_dst) +void Platform_thread::state(Thread_state s) { + PDBG("Not implemented"); + throw Cpu_session::State_access_failed(); +} + + +Thread_state Platform_thread::state() +{ + Thread_state s; + l4_umword_t old_eflags, ip, sp; l4_threadid_t thread = _l4_thread_id; l4_threadid_t pager = L4_INVALID_ID; @@ -117,10 +127,10 @@ int Platform_thread::state(Thread_state *state_dst) PWRN("old eflags == ~0 on ex_regs %x.%x", (int)thread.id.task, (int)thread.id.lthread); /* fill thread state structure */ - state_dst->ip = ip; - state_dst->sp = sp; + s.ip = ip; + s.sp = sp; - return 0; + return s; } diff --git a/base-foc/include/foc_cpu_session/client.h b/base-foc/include/foc_cpu_session/client.h index b95b93a37..1965be3c6 100644 --- a/base-foc/include/foc_cpu_session/client.h +++ b/base-foc/include/foc_cpu_session/client.h @@ -55,8 +55,11 @@ namespace Genode { return -1; } - int state(Thread_capability thread, Thread_state *dst_state) { - return call(thread, dst_state); } + Thread_state state(Thread_capability thread) { + return call(thread); } + + void state(Thread_capability thread, Thread_state const &state) { + call(thread, state); } void exception_handler(Thread_capability thread, Signal_context_capability handler) { call(thread, handler); } diff --git a/base-foc/src/base/thread/thread_start.cc b/base-foc/src/base/thread/thread_start.cc index bec30a5e5..37a52b494 100644 --- a/base-foc/src/base/thread/thread_start.cc +++ b/base-foc/src/base/thread/thread_start.cc @@ -53,7 +53,8 @@ void Thread_base::start() /* get gate-capability and badge of new thread */ Thread_state state; - env()->cpu_session()->state(_thread_cap, &state); + try { state = env()->cpu_session()->state(_thread_cap); } + catch (...) { throw Cpu_session::Thread_creation_failed(); } _tid = state.kcap; _context->utcb = state.utcb; diff --git a/base-foc/src/core/include/cpu_session_component.h b/base-foc/src/core/include/cpu_session_component.h index e82660c91..0353e72cb 100644 --- a/base-foc/src/core/include/cpu_session_component.h +++ b/base-foc/src/core/include/cpu_session_component.h @@ -139,7 +139,8 @@ namespace Genode { void single_step(Thread_capability thread_cap, bool enable); void cancel_blocking(Thread_capability); int name(Thread_capability, char *, size_t); - int state(Thread_capability, Thread_state *); + Thread_state state(Thread_capability); + void state(Thread_capability, Thread_state const &); void exception_handler(Thread_capability, Signal_context_capability); unsigned num_cpus() const; void affinity(Thread_capability, unsigned); diff --git a/base-foc/src/core/include/platform_thread.h b/base-foc/src/core/include/platform_thread.h index a80d5b6e3..fc9e76158 100644 --- a/base-foc/src/core/include/platform_thread.h +++ b/base-foc/src/core/include/platform_thread.h @@ -116,14 +116,18 @@ namespace Genode { void unbind(); /** - * Request thread state + * Override thread state with 's' * - * \param state_dst destination state buffer - * - * \retval 0 successful - * \retval -1 thread state not accessible + * \throw Cpu_session::State_access_failed */ - int state(Genode::Thread_state *state_dst); + void state(Thread_state s); + + /** + * Read thread state + * + * \throw Cpu_session::State_access_failed + */ + Thread_state state(); /** * Set the executing CPU for this thread diff --git a/base-foc/src/core/platform_thread.cc b/base-foc/src/core/platform_thread.cc index fde67aac8..845010600 100644 --- a/base-foc/src/core/platform_thread.cc +++ b/base-foc/src/core/platform_thread.cc @@ -161,16 +161,23 @@ void Platform_thread::pager(Pager_object *pager_obj) } -int Platform_thread::state(Thread_state *state_dst) +void Platform_thread::state(Thread_state s) { - if (_pager_obj) - *state_dst = _pager_obj->state; + PDBG("Not implemented"); + throw Cpu_session::State_access_failed(); +} - state_dst->kcap = _gate.remote; - state_dst->id = _gate.local.local_name(); - state_dst->utcb = _utcb; - return 0; +Thread_state Platform_thread::state() +{ + Thread_state s; + if (_pager_obj) s = _pager_obj->state; + + s.kcap = _gate.remote; + s.id = _gate.local.local_name(); + s.utcb = _utcb; + + return s; } diff --git a/base-host/src/core/include/platform_thread.h b/base-host/src/core/include/platform_thread.h index 113b70a94..b2991eaee 100644 --- a/base-host/src/core/include/platform_thread.h +++ b/base-host/src/core/include/platform_thread.h @@ -67,14 +67,18 @@ namespace Genode { void cancel_blocking(); /** - * Request thread state + * Override thread state with 's' * - * \param state_dst destination state buffer - * - * \retval 0 successful - * \retval -1 thread state not accessible + * \throw Cpu_session::State_access_failed */ - int state(Genode::Thread_state *state_dst); + void state(Thread_state s); + + /** + * Read thread state + * + * \throw Cpu_session::State_access_failed + */ + Thread_state state(); /************************ diff --git a/base-host/src/core/platform_thread.cc b/base-host/src/core/platform_thread.cc index 365fe3909..a23b8d23a 100644 --- a/base-host/src/core/platform_thread.cc +++ b/base-host/src/core/platform_thread.cc @@ -13,6 +13,7 @@ /* Genode includes */ #include +#include /* core includes */ #include @@ -45,10 +46,17 @@ void Platform_thread::resume() } -int Platform_thread::state(Thread_state *state_dst) +void Platform_thread::state(Thread_state s) { - PWRN("not implemented"); - return -1; + PDBG("Not implemented"); + throw Cpu_session::State_access_failed(); +} + + +Thread_state Platform_thread::state() +{ + PDBG("Not implemented"); + throw Cpu_session::State_access_failed(); } diff --git a/base-hw/src/core/include/platform_thread.h b/base-hw/src/core/include/platform_thread.h index b5348a2ef..9d1584945 100644 --- a/base-hw/src/core/include/platform_thread.h +++ b/base-hw/src/core/include/platform_thread.h @@ -19,6 +19,7 @@ #include #include #include +#include /* core includes */ #include @@ -119,18 +120,21 @@ namespace Genode { }; /** - * Request our raw thread state - * - * \param state_dst destination state buffer - * - * \retval 0 successful - * \retval -1 thread state not accessible + * Get raw thread state */ - int state(Genode::Thread_state * state_dst) + Thread_state state() { - kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n"; - while (1) ; - return -1; + Kernel::read_thread_state(id()); + return *(Thread_state *)Thread_base::myself()->utcb()->base(); + }; + + /** + * Override raw thread state + */ + void state(Thread_state s) + { + *(Thread_state *)Thread_base::myself()->utcb()->base() = s; + Kernel::write_thread_state(id()); }; /** diff --git a/base-linux/include/linux_cpu_session/client.h b/base-linux/include/linux_cpu_session/client.h index a97e14330..1748b4a6b 100644 --- a/base-linux/include/linux_cpu_session/client.h +++ b/base-linux/include/linux_cpu_session/client.h @@ -48,8 +48,11 @@ namespace Genode { void cancel_blocking(Thread_capability thread) { call(thread); } - int state(Thread_capability thread, Thread_state *dst_state) { - return call(thread, dst_state); } + Thread_state state(Thread_capability thread) { + return call(thread); } + + void state(Thread_capability thread, Thread_state const &state) { + call(thread, state); } void exception_handler(Thread_capability thread, Signal_context_capability handler) { call(thread, handler); } diff --git a/base-linux/src/core/include/cpu_session_component.h b/base-linux/src/core/include/cpu_session_component.h index 03c533006..65fee7fee 100644 --- a/base-linux/src/core/include/cpu_session_component.h +++ b/base-linux/src/core/include/cpu_session_component.h @@ -133,7 +133,8 @@ namespace Genode { void resume(Thread_capability thread_cap); void cancel_blocking(Thread_capability); int name(Thread_capability, char *, size_t); - int state(Thread_capability, Thread_state *); + Thread_state state(Thread_capability); + void state(Thread_capability, Thread_state const &); void exception_handler(Thread_capability, Signal_context_capability); unsigned num_cpus() const; void affinity(Thread_capability, unsigned); diff --git a/base-linux/src/core/include/platform_thread.h b/base-linux/src/core/include/platform_thread.h index 66743ccda..811e62d1b 100644 --- a/base-linux/src/core/include/platform_thread.h +++ b/base-linux/src/core/include/platform_thread.h @@ -18,6 +18,7 @@ #include #include +#include namespace Genode { @@ -64,7 +65,19 @@ namespace Genode { Pager_object *pager() { return 0; } void pager(Pager_object *) { } int start(void *ip, void *sp) { return 0; } - int state(Thread_state *state_dst) { return 0; } + + Thread_state state() + { + PDBG("Not implemented"); + throw Cpu_session::State_access_failed(); + } + + void state(Thread_state) + { + PDBG("Not implemented"); + throw Cpu_session::State_access_failed(); + } + const char *name() { return _name; } void affinity(unsigned) { } diff --git a/base-mb/src/core/include/platform_thread.h b/base-mb/src/core/include/platform_thread.h index ad95fe800..2021b783a 100755 --- a/base-mb/src/core/include/platform_thread.h +++ b/base-mb/src/core/include/platform_thread.h @@ -115,14 +115,18 @@ namespace Genode { void cancel_blocking(); /** - * Request thread state + * Override thread state with 's' * - * \param state_dst destination state buffer - * - * \retval 0 successful - * \retval -1 thread state not accessible + * \throw Cpu_session::State_access_failed */ - int state(Genode::Thread_state *state_dst); + void state(Thread_state s); + + /** + * Read thread state + * + * \throw Cpu_session::State_access_failed + */ + Thread_state state(); /************************ diff --git a/base-mb/src/core/platform_thread.cc b/base-mb/src/core/platform_thread.cc index 0828116ef..8c4c3bb94 100755 --- a/base-mb/src/core/platform_thread.cc +++ b/base-mb/src/core/platform_thread.cc @@ -18,6 +18,7 @@ #include #include #include "include/platform.h" +#include static bool const verbose = 0; @@ -87,10 +88,17 @@ void Platform_thread::affinity(unsigned int cpu_no) { PERR("not implemented"); } void Platform_thread::cancel_blocking() { PERR("not implemented"); } -int Platform_thread::state(Thread_state *state_dst) +void Platform_thread::state(Thread_state s) { - PERR("not implemented"); - return -1; + PDBG("Not implemented"); + throw Cpu_session::State_access_failed(); +} + + +Thread_state Platform_thread::state() +{ + PDBG("Not implemented"); + throw Cpu_session::State_access_failed(); } diff --git a/base-nova/include/base/thread_state.h b/base-nova/include/base/thread_state.h index 3ec23a9a9..2522cb68e 100644 --- a/base-nova/include/base/thread_state.h +++ b/base-nova/include/base/thread_state.h @@ -22,12 +22,13 @@ namespace Genode { struct Thread_state : public Cpu_state { - bool transfer; bool is_vcpu; addr_t sel_exc_base; - Thread_state(bool trans = false) : Cpu_state(), transfer(trans), - is_vcpu(false), sel_exc_base(~0UL) {} + Thread_state() : Cpu_state(), is_vcpu(false), sel_exc_base(~0UL) { } + + Thread_state(bool is_vcpu, addr_t sel_exc_base) + : is_vcpu(is_vcpu), sel_exc_base(sel_exc_base) { } }; } diff --git a/base-nova/include/cpu_session/client.h b/base-nova/include/cpu_session/client.h index e10662c74..03d91635e 100644 --- a/base-nova/include/cpu_session/client.h +++ b/base-nova/include/cpu_session/client.h @@ -34,11 +34,9 @@ namespace Genode { Ram_dataspace_capability utcb(Thread_capability thread) { return call(thread); } - void kill_thread(Thread_capability thread) { call(thread); } - int set_pager(Thread_capability thread, Pager_capability pager) { return call(thread, pager); } @@ -63,8 +61,11 @@ namespace Genode { void cancel_blocking(Thread_capability thread) { call(thread); } - int state(Thread_capability thread, Thread_state *dst_state) { - return call(thread, dst_state); } + Thread_state state(Thread_capability thread) { + return call(thread); } + + void state(Thread_capability thread, Thread_state const &state) { + call(thread, state); } void exception_handler(Thread_capability thread, Signal_context_capability handler) { call(thread, handler); } diff --git a/base-nova/src/base/server/server.cc b/base-nova/src/base/server/server.cc index 869134adf..85c3b9377 100644 --- a/base-nova/src/base/server/server.cc +++ b/base-nova/src/base/server/server.cc @@ -215,11 +215,12 @@ Rpc_entrypoint::Rpc_entrypoint(Cap_session *cap_session, size_t stack_size, addr_t thread_sp = (addr_t)&_context->stack[-4]; - Thread_state state(true); + Thread_state state; state.sel_exc_base = _tid.exc_pt_sel; - if (env()->cpu_session()->state(_thread_cap, &state) || - env()->cpu_session()->start(_thread_cap, 0, thread_sp)) + try { env()->cpu_session()->state(_thread_cap, state); } + catch(...) { throw Cpu_session::Thread_creation_failed(); } + if (env()->cpu_session()->start(_thread_cap, 0, thread_sp)) throw Cpu_session::Thread_creation_failed(); for (unsigned i = 0; i < Nova::PT_SEL_PARENT; i++) diff --git a/base-nova/src/base/thread/thread_nova.cc b/base-nova/src/base/thread/thread_nova.cc index 135cbc442..4454c042a 100644 --- a/base-nova/src/base/thread/thread_nova.cc +++ b/base-nova/src/base/thread/thread_nova.cc @@ -117,12 +117,13 @@ void Thread_base::start() /* create EC at core */ addr_t thread_sp = reinterpret_cast(&_context->stack[-4]); - Thread_state state(true); + Thread_state state; state.sel_exc_base = _tid.exc_pt_sel; state.is_vcpu = _tid.is_vcpu; - if (env()->cpu_session()->state(_thread_cap, &state) || - env()->cpu_session()->start(_thread_cap, (addr_t)_thread_start, + try { env()->cpu_session()->state(_thread_cap, state); } + catch (...) { throw Cpu_session::Thread_creation_failed(); } + if (env()->cpu_session()->start(_thread_cap, (addr_t)_thread_start, thread_sp)) throw Cpu_session::Thread_creation_failed(); diff --git a/base-nova/src/core/include/cpu_session_component.h b/base-nova/src/core/include/cpu_session_component.h index e279e425b..259a67544 100644 --- a/base-nova/src/core/include/cpu_session_component.h +++ b/base-nova/src/core/include/cpu_session_component.h @@ -138,7 +138,8 @@ namespace Genode { void single_step(Thread_capability thread_cap, bool enable); void cancel_blocking(Thread_capability); int name(Thread_capability, char *, size_t); - int state(Thread_capability, Thread_state *); + Thread_state state(Thread_capability); + void state(Thread_capability, Thread_state const &); void exception_handler(Thread_capability, Signal_context_capability); unsigned num_cpus() const; void affinity(Thread_capability, unsigned); diff --git a/base-nova/src/core/include/platform_thread.h b/base-nova/src/core/include/platform_thread.h index c97672d3c..bf7fa4291 100644 --- a/base-nova/src/core/include/platform_thread.h +++ b/base-nova/src/core/include/platform_thread.h @@ -84,14 +84,18 @@ namespace Genode { void cancel_blocking(); /** - * Request thread state + * Override thread state with 's' * - * \param state_dst destination state buffer - * - * \retval 0 successful - * \retval -1 thread state not accessible + * \throw Cpu_session::State_access_failed */ - int state(Genode::Thread_state *state_dst); + void state(Thread_state s); + + /** + * Read thread state + * + * \throw Cpu_session::State_access_failed + */ + Thread_state state(); /************************ diff --git a/base-nova/src/core/platform_thread.cc b/base-nova/src/core/platform_thread.cc index 7b3cc0a7d..b08609424 100644 --- a/base-nova/src/core/platform_thread.cc +++ b/base-nova/src/core/platform_thread.cc @@ -265,33 +265,32 @@ void Platform_thread::resume() _pager->wake_up(); } - -int Platform_thread::state(Thread_state *state_dst) +Thread_state Platform_thread::state() { - if (!state_dst || !_pager) return -1; + Thread_state s; + if (!_pager) throw Cpu_session::State_access_failed(); + _pager->copy_thread_state(&s); + return s; +}; - if (state_dst->transfer) { - /* Not permitted for main thread */ - if (_is_main_thread) return -2; +void Platform_thread::state(Thread_state s) +{ + /* not permitted for main thread */ + if (_is_main_thread) throw Cpu_session::State_access_failed(); - /* You can do it only once */ - if (_sel_exc_base != Native_thread::INVALID_INDEX) return -3; - - /** - * _sel_exc_base exception base of thread in caller - * protection domain - not in Core ! - * _is_vcpu If true it will run as vCPU, - * otherwise it will be a thread. - */ - _sel_exc_base = state_dst->sel_exc_base; - _is_vcpu = state_dst->is_vcpu; - - return 0; - } - - return _pager->copy_thread_state(state_dst); -} + /* you can do it only once */ + if (_sel_exc_base != Native_thread::INVALID_INDEX) + throw Cpu_session::State_access_failed(); + /** + * _sel_exc_base exception base of thread in caller + * protection domain - not in Core ! + * _is_vcpu If true it will run as vCPU, + * otherwise it will be a thread. + */ + _sel_exc_base = s.sel_exc_base; + _is_vcpu = s.is_vcpu; +}; void Platform_thread::cancel_blocking() { diff --git a/base-okl4/src/core/include/platform_thread.h b/base-okl4/src/core/include/platform_thread.h index 5b18408ad..dfbacc39c 100644 --- a/base-okl4/src/core/include/platform_thread.h +++ b/base-okl4/src/core/include/platform_thread.h @@ -99,14 +99,16 @@ namespace Genode { void unbind(); /** - * Request thread state + * Override thread state with 's' * - * \param state_dst destination state buffer - * - * \retval 0 successful - * \retval -1 thread state not accessible + * \throw Cpu_session::State_access_failed */ - int state(Genode::Thread_state *state_dst); + void state(Thread_state s); + + /** + * Read thread state + */ + Thread_state state(); /************************ diff --git a/base-okl4/src/core/x86/platform_thread_x86.cc b/base-okl4/src/core/x86/platform_thread_x86.cc index d02d7b736..1adc37355 100644 --- a/base-okl4/src/core/x86/platform_thread_x86.cc +++ b/base-okl4/src/core/x86/platform_thread_x86.cc @@ -23,9 +23,10 @@ using namespace Genode; using namespace Okl4; -int Platform_thread::state(Thread_state *state_dst) +Thread_state Platform_thread::state() { - state_dst->tid = _l4_thread_id; + Thread_state s; + s.tid = _l4_thread_id; L4_Copy_regs_to_mrs(_l4_thread_id); @@ -42,16 +43,23 @@ int Platform_thread::state(Thread_state *state_dst) MR_EAX = 9, }; - L4_StoreMR(MR_EIP, &state_dst->ip); - L4_StoreMR(MR_EFLAGS, &state_dst->eflags); - L4_StoreMR(MR_EDI, &state_dst->edi); - L4_StoreMR(MR_ESI, &state_dst->esi); - L4_StoreMR(MR_EBP, &state_dst->ebp); - L4_StoreMR(MR_ESP, &state_dst->sp); - L4_StoreMR(MR_EBX, &state_dst->ebx); - L4_StoreMR(MR_EDX, &state_dst->edx); - L4_StoreMR(MR_ECX, &state_dst->ecx); - L4_StoreMR(MR_EAX, &state_dst->eax); + L4_StoreMR(MR_EIP, &s.ip); + L4_StoreMR(MR_EFLAGS, &s.eflags); + L4_StoreMR(MR_EDI, &s.edi); + L4_StoreMR(MR_ESI, &s.esi); + L4_StoreMR(MR_EBP, &s.ebp); + L4_StoreMR(MR_ESP, &s.sp); + L4_StoreMR(MR_EBX, &s.ebx); + L4_StoreMR(MR_EDX, &s.edx); + L4_StoreMR(MR_ECX, &s.ecx); + L4_StoreMR(MR_EAX, &s.eax); - return 0; + return s; } + +void Platform_thread::state(Thread_state) +{ + PDBG("Not implemented"); + throw Cpu_session::State_access_failed(); +} + diff --git a/base-pistachio/src/core/include/platform_thread.h b/base-pistachio/src/core/include/platform_thread.h index 803657f00..b0f45ca1a 100644 --- a/base-pistachio/src/core/include/platform_thread.h +++ b/base-pistachio/src/core/include/platform_thread.h @@ -103,14 +103,16 @@ namespace Genode { void unbind(); /** - * Request thread state + * Override thread state with 's' * - * \param state_dst destination state buffer - * - * \retval 0 successful - * \retval -1 thread state not accessible + * \throw Cpu_session::State_access_failed */ - int state(Genode::Thread_state *state_dst); + void state(Thread_state s); + + /** + * Read thread state + */ + Thread_state state(); /************************ diff --git a/base-pistachio/src/core/platform_thread.cc b/base-pistachio/src/core/platform_thread.cc index 01261bdfa..6623bc9f1 100644 --- a/base-pistachio/src/core/platform_thread.cc +++ b/base-pistachio/src/core/platform_thread.cc @@ -162,8 +162,17 @@ void Platform_thread::unbind() } -int Platform_thread::state(Thread_state *state_dst) +void Platform_thread::state(Thread_state) { + PDBG("Not implemented"); + throw Cpu_session::State_access_failed(); +} + + +Thread_state Platform_thread::state() +{ + Thread_state s; + L4_Word_t dummy; L4_ThreadId_t dummy_tid; L4_Word_t ip, sp; @@ -177,9 +186,9 @@ int Platform_thread::state(Thread_state *state_dst) 0, 0, 0, 0, L4_nilthread, &dummy, &sp, &ip, &dummy, &dummy, &dummy_tid); - state_dst->ip = ip; - state_dst->sp = sp; - return 0; + s.ip = ip; + s.sp = sp; + return s; } diff --git a/base/include/cpu_session/client.h b/base/include/cpu_session/client.h index 33d7bc7b6..158b9296b 100644 --- a/base/include/cpu_session/client.h +++ b/base/include/cpu_session/client.h @@ -48,8 +48,11 @@ namespace Genode { void cancel_blocking(Thread_capability thread) { call(thread); } - int state(Thread_capability thread, Thread_state *dst_state) { - return call(thread, dst_state); } + Thread_state state(Thread_capability thread) { + return call(thread); } + + void state(Thread_capability thread, Thread_state const &state) { + call(thread, state); } void exception_handler(Thread_capability thread, Signal_context_capability handler) { call(thread, handler); } diff --git a/base/include/cpu_session/cpu_session.h b/base/include/cpu_session/cpu_session.h index df397389e..3d9bdec79 100644 --- a/base/include/cpu_session/cpu_session.h +++ b/base/include/cpu_session/cpu_session.h @@ -48,6 +48,7 @@ namespace Genode { *********************/ class Thread_creation_failed : public Exception { }; + class State_access_failed : public Exception { }; static const char *service_name() { return "CPU"; } @@ -124,15 +125,23 @@ namespace Genode { virtual void cancel_blocking(Thread_capability thread) = 0; /** - * Return thread state + * Get the current state of a specific thread * - * \param thread thread to spy on - * \param state_dst result - * - * \return 0 on success + * \param thread targeted thread + * \return state of the targeted thread + * \throw State_access_failed */ - virtual int state(Thread_capability thread, - Thread_state *state_dst) = 0; + virtual Thread_state state(Thread_capability thread) = 0; + + /** + * Override the current state of a specific thread + * + * \param thread targeted thread + * \param state state that shall be applied + * \throw State_access_failed + */ + virtual void state(Thread_capability thread, + Thread_state const &state) = 0; /** * Register signal handler for exceptions of the specified thread @@ -208,7 +217,12 @@ namespace Genode { GENODE_RPC(Rpc_pause, void, pause, Thread_capability); GENODE_RPC(Rpc_resume, void, resume, Thread_capability); GENODE_RPC(Rpc_cancel_blocking, void, cancel_blocking, Thread_capability); - GENODE_RPC(Rpc_state, int, state, Thread_capability, Thread_state *); + GENODE_RPC_THROW(Rpc_get_state, Thread_state, state, + GENODE_TYPE_LIST(State_access_failed), + Thread_capability); + GENODE_RPC_THROW(Rpc_set_state, void, state, + GENODE_TYPE_LIST(State_access_failed), + Thread_capability, Thread_state const &); GENODE_RPC(Rpc_exception_handler, void, exception_handler, Thread_capability, Signal_context_capability); GENODE_RPC(Rpc_single_step, void, single_step, Thread_capability, bool); @@ -231,13 +245,14 @@ namespace Genode { Meta::Type_tuple - > > > > > > > > > > > > Rpc_functions; + > > > > > > > > > > > > > Rpc_functions; }; } diff --git a/base/src/core/cpu_session_component.cc b/base/src/core/cpu_session_component.cc index 08d5c26a0..54af04ec0 100644 --- a/base/src/core/cpu_session_component.cc +++ b/base/src/core/cpu_session_component.cc @@ -122,15 +122,24 @@ void Cpu_session_component::cancel_blocking(Thread_capability thread_cap) } -int Cpu_session_component::state(Thread_capability thread_cap, - Thread_state *state_dst) +Thread_state Cpu_session_component::state(Thread_capability thread_cap) +{ + Cpu_thread_component * thread = _lookup_thread(thread_cap); + if (!thread) throw State_access_failed(); + Thread_state state = thread->platform_thread()->state(); + return state; +} + + +void Cpu_session_component::state(Thread_capability thread_cap, + Thread_state const &state) { Cpu_thread_component *thread = _lookup_thread(thread_cap); - if (!thread) return -1; - - return thread->platform_thread()->state(state_dst); + if (!thread) throw State_access_failed(); + thread->platform_thread()->state(state); } + void Cpu_session_component::exception_handler(Thread_capability thread_cap, Signal_context_capability sigh_cap) diff --git a/base/src/core/include/cpu_session_component.h b/base/src/core/include/cpu_session_component.h index 6c65515cc..f2c1617a9 100644 --- a/base/src/core/include/cpu_session_component.h +++ b/base/src/core/include/cpu_session_component.h @@ -130,7 +130,8 @@ namespace Genode { void resume(Thread_capability thread_cap); void cancel_blocking(Thread_capability); int name(Thread_capability, char *, size_t); - int state(Thread_capability, Thread_state *); + Thread_state state(Thread_capability); + void state(Thread_capability, Thread_state const &); void exception_handler(Thread_capability, Signal_context_capability); unsigned num_cpus() const; void affinity(Thread_capability, unsigned); diff --git a/ports-foc/src/lib/l4lx/include/vcpu.h b/ports-foc/src/lib/l4lx/include/vcpu.h index 449cdc273..cfc6f844d 100644 --- a/ports-foc/src/lib/l4lx/include/vcpu.h +++ b/ports-foc/src/lib/l4lx/include/vcpu.h @@ -86,8 +86,7 @@ namespace L4lx { vcpu_connection()->set_pager(_thread_cap, pager_cap); /* get gate-capability and badge of new thread */ - Thread_state state; - vcpu_connection()->state(_thread_cap, &state); + Thread_state state = vcpu_connection()->state(_thread_cap); _tid = state.kcap; _context->utcb = state.utcb; diff --git a/ports-okl4/src/lib/oklx/genode/genode_threads.cc b/ports-okl4/src/lib/oklx/genode/genode_threads.cc index 3b5171c88..8bc8b12a7 100644 --- a/ports-okl4/src/lib/oklx/genode/genode_threads.cc +++ b/ports-okl4/src/lib/oklx/genode/genode_threads.cc @@ -77,8 +77,7 @@ L4_ThreadId_t Oklx_thread_list::add() (addr_t)thd->stack_addr()); /* Get the OKL4 thread id of the new thread */ - Thread_state state; - _cpu.state(cap,&state); + Thread_state state = _cpu.state(cap); thd->set_tid(state.tid); /* Acknowledge startup and return */ @@ -127,7 +126,7 @@ Oklx_process::add_thread() * but will create the OKL4 thread inactive */ _cpu.start(th->cap(), 0xffffffff, 0xffffffff); - _cpu.state(th->cap(), &dst_state); + dst_state = _cpu.state(th->cap()); th->_tid = dst_state.tid; _threads.insert(th); return th->_tid; diff --git a/ports/src/app/gdb_monitor/cpu_session_component.cc b/ports/src/app/gdb_monitor/cpu_session_component.cc index 4bee6d608..f2afbffa4 100644 --- a/ports/src/app/gdb_monitor/cpu_session_component.cc +++ b/ports/src/app/gdb_monitor/cpu_session_component.cc @@ -165,10 +165,16 @@ void Cpu_session_component::cancel_blocking(Thread_capability thread_cap) } -int Cpu_session_component::state(Thread_capability thread_cap, - Thread_state *state_dst) +void Cpu_session_component::state(Thread_capability thread_cap, + Thread_state const &state) { - return _parent_cpu_session.state(thread_cap, state_dst); + _parent_cpu_session.state(thread_cap, state); +} + + +Thread_state Cpu_session_component::state(Thread_capability thread_cap) +{ + return _parent_cpu_session.state(thread_cap); } diff --git a/ports/src/app/gdb_monitor/cpu_session_component.h b/ports/src/app/gdb_monitor/cpu_session_component.h index 8e60826d9..ac7a6bc02 100644 --- a/ports/src/app/gdb_monitor/cpu_session_component.h +++ b/ports/src/app/gdb_monitor/cpu_session_component.h @@ -65,7 +65,8 @@ class Cpu_session_component : public Rpc_object void resume(Thread_capability thread_cap); void cancel_blocking(Thread_capability); int name(Thread_capability, char *, Genode::size_t); - int state(Thread_capability, Thread_state *); + Thread_state state(Thread_capability); + void state(Thread_capability, Thread_state const &); void exception_handler(Thread_capability thread, Signal_context_capability handler); void single_step(Thread_capability thread, bool enable); diff --git a/ports/src/lib/gdbserver_platform/fiasco_x86_low.cc b/ports/src/lib/gdbserver_platform/fiasco_x86_low.cc index 927ece0c9..43b716f58 100644 --- a/ports/src/lib/gdbserver_platform/fiasco_x86_low.cc +++ b/ports/src/lib/gdbserver_platform/fiasco_x86_low.cc @@ -29,8 +29,8 @@ extern "C" int genode_fetch_register(int regno, unsigned long *reg_content) { Thread_state thread_state; - if (!get_current_thread_state(thread_state)) - return 0; + try { thread_state = get_current_thread_state(); } + catch (...) { return 0; } switch((enum reg_index)regno) { diff --git a/ports/src/lib/gdbserver_platform/foc_arm_low.cc b/ports/src/lib/gdbserver_platform/foc_arm_low.cc index 115cf16b8..209970ead 100644 --- a/ports/src/lib/gdbserver_platform/foc_arm_low.cc +++ b/ports/src/lib/gdbserver_platform/foc_arm_low.cc @@ -49,8 +49,8 @@ extern "C" int genode_fetch_register(int regno, unsigned long *reg_content) { Thread_state thread_state; - if (!get_current_thread_state(thread_state)) - return 0; + try { thread_state = get_current_thread_state(); } + catch (...) { return 0; } if (in_syscall(thread_state)) { switch((enum reg_index)regno) diff --git a/ports/src/lib/gdbserver_platform/foc_x86_32_low.cc b/ports/src/lib/gdbserver_platform/foc_x86_32_low.cc index e6cbba516..9b8da7bdf 100644 --- a/ports/src/lib/gdbserver_platform/foc_x86_32_low.cc +++ b/ports/src/lib/gdbserver_platform/foc_x86_32_low.cc @@ -48,8 +48,8 @@ extern "C" int genode_fetch_register(int regno, unsigned long *reg_content) { Thread_state thread_state; - if (!get_current_thread_state(thread_state)) - return 0; + try { thread_state = get_current_thread_state(); } + catch (...) { return 0; } if (in_syscall(thread_state)) { switch((enum reg_index)regno) diff --git a/ports/src/lib/gdbserver_platform/gdbserver_platform_helper.cc b/ports/src/lib/gdbserver_platform/gdbserver_platform_helper.cc index 9ea367a5b..b753c05f5 100644 --- a/ports/src/lib/gdbserver_platform/gdbserver_platform_helper.cc +++ b/ports/src/lib/gdbserver_platform/gdbserver_platform_helper.cc @@ -27,12 +27,12 @@ using namespace Gdb_monitor; extern Gdb_stub_thread *gdb_stub_thread(); -bool get_current_thread_state(Thread_state &thread_state) +Thread_state get_current_thread_state() { Cpu_session_component *csc = gdb_stub_thread()->cpu_session_component(); ptid_t ptid = ((struct inferior_list_entry*)current_inferior)->id; - return !csc->state(csc->thread_cap(ptid.lwp), &thread_state); + return csc->state(csc->thread_cap(ptid.lwp)); } diff --git a/ports/src/lib/gdbserver_platform/gdbserver_platform_helper.h b/ports/src/lib/gdbserver_platform/gdbserver_platform_helper.h index c3610fb5b..51e0e1a6d 100644 --- a/ports/src/lib/gdbserver_platform/gdbserver_platform_helper.h +++ b/ports/src/lib/gdbserver_platform/gdbserver_platform_helper.h @@ -14,6 +14,9 @@ #ifndef GDBSERVER_PLATFORM_HELPER_H #define GDBSERVER_PLATFORM_HELPER_H -bool get_current_thread_state(Genode::Thread_state &thread_state); +/** + * \throw Cpu_session::State_access_failed + */ +Genode::Thread_state get_current_thread_state(); #endif /* GDBSERVER_PLATFORM_HELPER_H */ diff --git a/ports/src/lib/gdbserver_platform/linux_x86_32_low.cc b/ports/src/lib/gdbserver_platform/linux_x86_32_low.cc index 1d19f6947..5a7f9be71 100644 --- a/ports/src/lib/gdbserver_platform/linux_x86_32_low.cc +++ b/ports/src/lib/gdbserver_platform/linux_x86_32_low.cc @@ -29,8 +29,8 @@ extern "C" int genode_fetch_register(int regno, unsigned long *reg_content) { Thread_state thread_state; - if (!get_current_thread_state(thread_state)) - return 0; + try { thread_state = get_current_thread_state(); } + catch (...) { return 0; } switch((enum reg_index)regno) { diff --git a/ports/src/lib/gdbserver_platform/nova_x86_32_low.cc b/ports/src/lib/gdbserver_platform/nova_x86_32_low.cc index 505b2144e..7aba74128 100644 --- a/ports/src/lib/gdbserver_platform/nova_x86_32_low.cc +++ b/ports/src/lib/gdbserver_platform/nova_x86_32_low.cc @@ -22,8 +22,8 @@ extern "C" int genode_fetch_register(int regno, unsigned long *reg_content) { Thread_state thread_state; - if (!get_current_thread_state(thread_state)) - return -1; + try { thread_state = get_current_thread_state(); } + catch (...) { return -1; } switch((enum reg_index)regno) { diff --git a/ports/src/lib/gdbserver_platform/okl4_x86_low.cc b/ports/src/lib/gdbserver_platform/okl4_x86_low.cc index 9b16401dd..deb74f2fa 100644 --- a/ports/src/lib/gdbserver_platform/okl4_x86_low.cc +++ b/ports/src/lib/gdbserver_platform/okl4_x86_low.cc @@ -29,8 +29,8 @@ extern "C" int genode_fetch_register(int regno, unsigned long *reg_content) { Thread_state thread_state; - if (!get_current_thread_state(thread_state)) - return 0; + try { thread_state = get_current_thread_state(); } + catch (...) { return 0; } switch((enum reg_index)regno) { diff --git a/ports/src/lib/gdbserver_platform/pistachio_x86_low.cc b/ports/src/lib/gdbserver_platform/pistachio_x86_low.cc index a225b6429..f276c3d0d 100644 --- a/ports/src/lib/gdbserver_platform/pistachio_x86_low.cc +++ b/ports/src/lib/gdbserver_platform/pistachio_x86_low.cc @@ -29,8 +29,8 @@ extern "C" int genode_fetch_register(int regno, unsigned long *reg_content) { Thread_state thread_state; - if (!get_current_thread_state(thread_state)) - return 0; + try { thread_state = get_current_thread_state(); } + catch (...) { return 0; } switch((enum reg_index)regno) { diff --git a/ports/src/noux/cpu_session_component.h b/ports/src/noux/cpu_session_component.h index d68d90440..09e3b0293 100644 --- a/ports/src/noux/cpu_session_component.h +++ b/ports/src/noux/cpu_session_component.h @@ -95,7 +95,7 @@ namespace Noux { int set_pager(Thread_capability thread, Pager_capability pager) { - return _cpu.set_pager(thread, pager); } + return _cpu.set_pager(thread, pager); } int start(Thread_capability thread, addr_t ip, addr_t sp) { @@ -115,12 +115,15 @@ namespace Noux { void cancel_blocking(Thread_capability thread) { _cpu.cancel_blocking(thread); } - int state(Thread_capability thread, Thread_state *dst) { - return _cpu.state(thread, dst); } + Thread_state state(Thread_capability thread) { + return _cpu.state(thread); } + + void state(Thread_capability thread, Thread_state const &state) { + _cpu.state(thread, state); } void exception_handler(Thread_capability thread, Signal_context_capability handler) { - _cpu.exception_handler(thread, handler); } + _cpu.exception_handler(thread, handler); } void single_step(Thread_capability thread, bool enable) { _cpu.single_step(thread, enable); } diff --git a/ports/src/vancouver/main.cc b/ports/src/vancouver/main.cc index 66b81986b..c49b293b2 100644 --- a/ports/src/vancouver/main.cc +++ b/ports/src/vancouver/main.cc @@ -378,7 +378,7 @@ class Vcpu_dispatcher : public Genode::Thread, /* calculate maximal aligned order of page to be mapped */ do { crd = Nova::Mem_crd(map_page, map_order, - Nova::Rights(true, true, true)); + Nova::Rights(true, true, true)); map_order += 1; map_page &= ~((1UL << map_order) - 1); @@ -586,24 +586,24 @@ class Vcpu_dispatcher : public Genode::Thread, _guest_memory(guest_memory), _motherboard(motherboard) { - using namespace Genode; /* create new pager object and assign it to the new thread */ - Pager_capability pager_cap = + Pager_capability const pager_cap = env()->rm_session()->add_client(_thread_cap); + if (!pager_cap.valid()) throw Cpu_session::Thread_creation_failed(); if (env()->cpu_session()->set_pager(_thread_cap, pager_cap)) throw Cpu_session::Thread_creation_failed(); - addr_t thread_sp = (addr_t)&_context->stack[-4]; - Thread_state state(true); - state.sel_exc_base = _tid.exc_pt_sel; + env()->cpu_session()->state(_thread_cap, + Thread_state(false, _tid.exc_pt_sel)); - if (env()->cpu_session()->state(_thread_cap, &state) || - env()->cpu_session()->start(_thread_cap, 0, thread_sp)) + addr_t const thread_sp = (addr_t)&_context->stack[-4]; + + if (env()->cpu_session()->start(_thread_cap, 0, thread_sp)) throw Cpu_session::Thread_creation_failed(); /* Request exception portals for vCPU dispatcher */ @@ -611,7 +611,7 @@ class Vcpu_dispatcher : public Genode::Thread, request_event_portal(pager_cap, _tid.exc_pt_sel, i); request_event_portal(pager_cap, _tid.exc_pt_sel, - Nova::SM_SEL_EC); + Nova::SM_SEL_EC); request_event_portal(pager_cap, _tid.exc_pt_sel, Nova::PT_SEL_RECALL); @@ -1149,8 +1149,8 @@ int main(int argc, char **argv) if (guest_memory.backing_store_local_base()) Genode::printf("[0x%08p, 0x%08lx) - VMM local base of guest-physical" " memory\n", guest_memory.backing_store_local_base(), - (Genode::addr_t)guest_memory.backing_store_local_base() + - vm_size); + (Genode::addr_t)guest_memory.backing_store_local_base() + + vm_size); Genode::printf("[0x%08lx, 0x%08lx) - Genode thread context area\n", Genode::Native_config::context_area_virtual_base(),