vbox5: support more memory for VMs (4GB++)

Issue #2338
This commit is contained in:
Alexander Boettcher 2017-05-11 13:23:25 +02:00 committed by Christian Helmuth
parent b1419d7566
commit 6d8bfb677e
3 changed files with 68 additions and 31 deletions

View File

@ -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)

View File

@ -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 */
}

View File

@ -83,7 +83,6 @@ DUMMY(PGMR3DbgR3Ptr2GCPhys)
DUMMY(PGMR3MappingsUnfix)
DUMMY(PGMR3MappingsFix)
DUMMY(PGMR3MappingsDisable)
DUMMY(PGMR3MapPT)
DUMMY(PGMR3SharedModuleCheckAll)
DUMMY(PGMR3SharedModuleUnregister)