hw: remove access_thread_regs syscall

Issue #1652
This commit is contained in:
Alexander Boettcher 2015-08-24 10:57:40 +02:00 committed by Christian Helmuth
parent 6e481127ce
commit c5877b5575
14 changed files with 47 additions and 383 deletions

View File

@ -22,37 +22,6 @@ namespace Kernel
typedef Genode::uint32_t Call_arg;
typedef Genode::uint32_t Call_ret;
/**
* Registers that are provided by a kernel thread-object for user access
*/
struct Thread_reg_id
{
enum {
R0 = 0,
R1 = 1,
R2 = 2,
R3 = 3,
R4 = 4,
R5 = 5,
R6 = 6,
R7 = 7,
R8 = 8,
R9 = 9,
R10 = 10,
R11 = 11,
R12 = 12,
SP = 13,
LR = 14,
IP = 15,
CPSR = 16,
CPU_EXCEPTION = 17,
FAULT_TLB = 18,
FAULT_ADDR = 19,
FAULT_WRITES = 20,
FAULT_SIGNAL = 21,
};
};
/**
* Events that are provided by a kernel thread-object for user handling
*/

View File

@ -22,21 +22,6 @@ namespace Kernel
typedef Genode::uint64_t Call_arg;
typedef Genode::uint64_t Call_ret;
/**
* Registers that are provided by a kernel thread-object for user access
*/
struct Thread_reg_id
{
enum {
IP = 0,
SP = 1,
FAULT_TLB = 2,
FAULT_ADDR = 3,
FAULT_WRITES = 4,
FAULT_SIGNAL = 5,
};
};
/**
* Events that are provided by a kernel thread-object for user handling
*/

View File

