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(Dataspace_capability, addr_t, Attach_attr) override;
void attach_pic(addr_t) override { } void attach_pic(addr_t) override { }
void detach(addr_t, size_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_ */ #endif /* _CORE__VM_SESSION_COMPONENT_H_ */

View File

@ -107,10 +107,12 @@ Vcpu::~Vcpu()
_ram_alloc.free(_ds_cap); _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()) if (!cap.valid())
return; return ret;
auto lambda = [&] (Cpu_thread_component *thread) { auto lambda = [&] (Cpu_thread_component *thread) {
if (!thread) if (!thread)
@ -146,10 +148,11 @@ void Vm_session_component::_create_vcpu(Thread_capability cap)
} }
_vcpus.insert(vcpu); _vcpus.insert(vcpu);
_id_alloc++; ret.id = _id_alloc++;
}; };
_ep.apply(cap, lambda); _ep.apply(cap, lambda);
return ret;
} }
Dataspace_capability Vm_session_component::_cpu_state(Vcpu_id const vcpu_id) 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; struct Vcpu;
static Genode::Registry<Genode::Registered<Vcpu> > vcpus; static Genode::Registry<Genode::Registered<Vcpu> > vcpus;
static unsigned vcpu_id = 0;
struct Vcpu : Genode::Thread struct Vcpu : Genode::Thread
{ {
@ -202,7 +201,7 @@ struct Vcpu : Genode::Thread
Semaphore _wake_up { 0 }; Semaphore _wake_up { 0 };
Semaphore &_handler_ready; Semaphore &_handler_ready;
Allocator &_alloc; 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 _state { 0 };
addr_t _task { 0 }; addr_t _task { 0 };
enum Virt const _vm_type; enum Virt const _vm_type;
@ -1184,20 +1183,20 @@ struct Vcpu : Genode::Thread
public: public:
Vcpu(Env &env, Signal_context_capability &cap, Vcpu(Env &env, Signal_context_capability &cap,
Semaphore &handler_ready, Semaphore &handler_ready, enum Virt type,
Vm_session_client::Vcpu_id &id, enum Virt type,
Allocator &alloc, Affinity::Location location) Allocator &alloc, Affinity::Location location)
: :
Thread(env, "vcpu_thread", STACK_SIZE, location, Weight(), env.cpu()), Thread(env, "vcpu_thread", STACK_SIZE, location, Weight(), env.cpu()),
_signal(cap), _handler_ready(handler_ready), _alloc(alloc), _signal(cap), _handler_ready(handler_ready), _alloc(alloc),
_id(id), _vm_type(type) _vm_type(type)
{ } { }
Allocator &allocator() const { return _alloc; } Allocator &allocator() const { return _alloc; }
bool match(Vm_session_client::Vcpu_id id) { return id.id == _id.id; } 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) 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_session_client::create_vcpu(Allocator &alloc, Env &env,
Vm_handler_base &handler) Vm_handler_base &handler)
{ {
Vm_session_client::Vcpu_id id = { vcpu_id };
enum Virt vm_type = virt_type(env); enum Virt vm_type = virt_type(env);
if (vm_type == Virt::UNKNOWN) { if (vm_type == Virt::UNKNOWN) {
Genode::error("unsupported hardware virtualisation"); Genode::error("unsupported hardware virtualisation");
return id; return Vm_session::Vcpu_id();
} }
Thread * ep = reinterpret_cast<Thread *>(&handler._rpc_ep); 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 */ /* create thread that switches modes between thread/cpu */
Vcpu * vcpu = new (alloc) Registered<Vcpu>(vcpus, env, handler._cap, Vcpu * vcpu = new (alloc) Registered<Vcpu>(vcpus, env, handler._cap,
handler._done, id, vm_type, handler._done, vm_type,
alloc, location); alloc, location);
try { try {
/* now it gets actually valid - vcpu->cap() becomes valid */ /* now it gets actually valid - vcpu->cap() becomes valid */
vcpu->start(); vcpu->start();
call<Rpc_exception_handler>(handler._cap, vcpu->id());
/* instruct core to let it become a vCPU */ /* 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())); vcpu->assign_ds_state(env.rm(), call<Rpc_cpu_state>(vcpu->id()));
} catch (...) { } catch (...) {
@ -1299,9 +1296,7 @@ Vm_session_client::create_vcpu(Allocator &alloc, Env &env,
destroy(alloc, vcpu); destroy(alloc, vcpu);
throw; throw;
} }
return vcpu->id();
vcpu_id ++;
return id;
} }
void Vm_session_client::run(Vcpu_id 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(Dataspace_capability, addr_t, Attach_attr) override;
void attach_pic(addr_t) override; void attach_pic(addr_t) override;
void detach(addr_t, size_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_ */ #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 { void detach(addr_t /* vm_addr */, size_t /* size */) override {
warning("Not implemented for TrustZone case"); } 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_ */ #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(Dataspace_capability, addr_t, Attach_attr) override { }
void attach_pic(addr_t) override { } void attach_pic(addr_t) override { }
void detach(addr_t, size_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_ */ #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(); addr_t new_pt_id();
Vcpu_id id() { return _id; }
bool match(Vcpu_id const id) const { return id.id == _id.id; } bool match(Vcpu_id const id) const { return id.id == _id.id; }
Ram_dataspace_capability ds_cap() const { return _ds_cap; } 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(Dataspace_capability, addr_t, Attach_attr) override;
void attach_pic(addr_t) override {} void attach_pic(addr_t) override {}
void detach(addr_t, size_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_ */ #endif /* _CORE__VM_SESSION_COMPONENT_H_ */

View File

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

View File

@ -29,7 +29,6 @@ using namespace Genode;
struct Vcpu; struct Vcpu;
static Genode::Registry<Genode::Registered<Vcpu> > vcpus; static Genode::Registry<Genode::Registered<Vcpu> > vcpus;
static unsigned vcpu_id = 0;
struct Vcpu { struct Vcpu {
@ -425,8 +424,9 @@ struct Vcpu {
public: public:
Vcpu(Vm_handler_base &o, unsigned id, Allocator &alloc) Vcpu(Vm_handler_base &o, Vm_session::Vcpu_id const id,
: _obj(o), _alloc(alloc), _id({id}) { } Allocator &alloc)
: _obj(o), _alloc(alloc), _id(id) { }
virtual ~Vcpu() { } virtual ~Vcpu() { }
@ -703,9 +703,10 @@ Vm_session_client::create_vcpu(Allocator &alloc, Env &env,
Vm_handler_base &handler) Vm_handler_base &handler)
{ {
Thread * ep = reinterpret_cast<Thread *>(&handler._rpc_ep); 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())); vcpu->assign_ds_state(env.rm(), call<Rpc_cpu_state>(vcpu->id()));
Signal_context_capability dontcare_exit; 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(Dataspace_capability, addr_t, Attach_attr) override;
void attach_pic(addr_t) override {} void attach_pic(addr_t) override {}
void detach(addr_t, size_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_ */ #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); 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()) if (!cap.valid())
return; return ret;
auto lambda = [&] (Cpu_thread_component *thread) { auto lambda = [&] (Cpu_thread_component *thread) {
if (!thread) if (!thread)
@ -218,10 +220,11 @@ void Vm_session_component::_create_vcpu(Thread_capability cap)
} }
_vcpus.insert(vcpu); _vcpus.insert(vcpu);
_id_alloc++; ret.id = _id_alloc++;
}; };
_ep.apply(cap, lambda); _ep.apply(cap, lambda);
return ret;
} }
Dataspace_capability Vm_session_component::_cpu_state(Vcpu_id const vcpu_id) Dataspace_capability Vm_session_component::_cpu_state(Vcpu_id const vcpu_id)

View File

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

View File

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

View File

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