Remove Cpu_session::State_access_failed exception

This patch removes the exception formerly thrown by 'Cpu_thread::state'
and turns the 'Thread_state' structure into a plain compound type w/o a
constructor.

Issue #5245
Fixes #5250
This commit is contained in:
Norman Feske 2024-06-17 15:25:28 +02:00
parent 16b863fc6e
commit 14d3c4cb5e
42 changed files with 321 additions and 404 deletions

View File

@ -121,15 +121,11 @@ class Core::Platform_thread : Interface
/** /**
* Override thread state with 's' * Override thread state with 's'
*
* \throw Cpu_session::State_access_failed
*/ */
void state(Thread_state s); void state(Thread_state s);
/** /**
* Read thread state * Read thread state
*
* \throw Cpu_session::State_access_failed
*/ */
Thread_state state(); Thread_state state();

View File

@ -45,5 +45,5 @@ void Pager_object::wake_up()
void Pager_object::unresolved_page_fault_occurred() void Pager_object::unresolved_page_fault_occurred()
{ {
state.unresolved_page_fault = true; state.state = Thread_state::State::PAGE_FAULT;
} }

View File

@ -102,16 +102,12 @@ void Platform_thread::unbind()
} }
void Platform_thread::state(Thread_state) void Platform_thread::state(Thread_state) { }
{
warning(__func__, " not implemented");
throw Cpu_thread::State_access_failed();
}
Thread_state Platform_thread::state() Thread_state Platform_thread::state()
{ {
Thread_state s; Thread_state s { };
l4_umword_t old_eflags, ip, sp; l4_umword_t old_eflags, ip, sp;
l4_threadid_t thread = _l4_thread_id; l4_threadid_t thread = _l4_thread_id;
@ -128,8 +124,9 @@ Thread_state Platform_thread::state()
Hex(thread.id.task), ".", Hex(thread.id.lthread)); Hex(thread.id.task), ".", Hex(thread.id.lthread));
/* fill thread state structure */ /* fill thread state structure */
s.ip = ip; s.cpu.ip = ip;
s.sp = sp; s.cpu.sp = sp;
s.state = Thread_state::State::VALID;
return s; return s;
} }

View File

@ -25,14 +25,9 @@ namespace Genode { struct Foc_thread_state; }
struct Genode::Foc_thread_state : Thread_state struct Genode::Foc_thread_state : Thread_state
{ {
Foc::l4_cap_idx_t kcap; /* thread's gate cap in its PD */ Foc::l4_cap_idx_t kcap { Foc::L4_INVALID_CAP }; /* thread's gate cap in its PD */
uint16_t id; /* ID of gate capability */ uint16_t id { }; /* ID of gate capability */
addr_t utcb; /* thread's UTCB in its PD */ addr_t utcb { }; /* thread's UTCB in its PD */
/**
* Constructor
*/
Foc_thread_state() : kcap(Foc::L4_INVALID_CAP), id(0), utcb(0) { }
}; };
#endif /* _INCLUDE__FOC__THREAD_STATE_H_ */ #endif /* _INCLUDE__FOC__THREAD_STATE_H_ */

View File

@ -133,15 +133,11 @@ class Core::Platform_thread : Interface
/** /**
* Override thread state with 's' * Override thread state with 's'
*
* \throw Cpu_session::State_access_failed
*/ */
void state(Thread_state s); void state(Thread_state s);
/** /**
* Read thread state * Read thread state
*
* \throw Cpu_session::State_access_failed
*/ */
Foc_thread_state state(); Foc_thread_state state();

View File

@ -35,7 +35,7 @@ Native_capability Native_cpu_component::native_cap(Thread_capability cap)
Foc_thread_state Native_cpu_component::thread_state(Thread_capability cap) Foc_thread_state Native_cpu_component::thread_state(Thread_capability cap)
{ {
auto lambda = [&] (Cpu_thread_component *thread) { auto lambda = [&] (Cpu_thread_component *thread) {
return (!thread) ? Foc_thread_state() return (!thread) ? Foc_thread_state { }
: thread->platform_thread().state(); }; : thread->platform_thread().state(); };
return _thread_ep.apply(cap, lambda); return _thread_ep.apply(cap, lambda);

View File

@ -39,5 +39,5 @@ void Pager_object::wake_up()
void Pager_object::unresolved_page_fault_occurred() void Pager_object::unresolved_page_fault_occurred()
{ {
state.state.unresolved_page_fault = true; state.state.state = Thread_state::State::PAGE_FAULT;
} }

View File

@ -93,8 +93,8 @@ void Platform_thread::pause()
Foc_thread_state &reg_state = _pager_obj->state.state; Foc_thread_state &reg_state = _pager_obj->state.state;
reg_state.ip = ~0UL; reg_state.cpu.ip = ~0UL;
reg_state.sp = ~0UL; reg_state.cpu.sp = ~0UL;
unsigned const exc = _pager_obj->state.exceptions; unsigned const exc = _pager_obj->state.exceptions;
l4_umword_t flags = L4_THREAD_EX_REGS_TRIGGER_EXCEPTION; l4_umword_t flags = L4_THREAD_EX_REGS_TRIGGER_EXCEPTION;
@ -107,8 +107,8 @@ void Platform_thread::pause()
* The pager thread, which also acts as exception handler, will * The pager thread, which also acts as exception handler, will
* leave the thread in exception state until, it gets woken again * leave the thread in exception state until, it gets woken again
*/ */
l4_thread_ex_regs_ret(_thread.local.data()->kcap(), &reg_state.ip, l4_thread_ex_regs_ret(_thread.local.data()->kcap(), &reg_state.cpu.ip,
&reg_state.sp, &flags); &reg_state.cpu.sp, &flags);
/* /*
* The thread state ("ready") is encoded in the lowest bit of the flags. * The thread state ("ready") is encoded in the lowest bit of the flags.
@ -207,7 +207,7 @@ void Platform_thread::state(Thread_state s)
Foc_thread_state Platform_thread::state() Foc_thread_state Platform_thread::state()
{ {
Foc_thread_state s; Foc_thread_state s { };
if (_pager_obj) if (_pager_obj)
s = _pager_obj->state.state; s = _pager_obj->state.state;

View File

@ -33,45 +33,45 @@ void Ipc_pager::_parse_exception()
void Ipc_pager::get_regs(Foc_thread_state &state) const void Ipc_pager::get_regs(Foc_thread_state &state) const
{ {
state.ip = _regs.pc; state.cpu.ip = _regs.pc;
state.sp = _regs.sp; state.cpu.sp = _regs.sp;
state.r0 = _regs.r[0]; state.cpu.r0 = _regs.r[0];
state.r1 = _regs.r[1]; state.cpu.r1 = _regs.r[1];
state.r2 = _regs.r[2]; state.cpu.r2 = _regs.r[2];
state.r3 = _regs.r[3]; state.cpu.r3 = _regs.r[3];
state.r4 = _regs.r[4]; state.cpu.r4 = _regs.r[4];
state.r5 = _regs.r[5]; state.cpu.r5 = _regs.r[5];
state.r6 = _regs.r[6]; state.cpu.r6 = _regs.r[6];
state.r7 = _regs.r[7]; state.cpu.r7 = _regs.r[7];
state.r8 = _regs.r[8]; state.cpu.r8 = _regs.r[8];
state.r9 = _regs.r[9]; state.cpu.r9 = _regs.r[9];
state.r10 = _regs.r[10]; state.cpu.r10 = _regs.r[10];
state.r11 = _regs.r[11]; state.cpu.r11 = _regs.r[11];
state.r12 = _regs.r[12]; state.cpu.r12 = _regs.r[12];
state.lr = _regs.ulr; state.cpu.lr = _regs.ulr;
state.cpsr = _regs.cpsr; state.cpu.cpsr = _regs.cpsr;
} }
void Ipc_pager::set_regs(Foc_thread_state const &state) void Ipc_pager::set_regs(Foc_thread_state const &state)
{ {
_regs.pc = state.ip; _regs.pc = state.cpu.ip;
_regs.sp = state.sp; _regs.sp = state.cpu.sp;
_regs.r[0] = state.r0; _regs.r[0] = state.cpu.r0;
_regs.r[1] = state.r1; _regs.r[1] = state.cpu.r1;
_regs.r[2] = state.r2; _regs.r[2] = state.cpu.r2;
_regs.r[3] = state.r3; _regs.r[3] = state.cpu.r3;
_regs.r[4] = state.r4; _regs.r[4] = state.cpu.r4;
_regs.r[5] = state.r5; _regs.r[5] = state.cpu.r5;
_regs.r[6] = state.r6; _regs.r[6] = state.cpu.r6;
_regs.r[7] = state.r7; _regs.r[7] = state.cpu.r7;
_regs.r[8] = state.r8; _regs.r[8] = state.cpu.r8;
_regs.r[9] = state.r9; _regs.r[9] = state.cpu.r9;
_regs.r[10] = state.r10; _regs.r[10] = state.cpu.r10;
_regs.r[11] = state.r11; _regs.r[11] = state.cpu.r11;
_regs.r[12] = state.r12; _regs.r[12] = state.cpu.r12;
_regs.ulr = state.lr; _regs.ulr = state.cpu.lr;
_regs.cpsr = state.cpsr; _regs.cpsr = state.cpu.cpsr;
} }

View File

@ -33,15 +33,15 @@ void Ipc_pager::_parse_exception()
void Ipc_pager::get_regs(Foc_thread_state &state) const void Ipc_pager::get_regs(Foc_thread_state &state) const
{ {
state.ip = _regs.pc; state.cpu.ip = _regs.pc;
state.sp = _regs.sp; state.cpu.sp = _regs.sp;
} }
void Ipc_pager::set_regs(Foc_thread_state const &state) void Ipc_pager::set_regs(Foc_thread_state const &state)
{ {
_regs.pc = state.ip; _regs.pc = state.cpu.ip;
_regs.sp = state.sp; _regs.sp = state.cpu.sp;
} }
bool Ipc_pager::exec_fault() const bool Ipc_pager::exec_fault() const

View File

@ -21,36 +21,36 @@ using namespace Core;
void Ipc_pager::get_regs(Foc_thread_state &state) const void Ipc_pager::get_regs(Foc_thread_state &state) const
{ {
state.ip = _regs.ip; state.cpu.ip = _regs.ip;
state.sp = _regs.sp; state.cpu.sp = _regs.sp;
state.edi = _regs.edi; state.cpu.edi = _regs.edi;
state.esi = _regs.esi; state.cpu.esi = _regs.esi;
state.ebp = _regs.ebp; state.cpu.ebp = _regs.ebp;
state.ebx = _regs.ebx; state.cpu.ebx = _regs.ebx;
state.edx = _regs.edx; state.cpu.edx = _regs.edx;
state.ecx = _regs.ecx; state.cpu.ecx = _regs.ecx;
state.eax = _regs.eax; state.cpu.eax = _regs.eax;
state.gs = _regs.gs; state.cpu.gs = _regs.gs;
state.fs = _regs.fs; state.cpu.fs = _regs.fs;
state.eflags = _regs.flags; state.cpu.eflags = _regs.flags;
state.trapno = _regs.trapno; state.cpu.trapno = _regs.trapno;
} }
void Ipc_pager::set_regs(Foc_thread_state const &state) void Ipc_pager::set_regs(Foc_thread_state const &state)
{ {
_regs.ip = state.ip; _regs.ip = state.cpu.ip;
_regs.sp = state.sp; _regs.sp = state.cpu.sp;
_regs.edi = state.edi; _regs.edi = state.cpu.edi;
_regs.esi = state.esi; _regs.esi = state.cpu.esi;
_regs.ebp = state.ebp; _regs.ebp = state.cpu.ebp;
_regs.ebx = state.ebx; _regs.ebx = state.cpu.ebx;
_regs.edx = state.edx; _regs.edx = state.cpu.edx;
_regs.ecx = state.ecx; _regs.ecx = state.cpu.ecx;
_regs.eax = state.eax; _regs.eax = state.cpu.eax;
_regs.gs = state.gs; _regs.gs = state.cpu.gs;
_regs.fs = state.fs; _regs.fs = state.cpu.fs;
_regs.flags = state.eflags; _regs.flags = state.cpu.eflags;
_regs.trapno = state.trapno; _regs.trapno = state.cpu.trapno;
} }

View File

@ -21,50 +21,50 @@ using namespace Core;
void Ipc_pager::get_regs(Foc_thread_state &state) const void Ipc_pager::get_regs(Foc_thread_state &state) const
{ {
state.ip = _regs.ip; state.cpu.ip = _regs.ip;
state.sp = _regs.sp; state.cpu.sp = _regs.sp;
state.r8 = _regs.r8; state.cpu.r8 = _regs.r8;
state.r9 = _regs.r9; state.cpu.r9 = _regs.r9;
state.r10 = _regs.r10; state.cpu.r10 = _regs.r10;
state.r11 = _regs.r11; state.cpu.r11 = _regs.r11;
state.r12 = _regs.r12; state.cpu.r12 = _regs.r12;
state.r13 = _regs.r13; state.cpu.r13 = _regs.r13;
state.r14 = _regs.r14; state.cpu.r14 = _regs.r14;
state.r15 = _regs.r15; state.cpu.r15 = _regs.r15;
state.rax = _regs.rax; state.cpu.rax = _regs.rax;
state.rbx = _regs.rbx; state.cpu.rbx = _regs.rbx;
state.rcx = _regs.rcx; state.cpu.rcx = _regs.rcx;
state.rdx = _regs.rdx; state.cpu.rdx = _regs.rdx;
state.rdi = _regs.rdi; state.cpu.rdi = _regs.rdi;
state.rsi = _regs.rsi; state.cpu.rsi = _regs.rsi;
state.rbp = _regs.rbp; state.cpu.rbp = _regs.rbp;
state.ss = _regs.ss; state.cpu.ss = _regs.ss;
state.eflags = _regs.flags; state.cpu.eflags = _regs.flags;
state.trapno = _regs.trapno; state.cpu.trapno = _regs.trapno;
} }
void Ipc_pager::set_regs(Foc_thread_state const &state) void Ipc_pager::set_regs(Foc_thread_state const &state)
{ {
_regs.ip = state.ip; _regs.ip = state.cpu.ip;
_regs.sp = state.sp; _regs.sp = state.cpu.sp;
_regs.r8 = state.r8; _regs.r8 = state.cpu.r8;
_regs.r9 = state.r9; _regs.r9 = state.cpu.r9;
_regs.r10 = state.r10; _regs.r10 = state.cpu.r10;
_regs.r11 = state.r11; _regs.r11 = state.cpu.r11;
_regs.r12 = state.r12; _regs.r12 = state.cpu.r12;
_regs.r13 = state.r13; _regs.r13 = state.cpu.r13;
_regs.r14 = state.r14; _regs.r14 = state.cpu.r14;
_regs.r15 = state.r15; _regs.r15 = state.cpu.r15;
_regs.rax = state.rax; _regs.rax = state.cpu.rax;
_regs.rbx = state.rbx; _regs.rbx = state.cpu.rbx;
_regs.rcx = state.rcx; _regs.rcx = state.cpu.rcx;
_regs.rdx = state.rdx; _regs.rdx = state.cpu.rdx;
_regs.rdi = state.rdi; _regs.rdi = state.cpu.rdi;
_regs.rsi = state.rsi; _regs.rsi = state.cpu.rsi;
_regs.rbp = state.rbp; _regs.rbp = state.cpu.rbp;
_regs.ss = state.ss; _regs.ss = state.cpu.ss;
_regs.flags = state.eflags; _regs.flags = state.cpu.eflags;
_regs.trapno = state.trapno; _regs.trapno = state.cpu.trapno;
} }

View File

@ -96,9 +96,8 @@ void Thread::start()
Foc_native_cpu_client native_cpu(_cpu_session->native_cpu()); Foc_native_cpu_client native_cpu(_cpu_session->native_cpu());
/* get gate-capability and badge of new thread */ /* get gate-capability and badge of new thread */
Foc_thread_state state; Foc_thread_state state { };
try { state = native_cpu.thread_state(_thread_cap); } state = native_cpu.thread_state(_thread_cap);
catch (...) { throw Cpu_session::Thread_creation_failed(); }
/* remember UTCB of the new thread */ /* remember UTCB of the new thread */
Foc::l4_utcb_t * const foc_utcb = (Foc::l4_utcb_t *)state.utcb; Foc::l4_utcb_t * const foc_utcb = (Foc::l4_utcb_t *)state.utcb;

View File

@ -1 +1 @@
2024-05-28 5d9fb75e48cffe0aa520469c978f4100c7c5b13e 2024-06-17 00e7c40472ab9ff95a3bd163672d640475cd16a1

View File

@ -210,31 +210,30 @@ Core::Pager_object &Platform_thread::pager()
Thread_state Platform_thread::state() Thread_state Platform_thread::state()
{ {
Cpu_state cpu_state; Cpu_state cpu { };
Kernel::get_cpu_state(*_kobj, cpu_state); Kernel::get_cpu_state(*_kobj, cpu);
Thread_state state(cpu_state);
auto state = [&] () -> Thread_state::State
{
using Exception_state = Kernel::Thread::Exception_state; using Exception_state = Kernel::Thread::Exception_state;
switch (exception_state()) { switch (exception_state()) {
case Exception_state::NO_EXCEPTION: case Exception_state::NO_EXCEPTION: return Thread_state::State::VALID;
break; case Exception_state::MMU_FAULT: return Thread_state::State::PAGE_FAULT;
case Exception_state::MMU_FAULT: case Exception_state::EXCEPTION: return Thread_state::State::EXCEPTION;
state.unresolved_page_fault = true;
break;
case Exception_state::EXCEPTION:
state.exception = true;
break;
} }
return Thread_state::State::UNAVAILABLE;
};
return state; return {
.state = state(),
.cpu = cpu
};
} }
void Platform_thread::state(Thread_state thread_state) void Platform_thread::state(Thread_state thread_state)
{ {
Cpu_state cpu_state(thread_state); Kernel::set_cpu_state(*_kobj, thread_state.cpu);
Kernel::set_cpu_state(*_kobj, cpu_state);
} }

View File

@ -49,7 +49,7 @@ void Pager_entrypoint::entry()
warning("unresolvable exception: " warning("unresolvable exception: "
"pd='", pt->pd()->label(), "', " "pd='", pt->pd()->label(), "', "
"thread='", pt->label(), "', " "thread='", pt->label(), "', "
"ip=", Hex(pt->state().ip)); "ip=", Hex(pt->state().cpu.ip));
continue; continue;
} }

View File

@ -101,15 +101,10 @@ class Core::Platform_thread : public List<Platform_thread>::Element
Thread_state state() Thread_state state()
{ {
warning("Not implemented"); return { .state = Thread_state::State::UNAVAILABLE, .cpu = { } };
throw Cpu_thread::State_access_failed();
} }
void state(Thread_state) void state(Thread_state) { }
{
warning("Not implemented");
throw Cpu_thread::State_access_failed();
}
const char *name() { return _name; } const char *name() { return _name; }

View File

@ -320,7 +320,7 @@ class Core::Pager_object : public Object_pool<Pager_object>::Entry
*/ */
void unresolved_page_fault_occurred() void unresolved_page_fault_occurred()
{ {
_state.thread.unresolved_page_fault = true; _state.thread.state = Thread_state::State::PAGE_FAULT;
} }
/** /**

View File

@ -131,15 +131,11 @@ class Core::Platform_thread
/** /**
* Override thread state with 's' * Override thread state with 's'
*
* \throw Cpu_session::State_access_failed
*/ */
void state(Thread_state s); void state(Thread_state s);
/** /**
* Read thread state * Read thread state
*
* \throw Cpu_session::State_access_failed
*/ */
Thread_state state(); Thread_state state();

View File

@ -131,9 +131,9 @@ void Pager_object::_page_fault_handler(Pager_object &obj)
*/ */
obj._state_lock.acquire(); obj._state_lock.acquire();
obj._state.thread.ip = ipc_pager.fault_ip(); obj._state.thread.cpu.ip = ipc_pager.fault_ip();
obj._state.thread.sp = 0; obj._state.thread.cpu.sp = 0;
obj._state.thread.trapno = PT_SEL_PAGE_FAULT; obj._state.thread.cpu.trapno = PT_SEL_PAGE_FAULT;
obj._state.block(); obj._state.block();
obj._state.block_pause_sm(); obj._state.block_pause_sm();
@ -208,7 +208,7 @@ void Pager_object::exception(uint8_t exit_id)
_state_lock.acquire(); _state_lock.acquire();
/* remember exception type for Cpu_session::state() calls */ /* remember exception type for Cpu_session::state() calls */
_state.thread.trapno = exit_id; _state.thread.cpu.trapno = exit_id;
if (_exception_sigh.valid()) { if (_exception_sigh.valid()) {
_state.submit_signal(); _state.submit_signal();
@ -320,7 +320,7 @@ void Pager_object::_recall_handler(Pager_object &obj)
utcb.mtd = 0; utcb.mtd = 0;
/* switch on/off single step */ /* switch on/off single step */
bool singlestep_state = obj._state.thread.eflags & 0x100UL; bool singlestep_state = obj._state.thread.cpu.eflags & 0x100UL;
if (obj._state.singlestep() && !singlestep_state) { if (obj._state.singlestep() && !singlestep_state) {
utcb.flags |= 0x100UL; utcb.flags |= 0x100UL;
utcb.mtd |= Mtd::EFL; utcb.mtd |= Mtd::EFL;
@ -477,7 +477,7 @@ void Pager_object::wake_up()
if (!_state.blocked()) if (!_state.blocked())
return; return;
_state.thread.exception = false; _state.thread.state = Thread_state::State::VALID;
_state.unblock(); _state.unblock();

View File

@ -275,24 +275,17 @@ void Platform_thread::resume()
Thread_state Platform_thread::state() Thread_state Platform_thread::state()
{ {
if (!_pager) throw Cpu_thread::State_access_failed(); Thread_state s { };
if (_pager && _pager->copy_thread_state(&s))
Thread_state s;
if (_pager->copy_thread_state(&s))
return s; return s;
throw Cpu_thread::State_access_failed(); return { .state = Thread_state::State::UNAVAILABLE, .cpu = { } };
} }
void Platform_thread::state(Thread_state s) void Platform_thread::state(Thread_state s)
{ {
if (!_pager) throw Cpu_thread::State_access_failed(); if (_pager && _pager->copy_thread_state(s))
if (!_pager->copy_thread_state(s))
throw Cpu_thread::State_access_failed();
/* the new state is transferred to the kernel by the recall handler */ /* the new state is transferred to the kernel by the recall handler */
_pager->client_recall(false); _pager->client_recall(false);
} }

View File

@ -21,37 +21,38 @@ using namespace Core;
void Pager_object::_copy_state_from_utcb(Nova::Utcb const &utcb) void Pager_object::_copy_state_from_utcb(Nova::Utcb const &utcb)
{ {
_state.thread.eax = utcb.ax; _state.thread.cpu.eax = utcb.ax;
_state.thread.ecx = utcb.cx; _state.thread.cpu.ecx = utcb.cx;
_state.thread.edx = utcb.dx; _state.thread.cpu.edx = utcb.dx;
_state.thread.ebx = utcb.bx; _state.thread.cpu.ebx = utcb.bx;
_state.thread.ebp = utcb.bp; _state.thread.cpu.ebp = utcb.bp;
_state.thread.esi = utcb.si; _state.thread.cpu.esi = utcb.si;
_state.thread.edi = utcb.di; _state.thread.cpu.edi = utcb.di;
_state.thread.sp = utcb.sp; _state.thread.cpu.sp = utcb.sp;
_state.thread.ip = utcb.ip; _state.thread.cpu.ip = utcb.ip;
_state.thread.eflags = utcb.flags; _state.thread.cpu.eflags = utcb.flags;
_state.thread.exception = utcb.qual[0]; _state.thread.state = utcb.qual[0] ? Thread_state::State::EXCEPTION
: Thread_state::State::VALID;
} }
void Pager_object::_copy_state_to_utcb(Nova::Utcb &utcb) const void Pager_object::_copy_state_to_utcb(Nova::Utcb &utcb) const
{ {
utcb.ax = _state.thread.eax; utcb.ax = _state.thread.cpu.eax;
utcb.cx = _state.thread.ecx; utcb.cx = _state.thread.cpu.ecx;
utcb.dx = _state.thread.edx; utcb.dx = _state.thread.cpu.edx;
utcb.bx = _state.thread.ebx; utcb.bx = _state.thread.cpu.ebx;
utcb.bp = _state.thread.ebp; utcb.bp = _state.thread.cpu.ebp;
utcb.si = _state.thread.esi; utcb.si = _state.thread.cpu.esi;
utcb.di = _state.thread.edi; utcb.di = _state.thread.cpu.edi;
utcb.sp = _state.thread.sp; utcb.sp = _state.thread.cpu.sp;
utcb.ip = _state.thread.ip; utcb.ip = _state.thread.cpu.ip;
utcb.flags = _state.thread.eflags; utcb.flags = _state.thread.cpu.eflags;
utcb.mtd = Nova::Mtd::ACDB | utcb.mtd = Nova::Mtd::ACDB |
Nova::Mtd::EBSD | Nova::Mtd::EBSD |

View File

@ -21,55 +21,56 @@ using namespace Core;
void Pager_object::_copy_state_from_utcb(Nova::Utcb const &utcb) void Pager_object::_copy_state_from_utcb(Nova::Utcb const &utcb)
{ {
_state.thread.rax = utcb.ax; _state.thread.cpu.rax = utcb.ax;
_state.thread.rcx = utcb.cx; _state.thread.cpu.rcx = utcb.cx;
_state.thread.rdx = utcb.dx; _state.thread.cpu.rdx = utcb.dx;
_state.thread.rbx = utcb.bx; _state.thread.cpu.rbx = utcb.bx;
_state.thread.rbp = utcb.bp; _state.thread.cpu.rbp = utcb.bp;
_state.thread.rsi = utcb.si; _state.thread.cpu.rsi = utcb.si;
_state.thread.rdi = utcb.di; _state.thread.cpu.rdi = utcb.di;
_state.thread.r8 = utcb.r8; _state.thread.cpu.r8 = utcb.r8;
_state.thread.r9 = utcb.r9; _state.thread.cpu.r9 = utcb.r9;
_state.thread.r10 = utcb.r10; _state.thread.cpu.r10 = utcb.r10;
_state.thread.r11 = utcb.r11; _state.thread.cpu.r11 = utcb.r11;
_state.thread.r12 = utcb.r12; _state.thread.cpu.r12 = utcb.r12;
_state.thread.r13 = utcb.r13; _state.thread.cpu.r13 = utcb.r13;
_state.thread.r14 = utcb.r14; _state.thread.cpu.r14 = utcb.r14;
_state.thread.r15 = utcb.r15; _state.thread.cpu.r15 = utcb.r15;
_state.thread.sp = utcb.sp; _state.thread.cpu.sp = utcb.sp;
_state.thread.ip = utcb.ip; _state.thread.cpu.ip = utcb.ip;
_state.thread.eflags = utcb.flags; _state.thread.cpu.eflags = utcb.flags;
_state.thread.exception = utcb.qual[0]; _state.thread.state = utcb.qual[0] ? Thread_state::State::EXCEPTION
: Thread_state::State::VALID;
} }
void Pager_object::_copy_state_to_utcb(Nova::Utcb &utcb) const void Pager_object::_copy_state_to_utcb(Nova::Utcb &utcb) const
{ {
utcb.ax = _state.thread.rax; utcb.ax = _state.thread.cpu.rax;
utcb.cx = _state.thread.rcx; utcb.cx = _state.thread.cpu.rcx;
utcb.dx = _state.thread.rdx; utcb.dx = _state.thread.cpu.rdx;
utcb.bx = _state.thread.rbx; utcb.bx = _state.thread.cpu.rbx;
utcb.bp = _state.thread.rbp; utcb.bp = _state.thread.cpu.rbp;
utcb.si = _state.thread.rsi; utcb.si = _state.thread.cpu.rsi;
utcb.di = _state.thread.rdi; utcb.di = _state.thread.cpu.rdi;
utcb.r8 = _state.thread.r8; utcb.r8 = _state.thread.cpu.r8;
utcb.r9 = _state.thread.r9; utcb.r9 = _state.thread.cpu.r9;
utcb.r10 = _state.thread.r10; utcb.r10 = _state.thread.cpu.r10;
utcb.r11 = _state.thread.r11; utcb.r11 = _state.thread.cpu.r11;
utcb.r12 = _state.thread.r12; utcb.r12 = _state.thread.cpu.r12;
utcb.r13 = _state.thread.r13; utcb.r13 = _state.thread.cpu.r13;
utcb.r14 = _state.thread.r14; utcb.r14 = _state.thread.cpu.r14;
utcb.r15 = _state.thread.r15; utcb.r15 = _state.thread.cpu.r15;
utcb.sp = _state.thread.sp; utcb.sp = _state.thread.cpu.sp;
utcb.ip = _state.thread.ip; utcb.ip = _state.thread.cpu.ip;
utcb.flags = _state.thread.eflags; utcb.flags = _state.thread.cpu.eflags;
utcb.mtd = Nova::Mtd::ACDB | utcb.mtd = Nova::Mtd::ACDB |
Nova::Mtd::EBSD | Nova::Mtd::EBSD |

View File

@ -120,8 +120,6 @@ class Core::Platform_thread
/** /**
* Override thread state with 's' * Override thread state with 's'
*
* \throw Cpu_session::State_access_failed
*/ */
void state(Thread_state s); void state(Thread_state s);

View File

@ -44,5 +44,5 @@ void Pager_object::wake_up()
void Pager_object::unresolved_page_fault_occurred() void Pager_object::unresolved_page_fault_occurred()
{ {
state.unresolved_page_fault = true; state.state = Thread_state::State::PAGE_FAULT;
} }

View File

@ -23,7 +23,7 @@ using namespace Okl4;
Thread_state Platform_thread::state() Thread_state Platform_thread::state()
{ {
Thread_state s; Thread_state s { };
L4_Copy_regs_to_mrs(_l4_thread_id); L4_Copy_regs_to_mrs(_l4_thread_id);
@ -40,23 +40,19 @@ Thread_state Platform_thread::state()
MR_EAX = 9, MR_EAX = 9,
}; };
L4_StoreMR(MR_EIP, &s.ip); L4_StoreMR(MR_EIP, &s.cpu.ip);
L4_StoreMR(MR_EFLAGS, &s.eflags); L4_StoreMR(MR_EFLAGS, &s.cpu.eflags);
L4_StoreMR(MR_EDI, &s.edi); L4_StoreMR(MR_EDI, &s.cpu.edi);
L4_StoreMR(MR_ESI, &s.esi); L4_StoreMR(MR_ESI, &s.cpu.esi);
L4_StoreMR(MR_EBP, &s.ebp); L4_StoreMR(MR_EBP, &s.cpu.ebp);
L4_StoreMR(MR_ESP, &s.sp); L4_StoreMR(MR_ESP, &s.cpu.sp);
L4_StoreMR(MR_EBX, &s.ebx); L4_StoreMR(MR_EBX, &s.cpu.ebx);
L4_StoreMR(MR_EDX, &s.edx); L4_StoreMR(MR_EDX, &s.cpu.edx);
L4_StoreMR(MR_ECX, &s.ecx); L4_StoreMR(MR_ECX, &s.cpu.ecx);
L4_StoreMR(MR_EAX, &s.eax); L4_StoreMR(MR_EAX, &s.cpu.eax);
return s; return s;
} }
void Platform_thread::state(Thread_state)
{
warning("Platform_thread::state not implemented");
throw Cpu_thread::State_access_failed();
}
void Platform_thread::state(Thread_state) { }

View File

@ -134,8 +134,6 @@ class Core::Platform_thread : Interface
/** /**
* Override thread state with 's' * Override thread state with 's'
*
* \throw Cpu_session::State_access_failed
*/ */
void state(Thread_state s); void state(Thread_state s);

View File

@ -44,5 +44,5 @@ void Pager_object::wake_up()
void Pager_object::unresolved_page_fault_occurred() void Pager_object::unresolved_page_fault_occurred()
{ {
state.unresolved_page_fault = true; state.state = Thread_state::State::PAGE_FAULT;
} }

View File

@ -145,16 +145,12 @@ void Platform_thread::unbind()
} }
void Platform_thread::state(Thread_state) void Platform_thread::state(Thread_state) { }
{
warning(__func__, " not implemented");
throw Cpu_thread::State_access_failed();
}
Thread_state Platform_thread::state() Thread_state Platform_thread::state()
{ {
Thread_state s; Thread_state s { };
L4_Word_t dummy; L4_Word_t dummy;
L4_ThreadId_t dummy_tid; L4_ThreadId_t dummy_tid;
@ -169,8 +165,9 @@ Thread_state Platform_thread::state()
0, 0, 0, 0, L4_nilthread, 0, 0, 0, 0, L4_nilthread,
&dummy, &sp, &ip, &dummy, &dummy, &dummy, &sp, &ip, &dummy, &dummy,
&dummy_tid); &dummy_tid);
s.ip = ip; s.cpu.ip = ip;
s.sp = sp; s.cpu.sp = sp;
s.state = Thread_state::State::VALID;
return s; return s;
} }

View File

@ -123,15 +123,11 @@ class Core::Platform_thread : public List<Platform_thread>::Element
/** /**
* Override thread state with 's' * Override thread state with 's'
*
* \throw Cpu_session::State_access_failed
*/ */
void state(Thread_state s); void state(Thread_state s);
/** /**
* Read thread state * Read thread state
*
* \throw Cpu_session::State_access_failed
*/ */
Thread_state state(); Thread_state state();

View File

@ -143,7 +143,7 @@ void Pager_object::wake_up()
void Pager_object::unresolved_page_fault_occurred() void Pager_object::unresolved_page_fault_occurred()
{ {
state.unresolved_page_fault = true; state.state = Thread_state::State::PAGE_FAULT;
} }

View File

@ -202,11 +202,7 @@ void Platform_thread::resume()
} }
void Platform_thread::state(Thread_state) void Platform_thread::state(Thread_state) { }
{
warning(__PRETTY_FUNCTION__, " not implemented");
throw Cpu_thread::State_access_failed();
}
bool Platform_thread::install_mapping(Mapping const &mapping) bool Platform_thread::install_mapping(Mapping const &mapping)

