hw_x86_64_muen: Implement Muen Vm_session

* The Vm thread is always paused and on exception to make sure that guest VM
  execution is suspended whenever we handle an interrupt. Also signal the Vm
  session to poke waiting threads (e.g. Virtualbox EMT).

* Implement Vm::proceed
  Switch to the mode transition assembly code declared at the _vt_vm_entry
  label.

Issue #2016
This commit is contained in:
Adrian-Ken Rueegsegger 2015-06-03 17:45:35 +02:00 committed by Norman Feske
parent 082b141e66
commit cd6b3b1222
3 changed files with 33 additions and 11 deletions

View File

@ -33,6 +33,9 @@ class Genode::Vm_session_component
: public Genode::Rpc_object<Genode::Vm_session>, : public Genode::Rpc_object<Genode::Vm_session>,
public Kernel_object<Kernel::Vm> public Kernel_object<Kernel::Vm>
{ {
private:
Vm_state _state;
public: public:
Vm_session_component(Rpc_entrypoint*, size_t) { } Vm_session_component(Rpc_entrypoint*, size_t) { }
@ -47,7 +50,7 @@ class Genode::Vm_session_component
void exception_handler(Signal_context_capability handler) void exception_handler(Signal_context_capability handler)
{ {
if (!create(nullptr, handler.dst(), nullptr)) if (!create(&_state, handler.dst(), nullptr))
PWRN("Cannot instantiate vm kernel object, " PWRN("Cannot instantiate vm kernel object, "
"invalid signal context?"); "invalid signal context?");
} }

View File

@ -16,12 +16,8 @@
namespace Genode namespace Genode
{ {
/** using Cpu_state_modes = Cpu_state;
* Dummy using Vm_state = Cpu_state;
*/
struct Vm_state { };
using Cpu_state_modes = void*;
} }
#endif /* _VM_STATE_H_ */ #endif /* _VM_STATE_H_ */

View File

@ -1,6 +1,8 @@
/* /*
* \brief Kernel backend for virtual machines * \brief Kernel backend for virtual machines
* \author Stefan Kalkowski * \author Stefan Kalkowski
* \author Reto Buerki
* \author Adrian-Ken Rueegsegger
* \date 2015-06-03 * \date 2015-06-03
*/ */
@ -13,11 +15,16 @@
#include <platform_pd.h> #include <platform_pd.h>
#include <kernel/vm.h> #include <kernel/vm.h>
#include <cpu/cpu_state.h>
#include <pic.h>
Kernel::Vm::Vm(void * const, Kernel::Signal_context * const context, extern void * _vt_vm_entry;
extern void * _mt_client_context_ptr;
Kernel::Vm::Vm(void * const state, Kernel::Signal_context * const context,
void * const) void * const)
: Cpu_job(Cpu_priority::MIN, 0), : Cpu_job(Cpu_priority::MIN, 0),
_state(nullptr), _state((Genode::Vm_state * const) state),
_context(context), _context(context),
_table(nullptr) _table(nullptr)
{ {
@ -30,13 +37,29 @@ Kernel::Vm::~Vm() { }
void Kernel::Vm::exception(unsigned const cpu_id) void Kernel::Vm::exception(unsigned const cpu_id)
{ {
PDBG("Implement me please"); pause();
if (_state->trapno == 200) {
_context->submit(1);
return;
}
if (_state->trapno >= Genode::Cpu_state::INTERRUPTS_START &&
_state->trapno <= Genode::Cpu_state::INTERRUPTS_END) {
pic()->irq_occurred(_state->trapno);
_interrupt(cpu_id);
_context->submit(1);
return;
}
PWRN("VM: triggered unknown exception %lu with error code %lu",
_state->trapno, _state->errcode);
assert(false);
} }
void Kernel::Vm::proceed(unsigned const cpu_id) void Kernel::Vm::proceed(unsigned const cpu_id)
{ {
PDBG("Implement me please"); mtc()->switch_to(reinterpret_cast<Cpu::Context*>(_state), cpu_id,
(addr_t) &_vt_vm_entry, (addr_t) &_mt_client_context_ptr);
} }