vm_session: return vcpu id when creating vcpu

Ref #3553
This commit is contained in:
Stefan Kalkowski 2019-11-08 13:47:35 +01:00 committed by Norman Feske
parent 02d68fdb97
commit f82714f341
14 changed files with 63 additions and 55 deletions

View File

@ -108,7 +108,7 @@ class Genode::Vm_session_component
void attach(Dataspace_capability, addr_t, Attach_attr) override;
void attach_pic(addr_t) override { }
void detach(addr_t, size_t) override;
void _create_vcpu(Thread_capability);
Vcpu_id _create_vcpu(Thread_capability);
};
#endif /* _CORE__VM_SESSION_COMPONENT_H_ */

View File

@ -107,10 +107,12 @@ Vcpu::~Vcpu()
_ram_alloc.free(_ds_cap);
}
void Vm_session_component::_create_vcpu(Thread_capability cap)
Vm_session::Vcpu_id Vm_session_component::_create_vcpu(Thread_capability cap)
{
Vcpu_id ret;
if (!cap.valid())
return;
return ret;
auto lambda = [&] (Cpu_thread_component *thread) {
if (!thread)
@ -146,10 +148,11 @@ void Vm_session_component::_create_vcpu(Thread_capability cap)
}
_vcpus.insert(vcpu);
_id_alloc++;
ret.id = _id_alloc++;
};
_ep.apply(cap, lambda);
return ret;
}
Dataspace_capability Vm_session_component::_cpu_state(Vcpu_id const vcpu_id)

View File

