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'
*
* \throw Cpu_session::State_access_failed
*/
void state(Thread_state s);
/**
* Read thread state
*
* \throw Cpu_session::State_access_failed
*/
Thread_state state();

View File

@ -45,5 +45,5 @@ void Pager_object::wake_up()
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)
{
warning(__func__, " not implemented");
throw Cpu_thread::State_access_failed();
}
void Platform_thread::state(Thread_state) { }
Thread_state Platform_thread::state()
{
Thread_state s;
Thread_state s { };
l4_umword_t old_eflags, ip, sp;
l4_threadid_t thread = _l4_thread_id;
@ -128,8 +124,9 @@ Thread_state Platform_thread::state()
Hex(thread.id.task), ".", Hex(thread.id.lthread));
/* fill thread state structure */
s.ip = ip;
s.sp = sp;
s.cpu.ip = ip;
s.cpu.sp = sp;
s.state = Thread_state::State::VALID;
return s;
}

View File

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

View File

@ -133,15 +133,11 @@ class Core::Platform_thread : Interface
/**
* Override thread state with 's'
*
* \throw Cpu_session::State_access_failed
*/
void state(Thread_state s);
/**
* Read thread state
*
* \throw Cpu_session::State_access_failed
*/
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)
{
auto lambda = [&] (Cpu_thread_component *thread) {
return (!thread) ? Foc_thread_state()
return (!thread) ? Foc_thread_state { }
: thread->platform_thread().state(); };
return _thread_ep.apply(cap, lambda);

View File

@ -39,5 +39,5 @@ void Pager_object::wake_up()
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;
reg_state.ip = ~0UL;
reg_state.sp = ~0UL;
reg_state.cpu.ip = ~0UL;
reg_state.cpu.sp = ~0UL;
unsigned const exc = _pager_obj->state.exceptions;
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
* leave the thread in exception state until, it gets woken again
*/
l4_thread_ex_regs_ret(_thread.local.data()->kcap(), &reg_state.ip,
&reg_state.sp, &flags);
l4_thread_ex_regs_ret(_thread.local.data()->kcap(), &reg_state.cpu.ip,
&reg_state.cpu.sp, &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 s;
Foc_thread_state s { };
if (_pager_obj)
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
{
state.ip = _regs.pc;
state.sp = _regs.sp;
state.r0 = _regs.r[0];
state.r1 = _regs.r[1];
state.r2 = _regs.r[2];
state.r3 = _regs.r[3];
state.r4 = _regs.r[4];
state.r5 = _regs.r[5];
state.r6 = _regs.r[6];
state.r7 = _regs.r[7];
state.r8 = _regs.r[8];
state.r9 = _regs.r[9];
state.r10 = _regs.r[10];
state.r11 = _regs.r[11];
state.r12 = _regs.r[12];
state.lr = _regs.ulr;
state.cpsr = _regs.cpsr;
state.cpu.ip = _regs.pc;
state.cpu.sp = _regs.sp;
state.cpu.r0 = _regs.r[0];
state.cpu.r1 = _regs.r[1];
state.cpu.r2 = _regs.r[2];
state.cpu.r3 = _regs.r[3];
state.cpu.r4 = _regs.r[4];
state.cpu.r5 = _regs.r[5];
state.cpu.r6 = _regs.r[6];
state.cpu.r7 = _regs.r[7];
state.cpu.r8 = _regs.r[8];
state.cpu.r9 = _regs.r[9];
state.cpu.r10 = _regs.r[10];
state.cpu.r11 = _regs.r[11];
state.cpu.r12 = _regs.r[12];
state.cpu.lr = _regs.ulr;
state.cpu.cpsr = _regs.cpsr;
}
void Ipc_pager::set_regs(Foc_thread_state const &state)
{
_regs.pc = state.ip;
_regs.sp = state.sp;
_regs.r[0] = state.r0;
_regs.r[1] = state.r1;
_regs.r[2] = state.r2;
_regs.r[3] = state.r3;
_regs.r[4] = state.r4;
_regs.r[5] = state.r5;
_regs.r[6] = state.r6;
_regs.r[7] = state.r7;
_regs.r[8] = state.r8;
_regs.r[9] = state.r9;
_regs.r[10] = state.r10;
_regs.r[11] = state.r11;
_regs.r[12] = state.r12;
_regs.ulr = state.lr;
_regs.cpsr = state.cpsr;
_regs.pc = state.cpu.ip;
_regs.sp = state.cpu.sp;
_regs.r[0] = state.cpu.r0;
_regs.r[1] = state.cpu.r1;
_regs.r[2] = state.cpu.r2;
_regs.r[3] = state.cpu.r3;
_regs.r[4] = state.cpu.r4;
_regs.r[5] = state.cpu.r5;
_regs.r[6] = state.cpu.r6;
_regs.r[7] = state.cpu.r7;
_regs.r[8] = state.cpu.r8;
_regs.r[9] = state.cpu.r9;
_regs.r[10] = state.cpu.r10;
_regs.r[11] = state.cpu.r11;
_regs.r[12] = state.cpu.r12;
_regs.ulr = state.cpu.lr;
_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
{
state.ip = _regs.pc;
state.sp = _regs.sp;
state.cpu.ip = _regs.pc;
state.cpu.sp = _regs.sp;
}
void Ipc_pager::set_regs(Foc_thread_state const &state)
{
_regs.pc = state.ip;
_regs.sp = state.sp;
_regs.pc = state.cpu.ip;
_regs.sp = state.cpu.sp;
}
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
{
state.ip = _regs.ip;
state.sp = _regs.sp;
state.edi = _regs.edi;
state.esi = _regs.esi;
state.ebp = _regs.ebp;
state.ebx = _regs.ebx;
state.edx = _regs.edx;
state.ecx = _regs.ecx;
state.eax = _regs.eax;
state.gs = _regs.gs;
state.fs = _regs.fs;
state.eflags = _regs.flags;
state.trapno = _regs.trapno;
state.cpu.ip = _regs.ip;
state.cpu.sp = _regs.sp;
state.cpu.edi = _regs.edi;
state.cpu.esi = _regs.esi;
state.cpu.ebp = _regs.ebp;
state.cpu.ebx = _regs.ebx;
state.cpu.edx = _regs.edx;
state.cpu.ecx = _regs.ecx;
state.cpu.eax = _regs.eax;
state.cpu.gs = _regs.gs;
state.cpu.fs = _regs.fs;
state.cpu.eflags = _regs.flags;
state.cpu.trapno = _regs.trapno;
}
void Ipc_pager::set_regs(Foc_thread_state const &state)
{
_regs.ip = state.ip;
_regs.sp = state.sp;
_regs.edi = state.edi;
_regs.esi = state.esi;
_regs.ebp = state.ebp;
_regs.ebx = state.ebx;
_regs.edx = state.edx;
_regs.ecx = state.ecx;
_regs.eax = state.eax;
_regs.gs = state.gs;
_regs.fs = state.fs;
_regs.flags = state.eflags;
_regs.trapno = state.trapno;
_regs.ip = state.cpu.ip;
_regs.sp = state.cpu.sp;
_regs.edi = state.cpu.edi;
_regs.esi = state.cpu.esi;
_regs.ebp = state.cpu.ebp;
_regs.ebx = state.cpu.ebx;
_regs.edx = state.cpu.edx;
_regs.ecx = state.cpu.ecx;
_regs.eax = state.cpu.eax;
_regs.gs = state.cpu.gs;
_regs.fs = state.cpu.fs;
_regs.flags = state.cpu.eflags;
_regs.trapno = state.cpu.trapno;
}

View File

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

View File

@ -96,9 +96,8 @@ void Thread::start()
Foc_native_cpu_client native_cpu(_cpu_session->native_cpu());
/* get gate-capability and badge of new thread */
Foc_thread_state state;
try { state = native_cpu.thread_state(_thread_cap); }
catch (...) { throw Cpu_session::Thread_creation_failed(); }
Foc_thread_state state { };
state = native_cpu.thread_state(_thread_cap);
/* remember UTCB of the new thread */
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()
{
Cpu_state cpu_state;
Kernel::get_cpu_state(*_kobj, cpu_state);
Thread_state state(cpu_state);
Cpu_state cpu { };
Kernel::get_cpu_state(*_kobj, cpu);
using Exception_state = Kernel::Thread::Exception_state;
auto state = [&] () -> Thread_state::State
{
using Exception_state = Kernel::Thread::Exception_state;
switch (exception_state()) {
case Exception_state::NO_EXCEPTION: return Thread_state::State::VALID;
case Exception_state::MMU_FAULT: return Thread_state::State::PAGE_FAULT;
case Exception_state::EXCEPTION: return Thread_state::State::EXCEPTION;
}
return Thread_state::State::UNAVAILABLE;
};
switch (exception_state()) {
case Exception_state::NO_EXCEPTION:
break;
case Exception_state::MMU_FAULT:
state.unresolved_page_fault = true;
break;
case Exception_state::EXCEPTION:
state.exception = true;
break;
}
return state;
return {
.state = state(),
.cpu = cpu
};
}
void Platform_thread::state(Thread_state thread_state)
{
Cpu_state cpu_state(thread_state);
Kernel::set_cpu_state(*_kobj, cpu_state);
Kernel::set_cpu_state(*_kobj, thread_state.cpu);
}

View File

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

View File

@ -101,15 +101,10 @@ class Core::Platform_thread : public List<Platform_thread>::Element
Thread_state state()
{
warning("Not implemented");
throw Cpu_thread::State_access_failed();
return { .state = Thread_state::State::UNAVAILABLE, .cpu = { } };
}
void state(Thread_state)
{
warning("Not implemented");
throw Cpu_thread::State_access_failed();
}
void state(Thread_state) { }
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()
{
_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'
*
* \throw Cpu_session::State_access_failed
*/
void state(Thread_state s);
/**
* Read thread state
*
* \throw Cpu_session::State_access_failed
*/
Thread_state state();

View File

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

View File

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

View File

@ -21,41 +21,42 @@ using namespace Core;
void Pager_object::_copy_state_from_utcb(Nova::Utcb const &utcb)
{
_state.thread.eax = utcb.ax;
_state.thread.ecx = utcb.cx;
_state.thread.edx = utcb.dx;
_state.thread.ebx = utcb.bx;
_state.thread.cpu.eax = utcb.ax;
_state.thread.cpu.ecx = utcb.cx;
_state.thread.cpu.edx = utcb.dx;
_state.thread.cpu.ebx = utcb.bx;
_state.thread.ebp = utcb.bp;
_state.thread.esi = utcb.si;
_state.thread.edi = utcb.di;
_state.thread.cpu.ebp = utcb.bp;
_state.thread.cpu.esi = utcb.si;
_state.thread.cpu.edi = utcb.di;
_state.thread.sp = utcb.sp;
_state.thread.ip = utcb.ip;
_state.thread.eflags = utcb.flags;
_state.thread.cpu.sp = utcb.sp;
_state.thread.cpu.ip = utcb.ip;
_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
{
utcb.ax = _state.thread.eax;
utcb.cx = _state.thread.ecx;
utcb.dx = _state.thread.edx;
utcb.bx = _state.thread.ebx;
utcb.ax = _state.thread.cpu.eax;
utcb.cx = _state.thread.cpu.ecx;
utcb.dx = _state.thread.cpu.edx;
utcb.bx = _state.thread.cpu.ebx;
utcb.bp = _state.thread.ebp;
utcb.si = _state.thread.esi;
utcb.di = _state.thread.edi;
utcb.bp = _state.thread.cpu.ebp;
utcb.si = _state.thread.cpu.esi;
utcb.di = _state.thread.cpu.edi;
utcb.sp = _state.thread.sp;
utcb.ip = _state.thread.ip;
utcb.flags = _state.thread.eflags;
utcb.sp = _state.thread.cpu.sp;
utcb.ip = _state.thread.cpu.ip;
utcb.flags = _state.thread.cpu.eflags;
utcb.mtd = Nova::Mtd::ACDB |
Nova::Mtd::EBSD |
Nova::Mtd::ESP |
Nova::Mtd::EIP |
Nova::Mtd::EFL;
Nova::Mtd::EBSD |
Nova::Mtd::ESP |
Nova::Mtd::EIP |
Nova::Mtd::EFL;
}

View File

@ -21,55 +21,56 @@ using namespace Core;
void Pager_object::_copy_state_from_utcb(Nova::Utcb const &utcb)
{
_state.thread.rax = utcb.ax;
_state.thread.rcx = utcb.cx;
_state.thread.rdx = utcb.dx;
_state.thread.rbx = utcb.bx;
_state.thread.cpu.rax = utcb.ax;
_state.thread.cpu.rcx = utcb.cx;
_state.thread.cpu.rdx = utcb.dx;
_state.thread.cpu.rbx = utcb.bx;
_state.thread.rbp = utcb.bp;
_state.thread.rsi = utcb.si;
_state.thread.rdi = utcb.di;
_state.thread.cpu.rbp = utcb.bp;
_state.thread.cpu.rsi = utcb.si;
_state.thread.cpu.rdi = utcb.di;
_state.thread.r8 = utcb.r8;
_state.thread.r9 = utcb.r9;
_state.thread.r10 = utcb.r10;
_state.thread.r11 = utcb.r11;
_state.thread.r12 = utcb.r12;
_state.thread.r13 = utcb.r13;
_state.thread.r14 = utcb.r14;
_state.thread.r15 = utcb.r15;
_state.thread.cpu.r8 = utcb.r8;
_state.thread.cpu.r9 = utcb.r9;
_state.thread.cpu.r10 = utcb.r10;
_state.thread.cpu.r11 = utcb.r11;
_state.thread.cpu.r12 = utcb.r12;
_state.thread.cpu.r13 = utcb.r13;
_state.thread.cpu.r14 = utcb.r14;
_state.thread.cpu.r15 = utcb.r15;
_state.thread.sp = utcb.sp;
_state.thread.ip = utcb.ip;
_state.thread.eflags = utcb.flags;
_state.thread.cpu.sp = utcb.sp;
_state.thread.cpu.ip = utcb.ip;
_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
{
utcb.ax = _state.thread.rax;
utcb.cx = _state.thread.rcx;
utcb.dx = _state.thread.rdx;
utcb.bx = _state.thread.rbx;
utcb.ax = _state.thread.cpu.rax;
utcb.cx = _state.thread.cpu.rcx;
utcb.dx = _state.thread.cpu.rdx;
utcb.bx = _state.thread.cpu.rbx;
utcb.bp = _state.thread.rbp;
utcb.si = _state.thread.rsi;
utcb.di = _state.thread.rdi;
utcb.bp = _state.thread.cpu.rbp;
utcb.si = _state.thread.cpu.rsi;
utcb.di = _state.thread.cpu.rdi;
utcb.r8 = _state.thread.r8;
utcb.r9 = _state.thread.r9;
utcb.r10 = _state.thread.r10;
utcb.r11 = _state.thread.r11;
utcb.r12 = _state.thread.r12;
utcb.r13 = _state.thread.r13;
utcb.r14 = _state.thread.r14;
utcb.r15 = _state.thread.r15;
utcb.r8 = _state.thread.cpu.r8;
utcb.r9 = _state.thread.cpu.r9;
utcb.r10 = _state.thread.cpu.r10;
utcb.r11 = _state.thread.cpu.r11;
utcb.r12 = _state.thread.cpu.r12;
utcb.r13 = _state.thread.cpu.r13;
utcb.r14 = _state.thread.cpu.r14;
utcb.r15 = _state.thread.cpu.r15;
utcb.sp = _state.thread.sp;
utcb.ip = _state.thread.ip;
utcb.flags = _state.thread.eflags;
utcb.sp = _state.thread.cpu.sp;
utcb.ip = _state.thread.cpu.ip;
utcb.flags = _state.thread.cpu.eflags;
utcb.mtd = Nova::Mtd::ACDB |
Nova::Mtd::EBSD |

View File

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

View File

@ -44,5 +44,5 @@ void Pager_object::wake_up()
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 s;
Thread_state s { };
L4_Copy_regs_to_mrs(_l4_thread_id);
@ -40,23 +40,19 @@ Thread_state Platform_thread::state()
MR_EAX = 9,
};
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);
L4_StoreMR(MR_EIP, &s.cpu.ip);
L4_StoreMR(MR_EFLAGS, &s.cpu.eflags);
L4_StoreMR(MR_EDI, &s.cpu.edi);
L4_StoreMR(MR_ESI, &s.cpu.esi);
L4_StoreMR(MR_EBP, &s.cpu.ebp);
L4_StoreMR(MR_ESP, &s.cpu.sp);
L4_StoreMR(MR_EBX, &s.cpu.ebx);
L4_StoreMR(MR_EDX, &s.cpu.edx);
L4_StoreMR(MR_ECX, &s.cpu.ecx);
L4_StoreMR(MR_EAX, &s.cpu.eax);
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'
*
* \throw Cpu_session::State_access_failed
*/
void state(Thread_state s);

View File

@ -44,5 +44,5 @@ void Pager_object::wake_up()
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)
{
warning(__func__, " not implemented");
throw Cpu_thread::State_access_failed();
}
void Platform_thread::state(Thread_state) { }
Thread_state Platform_thread::state()
{
Thread_state s;
Thread_state s { };
L4_Word_t dummy;
L4_ThreadId_t dummy_tid;
@ -169,8 +165,9 @@ Thread_state Platform_thread::state()
0, 0, 0, 0, L4_nilthread,
&dummy, &sp, &ip, &dummy, &dummy,
&dummy_tid);
s.ip = ip;
s.sp = sp;
s.cpu.ip = ip;
s.cpu.sp = sp;
s.state = Thread_state::State::VALID;
return s;
}

View File

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

View File

@ -143,7 +143,7 @@ void Pager_object::wake_up()
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)
{
warning(__PRETTY_FUNCTION__, " not implemented");
throw Cpu_thread::State_access_failed();
}
void Platform_thread::state(Thread_state) { }
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,
register_count, &registers);
if (ret != seL4_NoError) {
error("reading thread state ", ret);
throw Cpu_thread::State_access_failed();
}
if (ret != seL4_NoError)
return { .state = Thread_state::State::UNAVAILABLE, .cpu = { } };
Thread_state state;
memset(&state, 0, sizeof(state));
Thread_state state { };
state.r0 = registers.r0;
state.r1 = registers.r1;
state.r2 = registers.r2;
state.r3 = registers.r3;
state.r4 = registers.r4;
state.r5 = registers.r5;
state.r6 = registers.r6;
state.r7 = registers.r7;
state.r8 = registers.r8;
state.r9 = registers.r9;
state.r10 = registers.r10;
state.r11 = registers.r11;
state.r12 = registers.r12;
state.sp = registers.sp;
state.lr = registers.r14;
state.ip = registers.pc;
state.cpsr = registers.cpsr;
state.cpu_exception = 0; /* XXX detect/track if in exception and report here */
state.cpu.r0 = registers.r0;
state.cpu.r1 = registers.r1;
state.cpu.r2 = registers.r2;
state.cpu.r3 = registers.r3;
state.cpu.r4 = registers.r4;
state.cpu.r5 = registers.r5;
state.cpu.r6 = registers.r6;
state.cpu.r7 = registers.r7;
state.cpu.r8 = registers.r8;
state.cpu.r9 = registers.r9;
state.cpu.r10 = registers.r10;
state.cpu.r11 = registers.r11;
state.cpu.r12 = registers.r12;
state.cpu.sp = registers.sp;
state.cpu.lr = registers.r14;
state.cpu.ip = registers.pc;
state.cpu.cpsr = registers.cpsr;
state.cpu.cpu_exception = 0; /* XXX detect/track if in exception and report here */
return state;
}

