diff --git a/repos/base-nova/include/nova/util.h b/repos/base-nova/include/nova/util.h index d4d19d97e5..45f94e2dda 100644 --- a/repos/base-nova/include/nova/util.h +++ b/repos/base-nova/include/nova/util.h @@ -57,35 +57,4 @@ inline void request_signal_sm_cap(Genode::addr_t const cap, } -inline void translate_remote_pager(Genode::addr_t const cap, - Genode::addr_t const sel) -{ - Genode::Thread * myself = Genode::Thread::myself(); - Nova::Utcb *utcb = reinterpret_cast(myself->utcb()); - - /* save original receive window */ - Nova::Crd orig_crd = utcb->crd_rcv; - - utcb->crd_rcv = Nova::Obj_crd(); - - Genode::uint8_t res = Nova::NOVA_OK; - enum { - TRANSLATE = true, THIS_PD = false, NON_GUEST = false, HOTSPOT = 0 - }; - - /* translate one item */ - utcb->msg()[0] = 0xaffe; - utcb->set_msg_word(1); - - Nova::Obj_crd obj_crd(sel, 0); - if (utcb->append_item(obj_crd, HOTSPOT, THIS_PD, NON_GUEST, TRANSLATE)) - /* trigger the translation */ - res = Nova::call(cap); - - /* restore original receive window */ - utcb->crd_rcv = orig_crd; - - if (res != Nova::NOVA_OK) - Genode::error("setting exception portals for vCPU failed res=", res); -} #endif /* _INCLUDE__NOVA__UTIL_H_ */ diff --git a/repos/base-nova/include/nova_native_cpu/nova_native_cpu.h b/repos/base-nova/include/nova_native_cpu/nova_native_cpu.h index 6134b8f714..a2747c93b2 100644 --- a/repos/base-nova/include/nova_native_cpu/nova_native_cpu.h +++ b/repos/base-nova/include/nova_native_cpu/nova_native_cpu.h @@ -20,7 +20,7 @@ struct Genode::Cpu_session::Native_cpu : Interface { - enum Thread_type { GLOBAL, LOCAL, VCPU }; + enum Thread_type { GLOBAL, LOCAL }; /* * Exception base of thread in caller protection domain - not in core! diff --git a/repos/base-nova/src/core/include/platform_thread.h b/repos/base-nova/src/core/include/platform_thread.h index ae9e1f0cfd..18cf1a4f7a 100644 --- a/repos/base-nova/src/core/include/platform_thread.h +++ b/repos/base-nova/src/core/include/platform_thread.h @@ -47,10 +47,8 @@ class Core::Platform_thread enum { MAIN_THREAD = 0x1U, - VCPU = 0x2U, - WORKER = 0x4U, - SC_CREATED = 0x8U, - REMOTE_PD = 0x10U, + WORKER = 0x2U, + SC_CREATED = 0x4U, }; uint8_t _features; uint8_t _priority; @@ -63,10 +61,8 @@ class Core::Platform_thread /* convenience function to access _feature variable */ inline bool main_thread() const { return _features & MAIN_THREAD; } - inline bool vcpu() const { return _features & VCPU; } inline bool worker() const { return _features & WORKER; } inline bool sc_created() const { return _features & SC_CREATED; } - inline bool remote_pd() const { return _features & REMOTE_PD; } /* * Noncopyable @@ -81,15 +77,6 @@ class Core::Platform_thread public: - /* mark as vcpu in remote pd if it is a vcpu */ - addr_t remote_vcpu() { - if (!vcpu()) - return Native_thread::INVALID_INDEX; - - _features |= Platform_thread::REMOTE_PD; - return _sel_exc_base; - } - /** * Constructor */ diff --git a/repos/base-nova/src/core/pager.cc b/repos/base-nova/src/core/pager.cc index 5b8a1b0ddc..60ae795032 100644 --- a/repos/base-nova/src/core/pager.cc +++ b/repos/base-nova/src/core/pager.cc @@ -387,39 +387,6 @@ void Pager_object::_invoke_handler(Pager_object &obj) addr_t const event = utcb.msg()[0]; - /* check for translated pager portals - required for vCPU in remote PDs */ - if (utcb.msg_items() == 1 && utcb.msg_words() == 1 && event == 0xaffe) { - - Nova::Utcb::Item const &item = *utcb.get_item(0); - Nova::Crd const cap(item.crd); - - /* valid item which got translated ? */ - if (!cap.is_null() && !item.is_del() && _core_ep_ptr) { - _core_ep_ptr->apply(cap.base(), - [&] (Cpu_thread_component *source) { - if (!source) - return; - - Platform_thread &p = source->platform_thread(); - addr_t const sel_exc_base = p.remote_vcpu(); - if (sel_exc_base == Native_thread::INVALID_INDEX) - return; - - /* delegate VM-exit portals */ - map_vcpu_portals(p.pager(), sel_exc_base, sel_exc_base, - utcb, obj.pd_sel()); - - /* delegate portal to contact pager */ - map_pagefault_portal(obj, p.pager().exc_pt_sel_client(), - sel_exc_base, obj.pd_sel(), utcb); - }); - } - - utcb.mtd = 0; - utcb.set_msg_word(0); - reply(my_stack_top()); - } - utcb.mtd = 0; utcb.set_msg_word(0); diff --git a/repos/base-nova/src/core/platform_thread.cc b/repos/base-nova/src/core/platform_thread.cc index 28117753f5..9aeddc32d8 100644 --- a/repos/base-nova/src/core/platform_thread.cc +++ b/repos/base-nova/src/core/platform_thread.cc @@ -67,7 +67,7 @@ void Platform_thread::affinity(Affinity::Location location) if (!_pager) return; - if (worker() || vcpu() || !sc_created()) + if (worker() || !sc_created()) return; _pager->migrate(platform_specific().sanitize(location)); @@ -109,7 +109,7 @@ void Platform_thread::start(void *ip, void *sp) Pager_object &pager = *_pager; - if (main_thread() && !vcpu() && (_pd.parent_pt_sel() == Native_thread::INVALID_INDEX)) { + if (main_thread() && (_pd.parent_pt_sel() == Native_thread::INVALID_INDEX)) { error("protection domain undefined"); return; } @@ -125,7 +125,7 @@ void Platform_thread::start(void *ip, void *sp) if (!main_thread()) { addr_t const initial_sp = reinterpret_cast(sp); - addr_t const utcb_addr = vcpu() ? 0 : round_page(initial_sp); + addr_t const utcb_addr = round_page(initial_sp); if (_sel_exc_base == Native_thread::INVALID_INDEX) { error("exception base not specified"); @@ -144,12 +144,11 @@ void Platform_thread::start(void *ip, void *sp) return; } - if (!vcpu()) - res = map_thread_portals(pager, _sel_exc_base, utcb); + res = map_thread_portals(pager, _sel_exc_base, utcb); if (res != NOVA_OK) { revoke(Obj_crd(_sel_ec(), 0)); - error("creation of new thread/vcpu failed ", res); + error("creation of new thread failed ", res); return; } @@ -164,28 +163,26 @@ void Platform_thread::start(void *ip, void *sp) return; } - if (!vcpu() && _sel_exc_base != Native_thread::INVALID_INDEX) { + if (_sel_exc_base != Native_thread::INVALID_INDEX) { error("thread already started"); return; } addr_t pd_utcb = 0; - if (!vcpu()) { - _sel_exc_base = 0; + _sel_exc_base = 0; - pd_utcb = stack_area_virtual_base() + stack_virtual_size() - get_page_size(); + pd_utcb = stack_area_virtual_base() + stack_virtual_size() - get_page_size(); - addr_t remap_src[] = { _pd.parent_pt_sel() }; - addr_t remap_dst[] = { PT_SEL_PARENT }; + addr_t remap_src[] = { _pd.parent_pt_sel() }; + addr_t remap_dst[] = { PT_SEL_PARENT }; - /* remap exception portals for first thread */ - for (unsigned i = 0; i < sizeof(remap_dst)/sizeof(remap_dst[0]); i++) { - if (map_local(source_pd, utcb, - Obj_crd(remap_src[i], 0), - Obj_crd(pager.exc_pt_sel_client() + remap_dst[i], 0))) - return; - } + /* remap exception portals for first thread */ + for (unsigned i = 0; i < sizeof(remap_dst)/sizeof(remap_dst[0]); i++) { + if (map_local(source_pd, utcb, + Obj_crd(remap_src[i], 0), + Obj_crd(pager.exc_pt_sel_client() + remap_dst[i], 0))) + return; } /* create first thread in task */ @@ -202,10 +199,7 @@ void Platform_thread::start(void *ip, void *sp) pager.initial_eip((addr_t)ip); pager.initial_esp((addr_t)sp); - if (vcpu()) - _features |= REMOTE_PD; - else - res = map_thread_portals(pager, 0, utcb); + res = map_thread_portals(pager, 0, utcb); if (res == NOVA_OK) { res = syscall_retry(pager, @@ -333,13 +327,11 @@ void Platform_thread::thread_type(Cpu_session::Native_cpu::Thread_type thread_ty if (_sel_exc_base != Native_thread::INVALID_INDEX) return; - if (!main_thread() || (thread_type == Cpu_session::Native_cpu::Thread_type::VCPU)) + if (!main_thread()) _sel_exc_base = exception_base.exception_base; if (thread_type == Cpu_session::Native_cpu::Thread_type::LOCAL) _features |= WORKER; - else if (thread_type == Cpu_session::Native_cpu::Thread_type::VCPU) - _features |= VCPU; } diff --git a/repos/ports/include/vmm/log.h b/repos/ports/include/vmm/log.h deleted file mode 100644 index 7cee9e8216..0000000000 --- a/repos/ports/include/vmm/log.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * \brief Utilities for implementing VMMs on Genode/NOVA - * \author Norman Feske - * \date 2013-08-20 - */ - -/* - * Copyright (C) 2013-2017 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__VMM__PRINTF_H_ -#define _INCLUDE__VMM__PRINTF_H_ - -/* Genode includes */ -#include -#include - -/* NOVA includes */ -#include - -namespace Vmm { - - using namespace Genode; - - /** - * Print message while preserving the UTCB content - */ - template - void log(ARGS... args) - { - struct Utcb_backup { char buf[Nova::Utcb::size()]; }; - - static Mutex mutex; - static Utcb_backup utcb_backup; - - Mutex::Guard guard(mutex); - - utcb_backup = *(Utcb_backup *)Thread::myself()->utcb(); - - Genode::log("VMM: ", args...); - - *(Utcb_backup *)Thread::myself()->utcb() = utcb_backup; - } - - template - void warning(ARGS... args) - { - struct Utcb_backup { char buf[Nova::Utcb::size()]; }; - - static Mutex mutex; - static Utcb_backup utcb_backup; - - Mutex::Guard guard(mutex); - - utcb_backup = *(Utcb_backup *)Thread::myself()->utcb(); - - Genode::warning("VMM: ", args...); - - *(Utcb_backup *)Thread::myself()->utcb() = utcb_backup; - } - - template - void error(ARGS... args) - { - struct Utcb_backup { char buf[Nova::Utcb::size()]; }; - - static Mutex mutex; - static Utcb_backup utcb_backup; - - Mutex::Guard guard(mutex); - - utcb_backup = *(Utcb_backup *)Thread::myself()->utcb(); - - Genode::error("VMM: ", args...); - - *(Utcb_backup *)Thread::myself()->utcb() = utcb_backup; - } -} - -#endif /* _INCLUDE__VMM__PRINTF_H_ */ diff --git a/repos/ports/include/vmm/utcb_guard.h b/repos/ports/include/vmm/utcb_guard.h deleted file mode 100644 index a8e29356b0..0000000000 --- a/repos/ports/include/vmm/utcb_guard.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * \brief Guard to save a UTCB and restore it during guard destruction - * \author Alexander Boettcher - * \date 2013-07-05 - */ - -/* - * Copyright (C) 2013-2017 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__VMM__UTCB_GUARD_H_ -#define _INCLUDE__VMM__UTCB_GUARD_H_ - -/* Genode includes */ -#include - -/* NOVA syscalls */ -#include - - -namespace Vmm { - using namespace Genode; - class Utcb_guard; -} - - -class Vmm::Utcb_guard -{ - public: - - struct Utcb_backup { char buf[Nova::Utcb::size()]; }; - - private: - - Utcb_backup &_backup_utcb; - - public: - - Utcb_guard(Utcb_backup &backup_utcb) : _backup_utcb(backup_utcb) - { - Nova::Utcb *utcb = - reinterpret_cast(Thread::myself()->utcb()); - - unsigned header_len = (char *)utcb->msg() - (char *)utcb; - unsigned len = header_len + utcb->msg_words() * sizeof(Nova::mword_t); - Genode::memcpy(&_backup_utcb, utcb, len); - - if (utcb->msg_items()) - Genode::warning("Error: msg items on UTCB are not saved and restored!"); - } - - ~Utcb_guard() - { - Nova::Utcb *utcb = reinterpret_cast(&_backup_utcb); - - unsigned header_len = (char *)utcb->msg() - (char *)utcb; - unsigned len = header_len + utcb->msg_words() * sizeof(Nova::mword_t); - Genode::memcpy(Thread::myself()->utcb(), utcb, len); - } -}; - -#endif /* _INCLUDE__VMM__UTCB_GUARD_H_ */ diff --git a/repos/ports/include/vmm/vcpu_dispatcher.h b/repos/ports/include/vmm/vcpu_dispatcher.h deleted file mode 100644 index a213ac7407..0000000000 --- a/repos/ports/include/vmm/vcpu_dispatcher.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * \brief Utilities for implementing VMMs on Genode/NOVA - * \author Norman Feske - * \date 2013-08-20 - */ - -/* - * Copyright (C) 2013-2017 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__VMM__VCPU_DISPATCHER_H_ -#define _INCLUDE__VMM__VCPU_DISPATCHER_H_ - -/* Genode includes */ -#include -#include -#include - -namespace Vmm { - - using namespace Genode; - - template - class Vcpu_dispatcher; -} - - -/** - * Thread that handles virtualization events of a 'Vmm::Vcpu_thread' - */ -template -class Vmm::Vcpu_dispatcher : public T -{ - private: - - enum { WEIGHT = Genode::Cpu_session::Weight::DEFAULT_WEIGHT }; - - Env &_env; - Nova_native_pd_client _native_pd { _env.pd().native_pd() }; - - /** - * Portal entry point entered on virtualization events - * - * For each event type used as argument of the 'register_handler' - * function template, the compiler automatically generates a separate - * instance of this function. The sole purpose of this function is to - * call the 'Vcpu' member function corresponding to the event type. - */ - template - static void _portal_entry() - { - /* obtain this pointer of the event handler */ - Genode::Thread *myself = Genode::Thread::myself(); - DISPATCHER *vd = static_cast(myself); - - vd->exit_reason = EV; - - /* call event-specific handler function */ - (vd->*FUNC)(); - - /* continue execution of the guest */ - Nova::reply(myself->stack_top()); - } - - public: - - unsigned int exit_reason = 0; - - Vcpu_dispatcher(Genode::Env &env, Genode::size_t stack_size, - Cpu_connection *, - Genode::Affinity::Location location, - const char * name = "vCPU dispatcher") - : - T(WEIGHT, name, stack_size, location), _env(env) - { - using namespace Genode; - - /* request creation of a 'local' EC */ - T::with_native_thread([&] (Native_thread &nt) { - nt.ec_sel = Native_thread::INVALID_INDEX - 1; }); - - T::start(); - - } - - /** - * Register virtualization event handler - */ - template - bool register_handler(addr_t exc_base, Nova::Mtd mtd) - { - /* - * Let the compiler generate an instance of a portal entry - */ - void (*entry)() = &_portal_entry; - - Untyped_capability handler { }; - - T::with_native_thread([&] (Native_thread &nt) { - - /* create the portal at the desired selector index (EV) */ - Native_capability thread_cap = - Capability_space::import(nt.ec_sel); - - Thread::myself()->with_native_thread([&] (Native_thread &myself_nt) { - - handler = retry( - [&] () { - /* manually define selector used for RPC result */ - myself_nt.client_rcv_sel = exc_base + EV; - return _native_pd.alloc_rpc_cap(thread_cap, (addr_t)entry, - mtd.value()); - }, - [&] () { - myself_nt.reset_client_rcv_sel(); - _env.parent().upgrade(Parent::Env::pd(), "ram_quota=16K"); - }); - - /* revert selector allocation to automatic mode of operation */ - myself_nt.reset_client_rcv_sel(); - }); - }); - - return handler.valid() && (exc_base + EV == (addr_t)handler.local_name()); - } - - /** - * Unused member of the 'Thread' interface - * - * Similarly to how 'Rpc_entrypoints' are handled, a 'Vcpu_dispatcher' - * comes with a custom initialization procedure, which does not call - * the thread's normal entry function. Instead, the thread's EC gets - * associated with several portals, each for handling a specific - * virtualization event. - */ - void entry() override { } -}; - -#endif /* _INCLUDE__VMM__VCPU_DISPATCHER_H_ */ diff --git a/repos/ports/include/vmm/vcpu_thread.h b/repos/ports/include/vmm/vcpu_thread.h deleted file mode 100644 index cc19fcfdd3..0000000000 --- a/repos/ports/include/vmm/vcpu_thread.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * \brief Utilities for implementing VMMs on Genode/NOVA - * \author Norman Feske - * \date 2013-08-20 - */ - -/* - * Copyright (C) 2013-2017 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__VMM__VCPU_THREAD_H_ -#define _INCLUDE__VMM__VCPU_THREAD_H_ - -/* Genode includes */ -#include -#include -#include -#include -#include -#include - -/* NOVA includes */ -#include -#include - -namespace Vmm { - - using namespace Genode; - - class Vcpu_thread; - class Vcpu_other_pd; - class Vcpu_same_pd; -} - -class Vmm::Vcpu_thread -{ - public: - - virtual Genode::addr_t exc_base() = 0; - virtual void start(Genode::addr_t) = 0; - - virtual ~Vcpu_thread() { }; -}; - -class Vmm::Vcpu_other_pd : public Vmm::Vcpu_thread -{ - private: - - Genode::Capability _pd_cap; - Genode::Affinity::Location _location; - Genode::Cpu_connection *_cpu_connection; - - Genode::addr_t _exc_pt_sel; - - /* - * Noncopyable - */ - Vcpu_other_pd(Vcpu_other_pd const &); - Vcpu_other_pd &operator = (Vcpu_other_pd const &); - - public: - - Vcpu_other_pd(Cpu_connection * cpu_connection, - Genode::Affinity::Location location, - Genode::Capability pd_cap, - Genode::size_t = 0 /* stack_size */) - : - _pd_cap(pd_cap), _location(location), _cpu_connection(cpu_connection), - _exc_pt_sel(Genode::cap_map().insert(Nova::NUM_INITIAL_VCPU_PT_LOG2)) - { } - - void start(Genode::addr_t sel_ec) override - { - using namespace Genode; - - Thread_capability vcpu_vm { }; - - while (!vcpu_vm.valid()) { - - bool denied = false; - - using Error = Cpu_session::Create_thread_error; - _cpu_connection->create_thread(_pd_cap, "vCPU", _location, - Cpu_session::Weight()).with_result( - [&] (Thread_capability cap) { vcpu_vm = cap; }, - [&] (Error e) { - if (e == Error::OUT_OF_RAM) _cpu_connection->upgrade_ram(8*1024); - else if (e == Error::OUT_OF_CAPS) _cpu_connection->upgrade_caps(2); - else - denied = true; - } - ); - - if (denied) { - error("Vcpu_other_pd: failed to create vCPU"); - return; - } - } - - /* tell parent that this will be a vCPU */ - Cpu_session::Native_cpu::Thread_type thread_type { Cpu_session::Native_cpu::Thread_type::VCPU }; - Cpu_session::Native_cpu::Exception_base exception_base { _exc_pt_sel }; - Nova_native_cpu_client native_cpu(_cpu_connection->native_cpu()); - native_cpu.thread_type(vcpu_vm, thread_type, exception_base); - - Cpu_thread_client cpu_thread(vcpu_vm); - - /* - * Translate vcpu_vm thread cap via current executing thread, - * which is used to lookup current PD to delegate VM-exit portals. - */ - Thread::myself()->with_native_thread([&] (Native_thread &nt) { - addr_t const current = nt.exc_pt_sel + Nova::PT_SEL_PAGE_FAULT; - translate_remote_pager(current, vcpu_vm.local_name()); }); - - /* start vCPU in separate PD */ - cpu_thread.start(0, 0); - - /* - * Request native EC thread cap used for recalling vCPU - */ - addr_t const pager_pt = _exc_pt_sel + Nova::PT_SEL_PAGE_FAULT; - request_native_ec_cap(pager_pt, sel_ec); - - /* solely needed for vcpu to request native ec cap - drop it */ - Nova::revoke(Nova::Obj_crd(pager_pt, 0)); - - /* request creation of SC to let vCPU run */ - cpu_thread.resume(); - } - - Genode::addr_t exc_base() override { return _exc_pt_sel; } -}; - -#endif /* _INCLUDE__VMM__VCPU_THREAD_H_ */