From 6d8bfb677edfe426d73ec9bbef6dd6ab2bb7acd4 Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Thu, 11 May 2017 13:23:25 +0200 Subject: [PATCH] vbox5: support more memory for VMs (4GB++) Issue #2338 --- repos/ports/src/virtualbox5/pgm.cc | 13 +++ repos/ports/src/virtualbox5/spec/nova/pgm.cc | 85 +++++++++++++------- repos/ports/src/virtualbox5/unimpl.cc | 1 - 3 files changed, 68 insertions(+), 31 deletions(-) diff --git a/repos/ports/src/virtualbox5/pgm.cc b/repos/ports/src/virtualbox5/pgm.cc index 5dd24c08a..6d2d6f67c 100644 --- a/repos/ports/src/virtualbox5/pgm.cc +++ b/repos/ports/src/virtualbox5/pgm.cc @@ -49,6 +49,18 @@ int PGMMapSetPage(PVM pVM, RTGCPTR GCPtr, uint64_t cb, uint64_t fFlags) } +int PGMR3MapPT(PVM, RTGCPTR GCPtr, uint32_t cb, uint32_t fFlags, + PFNPGMRELOCATE pfnRelocate, void *pvUser, const char *pszDesc) +{ + if (verbose) + Genode::log(__func__, " GCPtr=", Genode::Hex(GCPtr), "+", Genode::Hex(cb), + " flags=", Genode::Hex(fFlags), " pvUser=", pvUser, + " desc=", pszDesc); + + return VINF_SUCCESS; +} + + int PGMR3MappingsSize(PVM pVM, uint32_t *pcb) { Genode::log(__func__, ": not implemented ", __builtin_return_address(0)); @@ -59,6 +71,7 @@ int PGMR3MappingsSize(PVM pVM, uint32_t *pcb) } + int pgmMapActivateCR3(PVM, PPGMPOOLPAGE) { if (verbose) diff --git a/repos/ports/src/virtualbox5/spec/nova/pgm.cc b/repos/ports/src/virtualbox5/spec/nova/pgm.cc index 1fcf3016f..b0966d0f3 100644 --- a/repos/ports/src/virtualbox5/spec/nova/pgm.cc +++ b/repos/ports/src/virtualbox5/spec/nova/pgm.cc @@ -147,47 +147,72 @@ int Vcpu_handler::map_memory(RTGCPHYS GCPhys, size_t cbWrite, ); */ - if (PGM_PAGE_GET_PDE_TYPE(pPage) == PGM_PAGE_PDE_TYPE_PDE) { - Genode::addr_t const max_pages = pRam->cb >> PAGE_SHIFT; - Genode::addr_t const superpage_pages = (1 << 21) / 4096; - Genode::addr_t mask = (1 << 21) - 1; - Genode::addr_t super_gcphys = GCPhys & ~mask; + /* setup mapping for just a page as standard */ + fli = Flexpage_iterator(PGM_PAGE_GET_HCPHYS(pPage), 4096, + GCPhys & ~0xFFFUL, 4096, GCPhys & ~0xFFFUL); - RTGCPHYS max_off = super_gcphys - pRam->GCPhys; - Assert (max_off < pRam->cb); + if (PGM_PAGE_GET_PDE_TYPE(pPage) != PGM_PAGE_PDE_TYPE_PDE) + return VINF_SUCCESS; /* one page mapping */ - Genode::addr_t super_hcphys = PGM_PAGE_GET_HCPHYS(pPage) & ~mask; + Genode::addr_t const superpage_log2 = 21; + Genode::addr_t const max_pages = pRam->cb >> PAGE_SHIFT; + Genode::addr_t const superpage_pages = (1UL << superpage_log2) / 4096; + Genode::addr_t const mask = (1UL << superpage_log2) - 1; + Genode::addr_t const super_gcphys = GCPhys & ~mask; - unsigned const i_s = max_off >> PAGE_SHIFT; + RTGCPHYS max_off = super_gcphys - pRam->GCPhys; + if (max_off > pRam->cb) + return VINF_SUCCESS; - Assert (i_s + superpage_pages <= max_pages); + Genode::addr_t super_hcphys = PGM_PAGE_GET_HCPHYS(pPage) & ~mask; - if (VERBOSE_PGM) - Vmm::log(Genode::Hex(PGM_PAGE_GET_HCPHYS(pPage)), "->", - Genode::Hex(GCPhys), " - iPage ", iPage, " [", - i_s, ",", i_s + superpage_pages, ")", " " - "range_size=", Genode::Hex(pRam->cb)); + unsigned const i_s = max_off >> PAGE_SHIFT; - /* paranoia sanity checks */ - for (Genode::addr_t i = i_s; i < i_s + superpage_pages; i++) { - PPGMPAGE page = &pRam->aPages[i]; + if (i_s + superpage_pages > max_pages) + return VINF_SUCCESS; /* one page mapping */ - Genode::addr_t gcpage = pRam->GCPhys + i << PAGE_SHIFT; + if (VERBOSE_PGM) + Vmm::log(Genode::Hex(PGM_PAGE_GET_HCPHYS(pPage)), "->", + Genode::Hex(GCPhys), " - iPage ", iPage, " [", + i_s, ",", i_s + superpage_pages, ")", " " + "range_size=", Genode::Hex(pRam->cb)); - Assert(super_hcphys == (PGM_PAGE_GET_HCPHYS(page) & ~mask)); - Assert(super_gcphys == (gcpage & ~mask)); - Assert(PGM_PAGE_GET_PDE_TYPE(page) == PGM_PAGE_PDE_TYPE_PDE); - Assert(PGM_PAGE_GET_TYPE(page) == PGM_PAGE_GET_TYPE(pPage)); - Assert(PGM_PAGE_GET_STATE(page) == PGM_PAGE_GET_STATE(pPage)); + /* paranoia sanity checks */ + for (Genode::addr_t i = i_s; i < i_s + superpage_pages; i++) { + PPGMPAGE page = &pRam->aPages[i]; + + Genode::addr_t const gcpage = pRam->GCPhys + (i << PAGE_SHIFT); + + if (!(super_hcphys == (PGM_PAGE_GET_HCPHYS(page) & ~mask)) || + !(super_gcphys == (gcpage & ~mask)) || + !(PGM_PAGE_GET_PDE_TYPE(page) == PGM_PAGE_PDE_TYPE_PDE) || + !(PGM_PAGE_GET_TYPE(page) == PGM_PAGE_GET_TYPE(pPage)) || + !(PGM_PAGE_GET_STATE(page) == PGM_PAGE_GET_STATE(pPage))) + { + if (VERBOSE_PGM) + Vmm::error(Genode::Hex(PGM_PAGE_GET_HCPHYS(pPage)), "->", + Genode::Hex(GCPhys), " - iPage ", iPage, " i ", i, " [", + i_s, ",", i_s + superpage_pages, ")", " " + "range_size=", Genode::Hex(pRam->cb), " " + "super_hcphys=", Genode::Hex(super_hcphys), "?=", Genode::Hex((PGM_PAGE_GET_HCPHYS(page) & ~mask)), " " + "super_gcphys=", Genode::Hex(super_gcphys), "?=", Genode::Hex((gcpage & ~mask)), " ", + (int)(PGM_PAGE_GET_PDE_TYPE(page)), "?=", (int)PGM_PAGE_PDE_TYPE_PDE, " ", + (int)(PGM_PAGE_GET_TYPE(page)), "?=", (int)PGM_PAGE_GET_TYPE(pPage), " ", + (int)(PGM_PAGE_GET_STATE(page)), "?=", PGM_PAGE_GET_STATE(pPage)); + return VINF_SUCCESS; /* one page mapping */ } + } - fli = Flexpage_iterator(super_hcphys, 1 << 21, - super_gcphys, 1 << 21, super_gcphys); - } else - fli = Flexpage_iterator(PGM_PAGE_GET_HCPHYS(pPage), 4096, - GCPhys & ~0xFFFUL, 4096, GCPhys & ~0xFFFUL); + /* overwrite one-page mapping with super page mapping */ + fli = Flexpage_iterator(super_hcphys, 1 << superpage_log2, + super_gcphys, 1 << superpage_log2, super_gcphys); - return VINF_SUCCESS; + /* revoke old mappings, e.g. less permissions or small pages */ + Nova::Rights const revoke_rwx(true, true, true); + Nova::Crd crd = Nova::Mem_crd(super_hcphys >> 12, superpage_log2 - 12, revoke_rwx); + Nova::revoke(crd, false); + + return VINF_SUCCESS; /* super page mapping */ } diff --git a/repos/ports/src/virtualbox5/unimpl.cc b/repos/ports/src/virtualbox5/unimpl.cc index 75fa2f61c..b18f39484 100644 --- a/repos/ports/src/virtualbox5/unimpl.cc +++ b/repos/ports/src/virtualbox5/unimpl.cc @@ -83,7 +83,6 @@ DUMMY(PGMR3DbgR3Ptr2GCPhys) DUMMY(PGMR3MappingsUnfix) DUMMY(PGMR3MappingsFix) DUMMY(PGMR3MappingsDisable) -DUMMY(PGMR3MapPT) DUMMY(PGMR3SharedModuleCheckAll) DUMMY(PGMR3SharedModuleUnregister)