View File

@ -71,32 +71,29 @@ Thread_state Platform_thread::state()
long const ret = seL4_TCB_ReadRegisters(thread, suspend_source, arch_flags, long const ret = seL4_TCB_ReadRegisters(thread, suspend_source, arch_flags,
register_count, &registers); register_count, &registers);
if (ret != seL4_NoError) { if (ret != seL4_NoError)
error("reading thread state ", ret); return { .state = Thread_state::State::UNAVAILABLE, .cpu = { } };
throw Cpu_thread::State_access_failed();
}
Thread_state state; Thread_state state { };
memset(&state, 0, sizeof(state));
state.r0 = registers.r0; state.cpu.r0 = registers.r0;
state.r1 = registers.r1; state.cpu.r1 = registers.r1;
state.r2 = registers.r2; state.cpu.r2 = registers.r2;
state.r3 = registers.r3; state.cpu.r3 = registers.r3;
state.r4 = registers.r4; state.cpu.r4 = registers.r4;
state.r5 = registers.r5; state.cpu.r5 = registers.r5;
state.r6 = registers.r6; state.cpu.r6 = registers.r6;
state.r7 = registers.r7; state.cpu.r7 = registers.r7;
state.r8 = registers.r8; state.cpu.r8 = registers.r8;
state.r9 = registers.r9; state.cpu.r9 = registers.r9;
state.r10 = registers.r10; state.cpu.r10 = registers.r10;
state.r11 = registers.r11; state.cpu.r11 = registers.r11;
state.r12 = registers.r12; state.cpu.r12 = registers.r12;
state.sp = registers.sp; state.cpu.sp = registers.sp;
state.lr = registers.r14; state.cpu.lr = registers.r14;
state.ip = registers.pc; state.cpu.ip = registers.pc;
state.cpsr = registers.cpsr; state.cpu.cpsr = registers.cpsr;
state.cpu_exception = 0; /* XXX detect/track if in exception and report here */ state.cpu.cpu_exception = 0; /* XXX detect/track if in exception and report here */
return state; return state;
} }

