From 922fdd16284746b87cd2c4b777b79dbbbb160f9b Mon Sep 17 00:00:00 2001 From: Benjamin Lamowski Date: Thu, 21 Nov 2024 14:59:51 +0100 Subject: [PATCH] hw: factor out Vmid_allocator Move the static `Vmid_allocator` in each `Vm_session_component` into a common header file. Issue #5221 --- .../virtualization/vm_session_component.cc | 24 ++--- .../arm_v7/trustzone/vm_session_component.cc | 3 +- .../virtualization/vm_session_component.cc | 24 ++--- repos/base-hw/src/core/vm_root.h | 88 +++++++++++++++++++ repos/base-hw/src/core/vm_session_component.h | 9 +- repos/base-hw/src/core/vmid_allocator.h | 33 +++++++ 6 files changed, 140 insertions(+), 41 deletions(-) create mode 100644 repos/base-hw/src/core/vm_root.h create mode 100644 repos/base-hw/src/core/vmid_allocator.h diff --git a/repos/base-hw/src/core/spec/arm/virtualization/vm_session_component.cc b/repos/base-hw/src/core/spec/arm/virtualization/vm_session_component.cc index 309f059235..e83d7169f3 100644 --- a/repos/base-hw/src/core/spec/arm/virtualization/vm_session_component.cc +++ b/repos/base-hw/src/core/spec/arm/virtualization/vm_session_component.cc @@ -86,29 +86,14 @@ void * Vm_session_component::_alloc_table() } -using Vmid_allocator = Bit_allocator<256>; - -static Vmid_allocator &alloc() -{ - static Vmid_allocator * allocator = nullptr; - if (!allocator) { - allocator = unmanaged_singleton(); - - /* reserve VM ID 0 for the hypervisor */ - addr_t id = allocator->alloc(); - assert (id == 0); - } - return *allocator; -} - - Genode::addr_t Vm_session_component::_alloc_vcpu_data(Genode::addr_t ds_addr) { return ds_addr; } -Vm_session_component::Vm_session_component(Rpc_entrypoint &ds_ep, +Vm_session_component::Vm_session_component(Vmid_allocator & vmid_alloc, + Rpc_entrypoint &ds_ep, Resources resources, Label const &, Diag, @@ -126,7 +111,8 @@ Vm_session_component::Vm_session_component(Rpc_entrypoint &ds_ep, _table(*construct_at(_alloc_table())), _table_array(*(new (cma()) Board::Vm_page_table_array([] (void * virt) { return (addr_t)cma().phys_addr(virt);}))), - _id({(unsigned)alloc().alloc(), cma().phys_addr(&_table)}) + _vmid_alloc(vmid_alloc), + _id({(unsigned)_vmid_alloc.alloc(), cma().phys_addr(&_table)}) { /* configure managed VM area */ _map.add_range(0, 0UL - 0x1000); @@ -161,5 +147,5 @@ Vm_session_component::~Vm_session_component() /* free guest-to-host page tables */ destroy(platform().core_mem_alloc(), &_table); destroy(platform().core_mem_alloc(), &_table_array); - alloc().free(_id.id); + _vmid_alloc.free(_id.id); } diff --git a/repos/base-hw/src/core/spec/arm_v7/trustzone/vm_session_component.cc b/repos/base-hw/src/core/spec/arm_v7/trustzone/vm_session_component.cc index a189cc5d8c..2f64076c47 100644 --- a/repos/base-hw/src/core/spec/arm_v7/trustzone/vm_session_component.cc +++ b/repos/base-hw/src/core/spec/arm_v7/trustzone/vm_session_component.cc @@ -58,7 +58,7 @@ Genode::addr_t Vm_session_component::_alloc_vcpu_data(Genode::addr_t ds_addr) } -Vm_session_component::Vm_session_component(Rpc_entrypoint &ep, +Vm_session_component::Vm_session_component(Vmid_allocator &vmids, Rpc_entrypoint &ep, Resources resources, Label const &, Diag, @@ -74,6 +74,7 @@ Vm_session_component::Vm_session_component(Rpc_entrypoint &ep, _region_map(region_map), _table(*construct_at(_alloc_table())), _table_array(dummy_array()), + _vmid_alloc(vmids), _id({id_alloc++, nullptr}) { if (_id.id) { diff --git a/repos/base-hw/src/core/spec/x86_64/virtualization/vm_session_component.cc b/repos/base-hw/src/core/spec/x86_64/virtualization/vm_session_component.cc index 587a76a5e7..639c7fee1f 100644 --- a/repos/base-hw/src/core/spec/x86_64/virtualization/vm_session_component.cc +++ b/repos/base-hw/src/core/spec/x86_64/virtualization/vm_session_component.cc @@ -84,22 +84,6 @@ void * Vm_session_component::_alloc_table() } -using Vmid_allocator = Genode::Bit_allocator<256>; - -static Vmid_allocator &alloc() -{ - static Vmid_allocator * allocator = nullptr; - if (!allocator) { - allocator = unmanaged_singleton(); - - /* reserve VM ID 0 for the hypervisor */ - addr_t id = allocator->alloc(); - assert (id == 0); - } - return *allocator; -} - - Genode::addr_t Vm_session_component::_alloc_vcpu_data(Genode::addr_t ds_addr) { /* @@ -139,7 +123,8 @@ Genode::addr_t Vm_session_component::_alloc_vcpu_data(Genode::addr_t ds_addr) } -Vm_session_component::Vm_session_component(Rpc_entrypoint &ds_ep, +Vm_session_component::Vm_session_component(Vmid_allocator & vmid_alloc, + Rpc_entrypoint &ds_ep, Resources resources, Label const &, Diag, @@ -157,7 +142,8 @@ Vm_session_component::Vm_session_component(Rpc_entrypoint &ds_ep, _table(*construct_at(_alloc_table())), _table_array(*(new (cma()) Board::Vm_page_table_array([] (void * virt) { return (addr_t)cma().phys_addr(virt);}))), - _id({(unsigned)alloc().alloc(), cma().phys_addr(&_table)}) + _vmid_alloc(vmid_alloc), + _id({(unsigned)_vmid_alloc.alloc(), cma().phys_addr(&_table)}) { /* configure managed VM area */ _map.add_range(0UL, ~0UL); @@ -191,5 +177,5 @@ Vm_session_component::~Vm_session_component() /* free guest-to-host page tables */ destroy(platform().core_mem_alloc(), &_table); destroy(platform().core_mem_alloc(), &_table_array); - alloc().free(_id.id); + _vmid_alloc.free(_id.id); } diff --git a/repos/base-hw/src/core/vm_root.h b/repos/base-hw/src/core/vm_root.h new file mode 100644 index 0000000000..3e6b72dba9 --- /dev/null +++ b/repos/base-hw/src/core/vm_root.h @@ -0,0 +1,88 @@ +/* + * \brief base-hw specific Vm root interface + * \author Stefan Kalkowski + * \author Benjamin Lamowski + * \date 2012-10-08 + */ + +/* + * Copyright (C) 2012-2024 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _CORE__INCLUDE__VM_ROOT_H_ +#define _CORE__INCLUDE__VM_ROOT_H_ + +/* Genode includes */ +#include +#include + +/* core includes */ +#include + +#include + +namespace Core { class Vm_root; } + +class Core::Vm_root : public Root_component +{ + private: + + Ram_allocator &_ram_allocator; + Region_map &_local_rm; + Trace::Source_registry &_trace_sources; + Vmid_allocator _vmid_alloc { }; + + protected: + + Vm_session_component *_create_session(const char *args) override + { + unsigned priority = 0; + Arg a = Arg_string::find_arg(args, "priority"); + if (a.valid()) { + priority = (unsigned)a.ulong_value(0); + + /* clamp priority value to valid range */ + priority = min((unsigned)Cpu_session::PRIORITY_LIMIT - 1, priority); + } + + return new (md_alloc()) + Vm_session_component(_vmid_alloc, + *ep(), + session_resources_from_args(args), + session_label_from_args(args), + session_diag_from_args(args), + _ram_allocator, _local_rm, priority, + _trace_sources); + } + + void _upgrade_session(Vm_session_component *vm, const char *args) override + { + vm->upgrade(ram_quota_from_args(args)); + vm->upgrade(cap_quota_from_args(args)); + } + + public: + + /** + * Constructor + * + * \param session_ep entrypoint managing vm_session components + * \param md_alloc meta-data allocator to be used by root component + */ + Vm_root(Rpc_entrypoint &session_ep, + Allocator &md_alloc, + Ram_allocator &ram_alloc, + Region_map &local_rm, + Trace::Source_registry &trace_sources) + : + Root_component(&session_ep, &md_alloc), + _ram_allocator(ram_alloc), + _local_rm(local_rm), + _trace_sources(trace_sources) + { } +}; + +#endif /* _CORE__INCLUDE__VM_ROOT_H_ */ diff --git a/repos/base-hw/src/core/vm_session_component.h b/repos/base-hw/src/core/vm_session_component.h index ffc0824851..2eb6d2e2a9 100644 --- a/repos/base-hw/src/core/vm_session_component.h +++ b/repos/base-hw/src/core/vm_session_component.h @@ -30,6 +30,9 @@ #include #include +#include + + namespace Core { class Vm_session_component; } @@ -88,6 +91,7 @@ class Core::Vm_session_component Region_map &_region_map; Board::Vm_page_table &_table; Board::Vm_page_table_array &_table_array; + Vmid_allocator &_vmid_alloc; Kernel::Vm::Identity _id; unsigned _vcpu_id_alloc { 0 }; @@ -113,8 +117,9 @@ class Core::Vm_session_component using Cap_quota_guard::upgrade; using Rpc_object::cap; - Vm_session_component(Rpc_entrypoint &, Resources, Label const &, - Diag, Ram_allocator &ram, Region_map &, unsigned, + Vm_session_component(Vmid_allocator &, Rpc_entrypoint &, + Resources, Label const &, Diag, + Ram_allocator &ram, Region_map &, unsigned, Trace::Source_registry &); ~Vm_session_component(); diff --git a/repos/base-hw/src/core/vmid_allocator.h b/repos/base-hw/src/core/vmid_allocator.h new file mode 100644 index 0000000000..f6b05eadf5 --- /dev/null +++ b/repos/base-hw/src/core/vmid_allocator.h @@ -0,0 +1,33 @@ +/* + * \brief VM ID allocator + * \author Stefan Kalkowski + * \author Benjamin Lamowski + * \date 2024-11-21 + */ + +/* + * Copyright (C) 2015-2024 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _CORE__VMID_ALLOCATOR_H_ +#define _CORE__VMID_ALLOCATOR_H_ + +#include + +namespace Core { struct Vmid_allocator; } + +struct Core::Vmid_allocator +: Genode::Bit_allocator<256> +{ + Vmid_allocator() + { + /* reserve VM ID 0 for the hypervisor */ + addr_t id = alloc(); + assert (id == 0); + } +}; + +#endif /* _CORE__VMID_ALLOCATOR_H_ */