From d1461f6a72f8c5e3f11e4a93c66911d4100d75a7 Mon Sep 17 00:00:00 2001 From: Sebastian Sumpf Date: Fri, 8 Oct 2021 14:12:33 +0200 Subject: [PATCH] vbox6: machine power-down support Use 'StateChange' event to check for machine's 'PowerOff' state, close Gui connections and submit exit signal to EP which in turns calls exit. Fixes #4291 --- repos/ports/src/virtualbox6/main.cc | 30 +++++++++++++++++++++++++++++ repos/ports/src/virtualbox6/nem.cc | 2 +- repos/ports/src/virtualbox6/sup.cc | 17 ++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/repos/ports/src/virtualbox6/main.cc b/repos/ports/src/virtualbox6/main.cc index 390525ffab..62fce932ee 100644 --- a/repos/ports/src/virtualbox6/main.cc +++ b/repos/ports/src/virtualbox6/main.cc @@ -232,6 +232,8 @@ struct Main : Event_handler } } + void destruct_rom() { _rom.destruct(); } + void update_guest(bool enabled) { _guest = enabled; } bool update_from_rom() @@ -262,6 +264,8 @@ struct Main : Event_handler Mouse_shape _mouse_shape { _env }; + Signal_handler
_exit_handler { _env.ep(), *this, &Main::_handle_exit }; + Registry> _gui_connections { }; Signal_handler
_input_handler { _env.ep(), *this, &Main::_handle_input }; @@ -324,6 +328,20 @@ struct Main : Event_handler } } + void _power_down_machine() + { + _capslock.destruct_rom(); + + _gui_connections.for_each([&] (Gui::Connection &gui) { + delete &gui; + }); + + /* signal exit to main entrypoint */ + _exit_handler.local_submit(); + } + + void _handle_exit() { _env.parent().exit(0); } + void handle_vbox_event(VBoxEventType_T, IEvent &) override; bool const _vbox_event_handler_installed = ( _install_vbox_event_handler(), true ); @@ -342,6 +360,7 @@ struct Main : Event_handler event_types.push_back(VBoxEventType_OnMouseCapabilityChanged); event_types.push_back(VBoxEventType_OnMousePointerShapeChanged); event_types.push_back(VBoxEventType_OnKeyboardLedsChanged); + event_types.push_back(VBoxEventType_OnStateChanged); ievent_source->RegisterListener(listener, ComSafeArrayAsInParam(event_types), true); } @@ -449,6 +468,17 @@ void Main::handle_vbox_event(VBoxEventType_T ev_type, IEvent &ev) _capslock.update_guest(!!capslock); } break; + case VBoxEventType_OnStateChanged: + { + ComPtr state_change_ev = &ev; + MachineState_T machineState; + state_change_ev->COMGETTER(State)(&machineState); + + if (machineState == MachineState_PoweredOff) + _power_down_machine(); + + } break; + default: /* ignore other events */ break; } } diff --git a/repos/ports/src/virtualbox6/nem.cc b/repos/ports/src/virtualbox6/nem.cc index 8f08b157b4..466f17d08d 100644 --- a/repos/ports/src/virtualbox6/nem.cc +++ b/repos/ports/src/virtualbox6/nem.cc @@ -228,7 +228,7 @@ int nemR3NativeInitCompleted(PVM pVM, VMINITCOMPLETED enmWhat) } -int nemR3NativeTerm(PVM pVM) STOP +int nemR3NativeTerm(PVM pVM) TRACE(VINF_SUCCESS) /** diff --git a/repos/ports/src/virtualbox6/sup.cc b/repos/ports/src/virtualbox6/sup.cc index 2b4dda36fd..bfa1c14a80 100644 --- a/repos/ports/src/virtualbox6/sup.cc +++ b/repos/ports/src/virtualbox6/sup.cc @@ -631,6 +631,15 @@ static void ioctl(SUPCALLVMMR0 &request) rc = vmmr0_vmmr0_init_emt(request.u.In.pVMR0, request.u.In.idCpu); return; + /* XXX ignore ioctls called during poweroff */ + case VMMR0_DO_GVMM_DEREGISTER_VMCPU: + case VMMR0_DO_VMMR0_TERM: + case VMMR0_DO_PGM_FLUSH_HANDY_PAGES: + case VMMR0_DO_GMM_BALLOONED_PAGES: + case VMMR0_DO_GMM_RESET_SHARED_MODULES: + rc = VINF_SUCCESS; + return; + default: error(__func__, " operation=", (int)operation); rc = VERR_NOT_IMPLEMENTED; @@ -667,6 +676,13 @@ static void ioctl(SUPGETPAGINGMODE &request) } +static void ioctl(SUPPAGEFREE &request) +{ + warning("SUPPAGEFREE called"); + request.Hdr.rc = VINF_SUCCESS; +} + + static void ioctl(SUPPAGEALLOCEX &request) { /* @@ -739,6 +755,7 @@ int suplibOsIOCtl(PSUPLIBDATA pThis, uintptr_t opcode, void *req, size_t len) case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_GET_PAGING_MODE): ioctl(*(SUPGETPAGINGMODE *)req); break; case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_PAGE_ALLOC_EX): ioctl(*(SUPPAGEALLOCEX *)req); break; case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_SET_VM_FOR_FAST): ioctl(*(SUPSETVMFORFAST *)req); break; + case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_PAGE_FREE): ioctl(*(SUPPAGEFREE *)req); break; default: