diff --git a/base-hw/include/kernel/syscalls.h b/base-hw/include/kernel/syscalls.h index 17121d875..5687acbab 100644 --- a/base-hw/include/kernel/syscalls.h +++ b/base-hw/include/kernel/syscalls.h @@ -80,8 +80,9 @@ namespace Kernel ACK_SIGNAL = 29, /* vm specific */ - NEW_VM = 24, - RUN_VM = 25, + NEW_VM = 24, + RUN_VM = 25, + PAUSE_VM = 31, }; /***************************************************************** @@ -546,6 +547,17 @@ namespace Kernel */ inline void run_vm(unsigned const id) { syscall(RUN_VM, (Syscall_arg)id); } + + + /** + * Stop execution of a virtual-machine + * + * \param id ID of the targeted VM + * + * Restricted to core threads. + */ + inline void pause_vm(unsigned const id) { + syscall(PAUSE_VM, (Syscall_arg)id); } } #endif /* _INCLUDE__KERNEL__SYSCALLS_H_ */ diff --git a/base-hw/include/vm_session/client.h b/base-hw/include/vm_session/client.h index 482d25f49..b5f84a83b 100644 --- a/base-hw/include/vm_session/client.h +++ b/base-hw/include/vm_session/client.h @@ -41,8 +41,8 @@ namespace Genode void exception_handler(Signal_context_capability handler) { call(handler); } - void run() { - call(); } + void run() { call(); } + void pause() { call(); } }; } diff --git a/base-hw/include/vm_session/vm_session.h b/base-hw/include/vm_session/vm_session.h index 2dad7b335..51a8fa488 100644 --- a/base-hw/include/vm_session/vm_session.h +++ b/base-hw/include/vm_session/vm_session.h @@ -46,6 +46,12 @@ namespace Genode { */ virtual void run(void) {} + /** + * Stop execution of the VM + */ + virtual void pause(void) {} + + /********************* ** RPC declaration ** *********************/ @@ -54,7 +60,9 @@ namespace Genode { GENODE_RPC(Rpc_exception_handler, void, exception_handler, Signal_context_capability); GENODE_RPC(Rpc_run, void, run); - GENODE_RPC_INTERFACE(Rpc_cpu_state, Rpc_exception_handler, Rpc_run); + GENODE_RPC(Rpc_pause, void, pause); + GENODE_RPC_INTERFACE(Rpc_cpu_state, Rpc_exception_handler, + Rpc_run, Rpc_pause); }; } diff --git a/base-hw/src/core/include/vm_session_component.h b/base-hw/src/core/include/vm_session_component.h index c1f6a0b17..6a27f1000 100644 --- a/base-hw/src/core/include/vm_session_component.h +++ b/base-hw/src/core/include/vm_session_component.h @@ -67,6 +67,7 @@ namespace Genode { Dataspace_capability cpu_state(void) { return _ds_cap; } void exception_handler(Signal_context_capability handler); void run(void); + void pause(void); }; } diff --git a/base-hw/src/core/kernel.cc b/base-hw/src/core/kernel.cc index 38ec98415..6e6e21977 100644 --- a/base-hw/src/core/kernel.cc +++ b/base-hw/src/core/kernel.cc @@ -691,8 +691,13 @@ namespace Kernel Signal_context * const context) : _state(state), _context(context) { } - void run() { - cpu_scheduler()->insert(this); } + + /************************** + ** Vm_session interface ** + **************************/ + + void run() { cpu_scheduler()->insert(this); } + void pause() { cpu_scheduler()->remove(this); } /********************** @@ -1300,6 +1305,23 @@ namespace Kernel } + /** + * Do specific syscall for 'user', for details see 'syscall.h' + */ + void do_pause_vm(Thread * const user) + { + /* check permissions */ + assert(user->pd_id() == core_id()); + + /* get targeted vm via its id */ + Vm * const vm = Vm::pool()->object(user->user_arg_1()); + assert(vm); + + /* pause targeted vm */ + vm->pause(); + } + + /** * Handle a syscall request * @@ -1344,6 +1366,7 @@ namespace Kernel /* 28 */ do_resume_faulter, /* 29 */ do_ack_signal, /* 30 */ do_kill_signal_context, + /* 31 */ do_pause_vm, }; enum { MAX_SYSCALL = sizeof(handle_sysc)/sizeof(handle_sysc[0]) - 1 }; diff --git a/base-hw/src/core/vm_session_component.cc b/base-hw/src/core/vm_session_component.cc index 537c4570a..2c57b89d7 100644 --- a/base-hw/src/core/vm_session_component.cc +++ b/base-hw/src/core/vm_session_component.cc @@ -44,6 +44,16 @@ void Vm_session_component::run(void) } +void Vm_session_component::pause(void) +{ + if (!_vm_id) { + PWRN("No exception handler registered!"); + return; + } + Kernel::pause_vm(_vm_id); +} + + Vm_session_component::Vm_session_component(Rpc_entrypoint *ds_ep, Range_allocator *ram_alloc, size_t ram_quota)