View File

@ -70,33 +70,30 @@ Thread_state Platform_thread::state()
long const ret = seL4_TCB_ReadRegisters(thread, suspend_source, arch_flags, long const ret = seL4_TCB_ReadRegisters(thread, suspend_source, arch_flags,
register_count, &registers); register_count, &registers);
if (ret != seL4_NoError) { if (ret != seL4_NoError)
error("reading thread state ", ret); return { .state = Thread_state::State::UNAVAILABLE, .cpu = { } };
throw Cpu_thread::State_access_failed();
}
Thread_state state; Thread_state state { };
memset(&state, 0, sizeof(state));
state.ip = registers.rip; state.cpu.ip = registers.rip;
state.sp = registers.rsp; state.cpu.sp = registers.rsp;
state.rdi = registers.rdi; state.cpu.rdi = registers.rdi;
state.rsi = registers.rsi; state.cpu.rsi = registers.rsi;
state.rbp = registers.rbp; state.cpu.rbp = registers.rbp;
state.rbx = registers.rbx; state.cpu.rbx = registers.rbx;
state.rdx = registers.rdx; state.cpu.rdx = registers.rdx;
state.rcx = registers.rcx; state.cpu.rcx = registers.rcx;
state.rax = registers.rax; state.cpu.rax = registers.rax;
state.r8 = registers.r8; state.cpu.r8 = registers.r8;
state.r9 = registers.r9; state.cpu.r9 = registers.r9;
state.r10 = registers.r10; state.cpu.r10 = registers.r10;
state.r11 = registers.r11; state.cpu.r11 = registers.r11;
state.r12 = registers.r12; state.cpu.r12 = registers.r12;
state.r13 = registers.r13; state.cpu.r13 = registers.r13;
state.r14 = registers.r14; state.cpu.r14 = registers.r14;
state.r15 = registers.r15; state.cpu.r15 = registers.r15;
state.eflags = registers.rflags; state.cpu.eflags = registers.rflags;
state.trapno = 0; /* XXX detect/track if in exception and report here */ state.cpu.trapno = 0; /* XXX detect/track if in exception and report here */
/* registers.tls_base unused */ /* registers.tls_base unused */
return state; return state;

