From bafe3c3fc3cece3a18cd0abb53291698a6c46918 Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Wed, 13 Mar 2019 13:39:04 +0100 Subject: [PATCH] vbox5: check memory configuration stricter The required memory of the VMM depends on the VM memory configuration (vbox) and the available screen resolution. Check for insane configurations in the beginning to avoid late surprises. Issue #3216 --- repos/ports/src/virtualbox5/accloff/sup.cc | 9 +++++- repos/ports/src/virtualbox5/frontend/main.cc | 28 +++++++++++++++-- repos/ports/src/virtualbox5/spec/nova/sup.cc | 7 +++-- repos/ports/src/virtualbox5/sup.cc | 32 ++++++-------------- repos/ports/src/virtualbox5/sup.h | 2 +- 5 files changed, 48 insertions(+), 30 deletions(-) diff --git a/repos/ports/src/virtualbox5/accloff/sup.cc b/repos/ports/src/virtualbox5/accloff/sup.cc index fc234927b..800f605e5 100644 --- a/repos/ports/src/virtualbox5/accloff/sup.cc +++ b/repos/ports/src/virtualbox5/accloff/sup.cc @@ -127,7 +127,14 @@ void genode_update_tsc(void (*update_func)(void), unsigned long update_us) HRESULT genode_setup_machine(ComObjPtr machine) { - return genode_check_memory_config(machine); + ULONG memory_vbox; + HRESULT rc = machine->COMGETTER(MemorySize)(&memory_vbox); + if (FAILED(rc)) + return rc; + + size_t const vmm_memory = 1024ULL * 1024 * (memory_vbox + 16); + + return genode_check_memory_config(machine, vmm_memory); } diff --git a/repos/ports/src/virtualbox5/frontend/main.cc b/repos/ports/src/virtualbox5/frontend/main.cc index bd5d0d2d4..299f328fb 100644 --- a/repos/ports/src/virtualbox5/frontend/main.cc +++ b/repos/ports/src/virtualbox5/frontend/main.cc @@ -167,8 +167,7 @@ HRESULT setupmachine(Genode::Env &env) static Bstr gaFramebufferId[64]; - unsigned uScreenId; - for (uScreenId = 0; uScreenId < cMonitors; uScreenId++) + for (unsigned uScreenId = 0; uScreenId < cMonitors; uScreenId++) { Genodefb *fb = new Genodefb(env); HRESULT rc = display->AttachFramebuffer(uScreenId, fb, gaFramebufferId[uScreenId].asOutParam()); @@ -182,6 +181,12 @@ HRESULT setupmachine(Genode::Env &env) if (FAILED(rc)) return rc; + /* check whether enough memory is available for VM + VMM */ + ULONG const required_memory_vm = (13 * 1024 + 6 * memory_vbox) << 10; + rc = genode_check_memory_config(machine, required_memory_vm); + if (FAILED(rc)) + return rc; + /* wait until VM is up */ MachineState_T machineState = MachineState_Null; do { @@ -209,6 +214,25 @@ HRESULT setupmachine(Genode::Env &env) genodeConsole->init_backends(gKeyboard, gMouse); + /* check whether enough memory for the fb is available */ + ULONG required_memory_fb = 0; + for (unsigned uScreenId = 0; uScreenId < cMonitors; uScreenId++) + { + IFramebuffer * aFramebuffer = nullptr; + HRESULT rc = display->QueryFramebuffer(uScreenId, &aFramebuffer); + Genodefb * fb = dynamic_cast(aFramebuffer); + if (FAILED(rc) || !fb) + continue; + + required_memory_fb += fb->w() * fb->h() * 4; + } + if (!required_memory_fb) + required_memory_fb = 4096 * 2160 * 4; + + rc = genode_check_memory_config(machine, required_memory_fb); + if (FAILED(rc)) + return rc; + return rc; } diff --git a/repos/ports/src/virtualbox5/spec/nova/sup.cc b/repos/ports/src/virtualbox5/spec/nova/sup.cc index dde21ea4b..31d3f19b9 100644 --- a/repos/ports/src/virtualbox5/spec/nova/sup.cc +++ b/repos/ports/src/virtualbox5/spec/nova/sup.cc @@ -170,10 +170,11 @@ HRESULT genode_setup_machine(ComObjPtr machine) * - second chunkid (1..2) is reserved for handy pages allocation * - another chunkid is used additional for handy pages but as large page */ - HRESULT ret = genode_check_memory_config(machine); - + size_t const vmm_memory = 1024ULL * 1024 * (memory_vbox + 16) + + (CHUNKID_START + 1) * GMM_CHUNK_SIZE; + HRESULT ret = genode_check_memory_config(machine, vmm_memory); if (ret == VINF_SUCCESS) - vm_memory(1024ULL * 1024 * memory_vbox + (CHUNKID_START + 1) * GMM_CHUNK_SIZE); + vm_memory(vmm_memory); return ret; }; diff --git a/repos/ports/src/virtualbox5/sup.cc b/repos/ports/src/virtualbox5/sup.cc index aa7408f3b..02e08503d 100644 --- a/repos/ports/src/virtualbox5/sup.cc +++ b/repos/ports/src/virtualbox5/sup.cc @@ -376,30 +376,16 @@ void genode_VMMR0_DO_GVMM_REGISTER_VMCPU(PVMR0 pVMR0, VMCPUID idCpu) } -HRESULT genode_check_memory_config(ComObjPtr machine) +HRESULT genode_check_memory_config(ComObjPtr, + size_t const memory_vmm) { - HRESULT rc; - - /* Validate configured memory of vbox file and Genode config */ - ULONG memory_vbox; - rc = machine->COMGETTER(MemorySize)(&memory_vbox); - if (FAILED(rc)) - return rc; - /* Request max available memory */ - size_t memory_genode = genode_env().pd().avail_ram().value >> 20; - size_t memory_vmm = 28; + size_t const memory_available = genode_env().pd().avail_ram().value; - if (memory_vbox + memory_vmm > memory_genode) { - using Genode::error; - error("Configured memory ", memory_vbox, " MB (vbox file) is insufficient."); - error(memory_genode, " MB (1) - ", - memory_vmm, " MB (2) = ", - memory_genode - memory_vmm, " MB (3)"); - error("(1) available memory based defined by Genode config"); - error("(2) minimum memory required for VBox VMM"); - error("(3) maximal available memory to VM"); - return E_FAIL; - } - return S_OK; + if (memory_vmm <= memory_available) + return S_OK; + + Genode::error("Available memory too low to start the VM - available: ", + memory_vmm, "MB < ", memory_available, "MB requested"); + return E_FAIL; } diff --git a/repos/ports/src/virtualbox5/sup.h b/repos/ports/src/virtualbox5/sup.h index 6133c81a7..05f12958d 100644 --- a/repos/ports/src/virtualbox5/sup.h +++ b/repos/ports/src/virtualbox5/sup.h @@ -26,7 +26,7 @@ #include "MachineImpl.h" HRESULT genode_setup_machine(ComObjPtr machine); -HRESULT genode_check_memory_config(ComObjPtr machine); +HRESULT genode_check_memory_config(ComObjPtr machine, size_t); /** * Returns true if a vCPU could be started. If false we run without