@ -37,25 +37,24 @@ namespace Kernel
constexpr Call_arg call_id_start_thread() { return 17; }
constexpr Call_arg call_id_pause_thread() { return 18; }
constexpr Call_arg call_id_resume_thread() { return 19; }
constexpr Call_arg call_id_access_thread_regs() { return 20; }
constexpr Call_arg call_id_route_thread_event() { return 21; }
constexpr Call_arg call_id_thread_quota() { return 22; }
constexpr Call_arg call_id_update_pd() { return 23; }
constexpr Call_arg call_id_new_pd() { return 24; }
constexpr Call_arg call_id_delete_pd() { return 25; }
constexpr Call_arg call_id_new_signal_receiver() { return 26; }
constexpr Call_arg call_id_new_signal_context() { return 27; }
constexpr Call_arg call_id_delete_signal_context() { return 28; }
constexpr Call_arg call_id_delete_signal_receiver() { return 29; }
constexpr Call_arg call_id_new_vm() { return 30; }
constexpr Call_arg call_id_run_vm() { return 31; }
constexpr Call_arg call_id_pause_vm() { return 32; }
constexpr Call_arg call_id_delete_vm() { return 33; }
constexpr Call_arg call_id_new_irq() { return 34; }
constexpr Call_arg call_id_delete_irq() { return 35; }
constexpr Call_arg call_id_ack_irq() { return 36; }
constexpr Call_arg call_id_new_obj() { return 37; }
constexpr Call_arg call_id_delete_obj() { return 38; }
constexpr Call_arg call_id_route_thread_event() { return 20; }
constexpr Call_arg call_id_thread_quota() { return 21; }
constexpr Call_arg call_id_update_pd() { return 22; }
constexpr Call_arg call_id_new_pd() { return 23; }
constexpr Call_arg call_id_delete_pd() { return 24; }
constexpr Call_arg call_id_new_signal_receiver() { return 25; }
constexpr Call_arg call_id_new_signal_context() { return 26; }
constexpr Call_arg call_id_delete_signal_context() { return 27; }
constexpr Call_arg call_id_delete_signal_receiver() { return 28; }
constexpr Call_arg call_id_new_vm() { return 29; }
constexpr Call_arg call_id_run_vm() { return 30; }
constexpr Call_arg call_id_pause_vm() { return 31; }
constexpr Call_arg call_id_delete_vm() { return 32; }
constexpr Call_arg call_id_new_irq() { return 33; }
constexpr Call_arg call_id_delete_irq() { return 34; }
constexpr Call_arg call_id_ack_irq() { return 35; }
constexpr Call_arg call_id_new_obj() { return 36; }
constexpr Call_arg call_id_delete_obj() { return 37; }
/**
* Update locally effective domain configuration to in-memory state
@ -146,48 +145,6 @@ namespace Kernel
}
/**
* Access plain member variables of a kernel thread-object
*
* \param thread pointer to thread kernel object
* \param reads amount of read operations
* \param writes amount of write operations
* \param values base of the value buffer for all operations
*
* \return amount of undone operations according to the execution order
*
* Operations are executed in order of the appearance of the register names
* in the callers UTCB. If reads = 0, read_values is of no relevance. If
* writes = 0, write_values is of no relevance.
*
* Expected structure at the callers UTCB base:
*
* 0 * sizeof(addr_t): read register name #1
* ... ...
* (reads - 1) * sizeof(addr_t): read register name #reads
* (reads - 0) * sizeof(addr_t): write register name #1
* ... ...
* (reads + writes - 1) * sizeof(addr_t): write register name #writes
*
* Expected structure at values:
*
* 0 * sizeof(addr_t): read destination #1
* ... ...
* (reads - 1) * sizeof(addr_t): read destination #reads
* (reads - 0) * sizeof(addr_t): write value #1
* ... ...
* (reads + writes - 1) * sizeof(addr_t): write value #writes
*/
inline unsigned access_thread_regs(Thread * const thread,
unsigned const reads,
unsigned const writes,
addr_t * const values)
{
return call(call_id_access_thread_regs(), (Call_arg)thread,
reads, writes, (Call_arg)values);
}
/**
* Execute a virtual-machine (again)
*

View File

@ -141,43 +141,11 @@ class Kernel::Thread
*/
void _call();
/**
* Read a thread register
*
* \param id kernel name of targeted thread register
* \param value read-value buffer
*
* \retval 0 succeeded
* \retval -1 failed
*/
int _read_reg(addr_t const id, addr_t & value) const;
/**
* Return amount of timer tics that 'quota' is worth
*/
size_t _core_to_kernel_quota(size_t const quota) const;
/**
* Override a thread register
*
* \param id kernel name of targeted thread register
* \param value write-value buffer
*
* \retval 0 succeeded
* \retval -1 failed
*/
int _write_reg(addr_t const id, addr_t const value);
/**
* Map kernel names of thread registers to the corresponding data
*
* \param id kernel name of thread register
*
* \retval 0 failed
* \retval >0 pointer to register content
*/
addr_t Thread::* _reg(addr_t const id) const;
/**
* Print the activity of the thread
*
@ -224,7 +192,6 @@ class Kernel::Thread
void _call_delete_vm();
void _call_run_vm();
void _call_pause_vm();
void _call_access_thread_regs();
void _call_route_thread_event();
void _call_new_irq();
void _call_ack_irq();

View File

@ -41,6 +41,14 @@ class Kernel::Thread_base
* \param t generic part of kernel thread-object
*/
Thread_base(Thread * const t);
public:
/* Accessors */
addr_t fault_pd() const { return _fault_pd; }
addr_t fault_addr() const { return _fault_addr; }
addr_t fault_writes() const { return _fault_writes; }
addr_t fault_signal() const { return _fault_signal; }
};
#endif /* _KERNEL__THREAD_BASE_H_ */

View File

