mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-19 03:06:39 +00:00
parent
256a989550
commit
6ca7119267
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* \brief Virtual machine state
|
||||
* \author Benjamin Lamowski
|
||||
* \date 2022-10-14
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 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 _INCLUDE__SPEC__PC__VM_STATE_H_
|
||||
#define _INCLUDE__SPEC__PC__VM_STATE_H_
|
||||
|
||||
namespace Genode {
|
||||
|
||||
/**
|
||||
* CPU context of a virtual machine
|
||||
*/
|
||||
struct Vm_state;
|
||||
}
|
||||
|
||||
|
||||
struct Genode::Vm_state
|
||||
{
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__SPEC__PC__VM_STATE_H_ */
|
@ -8,6 +8,7 @@
|
||||
# add include paths
|
||||
REP_INC_DIR += src/core/board/pc
|
||||
REP_INC_DIR += src/core/spec/x86_64
|
||||
REP_INC_DIR += src/core/spec/x86_64/virtualization
|
||||
|
||||
LIBS += syscall-hw
|
||||
|
||||
@ -17,13 +18,17 @@ SRC_S += spec/x86_64/exception_vector.s
|
||||
|
||||
# add C++ sources
|
||||
SRC_CC += kernel/cpu_mp.cc
|
||||
SRC_CC += kernel/vm_thread_off.cc
|
||||
SRC_CC += kernel/vm_thread_on.cc
|
||||
SRC_CC += spec/x86_64/virtualization/kernel/vm.cc
|
||||
SRC_CC += spec/x86_64/virtualization/vm_session_component.cc
|
||||
SRC_CC += vm_session_common.cc
|
||||
SRC_CC += vm_session_component.cc
|
||||
SRC_CC += kernel/lock.cc
|
||||
SRC_CC += spec/x86_64/pic.cc
|
||||
SRC_CC += spec/x86_64/pit.cc
|
||||
SRC_CC += spec/x86_64/kernel/thread_exception.cc
|
||||
SRC_CC += spec/x86_64/platform_support.cc
|
||||
SRC_CC += spec/x86/platform_services.cc
|
||||
SRC_CC += spec/x86_64/virtualization/platform_services.cc
|
||||
|
||||
SRC_CC += spec/x86/io_port_session_component.cc
|
||||
SRC_CC += spec/x86/io_port_session_support.cc
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
/* base-hw internal includes */
|
||||
#include <hw/spec/x86_64/pc_board.h>
|
||||
/* PC virtualization */
|
||||
#include <spec/x86_64/virtualization/board.h>
|
||||
|
||||
/*
|
||||
* As long as Board::NR_OF_CPUS is used as constant within pic.h
|
||||
|
51
repos/base-hw/src/core/spec/x86_64/virtualization/board.h
Normal file
51
repos/base-hw/src/core/spec/x86_64/virtualization/board.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* \brief Board with PC virtualization support
|
||||
* \author Benjamin Lamowski
|
||||
* \date 2022-10-14
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 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__SPEC__PC__VIRTUALIZATION__BOARD_H_
|
||||
#define _CORE__SPEC__PC__VIRTUALIZATION__BOARD_H_
|
||||
|
||||
/* base-hw core includes */
|
||||
#include <kernel/configuration.h>
|
||||
#include <kernel/irq.h>
|
||||
|
||||
#include <hw/spec/x86_64/page_table.h>
|
||||
#include <cpu/vm_state_virtualization.h>
|
||||
|
||||
namespace Board {
|
||||
|
||||
using Vm_page_table = Hw::Page_table;
|
||||
using Vm_page_table_array =
|
||||
Vm_page_table::Allocator::Array<Kernel::DEFAULT_TRANSLATION_TABLE_MAX>;
|
||||
|
||||
struct Vcpu_context;
|
||||
|
||||
using Vm_state = Genode::Vm_state;
|
||||
|
||||
enum {
|
||||
VCPU_MAX = 16
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
namespace Kernel {
|
||||
class Cpu;
|
||||
class Vm;
|
||||
};
|
||||
|
||||
|
||||
struct Board::Vcpu_context
|
||||
{
|
||||
Vcpu_context(Kernel::Cpu & cpu);
|
||||
};
|
||||
|
||||
#endif /* _CORE__SPEC__PC__VIRTUALIZATION__BOARD_H_ */
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* \brief Interface between kernel and hypervisor
|
||||
* \author Benjamin Lamowski
|
||||
* \date 2022-10-14
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 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 _SPEC__PC__VIRTUALIZATION_HYPERVISOR_H_
|
||||
#define _SPEC__PC__VIRTUALIZATION_HYPERVISOR_H_
|
||||
|
||||
#include <base/stdint.h>
|
||||
#include <base/log.h>
|
||||
|
||||
namespace Hypervisor {
|
||||
|
||||
using Call_arg = Genode::umword_t;
|
||||
using Call_ret = Genode::umword_t;
|
||||
|
||||
inline void switch_world(Call_arg guest_state [[maybe_unused]],
|
||||
Call_arg host_state [[maybe_unused]],
|
||||
Call_arg pic_state [[maybe_unused]],
|
||||
Call_arg ttbr [[maybe_unused]])
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* _SPEC__PC__VIRTUALIZATION_HYPERVISOR_H_ */
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* \brief Kernel backend for x86 virtual machines
|
||||
* \author Benjamin Lamowski
|
||||
* \date 2022-10-14
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include <base/log.h>
|
||||
#include <cpu/vm_state_virtualization.h>
|
||||
#include <util/mmio.h>
|
||||
|
||||
#include <hw/assert.h>
|
||||
#include <map_local.h>
|
||||
#include <platform_pd.h>
|
||||
#include <kernel/cpu.h>
|
||||
#include <kernel/vm.h>
|
||||
#include <kernel/main.h>
|
||||
|
||||
#include <spec/x86_64/virtualization/hypervisor.h>
|
||||
|
||||
using Genode::addr_t;
|
||||
using Kernel::Cpu;
|
||||
using Kernel::Vm;
|
||||
|
||||
|
||||
Vm::Vm(Irq::Pool & user_irq_pool,
|
||||
Cpu & cpu,
|
||||
Genode::Vm_state & state,
|
||||
Kernel::Signal_context & context,
|
||||
Identity & id)
|
||||
:
|
||||
Kernel::Object { *this },
|
||||
Cpu_job(Cpu_priority::min(), 0),
|
||||
_user_irq_pool(user_irq_pool),
|
||||
_state(state),
|
||||
_context(context),
|
||||
_id(id),
|
||||
_vcpu_context(cpu)
|
||||
{
|
||||
affinity(cpu);
|
||||
|
||||
}
|
||||
|
||||
|
||||
Vm::~Vm()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Vm::exception(Cpu &)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Vm::proceed(Cpu &)
|
||||
{
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* \brief Platform specific services for x86
|
||||
* \author Stefan Kalkowski
|
||||
* \author Benjamin Lamowski
|
||||
* \date 2012-10-26
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2022 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/service.h>
|
||||
|
||||
/* core includes */
|
||||
#include <core_env.h>
|
||||
#include <platform.h>
|
||||
#include <platform_services.h>
|
||||
#include <vm_root.h>
|
||||
#include <io_port_root.h>
|
||||
|
||||
|
||||
/*
|
||||
* Add x86 specific ioport and virtualization service
|
||||
*/
|
||||
void Core::platform_add_local_services(Rpc_entrypoint &ep,
|
||||
Sliced_heap &sliced_heap,
|
||||
Registry<Service> &local_services,
|
||||
Trace::Source_registry &trace_sources)
|
||||
{
|
||||
static Io_port_root io_port_root(*core_env().pd_session(),
|
||||
platform().io_port_alloc(), sliced_heap);
|
||||
|
||||
static Vm_root vm_root(ep, sliced_heap, core_env().ram_allocator(),
|
||||
core_env().local_rm(), trace_sources);
|
||||
|
||||
static Core_service<Vm_session_component> vm_service(local_services, vm_root);
|
||||
|
||||
static Core_service<Io_port_session_component>
|
||||
io_port_ls(local_services, io_port_root);
|
||||
}
|
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* \brief VM session component for 'base-hw'
|
||||
* \author Stefan Kalkowski
|
||||
* \author Benjamin Lamowski
|
||||
* \date 2015-02-17
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015-2023 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/construct_at.h>
|
||||
|
||||
/* base internal includes */
|
||||
#include <base/internal/unmanaged_singleton.h>
|
||||
|
||||
/* core includes */
|
||||
#include <kernel/core_interface.h>
|
||||
#include <vm_session_component.h>
|
||||
#include <platform.h>
|
||||
#include <cpu_thread_component.h>
|
||||
#include <core_env.h>
|
||||
|
||||
using namespace Core;
|
||||
|
||||
|
||||
static Core_mem_allocator & cma() {
|
||||
return static_cast<Core_mem_allocator&>(platform().core_mem_alloc()); }
|
||||
|
||||
|
||||
void Vm_session_component::_attach(addr_t phys_addr, addr_t vm_addr, size_t size)
|
||||
{
|
||||
using namespace Hw;
|
||||
|
||||
Page_flags pflags { RW, NO_EXEC, USER, NO_GLOBAL, RAM, CACHED };
|
||||
|
||||
try {
|
||||
_table.insert_translation(vm_addr, phys_addr, size, pflags,
|
||||
_table_array.alloc());
|
||||
return;
|
||||
} catch(Hw::Out_of_tables &) {
|
||||
Genode::error("Translation table needs to much RAM");
|
||||
} catch(...) {
|
||||
Genode::error("Invalid mapping ", Genode::Hex(phys_addr), " -> ",
|
||||
Genode::Hex(vm_addr), " (", size, ")");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Vm_session_component::_attach_vm_memory(Dataspace_component &dsc,
|
||||
addr_t const vm_addr,
|
||||
Attach_attr const attribute)
|
||||
{
|
||||
_attach(dsc.phys_addr() + attribute.offset, vm_addr, attribute.size);
|
||||
}
|
||||
|
||||
|
||||
void Vm_session_component::attach_pic(addr_t )
|
||||
{ }
|
||||
|
||||
|
||||
void Vm_session_component::_detach_vm_memory(addr_t vm_addr, size_t size)
|
||||
{
|
||||
_table.remove_translation(vm_addr, size, _table_array.alloc());
|
||||
}
|
||||
|
||||
|
||||
void * Vm_session_component::_alloc_table()
|
||||
{
|
||||
/* get some aligned space for the translation table */
|
||||
return cma().alloc_aligned(sizeof(Board::Vm_page_table),
|
||||
Board::Vm_page_table::ALIGNM_LOG2).convert<void *>(
|
||||
[&] (void *table_ptr) {
|
||||
return table_ptr; },
|
||||
|
||||
[&] (Range_allocator::Alloc_error) -> void * {
|
||||
/* XXX handle individual error conditions */
|
||||
error("failed to allocate kernel object");
|
||||
throw Insufficient_ram_quota(); }
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
Vm_session_component::Vm_session_component(Rpc_entrypoint &ds_ep,
|
||||
Resources resources,
|
||||
Label const &,
|
||||
Diag,
|
||||
Ram_allocator &ram_alloc,
|
||||
Region_map ®ion_map,
|
||||
unsigned,
|
||||
Trace::Source_registry &)
|
||||
:
|
||||
Ram_quota_guard(resources.ram_quota),
|
||||
Cap_quota_guard(resources.cap_quota),
|
||||
_ep(ds_ep),
|
||||
_constrained_md_ram_alloc(ram_alloc, _ram_quota_guard(), _cap_quota_guard()),
|
||||
_sliced_heap(_constrained_md_ram_alloc, region_map),
|
||||
_region_map(region_map),
|
||||
_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)})
|
||||
{
|
||||
/* configure managed VM area */
|
||||
_map.add_range(0UL, ~0UL);
|
||||
}
|
||||
|
||||
|
||||
Vm_session_component::~Vm_session_component()
|
||||
{
|
||||
/* detach all regions */
|
||||
while (true) {
|
||||
addr_t out_addr = 0;
|
||||
|
||||
if (!_map.any_block_addr(&out_addr))
|
||||
break;
|
||||
|
||||
detach(out_addr);
|
||||
}
|
||||
|
||||
/* free region in allocator */
|
||||
for (unsigned i = 0; i < _vcpu_id_alloc; i++) {
|
||||
if (!_vcpus[i].constructed())
|
||||
continue;
|
||||
|
||||
Vcpu & vcpu = *_vcpus[i];
|
||||
if (vcpu.ds_cap.valid()) {
|
||||
_region_map.detach(vcpu.ds_addr);
|
||||
_constrained_md_ram_alloc.free(vcpu.ds_cap);
|
||||
}
|
||||
}
|
||||
|
||||
/* free guest-to-host page tables */
|
||||
destroy(platform().core_mem_alloc(), &_table);
|
||||
destroy(platform().core_mem_alloc(), &_table_array);
|
||||
alloc().free(_id.id);
|
||||
}
|
Loading…
Reference in New Issue
Block a user