nova: use 'Native_cpu' component for thread initialization
Pass the thread type and exception base to core with a 'Native_cpu' component instead of enhancing the 'Thread_state' class. Fixes #2298
This commit is contained in:
committed by
Christian Helmuth
parent
fbdfbc2476
commit
ca2871e2e4
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* \brief Thread state
|
||||
* \author Alexander Boettcher
|
||||
* \date 2012-08-09
|
||||
*
|
||||
* This file contains the NOVA specific thread state.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__BASE__THREAD_STATE_H_
|
||||
#define _INCLUDE__BASE__THREAD_STATE_H_
|
||||
|
||||
#include <base/thread_state_base.h>
|
||||
|
||||
namespace Genode { struct Thread_state; }
|
||||
|
||||
|
||||
struct Genode::Thread_state : Thread_state_base
|
||||
{
|
||||
bool vcpu;
|
||||
addr_t sel_exc_base;
|
||||
bool global_thread;
|
||||
|
||||
Thread_state() : vcpu(false), sel_exc_base(~0UL), global_thread(true) { }
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__BASE__THREAD_STATE_H_ */
|
||||
33
repos/base-nova/include/nova_native_cpu/client.h
Normal file
33
repos/base-nova/include/nova_native_cpu/client.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* \brief Client-side NOVA-specific CPU session interface
|
||||
* \author Norman Feske
|
||||
* \date 2016-04-21
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__NOVA_NATIVE_CPU__CLIENT_H_
|
||||
#define _INCLUDE__NOVA_NATIVE_CPU__CLIENT_H_
|
||||
|
||||
#include <nova_native_cpu/nova_native_cpu.h>
|
||||
#include <base/rpc_client.h>
|
||||
|
||||
namespace Genode { struct Nova_native_cpu_client; }
|
||||
|
||||
|
||||
struct Genode::Nova_native_cpu_client : Rpc_client<Nova_native_cpu>
|
||||
{
|
||||
explicit Nova_native_cpu_client(Capability<Native_cpu> cap)
|
||||
: Rpc_client<Nova_native_cpu>(static_cap_cast<Nova_native_cpu>(cap)) { }
|
||||
|
||||
void thread_type(Thread_capability thread_cap, Thread_type thread_type,
|
||||
Exception_base exception_base) {
|
||||
call<Rpc_thread_type>(thread_cap, thread_type, exception_base); }
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__NOVA_NATIVE_CPU__CLIENT_H_ */
|
||||
45
repos/base-nova/include/nova_native_cpu/nova_native_cpu.h
Normal file
45
repos/base-nova/include/nova_native_cpu/nova_native_cpu.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* \brief NOVA-specific part of the CPU session interface
|
||||
* \author Norman Feske
|
||||
* \date 2016-04-21
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__NOVA_NATIVE_CPU__FOC_NATIVE_CPU_H_
|
||||
#define _INCLUDE__NOVA_NATIVE_CPU__FOC_NATIVE_CPU_H_
|
||||
|
||||
#include <base/rpc.h>
|
||||
#include <cpu_session/cpu_session.h>
|
||||
|
||||
namespace Genode { struct Nova_native_cpu; }
|
||||
|
||||
|
||||
struct Genode::Nova_native_cpu : Cpu_session::Native_cpu
|
||||
{
|
||||
enum Thread_type { GLOBAL, LOCAL, VCPU };
|
||||
|
||||
/*
|
||||
* Exception base of thread in caller protection domain - not in core!
|
||||
*/
|
||||
struct Exception_base { addr_t exception_base; };
|
||||
|
||||
|
||||
virtual void thread_type(Thread_capability, Thread_type, Exception_base) = 0;
|
||||
|
||||
|
||||
/*********************
|
||||
** RPC declaration **
|
||||
*********************/
|
||||
|
||||
GENODE_RPC(Rpc_thread_type, void, thread_type, Thread_capability,
|
||||
Thread_type, Exception_base );
|
||||
GENODE_RPC_INTERFACE(Rpc_thread_type);
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__NOVA_NATIVE_CPU__FOC_NATIVE_CPU_H_ */
|
||||
@@ -23,6 +23,7 @@ SRC_CC += stack_area.cc \
|
||||
main.cc \
|
||||
pager.cc \
|
||||
pd_session_component.cc \
|
||||
native_cpu_component.cc \
|
||||
native_pd_component.cc \
|
||||
pd_upgrade_ram_quota.cc \
|
||||
pd_assign_pci.cc \
|
||||
|
||||
44
repos/base-nova/src/core/include/native_cpu_component.h
Normal file
44
repos/base-nova/src/core/include/native_cpu_component.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* \brief Kernel-specific part of the CPU-session interface
|
||||
* \author Norman Feske
|
||||
* \date 2016-04-21
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _CORE__INCLUDE__NATIVE_CPU_COMPONENT_H_
|
||||
#define _CORE__INCLUDE__NATIVE_CPU_COMPONENT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/rpc_server.h>
|
||||
#include <nova_native_cpu/nova_native_cpu.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Cpu_session_component;
|
||||
class Native_cpu_component;
|
||||
}
|
||||
|
||||
|
||||
class Genode::Native_cpu_component : public Rpc_object<Nova_native_cpu,
|
||||
Native_cpu_component>
|
||||
{
|
||||
private:
|
||||
|
||||
Cpu_session_component &_cpu_session;
|
||||
Rpc_entrypoint &_thread_ep;
|
||||
|
||||
public:
|
||||
|
||||
Native_cpu_component(Cpu_session_component &, char const *);
|
||||
~Native_cpu_component();
|
||||
|
||||
void thread_type(Thread_capability, Thread_type, Exception_base) override;
|
||||
};
|
||||
|
||||
#endif /* _CORE__INCLUDE__NATIVE_CPU_COMPONENT_H_ */
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <thread/capability.h>
|
||||
#include <base/thread_state.h>
|
||||
#include <base/thread.h>
|
||||
#include <nova_native_cpu/nova_native_cpu.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/stack.h>
|
||||
@@ -145,6 +146,12 @@ namespace Genode {
|
||||
** Accessor functions **
|
||||
************************/
|
||||
|
||||
/**
|
||||
* Set thread type and exception portal base
|
||||
*/
|
||||
void thread_type(Nova_native_cpu::Thread_type thread_type,
|
||||
Nova_native_cpu::Exception_base exception_base);
|
||||
|
||||
/**
|
||||
* Set pager
|
||||
*/
|
||||
|
||||
49
repos/base-nova/src/core/native_cpu_component.cc
Normal file
49
repos/base-nova/src/core/native_cpu_component.cc
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* \brief Core implementation of the CPU session interface extension
|
||||
* \author Norman Feske
|
||||
* \date 2016-04-21
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/stdint.h>
|
||||
|
||||
/* core-local includes */
|
||||
#include <native_cpu_component.h>
|
||||
#include <cpu_session_component.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
void Native_cpu_component::thread_type(Thread_capability thread_cap,
|
||||
Thread_type thread_type,
|
||||
Exception_base exception_base)
|
||||
{
|
||||
auto lambda = [&] (Cpu_thread_component *thread) {
|
||||
if (!thread)
|
||||
return;
|
||||
|
||||
thread->platform_thread().thread_type(thread_type, exception_base);
|
||||
};
|
||||
|
||||
_thread_ep.apply(thread_cap, lambda);
|
||||
}
|
||||
|
||||
Native_cpu_component::Native_cpu_component(Cpu_session_component &cpu_session, char const *)
|
||||
:
|
||||
_cpu_session(cpu_session), _thread_ep(*_cpu_session._thread_ep)
|
||||
{
|
||||
_thread_ep.manage(this);
|
||||
}
|
||||
|
||||
|
||||
Genode::Native_cpu_component::~Native_cpu_component()
|
||||
{
|
||||
_thread_ep.dissolve(this);
|
||||
}
|
||||
@@ -267,37 +267,13 @@ Thread_state Platform_thread::state()
|
||||
|
||||
void Platform_thread::state(Thread_state s)
|
||||
{
|
||||
if (_sel_exc_base == Native_thread::INVALID_INDEX) {
|
||||
if (!_pager) throw Cpu_thread::State_access_failed();
|
||||
|
||||
/* you can do it only once */
|
||||
if (!_pager->copy_thread_state(s))
|
||||
throw Cpu_thread::State_access_failed();
|
||||
|
||||
/*
|
||||
* s.sel_exc_base exception base of thread in caller
|
||||
* protection domain - not in Core !
|
||||
* s.is_vcpu If true it will run as vCPU,
|
||||
* otherwise it will be a thread.
|
||||
*/
|
||||
if (!main_thread() || s.vcpu)
|
||||
_sel_exc_base = s.sel_exc_base;
|
||||
|
||||
if (!s.global_thread)
|
||||
_features |= WORKER;
|
||||
|
||||
if (!s.vcpu)
|
||||
return;
|
||||
|
||||
_features |= VCPU;
|
||||
|
||||
} else {
|
||||
|
||||
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);
|
||||
}
|
||||
/* the new state is transferred to the kernel by the recall handler */
|
||||
_pager->client_recall(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -352,6 +328,23 @@ void Platform_thread::pager(Pager_object *pager)
|
||||
}
|
||||
|
||||
|
||||
void Platform_thread::thread_type(Nova_native_cpu::Thread_type thread_type,
|
||||
Nova_native_cpu::Exception_base exception_base)
|
||||
{
|
||||
/* you can do it only once */
|
||||
if (_sel_exc_base != Native_thread::INVALID_INDEX)
|
||||
return;
|
||||
|
||||
if (!main_thread() || (thread_type == Nova_native_cpu::Thread_type::VCPU))
|
||||
_sel_exc_base = exception_base.exception_base;
|
||||
|
||||
if (thread_type == Nova_native_cpu::Thread_type::LOCAL)
|
||||
_features |= WORKER;
|
||||
else if (thread_type == Nova_native_cpu::Thread_type::VCPU)
|
||||
_features |= VCPU;
|
||||
}
|
||||
|
||||
|
||||
Platform_thread::Platform_thread(size_t, const char *name, unsigned prio,
|
||||
Affinity::Location affinity, int thread_id)
|
||||
:
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <base/rpc_client.h>
|
||||
#include <session/session.h>
|
||||
#include <cpu_thread/client.h>
|
||||
#include <nova_native_cpu/client.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/stack.h>
|
||||
@@ -148,18 +149,27 @@ void Thread::start()
|
||||
using namespace Genode;
|
||||
|
||||
/* create EC at core */
|
||||
Thread_state state;
|
||||
state.sel_exc_base = native_thread().exc_pt_sel;
|
||||
state.vcpu = native_thread().vcpu;
|
||||
state.global_thread = global;
|
||||
|
||||
try {
|
||||
Nova_native_cpu::Thread_type thread_type;
|
||||
|
||||
if (native_thread().vcpu)
|
||||
thread_type = Nova_native_cpu::Thread_type::VCPU;
|
||||
else if (global)
|
||||
thread_type = Nova_native_cpu::Thread_type::GLOBAL;
|
||||
else
|
||||
thread_type = Nova_native_cpu::Thread_type::LOCAL;
|
||||
|
||||
Nova_native_cpu::Exception_base exception_base { native_thread().exc_pt_sel };
|
||||
|
||||
Nova_native_cpu_client native_cpu(_cpu_session->native_cpu());
|
||||
native_cpu.thread_type(_thread_cap, thread_type, exception_base);
|
||||
} catch (...) { throw Cpu_session::Thread_creation_failed(); }
|
||||
|
||||
/* local thread have no start instruction pointer - set via portal entry */
|
||||
addr_t thread_ip = global ? reinterpret_cast<addr_t>(_thread_start) : native_thread().initial_ip;
|
||||
|
||||
Cpu_thread_client cpu_thread(_thread_cap);
|
||||
try { cpu_thread.state(state); }
|
||||
catch (...) { throw Cpu_session::Thread_creation_failed(); }
|
||||
|
||||
cpu_thread.start(thread_ip, _stack->top());
|
||||
|
||||
/* request native EC thread cap */
|
||||
|
||||
Reference in New Issue
Block a user