@ -1,46 +0,0 @@
/*
* \brief Hardware specific base of kernel thread-objects
* \author Martin Stein
* \date 2013-11-13
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _KERNEL__THREAD_BASE_H_
#define _KERNEL__THREAD_BASE_H_
/* core includes */
#include <kernel/thread_event.h>
namespace Kernel
{
/**
* Hardware specific base of kernel thread-objects
*/
class Thread_base;
}
class Kernel::Thread_base
{
protected:
Thread_event _fault;
addr_t _fault_pd;
addr_t _fault_addr;
addr_t _fault_writes;
addr_t _fault_signal;
/**
* Constructor
*
* \param t generic part of kernel thread-object
*/
Thread_base(Thread * const t);
};
#endif /* _KERNEL__THREAD_BASE_H_ */

View File

@ -362,42 +362,6 @@ Signal_context * const Thread_event::signal_context() const {
return _signal_context; }
void Thread::_call_access_thread_regs()
{
/* get targeted thread */
unsigned const reads = user_arg_2();
unsigned const writes = user_arg_3();
Thread * const t = (Thread*) user_arg_1();
if (!t) {
PWRN("unknown thread");
user_arg_0(reads + writes);
return;
}
/* execute read operations */
addr_t * const utcb = (addr_t *) this->utcb()->base();
addr_t * const read_ids = &utcb[0];
addr_t * values = (addr_t *)user_arg_4();
for (unsigned i = 0; i < reads; i++) {
if (t->_read_reg(read_ids[i], *values)) {
user_arg_0(reads + writes - i);
return;
}
values++;
}
/* execute write operations */
addr_t * const write_ids = &utcb[reads];
for (unsigned i = 0; i < writes; i++) {
if (t->_write_reg(write_ids[i], *values)) {
user_arg_0(writes - i);
return;
}
values++;
}
user_arg_0(0);
return;
}
void Thread::_call_update_data_region()
{
/*
@ -648,32 +612,6 @@ void Thread::_call_delete_cap()
}
int Thread::_read_reg(addr_t const id, addr_t & value) const
{
addr_t Thread::* const reg = _reg(id);
if (reg) {
value = this->*reg;
return 0;
}
PWRN("%s -> %s: cannot read unknown thread register %p",
pd_label(), label(), (void*)id);
return -1;
}
int Thread::_write_reg(addr_t const id, addr_t const value)
{
addr_t Thread::* const reg = _reg(id);
if (reg) {
this->*reg = value;
return 0;
}
PWRN("%s -> %s: cannot write unknown thread register %p",
pd_label(), label(), (void*)id);
return -1;
}
void Thread::_call()
{
try {
@ -712,7 +650,6 @@ void Thread::_call()
case call_id_delete_thread(): _call_delete<Thread>(); return;
case call_id_start_thread(): _call_start_thread(); return;
case call_id_resume_thread(): _call_resume_thread(); return;
case call_id_access_thread_regs(): _call_access_thread_regs(); return;
case call_id_route_thread_event(): _call_route_thread_event(); return;
case call_id_update_pd(): _call_update_pd(); return;
case call_id_new_pd():

View File

@ -150,16 +150,8 @@ int Platform_thread::start(void * const ip, void * const sp)
}
/* initialize thread registers */
typedef Kernel::Thread_reg_id Reg_id;
enum { WRITES = 2 };
addr_t * write_regs = (addr_t*) Thread_base::myself()->utcb()->base();
write_regs[0] = Reg_id::IP;
write_regs[1] = Reg_id::SP;
addr_t values[] = { (addr_t)ip, (addr_t)sp };
if (Kernel::access_thread_regs(kernel_object(), 0, WRITES, values)) {
PERR("failed to initialize thread registers");
return -1;
}
kernel_object()->ip = reinterpret_cast<addr_t>(ip);
kernel_object()->sp = reinterpret_cast<addr_t>(sp);
/* start executing new thread */
if (!_pd) {
@ -200,38 +192,15 @@ void Platform_thread::pager(Pager_object * const pager)
Genode::Pager_object * Platform_thread::pager() { return _pager; }
addr_t const * cpu_state_regs();
size_t cpu_state_regs_length();
Thread_state Platform_thread::state()
{
static addr_t const * const src = cpu_state_regs();
static size_t const length = cpu_state_regs_length();
static size_t const size = length * sizeof(src[0]);
void * dst = (void*)Thread_base::myself()->utcb()->base();
Genode::memcpy(dst, src, size);
Thread_state thread_state;
Cpu_state * const cpu_state = static_cast<Cpu_state *>(&thread_state);
if (Kernel::access_thread_regs(kernel_object(), length, 0,
(addr_t *)cpu_state)) {
throw Cpu_session::State_access_failed();
}
return thread_state;
};
Thread_state_base bstate(*kernel_object());
return Thread_state(bstate);
}
void Platform_thread::state(Thread_state thread_state)
{
static addr_t const * const src = cpu_state_regs();
static size_t const length = cpu_state_regs_length();
static size_t const size = length * sizeof(src[0]);
void * dst = (void*)Thread_base::myself()->utcb()->base();
Genode::memcpy(dst, src, size);
Cpu_state * const cpu_state = static_cast<Cpu_state *>(&thread_state);
if (Kernel::access_thread_regs(kernel_object(), 0, length,
(addr_t *)cpu_state)) {
throw Cpu_session::State_access_failed();
}
};
Cpu_state * cstate = static_cast<Cpu_state *>(kernel_object());
*cstate = static_cast<Cpu_state>(thread_state);
}

