NOVA: add support to cpu_session to create vCPUs

Extend base-nova specific cpu_session to create also vCPUs.
This commit is contained in:
Alexander Boettcher 2012-08-08 17:12:39 +02:00 committed by Norman Feske
parent 4342d0d234
commit f68482f87a
7 changed files with 31 additions and 21 deletions

View File

@ -68,10 +68,11 @@ namespace Genode {
return call<Rpc_native_cap>(cap); }
int start_exc_base_vcpu(Thread_capability thread, addr_t ip,
addr_t sp, addr_t exc_base)
addr_t sp, addr_t exc_base,
bool vcpu = false)
{
return call<Rpc_start_exc_base_vcpu>(thread, ip, sp,
exc_base);
exc_base, vcpu);
}

View File

@ -25,7 +25,7 @@ namespace Genode {
virtual int
start_exc_base_vcpu(Thread_capability thread, addr_t ip,
addr_t sp, addr_t exc_base) = 0;
addr_t sp, addr_t exc_base, bool vcpu) = 0;
virtual
Native_capability native_cap(Thread_capability cap) = 0;
@ -34,7 +34,7 @@ namespace Genode {
*********************/
GENODE_RPC(Rpc_start_exc_base_vcpu, int, start_exc_base_vcpu,
Thread_capability, addr_t, addr_t, addr_t);
Thread_capability, addr_t, addr_t, addr_t, bool);
GENODE_RPC(Rpc_native_cap, Native_capability, native_cap,
Thread_capability);

View File

@ -118,7 +118,7 @@ void Thread_base::start()
Genode::Nova_cpu_connection cpu;
if (cpu.start_exc_base_vcpu(_thread_cap, (addr_t)_thread_start,
thread_sp, _tid.exc_pt_sel))
thread_sp, _tid.exc_pt_sel, _tid.is_vcpu))
throw Cpu_session::Thread_creation_failed();
/* request native EC thread cap */
@ -127,10 +127,14 @@ void Thread_base::start()
using namespace Nova;
/* request exception portals */
request_event_portal(pager_cap, _tid.exc_pt_sel, PT_SEL_STARTUP);
request_event_portal(pager_cap, _tid.exc_pt_sel, PT_SEL_PAGE_FAULT);
request_event_portal(pager_cap, _tid.exc_pt_sel, SM_SEL_EC);
/* request exception portals for normal threads */
if (!_tid.is_vcpu) {
request_event_portal(pager_cap, _tid.exc_pt_sel,
PT_SEL_STARTUP);
request_event_portal(pager_cap, _tid.exc_pt_sel,
PT_SEL_PAGE_FAULT);
request_event_portal(pager_cap, _tid.exc_pt_sel, SM_SEL_EC);
}
/* request creation of SC to let thread run*/
env()->cpu_session()->resume(_thread_cap);

View File

@ -32,12 +32,11 @@ Cpu_session_component::native_cap(Thread_capability thread_cap)
int
Cpu_session_component::start_exc_base_vcpu(Thread_capability thread_cap,
addr_t ip, addr_t sp,
addr_t exc_base)
addr_t exc_base, bool vcpu)
{
Cpu_thread_component *thread = _lookup_thread(thread_cap);
if (!thread) return -1;
return thread->platform_thread()->start((void *)ip, (void *)sp, exc_base);
return thread->platform_thread()->start((void *)ip, (void *)sp,
exc_base, vcpu);
}

View File

@ -148,7 +148,7 @@ namespace Genode {
***********************************/
int start_exc_base_vcpu(Thread_capability, addr_t,
addr_t, addr_t);
addr_t, addr_t, bool);
Native_capability native_cap(Thread_capability);
};
}

View File

@ -59,13 +59,18 @@ namespace Genode {
/**
* Start thread
*
* \param ip instruction pointer to start at
* \param sp stack pointer to use
* \param ip instruction pointer to start at
* \param sp stack pointer to use
* \param exc_base exception base of thread in caller
* protection domain
* \param vcpu If true it will run as vCPU,
* otherwise it will be a thread.
*
* \retval 0 successful
* \retval -1 thread could not be started
* \retval -1 thread/vCPU could not be started
*/
int start(void *ip, void *sp, addr_t exc_base = ~0UL);
int start(void *ip, void *sp, addr_t exc_base = ~0UL,
bool vcpu = false);
/**
* Pause this thread

View File

@ -40,7 +40,7 @@ void Platform_thread::set_cpu(unsigned int cpu_no)
}
int Platform_thread::start(void *ip, void *sp, addr_t exc_base)
int Platform_thread::start(void *ip, void *sp, addr_t exc_base, bool vcpu)
{
using namespace Nova;
@ -58,7 +58,7 @@ int Platform_thread::start(void *ip, void *sp, addr_t exc_base)
_pager->initial_eip((addr_t)ip);
if (!_is_main_thread) {
addr_t initial_sp = reinterpret_cast<addr_t>(sp);
addr_t utcb = round_page(initial_sp);
addr_t utcb = vcpu ? 0 : round_page(initial_sp);
_pager->initial_esp(initial_sp);
if (exc_base == ~0UL) {
@ -83,6 +83,7 @@ int Platform_thread::start(void *ip, void *sp, addr_t exc_base)
/* ip == 0 means that caller will use the thread as worker */
bool thread_global = ip;
res = create_ec(_sel_ec(), _pd->pd_sel(), _cpu_no, utcb,
initial_sp, exc_base, thread_global);
if (res)
@ -195,7 +196,7 @@ int Platform_thread::start(void *ip, void *sp, addr_t exc_base)
cap_selector_allocator()->free(_sel_exc_base, NUM_INITIAL_PT_LOG2);
_sel_exc_base = ~0UL;
return -1;
return -7;
}