nova: support to run VBox vCPUs within same PD

Issue #2173
This commit is contained in:
Alexander Boettcher 2016-11-24 21:57:33 +01:00 committed by Christian Helmuth
parent 1bea312ba2
commit d3d4381128
17 changed files with 166 additions and 131 deletions

View File

@ -569,7 +569,7 @@ namespace Nova {
struct Item {
mword_t crd;
mword_t hotspot;
bool is_del() { return hotspot & 0x1; }
bool is_del() const { return hotspot & 0x1; }
};
#ifdef __x86_64__

View File

@ -71,8 +71,8 @@ inline void request_signal_sm_cap(Genode::Native_capability const &cap,
}
inline void delegate_vcpu_portals(Genode::Native_capability const &cap,
Genode::addr_t const sel)
inline void translate_remote_pager(Genode::Native_capability const &cap,
Genode::addr_t const sel)
{
Genode::Thread * myself = Genode::Thread::myself();
Nova::Utcb *utcb = reinterpret_cast<Nova::Utcb *>(myself->utcb());
@ -84,34 +84,22 @@ inline void delegate_vcpu_portals(Genode::Native_capability const &cap,
Genode::uint8_t res = Nova::NOVA_OK;
enum {
TRANSLATE = true, THIS_PD = false, NON_GUEST = false, HOTSPOT = 0,
TRANSFER_ITEMS = 1U << (Nova::NUM_INITIAL_VCPU_PT_LOG2 - 1)
TRANSLATE = true, THIS_PD = false, NON_GUEST = false, HOTSPOT = 0
};
/* prepare translation items for every portal separately */
for (unsigned half = 0; !res && half < 2; half++) {
/* translate half of portals - due to size constraints on 64bit */
utcb->msg[0] = half;
utcb->set_msg_word(1);
/* add one translate item per portal */
for (unsigned i = 0; !res && i < TRANSFER_ITEMS; i++) {
Nova::Obj_crd obj_crd(sel + half * TRANSFER_ITEMS + i, 0);
if (!utcb->append_item(obj_crd, HOTSPOT, THIS_PD, NON_GUEST,
TRANSLATE))
res = 0xff;
}
if (res != Nova::NOVA_OK)
break;
/* translate one item */
utcb->msg[0] = 0xaffe;
utcb->set_msg_word(1);
Nova::Obj_crd obj_crd(sel, 0);
if (utcb->append_item(obj_crd, HOTSPOT, THIS_PD, NON_GUEST, TRANSLATE))
/* trigger the translation */
res = Nova::call(cap.local_name());
}
/* restore original receive window */
utcb->crd_rcv = orig_crd;
if (res)
if (res != Nova::NOVA_OK)
Genode::error("setting exception portals for vCPU failed res=", res);
}
#endif /* _INCLUDE__NOVA__UTIL_H_ */

View File

@ -75,7 +75,6 @@ namespace Genode {
addr_t _initial_esp;
addr_t _initial_eip;
addr_t _client_exc_pt_sel;
addr_t _client_exc_vcpu;
Lock _state_lock;
@ -121,7 +120,8 @@ namespace Genode {
Affinity::Location const _location;
Exception_handlers _exceptions;
addr_t _pd;
addr_t _pd_target;
addr_t _pd_source;
void _copy_state_from_utcb(Nova::Utcb * utcb);
void _copy_state_to_utcb(Nova::Utcb * utcb);
@ -179,8 +179,15 @@ namespace Genode {
/**
* Assign PD selector to PD
*/
void assign_pd(addr_t pd_sel) { _pd = pd_sel; }
addr_t pd_sel() const { return _pd; }
void assign_pd(addr_t pd_sel)
{
if (_pd_target == _pd_source)
_pd_source = pd_sel;
_pd_target = pd_sel;
}
addr_t pd_sel() const { return _pd_target; }
addr_t pd_source() const { return _pd_source; }
void exception(uint8_t exit_id);
@ -188,7 +195,6 @@ namespace Genode {
* Return base of initial portal window
*/
addr_t exc_pt_sel_client() { return _client_exc_pt_sel; }
addr_t exc_pt_vcpu() { return _client_exc_vcpu; }
/**
* Set initial stack pointer used by the startup handler
@ -324,14 +330,6 @@ namespace Genode {
*/
void cleanup_call();
/**
* Open receive window for initial portals for vCPU.
*/
void prepare_vCPU_portals()
{
_client_exc_vcpu = cap_map()->insert(Nova::NUM_INITIAL_VCPU_PT_LOG2);
}
/**
* Portal called by thread that causes a out of memory in kernel.
*/
@ -412,6 +410,7 @@ namespace Genode {
* constructor.
*/
void ep(Pager_entrypoint *ep) { _ep = ep; }
Pager_entrypoint *ep() { return _ep; }
/**
* Thread interface

View File

@ -301,32 +301,20 @@ void Pager_object::_invoke_handler(addr_t pager_obj)
addr_t const event = utcb->msg[0];
addr_t const logcount = utcb->msg[1];
/* check for translated vCPU portals */
unsigned const items_count = 1U << (Nova::NUM_INITIAL_VCPU_PT_LOG2 - 1);
/* check for translated pager portals - required for vCPU in remote PDs */
if (utcb->msg_items() == 1 && utcb->msg_words() == 1 && event == 0xaffe) {
if ((obj->_client_exc_vcpu != Native_thread::INVALID_INDEX) &&
(utcb->msg_items() == items_count) &&
(utcb->msg_words() == 1 && (event == 0UL || event == 1UL))) {
/* check all translated item and remap if valid */
for (unsigned i = 0; i < items_count; i++) {
Nova::Utcb::Item * item = utcb->get_item(i);
Nova::Utcb::Item const * const item = utcb->get_item(0);
Nova::Crd const cap(item->crd);
if (!item)
break;
Nova::Crd cap(item->crd);
if (cap.is_null() || item->is_del())
continue;
/**
* Remap portal to dense packed region - required for vCPU running
* in separate PD (non-colocated case)
*/
Obj_crd snd(cap.base(), 0);
Obj_crd rcv(obj->_client_exc_vcpu + event * items_count + i, 0);
if (map_local(utcb, snd, rcv))
warning("could not remap vCPU portal ", Hex(i));
/* valid item which got translated ? */
if (!cap.is_null() && !item->is_del()) {
using Pool = Object_pool<Pager_object>;
pager_threads[0]->ep()->Pool::apply(cap.base(),
[&] (Pager_object *source) {
/* set source PD (VMM) where vCPU exception portals are */
obj->_pd_source = source->pd_sel();
});
}
}
@ -591,10 +579,11 @@ Pager_object::Pager_object(Cpu_session_capability cpu_session_cap,
_badge(badge),
_selectors(cap_map()->insert(2)),
_client_exc_pt_sel(cap_map()->insert(NUM_INITIAL_PT_LOG2)),
_client_exc_vcpu(Native_thread::INVALID_INDEX),
_cpu_session_cap(cpu_session_cap), _thread_cap(thread_cap),
_location(location),
_exceptions(this)
_exceptions(this),
_pd_target(Native_thread::INVALID_INDEX),
_pd_source(Native_thread::INVALID_INDEX)
{
uint8_t res;
@ -681,15 +670,9 @@ Pager_object::~Pager_object()
revoke(Obj_crd(_selectors, 2));
cap_map()->remove(_selectors, 2, false);
cap_map()->remove(exc_pt_sel_client(), NUM_INITIAL_PT_LOG2, false);
if (_client_exc_vcpu == Native_thread::INVALID_INDEX)
return;
/* revoke vCPU exception portals */
revoke(Obj_crd(_client_exc_vcpu, NUM_INITIAL_VCPU_PT_LOG2));
cap_map()->remove(_client_exc_vcpu, NUM_INITIAL_VCPU_PT_LOG2, false);
}
uint8_t Pager_object::handle_oom(addr_t transfer_from,
char const * src_pd, char const * src_thread,
enum Pager_object::Policy policy)

View File

@ -62,8 +62,17 @@ int Platform_thread::start(void *ip, void *sp)
return -2;
}
if (_pager->pd_sel() != Native_thread::INVALID_INDEX) {
error("thread already started");
return -2;
}
Utcb * const utcb = reinterpret_cast<Utcb *>(Thread::myself()->utcb());
addr_t const pts = vcpu() ? NUM_INITIAL_VCPU_PT_LOG2
: NUM_INITIAL_PT_LOG2;
addr_t const pt_oom = _pager->get_oom_portal();
if (!pt_oom || map_local((Utcb *)Thread::myself()->utcb(),
if (!pt_oom || map_local(utcb,
Obj_crd(pt_oom, 0), Obj_crd(_sel_pt_oom(), 0))) {
error("setup of out-of-memory notification portal - failed");
return -8;
@ -71,7 +80,7 @@ int Platform_thread::start(void *ip, void *sp)
if (!main_thread()) {
addr_t const initial_sp = reinterpret_cast<addr_t>(sp);
addr_t const utcb = vcpu() ? 0 : round_page(initial_sp);
addr_t const utcb_addr = vcpu() ? 0 : round_page(initial_sp);
if (_sel_exc_base == Native_thread::INVALID_INDEX) {
error("exception base not specified");
@ -80,11 +89,27 @@ int Platform_thread::start(void *ip, void *sp)
_pager->assign_pd(_pd->pd_sel());
/* second++ vcpu case which runs in other pd than VMM */
if (vcpu() && _pager->pd_sel() != _pager->pd_source()) {
Obj_crd const source_initial_caps(_sel_exc_base, pts);
Obj_crd const target_initial_caps(_sel_exc_base, pts);
/* asynchronously map capabilities */
utcb->set_msg_word(0);
if (!utcb->append_item(source_initial_caps, 0))
return -3;
uint8_t res = Nova::delegate(_pager->pd_source(), _pager->pd_sel(),
target_initial_caps);
if (res != NOVA_OK)
return -3;
}
uint8_t res;
do {
unsigned const kernel_cpu_id = platform_specific()->kernel_cpu_id(_location.xpos());
res = create_ec(_sel_ec(), _pd->pd_sel(), kernel_cpu_id,
utcb, initial_sp, _sel_exc_base, !worker());
utcb_addr, initial_sp, _sel_exc_base, !worker());
if (res == Nova::NOVA_PD_OOM && Nova::NOVA_OK != _pager->handle_oom()) {
_pager->assign_pd(Native_thread::INVALID_INDEX);
error("creation of new thread failed ", res);
@ -104,24 +129,31 @@ int Platform_thread::start(void *ip, void *sp)
return 0;
}
if (_sel_exc_base != Native_thread::INVALID_INDEX) {
if (!vcpu() && _sel_exc_base != Native_thread::INVALID_INDEX) {
error("thread already started");
return -5;
}
addr_t pd_utcb = 0;
_sel_exc_base = vcpu() ? _pager->exc_pt_vcpu() : _pager->exc_pt_sel_client();
Obj_crd initial_pts;
if (!vcpu()) {
_sel_exc_base = _pager->exc_pt_sel_client();
pd_utcb = stack_area_virtual_base() + stack_virtual_size() - get_page_size();
addr_t const rights = Obj_crd::RIGHT_EC_RECALL |
Obj_crd::RIGHT_PT_CTRL | Obj_crd::RIGHT_PT_CALL |
Obj_crd::RIGHT_SM_UP | Obj_crd::RIGHT_SM_DOWN;
initial_pts = Obj_crd(_sel_exc_base, pts, rights);
addr_t remap_src[] = { _pd->parent_pt_sel(),
(unsigned long)_pager->Object_pool<Pager_object>::Entry::cap().local_name() };
addr_t remap_dst[] = { PT_SEL_PARENT, PT_SEL_MAIN_PAGER };
/* remap exception portals for first thread */
for (unsigned i = 0; i < sizeof(remap_dst)/sizeof(remap_dst[0]); i++) {
if (map_local((Utcb *)Thread::myself()->utcb(),
if (map_local(utcb,
Obj_crd(remap_src[i], 0),
Obj_crd(_sel_exc_base + remap_dst[i], 0)))
return -6;
@ -130,16 +162,12 @@ int Platform_thread::start(void *ip, void *sp)
/* create task */
addr_t const pd_sel = cap_map()->insert();
addr_t const rights = Obj_crd::RIGHT_EC_RECALL |
Obj_crd::RIGHT_PT_CTRL | Obj_crd::RIGHT_PT_CALL |
Obj_crd::RIGHT_SM_UP | Obj_crd::RIGHT_SM_DOWN;
unsigned pts = vcpu() ? NUM_INITIAL_VCPU_PT_LOG2 : NUM_INITIAL_PT_LOG2;
enum { KEEP_FREE_PAGES_NOT_AVAILABLE_FOR_UPGRADE = 2, UPPER_LIMIT_PAGES = 32 };
Obj_crd initial_pts(_sel_exc_base, pts, rights);
uint8_t res = create_pd(pd_sel, platform_specific()->core_pd_sel(),
initial_pts,
KEEP_FREE_PAGES_NOT_AVAILABLE_FOR_UPGRADE, UPPER_LIMIT_PAGES);
KEEP_FREE_PAGES_NOT_AVAILABLE_FOR_UPGRADE,
UPPER_LIMIT_PAGES);
if (res != NOVA_OK) {
error("create_pd returned ", res);
goto cleanup_pd;
@ -148,7 +176,8 @@ int Platform_thread::start(void *ip, void *sp)
/* create first thread in task */
enum { THREAD_GLOBAL = true };
res = create_ec(_sel_ec(), pd_sel,
platform_specific()->kernel_cpu_id(_location.xpos()), pd_utcb, 0, 0,
platform_specific()->kernel_cpu_id(_location.xpos()),
pd_utcb, 0, 0,
THREAD_GLOBAL);
if (res != NOVA_OK) {
error("create_ec returned ", res);
@ -165,11 +194,25 @@ int Platform_thread::start(void *ip, void *sp)
_pager->initial_esp((addr_t)sp);
_pager->assign_pd(pd_sel);
do {
/* let the thread run */
res = create_sc(_sel_sc(), pd_sel, _sel_ec(),
Qpd(Qpd::DEFAULT_QUANTUM, _priority));
} while (res == Nova::NOVA_PD_OOM && Nova::NOVA_OK == _pager->handle_oom());
if (vcpu() && _pager->pd_sel() != _pager->pd_source()) {
Obj_crd const source_initial_caps(_sel_exc_base, pts);
Obj_crd const target_initial_caps(0, pts);
/* asynchronously map capabilities */
utcb->set_msg_word(0);
res = utcb->append_item(source_initial_caps, 0);
if (res)
res = Nova::delegate(_pager->pd_source(), _pager->pd_sel(),
target_initial_caps);
}
if (res == NOVA_OK) {
do {
/* let the thread run */
res = create_sc(_sel_sc(), pd_sel, _sel_ec(),
Qpd(Qpd::DEFAULT_QUANTUM, _priority));
} while (res == Nova::NOVA_PD_OOM && Nova::NOVA_OK == _pager->handle_oom());
}
if (res != NOVA_OK) {
/*
@ -184,8 +227,9 @@ int Platform_thread::start(void *ip, void *sp)
error("create_sc returned ", res);
goto cleanup_ec;
} else
_features |= SC_CREATED;
}
_features |= SC_CREATED;
return 0;
@ -262,7 +306,7 @@ void Platform_thread::state(Thread_state s)
* s.is_vcpu If true it will run as vCPU,
* otherwise it will be a thread.
*/
if (!main_thread())
if (!main_thread() || s.vcpu)
_sel_exc_base = s.sel_exc_base;
if (!s.global_thread)
@ -273,9 +317,6 @@ void Platform_thread::state(Thread_state s)
_features |= VCPU;
if (main_thread() && _pager)
_pager->prepare_vCPU_portals();
} else {
if (!_pager) throw Cpu_thread::State_access_failed();

View File

@ -48,7 +48,7 @@ class Vmm::Vcpu_other_pd : public Vmm::Vcpu_thread
{
private:
Genode::Pd_connection _pd_session;
Genode::Capability<Genode::Pd_session> _pd_cap;
Genode::Affinity::Location _location;
Genode::Cpu_session *_cpu_session;
@ -58,9 +58,10 @@ class Vmm::Vcpu_other_pd : public Vmm::Vcpu_thread
Vcpu_other_pd(Cpu_session * cpu_session,
Genode::Affinity::Location location,
Genode::Capability<Genode::Pd_session> pd_cap,
Genode::size_t = 0 /* stack_size */)
:
_pd_session("VM"), _location(location), _cpu_session(cpu_session),
_pd_cap(pd_cap), _location(location), _cpu_session(cpu_session),
_exc_pt_sel(Genode::cap_map()->insert(Nova::NUM_INITIAL_VCPU_PT_LOG2))
{ }
@ -69,12 +70,12 @@ class Vmm::Vcpu_other_pd : public Vmm::Vcpu_thread
using namespace Genode;
Thread_capability vcpu_vm =
_cpu_session->create_thread(_pd_session, "vCPU",
_cpu_session->create_thread(_pd_cap, "vCPU",
_location, Cpu_session::Weight());
/* tell parent that this will be a vCPU */
Thread_state state;
state.sel_exc_base = Native_thread::INVALID_INDEX;
state.sel_exc_base = _exc_pt_sel;
state.vcpu = true;
Cpu_thread_client cpu_thread(vcpu_vm);
@ -88,10 +89,11 @@ class Vmm::Vcpu_other_pd : public Vmm::Vcpu_thread
Native_capability pager_cap = native_cpu.pager_cap(vcpu_vm);
/*
* Delegate parent the vCPU exception portals required during PD
* creation.
* Translate pager cap of current executing thread, which is used
* to lookup current PD - required during PD creation.
*/
delegate_vcpu_portals(pager_cap, exc_base());
translate_remote_pager(pager_cap,
Thread::myself()->native_thread().ec_sel + 1);
/* start vCPU in separate PD */
cpu_thread.start(0, 0);
@ -101,6 +103,9 @@ class Vmm::Vcpu_other_pd : public Vmm::Vcpu_thread
* SM cap - see Vcpu_dispatcher->sel_sm_ec description
*/
request_native_ec_cap(pager_cap, sel_ec);
/* request creation of SC to let vCPU run */
cpu_thread.resume();
}
Genode::addr_t exc_base() { return _exc_pt_sel; }
@ -115,6 +120,7 @@ class Vmm::Vcpu_same_pd : public Vmm::Vcpu_thread, Genode::Thread
Vcpu_same_pd(Cpu_session * cpu_session,
Genode::Affinity::Location location,
Genode::Capability<Genode::Pd_session>,
Genode::size_t stack_size)
:
Thread(WEIGHT, "vCPU", stack_size, Type::NORMAL, cpu_session, location)

View File

@ -34,9 +34,9 @@ append qemu_args " -m 512 "
append qemu_args " -cpu phenom "
append qemu_args " -nographic "
run_genode_until {.*VMM: vcpu_s_1 _svm_startup called.*\n} 30
run_genode_until {.*VMM: vcpu_s_2 _svm_startup called.*\n} 10 [output_spawn_id]
run_genode_until {.*VMM: vcpu_o_1 _svm_startup called.*\n} 10 [output_spawn_id]
run_genode_until {.*VMM: vcpu_o_2 _svm_startup called.*\n} 10 [output_spawn_id]
run_genode_until {.*VMM: vcpu_s_1 _vcpu_startup called.*\n} 30
run_genode_until {.*VMM: vcpu_s_2 _vcpu_startup called.*\n} 10 [output_spawn_id]
run_genode_until {.*VMM: vcpu_o_1 _vcpu_startup called.*\n} 10 [output_spawn_id]
run_genode_until {.*VMM: vcpu_o_2 _vcpu_startup called.*\n} 10 [output_spawn_id]
puts "Test succeeded"

View File

@ -862,6 +862,7 @@ class Machine : public StaticReceiver<Machine>
Guest_memory &_guest_memory;
Boot_module_provider &_boot_modules;
Alarm_thread *_alarm_thread;
Genode::Pd_connection *_pd_vcpus = nullptr;
bool _alloc_fb_mem; /* For detecting FB alloc message */
bool _colocate_vm_vmm;
@ -949,9 +950,13 @@ class Machine : public StaticReceiver<Machine>
Vmm::Vcpu_thread * vcpu_thread;
if (_colocate_vm_vmm)
vcpu_thread = new Vmm::Vcpu_same_pd(cpu_session, location, Vcpu_dispatcher::STACK_SIZE);
else
vcpu_thread = new Vmm::Vcpu_other_pd(cpu_session, location);
vcpu_thread = new Vmm::Vcpu_same_pd(cpu_session, location, _env.pd_session_cap(), Vcpu_dispatcher::STACK_SIZE);
else {
if (!_pd_vcpus)
_pd_vcpus = new Genode::Pd_connection("VM");
vcpu_thread = new Vmm::Vcpu_other_pd(cpu_session, location, *_pd_vcpus);
}
Vcpu_dispatcher *vcpu_dispatcher =
new Vcpu_dispatcher(_motherboard_lock,

View File

@ -46,21 +46,23 @@ class Vcpu_dispatcher : public Vmm::Vcpu_dispatcher<Genode::Thread>
** Virtualization event handlers **
***********************************/
void _svm_startup()
void _vcpu_startup()
{
Vmm::log(name(), " _svm_startup called");
Vmm::log(name(), " ", __func__, " called");
}
public:
enum Type { SVM, VTX };
Vcpu_dispatcher(Genode::Env &env, Type type, char const * name)
Vcpu_dispatcher(Genode::Env &env, Type type, char const * name,
Genode::Capability<Genode::Pd_session> pd_cap)
:
Vmm::Vcpu_dispatcher<Genode::Thread>(env, STACK_SIZE, &env.cpu(),
Genode::Affinity::Location(),
name),
_vcpu_thread(&env.cpu(), Genode::Affinity::Location(), STACK_SIZE)
_vcpu_thread(&env.cpu(), Genode::Affinity::Location(), pd_cap,
STACK_SIZE)
{
using namespace Nova;
@ -73,7 +75,7 @@ class Vcpu_dispatcher : public Vmm::Vcpu_dispatcher<Genode::Thread>
/* register virtualization event handlers */
if (type == SVM) {
_register_handler<0xfe, &This::_svm_startup>
_register_handler<0xfe, &This::_vcpu_startup>
(exc_base, mtd_all);
}
@ -87,11 +89,12 @@ void Component::construct(Genode::Env &env)
{
typedef Vcpu_dispatcher<Vmm::Vcpu_same_pd> Vcpu_s;
static Vcpu_s vcpu_s_1(env, Vcpu_s::SVM, "vcpu_s_1");
static Vcpu_s vcpu_s_2(env, Vcpu_s::SVM, "vcpu_s_2");
static Vcpu_s vcpu_s_1(env, Vcpu_s::SVM, "vcpu_s_1", env.pd_session_cap());
static Vcpu_s vcpu_s_2(env, Vcpu_s::SVM, "vcpu_s_2", env.pd_session_cap());
typedef Vcpu_dispatcher<Vmm::Vcpu_other_pd> Vcpu_o;
static Vcpu_o vcpu_o_1(env, Vcpu_o::SVM, "vcpu_o_1");
static Vcpu_o vcpu_o_2(env, Vcpu_o::SVM, "vcpu_o_2");
static Genode::Pd_connection remote_pd("VM");
static Vcpu_o vcpu_o_1(env, Vcpu_o::SVM, "vcpu_o_1", remote_pd);
static Vcpu_o vcpu_o_2(env, Vcpu_o::SVM, "vcpu_o_2", remote_pd);
}

View File

@ -299,19 +299,21 @@ bool create_emt_vcpu(pthread_t * pthread, size_t stack,
if (!hip->has_feature_vmx() && !hip->has_feature_svm())
return false;
static Genode::Pd_connection pd_vcpus("VM");
Vcpu_handler *vcpu_handler = 0;
if (hip->has_feature_vmx())
vcpu_handler = new (0x10) Vcpu_handler_vmx(genode_env(),
stack, attr, start_routine,
arg, cpu_session, location,
cpu_id, name);
cpu_id, name, pd_vcpus);
if (hip->has_feature_svm())
vcpu_handler = new (0x10) Vcpu_handler_svm(genode_env(),
stack, attr, start_routine,
arg, cpu_session, location,
cpu_id, name);
cpu_id, name, pd_vcpus);
Assert(!(reinterpret_cast<unsigned long>(vcpu_handler) & 0xf));

View File

@ -762,12 +762,13 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher<pthread>,
void *(*start_routine) (void *), void *arg,
Genode::Cpu_session * cpu_session,
Genode::Affinity::Location location,
unsigned int cpu_id, const char * name)
unsigned int cpu_id, const char * name,
Genode::Pd_session_capability pd_vcpu)
:
Vmm::Vcpu_dispatcher<pthread>(env, stack_size, cpu_session, location,
attr ? *attr : 0, start_routine, arg,
name),
_vcpu(cpu_session, location),
_vcpu(cpu_session, location, pd_vcpu),
_ec_sel(Genode::cap_map()->insert()),
_irq_win(false),
_cpu_id(cpu_id)

View File

@ -88,10 +88,11 @@ class Vcpu_handler_svm : public Vcpu_handler
void *(*start_routine) (void *), void *arg,
Genode::Cpu_session * cpu_session,
Genode::Affinity::Location location,
unsigned int cpu_id, const char * name)
unsigned int cpu_id, const char * name,
Genode::Pd_session_capability pd_vcpu)
:
Vcpu_handler(env, stack_size, attr, start_routine, arg, cpu_session,
location, cpu_id, name)
location, cpu_id, name, pd_vcpu)
{
using namespace Nova;

View File

@ -162,10 +162,11 @@ class Vcpu_handler_vmx : public Vcpu_handler
void *(*start_routine) (void *), void *arg,
Genode::Cpu_session * cpu_session,
Genode::Affinity::Location location,
unsigned int cpu_id, const char * name)
unsigned int cpu_id, const char * name,
Genode::Pd_session_capability pd_vcpu)
:
Vcpu_handler(env, stack_size, attr, start_routine, arg, cpu_session,
location, cpu_id, name)
location, cpu_id, name, pd_vcpu)
{
using namespace Nova;

View File

@ -560,19 +560,21 @@ bool create_emt_vcpu(pthread_t * pthread, ::size_t stack,
if (!hip->has_feature_vmx() && !hip->has_feature_svm())
return false;
static Genode::Pd_connection pd_vcpus("VM");
Vcpu_handler *vcpu_handler = 0;
if (hip->has_feature_vmx())
vcpu_handler = new (0x10) Vcpu_handler_vmx(genode_env(),
stack, attr, start_routine,
arg, cpu_session, location,
cpu_id, name);
cpu_id, name, pd_vcpus);
if (hip->has_feature_svm())
vcpu_handler = new (0x10) Vcpu_handler_svm(genode_env(),
stack, attr, start_routine,
arg, cpu_session, location,
cpu_id, name);
cpu_id, name, pd_vcpus);
Assert(!(reinterpret_cast<unsigned long>(vcpu_handler) & 0xf));

View File

@ -765,12 +765,13 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher<pthread>,
void *(*start_routine) (void *), void *arg,
Genode::Cpu_session * cpu_session,
Genode::Affinity::Location location,
unsigned int cpu_id, const char * name)
unsigned int cpu_id, const char * name,
Genode::Pd_session_capability pd_vcpu)
:
Vmm::Vcpu_dispatcher<pthread>(env, stack_size, cpu_session, location,
attr ? *attr : 0, start_routine, arg,
name),
_vcpu(cpu_session, location),
_vcpu(cpu_session, location, pd_vcpu),
_ec_sel(Genode::cap_map()->insert()),
_irq_win(false),
_cpu_id(cpu_id)

View File

@ -88,10 +88,11 @@ class Vcpu_handler_svm : public Vcpu_handler
void *(*start_routine) (void *), void *arg,
Genode::Cpu_session * cpu_session,
Genode::Affinity::Location location,
unsigned int cpu_id, const char * name)
unsigned int cpu_id, const char * name,
Genode::Pd_session_capability pd_vcpu)
:
Vcpu_handler(env, stack_size, attr, start_routine, arg, cpu_session,
location, cpu_id, name)
location, cpu_id, name, pd_vcpu)
{
using namespace Nova;

View File

@ -170,10 +170,11 @@ class Vcpu_handler_vmx : public Vcpu_handler
void *(*start_routine) (void *), void *arg,
Genode::Cpu_session * cpu_session,
Genode::Affinity::Location location,
unsigned int cpu_id, const char * name)
unsigned int cpu_id, const char * name,
Genode::Pd_session_capability pd_vcpu)
:
Vcpu_handler(env, stack_size, attr, start_routine, arg, cpu_session,
location, cpu_id, name)
location, cpu_id, name, pd_vcpu)
{
using namespace Nova;