diff --git a/repos/base-foc/src/core/include/vm_session_component.h b/repos/base-foc/src/core/include/vm_session_component.h index 8757aa98f..b0408087c 100644 --- a/repos/base-foc/src/core/include/vm_session_component.h +++ b/repos/base-foc/src/core/include/vm_session_component.h @@ -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_ */ diff --git a/repos/base-foc/src/core/vm_session_component.cc b/repos/base-foc/src/core/vm_session_component.cc index 7e9cbe7fb..cc0dc5587 100644 --- a/repos/base-foc/src/core/vm_session_component.cc +++ b/repos/base-foc/src/core/vm_session_component.cc @@ -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) diff --git a/repos/base-foc/src/lib/base/x86/vm_session.cc b/repos/base-foc/src/lib/base/x86/vm_session.cc index 5de6c8f69..5911003ae 100644 --- a/repos/base-foc/src/lib/base/x86/vm_session.cc +++ b/repos/base-foc/src/lib/base/x86/vm_session.cc @@ -50,7 +50,6 @@ static bool svm_np() { return svm_features() & (1U << 0); } struct Vcpu; static Genode::Registry > 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(&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(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(handler._cap, vcpu->id()); - /* instruct core to let it become a vCPU */ - call(vcpu->cap()); + vcpu->id(call(vcpu->cap())); + + call(handler._cap, vcpu->id()); vcpu->assign_ds_state(env.rm(), call(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) diff --git a/repos/base-hw/src/core/spec/arm/virtualization/vm_session_component.h b/repos/base-hw/src/core/spec/arm/virtualization/vm_session_component.h index b87010682..6d507d2e1 100644 --- a/repos/base-hw/src/core/spec/arm/virtualization/vm_session_component.h +++ b/repos/base-hw/src/core/spec/arm/virtualization/vm_session_component.h @@ -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_ */ diff --git a/repos/base-hw/src/core/spec/arm_v7/trustzone/vm_session_component.h b/repos/base-hw/src/core/spec/arm_v7/trustzone/vm_session_component.h index c133fb29c..e8ea2e3af 100644 --- a/repos/base-hw/src/core/spec/arm_v7/trustzone/vm_session_component.h +++ b/repos/base-hw/src/core/spec/arm_v7/trustzone/vm_session_component.h @@ -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_ */ diff --git a/repos/base-hw/src/core/spec/x86_64/muen/vm_session_component.h b/repos/base-hw/src/core/spec/x86_64/muen/vm_session_component.h index c4319ffd2..1e66a43e0 100644 --- a/repos/base-hw/src/core/spec/x86_64/muen/vm_session_component.h +++ b/repos/base-hw/src/core/spec/x86_64/muen/vm_session_component.h @@ -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_ */ diff --git a/repos/base-nova/src/core/include/vm_session_component.h b/repos/base-nova/src/core/include/vm_session_component.h index 3a9673a8f..748d0397f 100644 --- a/repos/base-nova/src/core/include/vm_session_component.h +++ b/repos/base-nova/src/core/include/vm_session_component.h @@ -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_ */ diff --git a/repos/base-nova/src/core/vm_session_component.cc b/repos/base-nova/src/core/vm_session_component.cc index 55f6c91f2..f801f5890 100644 --- a/repos/base-nova/src/core/vm_session_component.cc +++ b/repos/base-nova/src/core/vm_session_component.cc @@ -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) diff --git a/repos/base-nova/src/lib/base/vm_session.cc b/repos/base-nova/src/lib/base/vm_session.cc index 30daf44ca..922260cbd 100644 --- a/repos/base-nova/src/lib/base/vm_session.cc +++ b/repos/base-nova/src/lib/base/vm_session.cc @@ -29,7 +29,6 @@ using namespace Genode; struct Vcpu; static Genode::Registry > 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(&handler._rpc_ep); - call(ep->cap()); - Vcpu * vcpu = new (alloc) Registered (vcpus, handler, vcpu_id++, alloc); + Vcpu * vcpu = new (alloc) Registered (vcpus, handler, + call(ep->cap()), + alloc); vcpu->assign_ds_state(env.rm(), call(vcpu->id())); Signal_context_capability dontcare_exit; diff --git a/repos/base-sel4/src/core/include/vm_session_component.h b/repos/base-sel4/src/core/include/vm_session_component.h index de814b2d8..63544ea75 100644 --- a/repos/base-sel4/src/core/include/vm_session_component.h +++ b/repos/base-sel4/src/core/include/vm_session_component.h @@ -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_ */ diff --git a/repos/base-sel4/src/core/spec/x86/vm_session_component.cc b/repos/base-sel4/src/core/spec/x86/vm_session_component.cc index 642fd288a..ee9b907f4 100644 --- a/repos/base-sel4/src/core/spec/x86/vm_session_component.cc +++ b/repos/base-sel4/src/core/spec/x86/vm_session_component.cc @@ -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) diff --git a/repos/base-sel4/src/lib/base/x86/vm_session.cc b/repos/base-sel4/src/lib/base/x86/vm_session.cc index 062000f57..5d7155404 100644 --- a/repos/base-sel4/src/lib/base/x86/vm_session.cc +++ b/repos/base-sel4/src/lib/base/x86/vm_session.cc @@ -32,7 +32,6 @@ using namespace Genode; struct Vcpu; static Genode::Registry > 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 (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(vcpu->cap())); call(handler._cap, vcpu->id()); - call(vcpu->cap()); vcpu->assign_ds_state(env.rm(), call(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(); } diff --git a/repos/base/include/vm_session/vm_session.h b/repos/base/include/vm_session/vm_session.h index 8a050c71e..0a2c6b325 100644 --- a/repos/base/include/vm_session/vm_session.h +++ b/repos/base/include/vm_session/vm_session.h @@ -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); diff --git a/repos/base/src/lib/base/vm_session.cc b/repos/base/src/lib/base/vm_session.cc index fe8be6307..2fe995908 100644 --- a/repos/base/src/lib/base/vm_session.cc +++ b/repos/base/src/lib/base/vm_session.cc @@ -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(Thread_capability()); + Thread * ep = reinterpret_cast(&handler._rpc_ep); + Vcpu_id vcpu_id { call(ep->cap()) }; call(handler._cap, vcpu_id); return vcpu_id; }