@ -50,7 +50,6 @@ static bool svm_np() { return svm_features() & (1U << 0); }
struct Vcpu;
static Genode::Registry<Genode::Registered<Vcpu> > vcpus;
static unsigned vcpu_id = 0;
struct Vcpu : Genode::Thread
{
@ -202,7 +201,7 @@ struct Vcpu : Genode::Thread
Semaphore _wake_up { 0 };
Semaphore &_handler_ready;
Allocator &_alloc;
Vm_session_client::Vcpu_id _id;
Vm_session_client::Vcpu_id _id { Vm_session_client::Vcpu_id::INVALID };
addr_t _state { 0 };
addr_t _task { 0 };
enum Virt const _vm_type;
@ -1184,20 +1183,20 @@ struct Vcpu : Genode::Thread
public:
Vcpu(Env &env, Signal_context_capability &cap,
Semaphore &handler_ready,
Vm_session_client::Vcpu_id &id, enum Virt type,
Semaphore &handler_ready, enum Virt type,
Allocator &alloc, Affinity::Location location)
:
Thread(env, "vcpu_thread", STACK_SIZE, location, Weight(), env.cpu()),
_signal(cap), _handler_ready(handler_ready), _alloc(alloc),
_id(id), _vm_type(type)
_vm_type(type)
{ }
Allocator &allocator() const { return _alloc; }
bool match(Vm_session_client::Vcpu_id id) { return id.id == _id.id; }
Genode::Vm_session_client::Vcpu_id id() const { return _id; }
Genode::Vm_session_client::Vcpu_id id() const { return _id; }
void id(Genode::Vm_session_client::Vcpu_id id) { _id = id; }
void assign_ds_state(Region_map &rm, Dataspace_capability cap)
{
@ -1266,12 +1265,10 @@ Vm_session_client::Vcpu_id
Vm_session_client::create_vcpu(Allocator &alloc, Env &env,
Vm_handler_base &handler)
{
Vm_session_client::Vcpu_id id = { vcpu_id };
enum Virt vm_type = virt_type(env);
if (vm_type == Virt::UNKNOWN) {
Genode::error("unsupported hardware virtualisation");
return id;
return Vm_session::Vcpu_id();
}
Thread * ep = reinterpret_cast<Thread *>(&handler._rpc_ep);
@ -1279,17 +1276,17 @@ Vm_session_client::create_vcpu(Allocator &alloc, Env &env,
/* create thread that switches modes between thread/cpu */
Vcpu * vcpu = new (alloc) Registered<Vcpu>(vcpus, env, handler._cap,
handler._done, id, vm_type,
handler._done, vm_type,
alloc, location);
try {
/* now it gets actually valid - vcpu->cap() becomes valid */
vcpu->start();
call<Rpc_exception_handler>(handler._cap, vcpu->id());
/* instruct core to let it become a vCPU */
call<Rpc_create_vcpu>(vcpu->cap());
vcpu->id(call<Rpc_create_vcpu>(vcpu->cap()));
call<Rpc_exception_handler>(handler._cap, vcpu->id());
vcpu->assign_ds_state(env.rm(), call<Rpc_cpu_state>(vcpu->id()));
} catch (...) {
@ -1299,9 +1296,7 @@ Vm_session_client::create_vcpu(Allocator &alloc, Env &env,
destroy(alloc, vcpu);
throw;
}
vcpu_id ++;
return id;
return vcpu->id();
}
void Vm_session_client::run(Vcpu_id vcpu_id)

View File

@ -111,7 +111,7 @@ class Genode::Vm_session_component
void attach(Dataspace_capability, addr_t, Attach_attr) override;
void attach_pic(addr_t) override;
void detach(addr_t, size_t) override;
void _create_vcpu(Thread_capability) {}
Vcpu_id _create_vcpu(Thread_capability) { return 0; }
};
#endif /* _CORE__SPEC__ARM_V7__VIRTUALIZATION__VM_SESSION_COMPONENT_H_ */

View File

@ -89,7 +89,7 @@ class Genode::Vm_session_component
void detach(addr_t /* vm_addr */, size_t /* size */) override {
warning("Not implemented for TrustZone case"); }
void _create_vcpu(Thread_capability) {}
unsigned _create_vcpu(Thread_capability) { return 0; }
};
#endif /* _CORE__SPEC__ARM_V7__TRUSTZONE__VM_SESSION_COMPONENT_H_ */

View File

@ -82,7 +82,7 @@ class Genode::Vm_session_component
void attach(Dataspace_capability, addr_t, Attach_attr) override { }
void attach_pic(addr_t) override { }
void detach(addr_t, size_t) override { }
void _create_vcpu(Thread_capability) { }
Vcpu_id _create_vcpu(Thread_capability) { return 0; }
};
#endif /* _CORE__SPEC__X86_64__MUEN__VM_SESSION_COMPONENT_H_ */

View File

@ -78,6 +78,7 @@ class Genode::Vm_session_component
addr_t new_pt_id();
Vcpu_id id() { return _id; }
bool match(Vcpu_id const id) const { return id.id == _id.id; }
Ram_dataspace_capability ds_cap() const { return _ds_cap; }
@ -180,7 +181,7 @@ class Genode::Vm_session_component
void attach(Dataspace_capability, addr_t, Attach_attr) override;
void attach_pic(addr_t) override {}
void detach(addr_t, size_t) override;
void _create_vcpu(Thread_capability);
Vcpu_id _create_vcpu(Thread_capability);
};
#endif /* _CORE__VM_SESSION_COMPONENT_H_ */

View File

