hw: factor out Vmid_allocator

Move the static `Vmid_allocator` in each `Vm_session_component` into a
common header file.

Issue #5221
This commit is contained in:
Benjamin Lamowski 2024-11-21 14:59:51 +01:00 committed by Christian Helmuth
parent c0c6f3f660
commit 922fdd1628
6 changed files with 140 additions and 41 deletions

View File

@ -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<Vmid_allocator>();
/* 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<Board::Vm_page_table>(_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);
}

View File

@ -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<Board::Vm_page_table>(_alloc_table())),
_table_array(dummy_array()),
_vmid_alloc(vmids),
_id({id_alloc++, nullptr})
{
if (_id.id) {

View File

@ -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<Vmid_allocator>();
/* 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<Board::Vm_page_table>(_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);
}

View File

@ -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 <root/component.h>
#include <base/heap.h>
/* core includes */
#include <vm_session_component.h>
#include <vmid_allocator.h>
namespace Core { class Vm_root; }
class Core::Vm_root : public Root_component<Vm_session_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<Vm_session_component>(&session_ep, &md_alloc),
_ram_allocator(ram_alloc),
_local_rm(local_rm),
_trace_sources(trace_sources)
{ }
};
#endif /* _CORE__INCLUDE__VM_ROOT_H_ */

View File

@ -30,6 +30,9 @@
#include <kernel/vm.h>
#include <trace/source_registry.h>
#include <vmid_allocator.h>
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<Vm_session, Vm_session_component>::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();

View File

@ -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 <util/bit_allocator.h>
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_ */