View File

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

View File

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

View File

@ -15,7 +15,6 @@
#define _INCLUDE__CPU_THREAD__CPU_THREAD_H_
#include <base/stdint.h>
#include <base/exception.h>
#include <base/thread_state.h>
#include <base/signal.h>
#include <base/affinity.h>
@ -26,8 +25,6 @@ namespace Genode { struct Cpu_thread; }
struct Genode::Cpu_thread : Interface
{
class State_access_failed : public Exception { };
/**
* 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
*
* \return state of the targeted thread
* \throw State_access_failed
*/
virtual Thread_state state() = 0;
@ -67,7 +63,6 @@ struct Genode::Cpu_thread : Interface
* Override the current thread state
*
* \param state state that shall be applied
* \throw State_access_failed
*/
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_pause, void, pause);
GENODE_RPC(Rpc_resume, void, resume);
GENODE_RPC_THROW(Rpc_get_state, Thread_state, state,
GENODE_TYPE_LIST(State_access_failed));
GENODE_RPC_THROW(Rpc_set_state, void, state,
GENODE_TYPE_LIST(State_access_failed),
Thread_state const &);
GENODE_RPC(Rpc_get_state, Thread_state, state);
GENODE_RPC(Rpc_set_state, void, state, Thread_state const &);
GENODE_RPC(Rpc_exception_sigh, void, exception_sigh, Signal_context_capability);
GENODE_RPC(Rpc_single_step, void, single_step, bool);
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) { }
Thread_state state;
Thread_state state { };
Cpu_thread_client thread_client(thread.cap());
log("--- pausing ---");
@ -278,11 +278,10 @@ static void test_pause_resume(Env &env)
log("--- paused ---");
log("--- reading thread state ---");
try {
state = thread_client.state();
} catch (Cpu_thread::State_access_failed) {
state = thread_client.state();
if (state.state == Thread_state::State::UNAVAILABLE)
throw -10;
}
if (loop_paused != thread.loop)
throw -11;

View File

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

View File

@ -280,30 +280,24 @@ struct Monitor::Gdb::State : Noncopyable
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()) {
try {
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());
}
Thread_state const thread_state = _current->thread->thread._real.call<Cpu_thread::Rpc_get_state>();
if (thread_state.state == Thread_state::State::UNAVAILABLE) {
warning("unable to access state of thread ", _current->thread->thread.id());
return;
}
fn(thread_state);
};
}
bool current_thread_state(Thread_state const &thread_state)
{
if (_current.constructed() && _current->thread.constructed()) {
try {
_current->thread->thread._real.call<Cpu_thread::Rpc_set_state>(thread_state);
return true;
} catch (Cpu_thread::State_access_failed) {
warning("unable to set state of thread ", _current->thread->thread.id());
}
}
return false;
if (!_current.constructed() || !_current->thread.constructed())
return false;
_current->thread->thread._real.call<Cpu_thread::Rpc_set_state>(thread_state);
return true;
}
State(Inferiors &inferiors, Memory_accessor &memory_accessor,
@ -666,7 +660,7 @@ struct g : Command_without_separator
gdb_response(out, [&] (Output &out) {
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)
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))
gdb_ok(out);

View File

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

View File

@ -72,7 +72,7 @@ void Monitor::Monitored_thread::_handle_exception()
_original_first_instruction);
stop_reply_signal = Stop_reply_signal::STOP;
} 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:
stop_reply_signal = Stop_reply_signal::TRAP;
break;

View File

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