@ -33,6 +33,7 @@
using Genode::addr_t;
using Genode::Vm_session_component;
using Vcpu_id = Genode::Vm_session::Vcpu_id;
enum { CAP_RANGE_LOG2 = 2, CAP_RANGE = 1 << CAP_RANGE_LOG2 };
@ -153,10 +154,10 @@ static Genode::uint8_t _with_kernel_quota_upgrade(addr_t const pd_target,
return res;
}
void Vm_session_component::_create_vcpu(Thread_capability cap)
Vcpu_id Vm_session_component::_create_vcpu(Thread_capability cap)
{
if (!cap.valid())
return;
Vcpu_id ret;
if (!cap.valid()) return ret;
/* lookup vmm pd and cpu location of handler thread in VMM */
addr_t kernel_cpu_id = 0;
@ -178,7 +179,7 @@ void Vm_session_component::_create_vcpu(Thread_capability cap)
/* if VMM pd lookup failed then deny to create vCPU */
if (!vmm_pd_sel || vmm_pd_sel == Vcpu::invalid())
return;
return ret;
/* allocate vCPU object */
Vcpu &vcpu = *new (_heap) Vcpu(_constrained_md_ram_alloc,
@ -191,7 +192,7 @@ void Vm_session_component::_create_vcpu(Thread_capability cap)
/* we ran out of caps in core */
if (!vcpu.ds_cap().valid())
return;
return ret;
/* core PD selector */
addr_t const core_pd = platform_specific().core_pd_sel();
@ -204,7 +205,7 @@ void Vm_session_component::_create_vcpu(Thread_capability cap)
if (res != Nova::NOVA_OK) {
error("create_sm = ", res);
destroy(_heap, &vcpu);
return;
return ret;
}
addr_t const event_base = (1U << Nova::NUM_INITIAL_VCPU_PT_LOG2) * _id_alloc;
@ -217,7 +218,7 @@ void Vm_session_component::_create_vcpu(Thread_capability cap)
if (res != Nova::NOVA_OK) {
error("create_ec = ", res);
destroy(_heap, &vcpu);
return;
return ret;
}
addr_t const dst_sm_ec_sel = Nova::NUM_INITIAL_PT_RESERVED
@ -239,11 +240,12 @@ void Vm_session_component::_create_vcpu(Thread_capability cap)
{
error("map sm ", res, " ", _id_alloc);
destroy(_heap, &vcpu);
return;
return ret;
}
_id_alloc++;
_vcpus.insert(&vcpu);
_id_alloc++;
return vcpu.id();
}
void Vm_session_component::_run(Vcpu_id const vcpu_id)

View File

@ -29,7 +29,6 @@ using namespace Genode;
struct Vcpu;
static Genode::Registry<Genode::Registered<Vcpu> > vcpus;
static unsigned vcpu_id = 0;
struct Vcpu {
@ -425,8 +424,9 @@ struct Vcpu {
public:
Vcpu(Vm_handler_base &o, unsigned id, Allocator &alloc)
: _obj(o), _alloc(alloc), _id({id}) { }
Vcpu(Vm_handler_base &o, Vm_session::Vcpu_id const id,
Allocator &alloc)
: _obj(o), _alloc(alloc), _id(id) { }
virtual ~Vcpu() { }
@ -703,9 +703,10 @@ Vm_session_client::create_vcpu(Allocator &alloc, Env &env,
Vm_handler_base &handler)
{
Thread * ep = reinterpret_cast<Thread *>(&handler._rpc_ep);
call<Rpc_create_vcpu>(ep->cap());
Vcpu * vcpu = new (alloc) Registered<Vcpu> (vcpus, handler, vcpu_id++, alloc);
Vcpu * vcpu = new (alloc) Registered<Vcpu> (vcpus, handler,
call<Rpc_create_vcpu>(ep->cap()),
alloc);
vcpu->assign_ds_state(env.rm(), call<Rpc_cpu_state>(vcpu->id()));
Signal_context_capability dontcare_exit;

View File

@ -121,7 +121,7 @@ class Genode::Vm_session_component
void attach(Dataspace_capability, addr_t, Attach_attr) override;
void attach_pic(addr_t) override {}
void detach(addr_t, size_t) override;
void _create_vcpu(Thread_capability);
Vcpu_id _create_vcpu(Thread_capability);
};
#endif /* _CORE__VM_SESSION_COMPONENT_H_ */

View File

@ -177,10 +177,12 @@ Vm_session_component::~Vm_session_component()
Platform_pd::pd_id_alloc().free(_pd_id);
}
void Vm_session_component::_create_vcpu(Thread_capability cap)
Vm_session::Vcpu_id Vm_session_component::_create_vcpu(Thread_capability cap)
{
Vcpu_id ret;
if (!cap.valid())
return;
return ret;
auto lambda = [&] (Cpu_thread_component *thread) {
if (!thread)
@ -218,10 +220,11 @@ void Vm_session_component::_create_vcpu(Thread_capability cap)
}
_vcpus.insert(vcpu);
_id_alloc++;
ret.id = _id_alloc++;
};
_ep.apply(cap, lambda);
return ret;
}
Dataspace_capability Vm_session_component::_cpu_state(Vcpu_id const vcpu_id)

View File

@ -32,7 +32,6 @@ using namespace Genode;
struct Vcpu;
static Genode::Registry<Genode::Registered<Vcpu> > vcpus;
static unsigned vcpu_id = 0;
struct Vcpu : Genode::Thread
{
@ -43,7 +42,7 @@ struct Vcpu : Genode::Thread
Semaphore &_handler_ready;
Allocator &_alloc;
Lock _startup { Genode::Lock::LOCKED };
Vm_session_client::Vcpu_id _id;
Vm_session_client::Vcpu_id _id {};
addr_t _state { 0 };
addr_t _recall { 0 };
uint64_t _tsc_offset { 0 };
@ -713,12 +712,12 @@ struct Vcpu : Genode::Thread
public:
Vcpu(Genode::Env &env, Genode::Signal_context_capability &cap,
Semaphore &handler_ready, unsigned id, Allocator &alloc,
Semaphore &handler_ready, Allocator &alloc,
Affinity::Location &location)
:
Thread(env, "vcpu_thread", STACK_SIZE, location, Weight(), env.cpu()),
_signal(cap),
_handler_ready(handler_ready), _alloc(alloc), _id({id})
_handler_ready(handler_ready), _alloc(alloc)
{ }
Allocator &allocator() { return _alloc; }
@ -728,7 +727,8 @@ struct Vcpu : Genode::Thread
_startup.lock();
}
Genode::Vm_session_client::Vcpu_id id() const { return _id; }
Genode::Vm_session_client::Vcpu_id id() const { return _id; }
void id(Genode::Vm_session_client::Vcpu_id id) { _id = id; }
void assign_ds_state(Region_map &rm, Dataspace_capability cap) {
_state = rm.attach(cap); }
@ -775,7 +775,7 @@ Genode::Vm_session_client::create_vcpu(Allocator &alloc, Env &env,
Vcpu * vcpu = new (alloc) Genode::Registered<Vcpu> (vcpus, env,
handler._cap,
handler._done,
vcpu_id, alloc,
alloc,
location);
try {
@ -783,8 +783,8 @@ Genode::Vm_session_client::create_vcpu(Allocator &alloc, Env &env,
vcpu->start();
/* instruct core to let it become a vCPU */
vcpu->id(call<Rpc_create_vcpu>(vcpu->cap()));
call<Rpc_exception_handler>(handler._cap, vcpu->id());
call<Rpc_create_vcpu>(vcpu->cap());
vcpu->assign_ds_state(env.rm(), call<Rpc_cpu_state>(vcpu->id()));
} catch (...) {
@ -794,7 +794,6 @@ Genode::Vm_session_client::create_vcpu(Allocator &alloc, Env &env,
vcpu->initial_resume();
vcpu_id++;
return vcpu->id();
}

View File

@ -27,7 +27,12 @@ struct Genode::Vm_session : Session
{
static const char *service_name() { return "VM"; }
struct Vcpu_id { unsigned id; };
struct Vcpu_id
{
enum { INVALID = ~0U };
unsigned id { INVALID };
};
struct Attach_attr
{
addr_t offset;
@ -88,7 +93,7 @@ struct Genode::Vm_session : Session
Dataspace_capability, addr_t, Attach_attr);
GENODE_RPC(Rpc_detach, void, detach, addr_t, size_t);
GENODE_RPC(Rpc_attach_pic, void, attach_pic, addr_t);
GENODE_RPC_THROW(Rpc_create_vcpu, void, _create_vcpu,
GENODE_RPC_THROW(Rpc_create_vcpu, Vcpu_id, _create_vcpu,
GENODE_TYPE_LIST(Out_of_ram, Out_of_caps),
Thread_capability);

View File

@ -18,9 +18,8 @@ using namespace Genode;
Vm_session::Vcpu_id
Vm_session_client::create_vcpu(Allocator &, Env &, Vm_handler_base &handler)
{
Vcpu_id vcpu_id { 0 };
call<Rpc_create_vcpu>(Thread_capability());
Thread * ep = reinterpret_cast<Thread *>(&handler._rpc_ep);
Vcpu_id vcpu_id { call<Rpc_create_vcpu>(ep->cap()) };
call<Rpc_exception_handler>(handler._cap, vcpu_id);
return vcpu_id;
}