View File

@ -78,18 +78,13 @@ void Pager_entrypoint::entry()
PWRN("failed to get platform thread of faulter");
continue;
}
typedef Kernel::Thread_reg_id Reg_id;
static addr_t const read_regs[] = {
Reg_id::FAULT_TLB, Reg_id::IP, Reg_id::FAULT_ADDR,
Reg_id::FAULT_WRITES, Reg_id::FAULT_SIGNAL };
enum { READS = sizeof(read_regs)/sizeof(read_regs[0]) };
memcpy((void*)Thread_base::myself()->utcb()->base(),
read_regs, sizeof(read_regs));
addr_t * const values = (addr_t *)&_fault;
if (Kernel::access_thread_regs(pt->kernel_object(), READS, 0, values)) {
PWRN("failed to read fault data");
continue;
}
_fault.pd = pt->kernel_object()->fault_pd();
_fault.ip = pt->kernel_object()->ip;
_fault.addr = pt->kernel_object()->fault_addr();
_fault.writes = pt->kernel_object()->fault_writes();
_fault.signal = pt->kernel_object()->fault_signal();
/* try to resolve fault directly via local region managers */
if (pog->pager(*this)) { continue; }

View File

@ -63,36 +63,6 @@ void Thread::exception(unsigned const cpu)
}
addr_t Thread::* Thread::_reg(addr_t const id) const
{
static addr_t Thread::* const _regs[] = {
/* [0] */ (addr_t Thread::*)&Thread::r0,
/* [1] */ (addr_t Thread::*)&Thread::r1,
/* [2] */ (addr_t Thread::*)&Thread::r2,
/* [3] */ (addr_t Thread::*)&Thread::r3,
/* [4] */ (addr_t Thread::*)&Thread::r4,
/* [5] */ (addr_t Thread::*)&Thread::r5,
/* [6] */ (addr_t Thread::*)&Thread::r6,
/* [7] */ (addr_t Thread::*)&Thread::r7,
/* [8] */ (addr_t Thread::*)&Thread::r8,
/* [9] */ (addr_t Thread::*)&Thread::r9,
/* [10] */ (addr_t Thread::*)&Thread::r10,
/* [11] */ (addr_t Thread::*)&Thread::r11,
/* [12] */ (addr_t Thread::*)&Thread::r12,
/* [13] */ (addr_t Thread::*)&Thread::sp,
/* [14] */ (addr_t Thread::*)&Thread::lr,
/* [15] */ (addr_t Thread::*)&Thread::ip,
/* [16] */ (addr_t Thread::*)&Thread::cpsr,
/* [17] */ (addr_t Thread::*)&Thread::cpu_exception,
/* [18] */ (addr_t Thread::*)&Thread::_fault_pd,
/* [19] */ (addr_t Thread::*)&Thread::_fault_addr,
/* [20] */ (addr_t Thread::*)&Thread::_fault_writes,
/* [21] */ (addr_t Thread::*)&Thread::_fault_signal
};
return id < sizeof(_regs)/sizeof(_regs[0]) ? _regs[id] : 0;
}
Thread_event Thread::* Thread::_event(unsigned const id) const
{
static Thread_event Thread::* _events[] = {

View File

@ -30,24 +30,3 @@ Thread_base::Thread_base(Thread * const t)
_fault_writes(0),
_fault_signal(0)
{ }
/*************************
** CPU-state utilities **
*************************/
typedef Thread_reg_id Reg_id;
static addr_t const _cpu_state_regs[] = {
Reg_id::R0, Reg_id::R1, Reg_id::R2, Reg_id::R3, Reg_id::R4,
Reg_id::R5, Reg_id::R6, Reg_id::R7, Reg_id::R8, Reg_id::R9,
Reg_id::R10, Reg_id::R11, Reg_id::R12, Reg_id::SP, Reg_id::LR,
Reg_id::IP, Reg_id::CPSR, Reg_id::CPU_EXCEPTION };
addr_t const * cpu_state_regs() { return _cpu_state_regs; }
size_t cpu_state_regs_length()
{
return sizeof(_cpu_state_regs)/sizeof(_cpu_state_regs[0]);
}

View File

@ -39,20 +39,6 @@ Thread_base::Thread_base(Thread * const t)
** Kernel::Thread **
********************/
addr_t Thread::* Thread::_reg(addr_t const id) const
{
static addr_t Thread::* const _regs[] = {
/* [0] */ (addr_t Thread::*)&Thread::ip,
/* [1] */ (addr_t Thread::*)&Thread::sp,
/* [2] */ (addr_t Thread::*)&Thread::_fault_pd,
/* [3] */ (addr_t Thread::*)&Thread::_fault_addr,
/* [4] */ (addr_t Thread::*)&Thread::_fault_writes,
/* [5] */ (addr_t Thread::*)&Thread::_fault_signal
};
return id < sizeof(_regs)/sizeof(_regs[0]) ? _regs[id] : 0;
}
Thread_event Thread::* Thread::_event(unsigned const id) const
{
static Thread_event Thread::* _events[] = {
@ -95,20 +81,3 @@ void Kernel::Cpu_context::_init(size_t const stack_size, addr_t const table)
*/
sp = sp + stack_size;
}
/*************************
** CPU-state utilities **
*************************/
typedef Thread_reg_id Reg_id;
static addr_t const _cpu_state_regs[] = { };
addr_t const * cpu_state_regs() { return _cpu_state_regs; }
size_t cpu_state_regs_length()
{
return sizeof(_cpu_state_regs)/sizeof(_cpu_state_regs[0]);
}

View File

@ -21,6 +21,10 @@
namespace Genode { struct Thread_state; }
struct Genode::Thread_state : Thread_state_base { };
struct Genode::Thread_state : Thread_state_base
{
Thread_state() {}
Thread_state(Thread_state_base &base) : Thread_state_base(base) {}
};
#endif /* _INCLUDE__BASE__THREAD_STATE_H_ */

View File

@ -25,6 +25,7 @@ struct Genode::Thread_state_base : Cpu_state
bool unresolved_page_fault;
Thread_state_base() : unresolved_page_fault(false) { };
Thread_state_base(Cpu_state &c) : Cpu_state(c), unresolved_page_fault(false) { };
};
#endif /* _INCLUDE__BASE__THREAD_STATE_BASE_H_ */