View File

@ -18,13 +18,12 @@
namespace Genode { struct Thread_state; } namespace Genode { struct Thread_state; }
struct Genode::Thread_state : Cpu_state
{
bool unresolved_page_fault = false;
bool exception = false;
Thread_state() { }; struct Genode::Thread_state
Thread_state(Cpu_state &c) : Cpu_state(c) { }; {
enum class State { VALID, UNAVAILABLE, PAGE_FAULT, EXCEPTION } state;
Cpu_state cpu;
}; };
#endif /* _INCLUDE__BASE__THREAD_STATE_H_ */ #endif /* _INCLUDE__BASE__THREAD_STATE_H_ */

View File

@ -15,7 +15,6 @@
#define _INCLUDE__CPU_THREAD__CPU_THREAD_H_ #define _INCLUDE__CPU_THREAD__CPU_THREAD_H_
#include <base/stdint.h> #include <base/stdint.h>
#include <base/exception.h>
#include <base/thread_state.h> #include <base/thread_state.h>
#include <base/signal.h> #include <base/signal.h>
#include <base/affinity.h> #include <base/affinity.h>
@ -26,8 +25,6 @@ namespace Genode { struct Cpu_thread; }
struct Genode::Cpu_thread : Interface struct Genode::Cpu_thread : Interface
{ {
class State_access_failed : public Exception { };
/** /**
* Get dataspace of the thread's user-level thread-control block (UTCB) * Get dataspace of the thread's user-level thread-control block (UTCB)
*/ */
@ -59,7 +56,6 @@ struct Genode::Cpu_thread : Interface
* Get the current thread state * Get the current thread state
* *
* \return state of the targeted thread * \return state of the targeted thread
* \throw State_access_failed
*/ */
virtual Thread_state state() = 0; virtual Thread_state state() = 0;
@ -67,7 +63,6 @@ struct Genode::Cpu_thread : Interface
* Override the current thread state * Override the current thread state
* *
* \param state state that shall be applied * \param state state that shall be applied
* \throw State_access_failed
*/ */
virtual void state(Thread_state const &state) = 0; virtual void state(Thread_state const &state) = 0;
@ -136,11 +131,8 @@ struct Genode::Cpu_thread : Interface
GENODE_RPC(Rpc_start, void, start, addr_t, addr_t); GENODE_RPC(Rpc_start, void, start, addr_t, addr_t);
GENODE_RPC(Rpc_pause, void, pause); GENODE_RPC(Rpc_pause, void, pause);
GENODE_RPC(Rpc_resume, void, resume); GENODE_RPC(Rpc_resume, void, resume);
GENODE_RPC_THROW(Rpc_get_state, Thread_state, state, GENODE_RPC(Rpc_get_state, Thread_state, state);
GENODE_TYPE_LIST(State_access_failed)); GENODE_RPC(Rpc_set_state, void, state, Thread_state const &);
GENODE_RPC_THROW(Rpc_set_state, void, state,
GENODE_TYPE_LIST(State_access_failed),
Thread_state const &);
GENODE_RPC(Rpc_exception_sigh, void, exception_sigh, Signal_context_capability); GENODE_RPC(Rpc_exception_sigh, void, exception_sigh, Signal_context_capability);
GENODE_RPC(Rpc_single_step, void, single_step, bool); GENODE_RPC(Rpc_single_step, void, single_step, bool);
GENODE_RPC(Rpc_affinity, void, affinity, Affinity::Location); GENODE_RPC(Rpc_affinity, void, affinity, Affinity::Location);

View File

@ -269,7 +269,7 @@ static void test_pause_resume(Env &env)
while (thread.loop < 1) { } while (thread.loop < 1) { }
Thread_state state; Thread_state state { };
Cpu_thread_client thread_client(thread.cap()); Cpu_thread_client thread_client(thread.cap());
log("--- pausing ---"); log("--- pausing ---");
@ -278,11 +278,10 @@ static void test_pause_resume(Env &env)
log("--- paused ---"); log("--- paused ---");
log("--- reading thread state ---"); log("--- reading thread state ---");
try {
state = thread_client.state(); state = thread_client.state();
} catch (Cpu_thread::State_access_failed) { if (state.state == Thread_state::State::UNAVAILABLE)
throw -10; throw -10;
}
if (loop_paused != thread.loop) if (loop_paused != thread.loop)
throw -11; throw -11;

View File

@ -69,15 +69,9 @@ void Cpu_sampler::Cpu_thread_component::take_sample()
_parent_cpu_thread.pause(); _parent_cpu_thread.pause();
try { Thread_state const thread_state = _parent_cpu_thread.state();
if (thread_state.state == Thread_state::State::VALID)
Thread_state thread_state = _parent_cpu_thread.state(); _sample_buf[_sample_buf_index++] = thread_state.cpu.ip;
_sample_buf[_sample_buf_index++] = thread_state.ip;
} catch (State_access_failed) {
continue;
}
_parent_cpu_thread.resume(); _parent_cpu_thread.resume();

View File

@ -280,30 +280,24 @@ struct Monitor::Gdb::State : Noncopyable
void with_current_thread_state(auto const &fn) void with_current_thread_state(auto const &fn)
{ {
Thread_state thread_state { }; if (!_current.constructed() || !_current->thread.constructed())
return;
if (_current.constructed() && _current->thread.constructed()) { Thread_state const thread_state = _current->thread->thread._real.call<Cpu_thread::Rpc_get_state>();
try { if (thread_state.state == Thread_state::State::UNAVAILABLE) {
thread_state = _current->thread->thread._real.call<Cpu_thread::Rpc_get_state>();
} catch (Cpu_thread::State_access_failed) {
warning("unable to access state of thread ", _current->thread->thread.id()); warning("unable to access state of thread ", _current->thread->thread.id());
return;
} }
}
fn(thread_state); fn(thread_state);
}; }
bool current_thread_state(Thread_state const &thread_state) bool current_thread_state(Thread_state const &thread_state)
{ {
if (_current.constructed() && _current->thread.constructed()) { if (!_current.constructed() || !_current->thread.constructed())
try { return false;
_current->thread->thread._real.call<Cpu_thread::Rpc_set_state>(thread_state); _current->thread->thread._real.call<Cpu_thread::Rpc_set_state>(thread_state);
return true; return true;
} catch (Cpu_thread::State_access_failed) {
warning("unable to set state of thread ", _current->thread->thread.id());
}
}
return false;
} }
State(Inferiors &inferiors, Memory_accessor &memory_accessor, State(Inferiors &inferiors, Memory_accessor &memory_accessor,
@ -666,7 +660,7 @@ struct g : Command_without_separator
gdb_response(out, [&] (Output &out) { gdb_response(out, [&] (Output &out) {
state.with_current_thread_state([&] (Thread_state const &thread_state) { state.with_current_thread_state([&] (Thread_state const &thread_state) {
print_registers(out, thread_state); }); }); print_registers(out, thread_state.cpu); }); });
} }
}; };
@ -1140,9 +1134,9 @@ struct G : Command_without_separator
if (_verbose) if (_verbose)
log("G command args: ", Cstring(args.start, args.num_bytes)); log("G command args: ", Cstring(args.start, args.num_bytes));
Thread_state thread_state; Thread_state thread_state { };
parse_registers(args, thread_state); parse_registers(args, thread_state.cpu);
if (state.current_thread_state(thread_state)) if (state.current_thread_state(thread_state))
gdb_ok(out); gdb_ok(out);

View File

@ -77,15 +77,11 @@ struct Monitor::Inferior_pd : Monitored_pd_session
if (thread.stop_state != Monitored_thread::Stop_state::RUNNING) if (thread.stop_state != Monitored_thread::Stop_state::RUNNING)
return; return;
try {
Thread_state thread_state = thread.state(); Thread_state thread_state = thread.state();
if (thread_state.unresolved_page_fault) { if (thread_state.state == Thread_state::State::PAGE_FAULT) {
thread.handle_page_fault(); thread.handle_page_fault();
thread_found = true; thread_found = true;
} }
} catch (Cpu_thread::State_access_failed) {
/* this exception occurs for running threads */
}
}); });
if (!thread_found) { if (!thread_found) {

View File

@ -72,7 +72,7 @@ void Monitor::Monitored_thread::_handle_exception()
_original_first_instruction); _original_first_instruction);
stop_reply_signal = Stop_reply_signal::STOP; stop_reply_signal = Stop_reply_signal::STOP;
} else { } else {
switch(Cpu_state::Esr::Ec::get(thread_state.esr_el1)) { switch(Cpu_state::Esr::Ec::get(thread_state.cpu.esr_el1)) {
case Cpu_state::Esr::Ec::SOFTWARE_STEP: case Cpu_state::Esr::Ec::SOFTWARE_STEP:
stop_reply_signal = Stop_reply_signal::TRAP; stop_reply_signal = Stop_reply_signal::TRAP;
break; break;

View File

@ -89,8 +89,8 @@ void Monitor::Monitored_thread::_handle_exception()
Thread_state thread_state = _real.call<Rpc_get_state>(); Thread_state thread_state = _real.call<Rpc_get_state>();
if (thread_state.trapno == Cpu_state::Cpu_exception::BREAKPOINT) { if (thread_state.cpu.trapno == Cpu_state::Cpu_exception::BREAKPOINT) {
thread_state.ip -= Gdb::breakpoint_instruction_len(); thread_state.cpu.ip -= Gdb::breakpoint_instruction_len();
_real.call<Rpc_set_state>(thread_state); _real.call<Rpc_set_state>(thread_state);
} }
@ -100,7 +100,7 @@ void Monitor::Monitored_thread::_handle_exception()
_original_first_instruction); _original_first_instruction);
stop_reply_signal = Stop_reply_signal::STOP; stop_reply_signal = Stop_reply_signal::STOP;
} else { } else {
switch(thread_state.trapno) { switch(thread_state.cpu.trapno) {
case Cpu_state::Cpu_exception::DIVIDE_ERROR: case Cpu_state::Cpu_exception::DIVIDE_ERROR:
stop_reply_signal = Stop_reply_signal::FPE; stop_reply_signal = Stop_reply_signal::FPE;
break; break;