vbox: support resetting of a VM

Fixes #1290
This commit is contained in:
Alexander Boettcher 2014-11-11 16:57:01 +01:00 committed by Christian Helmuth
parent cb51d67c8d
commit 3babee4e19
9 changed files with 390 additions and 277 deletions

View File

@ -1 +1 @@
64bd2d2de0305c36048e46c05af5bc6578533ed3
cc82990bfeded59df2befde90f20004f2a5a331d

View File

@ -100,7 +100,7 @@ uint64_t genode_cpu_hz() {
}
bool Vmm_memory::unmap_from_vm(RTGCPHYS GCPhys)
bool Vmm_memory::revoke_from_vm(Region *r)
{
PWRN("%s unimplemented", __func__);
return false;

View File

@ -14,48 +14,48 @@
#include <base/printf.h>
#include <base/thread.h>
#include <iprt/types.h>
#include <stddef.h>
#include <time.h>
extern "C" {
typedef long DUMMY;
#define DUMMY(retval, name) \
DUMMY name(void) { \
int name(void) { \
PDBG( #name " called, not implemented, eip=%p", __builtin_return_address(0)); \
for (;;); \
return retval; \
}
#define CHECKED_DUMMY(retval, name) \
DUMMY name(void) { \
#define CHECKED_DUMMY(TYPE, retval, name) \
TYPE name(void) { \
PINF( #name " called, not implemented, eip=%p", __builtin_return_address(0)); \
return retval; \
}
CHECKED_DUMMY( 0, cpumR3DbgInit)
CHECKED_DUMMY( 0, DBGFR3Init) /* debugger */
CHECKED_DUMMY(int, 0, cpumR3DbgInit)
CHECKED_DUMMY(int, 0, DBGFR3Init) /* debugger */
DUMMY(-1, DBGFR3CoreWrite)
CHECKED_DUMMY( 0, FTMR3Init) /* fault tolerance manager */
CHECKED_DUMMY( 0, pdmR3LdrInitU) /* module loader of pluggable device manager */
CHECKED_DUMMY( 0, PDMR3LdrLoadVMMR0U) /* pretend to have successfully loaded the r0 module */
CHECKED_DUMMY( 0, pdmR3LoadR3U)
CHECKED_DUMMY( 0, pthread_atfork)
CHECKED_DUMMY( 0, pthread_attr_setdetachstate)
CHECKED_DUMMY( 0, pthread_attr_setstacksize)
CHECKED_DUMMY( 0, RTMemProtect)
CHECKED_DUMMY( 0, SELMR3Init) /* selector manager - GDT handling */
CHECKED_DUMMY( 0, sigfillset)
CHECKED_DUMMY( 0, vmmR3SwitcherInit) /* world switcher */
CHECKED_DUMMY(-1, atexit)
CHECKED_DUMMY(-1, getpid)
CHECKED_DUMMY(-1, pdmR3FileR3)
CHECKED_DUMMY(0, setlocale)
CHECKED_DUMMY(-1, sigaddset)
CHECKED_DUMMY(-1, sigemptyset)
CHECKED_DUMMY(-1, siginterrupt)
CHECKED_DUMMY(-1, sysctl)
CHECKED_DUMMY(int, 0, FTMR3Init) /* fault tolerance manager */
CHECKED_DUMMY(int, 0, pdmR3LdrInitU) /* module loader of pluggable device manager */
CHECKED_DUMMY(int, 0, PDMR3LdrLoadVMMR0U) /* pretend to have successfully loaded the r0 module */
CHECKED_DUMMY(int, 0, pdmR3LoadR3U)
CHECKED_DUMMY(int, 0, pthread_atfork)
CHECKED_DUMMY(int, 0, pthread_attr_setdetachstate)
CHECKED_DUMMY(int, 0, pthread_attr_setstacksize)
CHECKED_DUMMY(int, 0, RTMemProtect)
CHECKED_DUMMY(int, 0, SELMR3Init) /* selector manager - GDT handling */
CHECKED_DUMMY(int, 0, sigfillset)
CHECKED_DUMMY(int, 0, vmmR3SwitcherInit) /* world switcher */
CHECKED_DUMMY(int, -1, atexit)
CHECKED_DUMMY(pid_t, -1, getpid)
CHECKED_DUMMY(char *, (char *)-1, pdmR3FileR3)
CHECKED_DUMMY(char *, nullptr, setlocale)
CHECKED_DUMMY(int, -1, sigaddset)
CHECKED_DUMMY(int, -1, sigemptyset)
CHECKED_DUMMY(int, -1, siginterrupt)
CHECKED_DUMMY(int, -1, sysctl)
DUMMY( 0, RTErrCOMGet)
void CPUMPushHyper() { } /* called by 'VMMR3InitRC', but we don't use GC */
DUMMY(-1, DBGCRegisterCommands)
@ -63,12 +63,12 @@ DUMMY(-1, DBGFR3Event)
DUMMY(-1, DBGFR3EventAssertion)
DUMMY(-1, DBGFR3EventBreakpoint)
DUMMY(-1, DBGFR3EventSrc)
CHECKED_DUMMY( 0, DBGFR3EventSrcV)
CHECKED_DUMMY(int, 0, DBGFR3EventSrcV)
void DBGFR3Relocate() { }
DUMMY(-1, DBGFR3Term)
DUMMY(-1, DBGFR3VMMForcedAction)
CHECKED_DUMMY(-4, DBGFR3AsSymbolByAddr) /* -4 == VERR_INVALID_HANDLE */
CHECKED_DUMMY(int, -4, DBGFR3AsSymbolByAddr) /* -4 == VERR_INVALID_HANDLE */
DUMMY(-1, _flockfile)
@ -85,12 +85,12 @@ DUMMY(-1, HWACCMR3PatchTprInstr)
DUMMY(-1, HWACCMR3CheckError)
DUMMY(-1, HWACCMR3RestartPendingIOInstr)
void HWACCMR3Relocate() { }
DUMMY(-1, HWACCMR3Reset)
void HWACCMR3Reset() { }
DUMMY(-1, HWACCMR3Term)
DUMMY(-1, HWACMMR3EnablePatching)
DUMMY(-1, HWACMMR3DisablePatching)
CHECKED_DUMMY( 0, IEMR3Init) /* interpreted execution manager (seems to be just a skeleton) */
CHECKED_DUMMY(int, 0, IEMR3Init) /* interpreted execution manager (seems to be just a skeleton) */
void IEMR3Relocate() { }
DUMMY(-1, IEMR3Term)
@ -98,17 +98,17 @@ DUMMY(-1, MMHyperR0ToCC)
DUMMY(-1, MMHyperR0ToR3)
DUMMY(-1, MMHyperRCToCC)
DUMMY(-1, MMHyperRCToR3)
CHECKED_DUMMY(0, MMHyperGetArea)
CHECKED_DUMMY(RTGCPTR, 0, MMHyperGetArea)
DUMMY(-1, MMR3HeapAPrintfV)
CHECKED_DUMMY( 0, MMR3HyperInitFinalize)
CHECKED_DUMMY( 0, MMR3HyperSetGuard)
CHECKED_DUMMY(int, 0, MMR3HyperInitFinalize)
CHECKED_DUMMY(int, 0, MMR3HyperSetGuard)
DUMMY(-1, MMR3LockCall)
DUMMY(-1, MMR3Term)
DUMMY(-1, MMR3TermUVM)
DUMMY(-1, PDMR3AsyncCompletionTemplateCreateDriver)
DUMMY(-1, PDMR3LdrGetInterfaceSymbols)
CHECKED_DUMMY( 0, PDMR3LdrRelocateU)
void PDMR3LdrRelocateU() { }
DUMMY(-1, pdmR3LdrTermU)
DUMMY(-1, PGMNotifyNxeChanged)
@ -118,11 +118,11 @@ DUMMY(-1, PGMPhysSimpleReadGCPtr)
DUMMY(-1, PGMPhysSimpleWriteGCPtr)
DUMMY(-1, PGMSyncCR3)
CHECKED_DUMMY( 0, PGMR3CheckIntegrity)
CHECKED_DUMMY( 0, PGMR3FinalizeMappings)
CHECKED_DUMMY( 0, PGMR3InitCompleted)
CHECKED_DUMMY( 0, PGMR3InitDynMap) /* reserve space for "dynamic mappings" */
CHECKED_DUMMY( 0, PGMR3InitFinalize)
CHECKED_DUMMY(int, 0, PGMR3CheckIntegrity)
CHECKED_DUMMY(int, 0, PGMR3FinalizeMappings)
CHECKED_DUMMY(int, 0, PGMR3InitCompleted)
CHECKED_DUMMY(int, 0, PGMR3InitDynMap) /* reserve space for "dynamic mappings" */
CHECKED_DUMMY(int, 0, PGMR3InitFinalize)
DUMMY(-1, PGMR3SharedModuleCheckAll)
DUMMY(-1, PGMR3SharedModuleUnregister)
@ -130,7 +130,7 @@ DUMMY(-1, PGMR3SharedModuleRegister)
DUMMY(-1, PGMR3MappingsUnfix)
DUMMY(-1, PGMR3PhysChangeMemBalloon)
DUMMY(-1, PGMR3MappingsFix)
CHECKED_DUMMY( 0, PGMR3MappingsDisable)
DUMMY(-1, PGMR3MappingsDisable)
DUMMY(-1, PGMR3LockCall)
DUMMY(-1, PGMR3PhysAllocateHandyPages)
DUMMY(-1, PGMR3PhysAllocateLargeHandyPage)
@ -158,39 +158,39 @@ DUMMY(-1, PGMSetLargePageUsage)
DUMMY(-1, PGMPhysSimpleDirtyWriteGCPtr)
DUMMY(-1, PGMGetShadowMode)
DUMMY(-1, PGMGetHostMode)
CHECKED_DUMMY(int, 0, PGMGetGuestMode) /* PGMMODE_INVALID == 0 */
int PGMChangeMode() { return 0; }
CHECKED_DUMMY(0, poll) /* needed by 'DrvHostSerial.cpp' */
CHECKED_DUMMY(int, 0, poll) /* needed by 'DrvHostSerial.cpp' */
DUMMY(-1, pthread_key_delete)
DUMMY(-1, RTMemExecFree)
DUMMY(-1, RTMemPageFree)
DUMMY(-1, RTPathAppend)
DUMMY(-1, RTSemEventWaitEx)
CHECKED_DUMMY( 0, SELMR3InitFinalize)
CHECKED_DUMMY(int, 0, SELMR3InitFinalize)
void SELMR3Relocate() { }
CHECKED_DUMMY( 0, SELMR3DisableMonitoring)
DUMMY(-1, SELMR3Reset)
void SELMR3DisableMonitoring () { }
void SELMR3Reset() { }
DUMMY(-1, SELMR3Term)
DUMMY(-1, SELMR3GetSelectorInfo)
DUMMY(-1, libc_select_notify) /* needed for libc_terminal plugin */
DUMMY(-1, DISInstrToStrEx)
CHECKED_DUMMY(-1, signal)
DUMMY(-1, strcat)
DUMMY(-1, strerror)
DUMMY(-1, strpbrk)
CHECKED_DUMMY( 0, SUPR3SetVMForFastIOCtl)
CHECKED_DUMMY(int, 0, SUPR3SetVMForFastIOCtl)
DUMMY(-1, SUPR3HardenedLdrLoadPlugIn)
DUMMY(-1, SUPR3Term)
CHECKED_DUMMY(100000*10, SUPSemEventMultiGetResolution) /* called by 'vmR3HaltGlobal1Init' */
CHECKED_DUMMY(-1, __swsetup)
uint32_t SUPSemEventMultiGetResolution()
{ return 100000*10; /* called by 'vmR3HaltGlobal1Init' */ }
DUMMY(-1, VMMR3FatalDump)
void vmmR3SwitcherRelocate() { }
CHECKED_DUMMY( 0, VMMR3DisableSwitcher)
DUMMY(-1, VMMR3GetHostToGuestSwitcher)
DUMMY(-1, pthread_kill)
@ -202,7 +202,7 @@ DUMMY(-1, RTHeapSimpleFree)
DUMMY(-1, RTAvloU32Get)
DUMMY(-1, RTAvloU32Remove)
DUMMY(-1, RTAvloU32GetBestFit)
DUMMY( 0, RTAvloU32RemoveBestFit)
CHECKED_DUMMY(void *, nullptr, RTAvloU32RemoveBestFit)
DUMMY(-1, RTAvlU32Destroy)
DUMMY(-1, RTAvlU32GetBestFit)
DUMMY(-1, RTAvloU32DoWithAll)
@ -211,13 +211,13 @@ DUMMY(-1, RTAvlU32Get)
DUMMY(-1, RTAvlU32DoWithAll)
DUMMY(-1, RTAvlU32Insert)
CHECKED_DUMMY( 0, IOMR3Init)
CHECKED_DUMMY(int, 0, IOMR3Init)
int IOMR3IOPortRegisterR0() { return 0; }
int IOMR3IOPortRegisterRC() { return 0; }
CHECKED_DUMMY( 0, IOMR3MmioRegisterR0)
CHECKED_DUMMY( 0, IOMR3MmioRegisterRC)
CHECKED_DUMMY(int, 0, IOMR3MmioRegisterR0)
CHECKED_DUMMY(int, 0, IOMR3MmioRegisterRC)
void IOMR3Relocate() { }
DUMMY(-1, IOMR3Reset)
void IOMR3Reset() { }
DUMMY(-1, IOMR3Term)
DUMMY(-1, IOMInterpretOUT)
@ -232,8 +232,8 @@ DUMMY(-1, RTFileQueryFsSizes)
DUMMY(-1, pthread_mutex_timedlock)
CHECKED_DUMMY( 0, PGMHandlerVirtualDeregister) /* XXX */
CHECKED_DUMMY( 0, PGMR3HandlerVirtualRegister) /* XXX */
CHECKED_DUMMY(int, 0, PGMHandlerVirtualDeregister) /* XXX */
CHECKED_DUMMY(int, 0, PGMR3HandlerVirtualRegister) /* XXX */
/*
* Dummies added for storage
@ -278,8 +278,8 @@ DUMMY(-1, RTSymlinkDelete)
DUMMY(-1, RTNetIPv6PseudoChecksumEx)
CHECKED_DUMMY(0, futimes)
CHECKED_DUMMY(0, lutimes)
CHECKED_DUMMY(int, 0, futimes)
CHECKED_DUMMY(int, 0, lutimes)
int __isthreaded;
@ -290,10 +290,10 @@ int PGMFlushTLB() { return 0; }
int PGMInvalidatePage() { return 0; } /* seems to be needed on raw mode only */
int PGMHandlerPhysicalPageTempOff() { return 0; }
int PGMIsLockOwner() { return 0; } /* assertion in EMRemLock */
bool IOMIsLockOwner() { return 0; } /* XXX */
bool PGMIsLockOwner() { return false; } /* assertion in EMRemLock */
bool IOMIsLockOwner() { return false; } /* XXX */
int MMHyperIsInsideArea() { return 0; } /* used by dbgfR3DisasInstrRead */
int PGMPhysReleasePageMappingLock() { return 0; }
void PGMPhysReleasePageMappingLock() { }
} /* extern "C" */

View File

@ -161,8 +161,11 @@ class Guest_ioports
/*
Range *r = _lookup(PortStart, cPorts);
if (r) {
PERR("failure 0x%lx+0x%lx", PortStart, cPorts);
while (1) {}
PERR("io port inseration failure 0x%x+0x%x - '%s'",
PortStart, cPorts,
pDevIns && pDevIns->pReg ? pDevIns->pReg->szName : 0);
dump();
Assert(!r);
return VERR_GENERAL_FAILURE;
}
*/

View File

@ -152,24 +152,32 @@ uint64_t genode_cpu_hz()
}
bool Vmm_memory::unmap_from_vm(RTGCPHYS GCPhys)
bool Vmm_memory::revoke_from_vm(Region *r)
{
size_t const size = 1;
Assert(r);
Region *r = _lookup_unsynchronized(GCPhys, size);
if (!r) return false;
using namespace Genode;
using Genode::addr_t;
addr_t const vmm_local = (addr_t)r->local_addr<addr_t>();
Assert(vmm_local);
Assert(!((r->size() - 1) & vmm_local));
using namespace Nova;
unsigned const order = Genode::log2(r->size() >> PAGE_SIZE_LOG2);
Flexpage_iterator fli(vmm_local, r->size(), 0, ~0UL, 0);
Rights rwx(true, true, true);
revoke(Mem_crd(vmm_local >> PAGE_SIZE_LOG2, order, rwx), false);
Flexpage revoke_page = fli.page();
while (revoke_page.valid()) {
Assert(revoke_page.log2_order >= 12);
Assert(!(((1UL << revoke_page.log2_order) - 1) & revoke_page.addr));
using namespace Nova;
Rights const revoke_rwx(true, true, true);
Crd crd = Mem_crd(revoke_page.addr >> 12, revoke_page.log2_order - 12,
revoke_rwx);
revoke(crd, false);
/* request next page(s) to be revoked */
revoke_page = fli.page();
}
return true;
}

View File

@ -66,7 +66,8 @@ static inline Genode::uint32_t sel_ar_conv_from_nova(Genode::uint16_t v)
* Used to map mmio memory to VM
*/
extern "C" int MMIO2_MAPPED_SYNC(PVM pVM, RTGCPHYS GCPhys, size_t cbWrite,
void **ppv);
void **ppv, Genode::Flexpage_iterator &fli,
bool &writeable);
class Vcpu_handler : public Vmm::Vcpu_dispatcher<pthread>
@ -213,6 +214,7 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher<pthread>
enum { MAP_SIZE = 0x1000UL };
bool writeable = true;
Flexpage_iterator fli;
void *pv = guest_memory()->lookup_ram(reason, MAP_SIZE, fli);
@ -221,11 +223,9 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher<pthread>
* Check whether this is some mmio memory provided by VMM
* we can map, e.g. VMMDev memory or framebuffer currently.
*/
int res = MMIO2_MAPPED_SYNC(_current_vm, reason, MAP_SIZE, &pv);
if (pv && (res == VINF_SUCCESS))
fli = Genode::Flexpage_iterator((addr_t)pv, MAP_SIZE,
reason, MAP_SIZE, reason);
else
int res = MMIO2_MAPPED_SYNC(_current_vm, reason, MAP_SIZE, &pv,
fli, writeable);
if (res != VINF_SUCCESS)
pv = 0;
}
@ -233,16 +233,16 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher<pthread>
if (!pv)
_fpu_save_and_longjmp();
/* fault region is ram - so map it */
enum {
USER_PD = false, GUEST_PGT = true,
READABLE = true, WRITEABLE = true, EXECUTABLE = true
};
Rights const permission(READABLE, WRITEABLE, EXECUTABLE);
/* prepare utcb */
/* fault region can be mapped - prepare utcb */
utcb->set_msg_word(0);
utcb->mtd = Mtd::FPU;
enum {
USER_PD = false, GUEST_PGT = true,
READABLE = true, EXECUTABLE = true
};
Rights permission(READABLE, writeable, EXECUTABLE);
/* add map items until no space is left on utcb anymore */
bool res;

View File

@ -33,6 +33,8 @@
using Genode::Ram_session;
using Genode::Rm_session;
static bool debug = false;
static bool verbose_debug = false;
Vmm_memory *vmm_memory()
{
@ -48,24 +50,60 @@ Guest_memory *guest_memory()
}
static DECLCALLBACK(int) romwritehandler(PVM pVM, RTGCPHYS GCPhys,
void *pvPhys, void *pvBuf,
size_t cbBuf,
PGMACCESSTYPE enmAccessType,
void *pvUser)
{
while (1) {
Assert(!"Somebody tries to write to ROM");
}
return 0;
}
int PGMR3PhysRomRegister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys,
RTGCPHYS cb, const void *pvBinary, uint32_t cbBinary,
uint32_t fFlags, const char *pszDesc)
{
PLOG("PGMR3PhysRomRegister: GCPhys=0x%lx cb=0x%zx pvBinary=0x%p",
(long)GCPhys, (size_t)cb, pvBinary);
PLOG("PGMR3PhysRomRegister: GCPhys=0x%llx cb=0x%llx pvBinary=0x%p - '%s'",
GCPhys, cb, pvBinary, pszDesc);
try {
guest_memory()->add_rom_mapping(GCPhys, cb, pvBinary, pDevIns);
RTGCPHYS GCPhysLast = GCPhys + (cb - 1);
/*
* XXX Try to understand the fShadowed condition
* (see pgmR3PhysRomRegister)
*/
REMR3NotifyPhysRomRegister(pVM, GCPhys, cb, NULL, false /* fShadowed */);
size_t size = (size_t)cb;
Assert(cb == size);
} catch (Guest_memory::Region_conflict) {
return VERR_PGM_MAPPING_CONFLICT; }
void *pv = vmm_memory()->alloc_rom(size, pDevIns);
Assert(pv);
memcpy(pv, pvBinary, size);
/* associate memory of VMM with guest VM */
vmm_memory()->map_to_vm(pDevIns, GCPhys);
guest_memory()->add_rom_mapping(GCPhys, cb, pv, pDevIns);
bool fShadowed = fFlags & PGMPHYS_ROM_FLAGS_SHADOWED;
Assert(!fShadowed);
int rc = PGMR3HandlerPhysicalRegister(pVM,
PGMPHYSHANDLERTYPE_PHYSICAL_WRITE,
GCPhys, GCPhysLast,
romwritehandler,
NULL,
NULL, NULL, 0,
NULL, NULL, 0, pszDesc);
Assert(rc == VINF_SUCCESS);
#ifdef VBOX_WITH_REM
REMR3NotifyPhysRomRegister(pVM, GCPhys, cb, NULL, fShadowed);
#endif
}
catch (Guest_memory::Region_conflict) { return VERR_PGM_MAPPING_CONFLICT; }
catch (Ram_session::Alloc_failed) { return VERR_PGM_MAPPING_CONFLICT; }
catch (Rm_session::Attach_failed) { return VERR_PGM_MAPPING_CONFLICT; }
return VINF_SUCCESS;
}
@ -94,13 +132,13 @@ int PGMPhysWrite(PVM pVM, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
int rc = pfnHandlerR3(pVM, GCPhys, 0, 0, cbWrite, PGMACCESSTYPE_WRITE,
pvUserR3);
if (rc == VINF_PGM_HANDLER_DO_DEFAULT) {
memcpy(pv, pvBuf, cbWrite);
return VINF_SUCCESS;
if (rc != VINF_PGM_HANDLER_DO_DEFAULT) {
PERR("unexpected %s return code %d", __FUNCTION__, rc);
return VERR_GENERAL_FAILURE;
}
PERR("unexpected %s return code %d", __FUNCTION__, rc);
return VERR_GENERAL_FAILURE;
memcpy(pv, pvBuf, cbWrite);
return VINF_SUCCESS;
}
@ -168,7 +206,7 @@ int PGMR3PhysMMIO2Register(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion,
int PGMR3PhysMMIO2Map(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion,
RTGCPHYS GCPhys)
{
size_t cb = vmm_memory()->map_to_vm(pDevIns, iRegion, GCPhys);
size_t cb = vmm_memory()->map_to_vm(pDevIns, GCPhys, iRegion);
if (cb == 0) {
PERR("PGMR3PhysMMIO2Map: lookup for pDevIns=%p iRegion=%u failed\n",
pDevIns, iRegion);
@ -178,7 +216,9 @@ int PGMR3PhysMMIO2Map(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion,
PLOG("PGMR3PhysMMIO2Map: pDevIns=%p iRegion=%u cb=0x%zx GCPhys=0x%lx\n",
pDevIns, iRegion, cb, (long)GCPhys);
#ifdef VBOX_WITH_REM
REMR3NotifyPhysRamRegister(pVM, GCPhys, cb, REM_NOTIFY_PHYS_RAM_FLAGS_MMIO2);
#endif
return VINF_SUCCESS;
}
@ -187,10 +227,20 @@ int PGMR3PhysMMIO2Map(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion,
int PGMR3PhysMMIO2Unmap(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion,
RTGCPHYS GCPhys)
{
PDBG("called %x %x", GCPhys, iRegion);
if (debug)
PDBG("called phys=%llx iRegion=0x%x", GCPhys, iRegion);
vmm_memory()->map_to_vm(pDevIns, iRegion, 0);
size_t size = 1;
bool INVALIDATE = true;
bool ok = vmm_memory()->unmap_from_vm(GCPhys, size, INVALIDATE);
Assert(ok);
#ifdef VBOX_WITH_REM
#if 0 /* XXX */
if (fInformREM)
REMR3NotifyPhysRamDeregister(pVM, GCPhysRangeREM, cbRangeREM);
#endif
#endif
return VINF_SUCCESS;
}
@ -198,7 +248,8 @@ int PGMR3PhysMMIO2Unmap(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion,
bool PGMR3PhysMMIO2IsBase(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys)
{
bool res = vmm_memory()->lookup(GCPhys, 1);
PDBG("called %x %u", GCPhys, res);
if (debug)
PDBG("called phys=%llx res=%u", GCPhys, res);
return res;
}
@ -212,13 +263,18 @@ int PGMR3HandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERTYPE enmType,
const char *pszHandlerRC,
RTRCPTR pvUserRC, const char *pszDesc)
{
PLOG("PGMR3HandlerPhysicalRegister: pszDesc=%s %u GCPhys=0x%lx GCPhysLast=0x%lx r3=0x%p\n",
pszDesc, enmType, (long)GCPhys, (long)GCPhysLast, (void *)pfnHandlerR3);
PLOG("PGMR3HandlerPhysicalRegister: GCPhys=0x%llx-%llx r3=0x%p "
"enmType=%x - '%s'\n",
GCPhys, GCPhysLast, pfnHandlerR3, enmType, pszDesc);
REMR3NotifyHandlerPhysicalRegister(pVM, enmType, GCPhys, GCPhysLast - GCPhys + 1, !!pfnHandlerR3);
bool ok = vmm_memory()->add_handler(GCPhys, GCPhysLast - GCPhys + 1,
pfnHandlerR3, pvUserR3, enmType);
Assert(ok);
vmm_memory()->add_handler(GCPhys, GCPhysLast - GCPhys + 1, pfnHandlerR3,
pvUserR3);
#ifdef VBOX_WITH_REM
REMR3NotifyHandlerPhysicalRegister(pVM, enmType, GCPhys, GCPhysLast -
GCPhys + 1, !!pfnHandlerR3);
#endif
return VINF_SUCCESS;
}
@ -226,15 +282,36 @@ int PGMR3HandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERTYPE enmType,
int PGMHandlerPhysicalDeregister(PVM pVM, RTGCPHYS GCPhys)
{
PDBG("called %x", GCPhys);
/*
for(;;);
pgmHandlerPhysicalResetRamFlags(pVM, pCur);
REMR3NotifyHandlerPhysicalDeregister(pVM, pCur->enmType, GCPhysStart, GCPhysLast - GCPhysStart + 1, !!pCur->pfnHandlerR3, fRestoreAsRAM);
*/
vmm_memory()->add_handler(GCPhys, GCPhys + 1, 0, 0);
size_t size = 1;
#ifdef VBOX_WITH_REM
PFNPGMR3PHYSHANDLER pfnHandlerR3 = 0;
PGMPHYSHANDLERTYPE enmType;
void * pv = vmm_memory()->lookup(GCPhys, size, &pfnHandlerR3, 0, &enmType);
Assert(pv);
if (debug)
PDBG("called phys=%llx enmType=%x", GCPhys, enmType);
#endif
bool ok = vmm_memory()->add_handler(GCPhys, size, 0, 0);
Assert(ok);
#ifdef VBOX_WITH_REM
bool fRestoreAsRAM = pfnHandlerR3 && enmType != PGMPHYSHANDLERTYPE_MMIO;
/* GCPhysstart and size gets written ! */
RTGCPHYS GCPhysStart = GCPhys;
bool io = vmm_memory()->lookup_range(GCPhysStart, size);
Assert(io);
REMR3NotifyHandlerPhysicalDeregister(pVM, enmType, GCPhysStart, size,
!!pfnHandlerR3, fRestoreAsRAM);
#endif
return VINF_SUCCESS;
return VERR_PGM_HANDLER_NOT_FOUND;
}
@ -251,7 +328,9 @@ int PGMR3PhysRegisterRam(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb,
* The lack of allocation-related VERR_PGM_ error codes suggests
* so.
*/
void *pv = vmm_memory()->alloc_ram((size_t)cb);
size_t size = (size_t)cb;
Assert(cb == size);
void *pv = vmm_memory()->alloc_ram(size);
guest_memory()->add_ram_mapping(GCPhys, cb, pv);
@ -270,8 +349,8 @@ int PGMR3PhysRegisterRam(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb,
int PGMMapSetPage(PVM pVM, RTGCPTR GCPtr, uint64_t cb, uint64_t fFlags)
{
PLOG("PGMMapSetPage: GCPtr=0x%lx cb=0x%lx, flags=0x%lx",
(long)GCPtr, (long)cb, (long)fFlags);
PLOG("PGMMapSetPage: GCPtr=0x%llx cb=0x%llx, flags=0x%llx",
GCPtr, cb, fFlags);
return VINF_SUCCESS;
}
@ -303,33 +382,57 @@ int PGMR3Init(PVM pVM)
}
int PGMPhysGCPtr2CCPtrReadOnly(PVMCPU pVCpu, RTGCPTR GCPtr, void const **ppv,
PPGMPAGEMAPLOCK pLock)
{
PERR("%s not implemented - caller 0x%p",
__func__, __builtin_return_address(0));
while (1) { asm volatile ("ud2a"); }
return VERR_GENERAL_FAILURE;
}
int PGMR3PhysTlbGCPhys2Ptr(PVM pVM, RTGCPHYS GCPhys, bool fWritable, void **ppv)
{
size_t const size = 1;
void *pv = guest_memory()->lookup(GCPhys, size);
if (pv) {
*ppv = pv;
return VINF_SUCCESS;
}
size_t const size = 1;
PFNPGMR3PHYSHANDLER pfnHandlerR3 = 0;
void *pvUserR3 = 0;
PGMPHYSHANDLERTYPE enmType;
pv = vmm_memory()->lookup(GCPhys, size, &pfnHandlerR3, &pvUserR3);
void * pv = vmm_memory()->lookup(GCPhys, size, &pfnHandlerR3, &pvUserR3,
&enmType);
if (!pv) {
PERR("%s: lookup for GCPhys=0x%p failed", __func__, GCPhys);
return VERR_PGM_PHYS_TLB_UNASSIGNED;
/* It could be ordinary guest memory - look it up. */
pv = guest_memory()->lookup(GCPhys, size);
if (!pv) {
PERR("%s: lookup for GCPhys=0x%llx failed", __func__, GCPhys);
return VERR_PGM_PHYS_TLB_UNASSIGNED;
}
*ppv = pv;
if (verbose_debug)
PDBG("%llx %u -> 0x%p", GCPhys, fWritable, pv);
return VINF_SUCCESS;
}
/* pv valid - check handlers next */
if (!pfnHandlerR3 && !pvUserR3) {
PERR("%s: %llx %u -> 0x%p no handlers", __func__, GCPhys, fWritable, pv);
*ppv = pv;
return VINF_SUCCESS;
}
PERR("%s: denied access - handlers set - GCPhys=0x%p", __func__, GCPhys);
if (enmType == PGMPHYSHANDLERTYPE_PHYSICAL_WRITE) {
*ppv = pv;
return VINF_PGM_PHYS_TLB_CATCH_WRITE;
}
PERR("%s: denied access - handlers set - GCPhys=0x%llx %p %p %x", __func__, GCPhys, pfnHandlerR3, pvUserR3, enmType);
return VERR_PGM_PHYS_TLB_CATCH_ALL;
}
@ -338,7 +441,9 @@ void PGMR3PhysSetA20(PVMCPU pVCpu, bool fEnable)
{
if (!pVCpu->pgm.s.fA20Enabled != fEnable) {
pVCpu->pgm.s.fA20Enabled = fEnable;
#ifdef VBOX_WITH_REM
REMR3A20Set(pVCpu->pVMR3, pVCpu, fEnable);
#endif
}
return;
@ -356,7 +461,7 @@ void PGMR3PhysWriteU8(PVM pVM, RTGCPHYS GCPhys, uint8_t value)
void *pv = guest_memory()->lookup(GCPhys, sizeof(value));
if (!pv) {
PDBG("invalid write attempt");
PERR("%s: invalid write attempt phy=%llx", __func__, GCPhys);
return;
}
@ -369,7 +474,7 @@ void PGMR3PhysWriteU16(PVM pVM, RTGCPHYS GCPhys, uint16_t value)
void *pv = guest_memory()->lookup(GCPhys, sizeof(value));
if (!pv) {
PDBG("invalid write attempt");
PERR("%s: invalid write attempt phy=%llx", __func__, GCPhys);
return;
}
@ -382,7 +487,7 @@ void PGMR3PhysWriteU32(PVM pVM, RTGCPHYS GCPhys, uint32_t value)
void *pv = guest_memory()->lookup(GCPhys, sizeof(value));
if (!pv) {
PDBG("invalid write attempt");
PERR("%s: invalid write attempt phy=%llx", __func__, GCPhys);
return;
}
@ -395,7 +500,7 @@ uint32_t PGMR3PhysReadU32(PVM pVM, RTGCPHYS GCPhys)
void *pv = guest_memory()->lookup(GCPhys, 4);
if (!pv) {
PDBG("invalid read attempt");
PERR("%s: invalid read attempt phys=%llx", __func__, GCPhys);
return 0;
}
@ -403,113 +508,13 @@ uint32_t PGMR3PhysReadU32(PVM pVM, RTGCPHYS GCPhys)
}
int PGMPhysGCPtr2CCPtrReadOnly(PVMCPU pVCpu, RTGCPTR GCPtr, void const **ppv,
PPGMPAGEMAPLOCK pLock)
{
PDBG("not implemented");
while (1) {}
return VINF_SUCCESS;
}
int PGMR3ChangeMode(PVM pVM, PVMCPU pVCpu, PGMMODE enmGuestMode) {
// Assert(pVCpu->pgm.s.enmShadowMode == PGMMODE_EPT);
// PDBG("not implemented %x %x", pVCpu->pgm.s.enmShadowMode, PGMMODE_EPT);
pVCpu->pgm.s.enmGuestMode = enmGuestMode;
HWACCMR3PagingModeChanged(pVM, pVCpu, pVCpu->pgm.s.enmShadowMode, pVCpu->pgm.s.enmGuestMode);
return VINF_SUCCESS;
}
int PGMChangeMode(PVMCPU pVCpu, uint64_t cr0, uint64_t cr4, uint64_t efer)
{
PGMMODE enmGuestMode;
VMCPU_ASSERT_EMT(pVCpu);
/*
* Calc the new guest mode.
*/
if (!(cr0 & X86_CR0_PE))
enmGuestMode = PGMMODE_REAL;
else if (!(cr0 & X86_CR0_PG))
enmGuestMode = PGMMODE_PROTECTED;
else if (!(cr4 & X86_CR4_PAE))
{
bool const fPse = !!(cr4 & X86_CR4_PSE);
if (pVCpu->pgm.s.fGst32BitPageSizeExtension != fPse)
Log(("PGMChangeMode: CR4.PSE %d -> %d\n", pVCpu->pgm.s.fGst32BitPageSizeExtension, fPse));
pVCpu->pgm.s.fGst32BitPageSizeExtension = fPse;
enmGuestMode = PGMMODE_32_BIT;
}
else if (!(efer & MSR_K6_EFER_LME))
{
if (!(efer & MSR_K6_EFER_NXE))
enmGuestMode = PGMMODE_PAE;
else
enmGuestMode = PGMMODE_PAE_NX;
}
else
{
if (!(efer & MSR_K6_EFER_NXE))
enmGuestMode = PGMMODE_AMD64;
else
enmGuestMode = PGMMODE_AMD64_NX;
}
/*
* Did it change?
*/
if (pVCpu->pgm.s.enmGuestMode == enmGuestMode)
return VINF_SUCCESS;
/* Flush the TLB */
// PGM_INVL_VCPU_TLBS(pVCpu);
VMCPU_FF_SET(pVCpu, VMCPU_FF_TLB_FLUSH);
// PDBG("not implemented %x %x before", enmGuestMode, pVCpu->pgm.s.enmGuestMode);
int rc = PGMR3ChangeMode(pVCpu->CTX_SUFF(pVM), pVCpu, enmGuestMode);
// PDBG("not implemented %x %x out %p", enmGuestMode, pVCpu->pgm.s.enmGuestMode, __builtin_return_address(0));
// return VINF_PGM_CHANGE_MODE;
return rc;
}
/*
* Copied from src/VBox/VMM/VMMAll/PGMAll.cpp
*/
PGMMODE PGMGetGuestMode(PVMCPU pVCpu) { return pVCpu->pgm.s.enmGuestMode; }
VMMDECL(const char *) PGMGetModeName(PGMMODE enmMode)
{
switch (enmMode)
{
case PGMMODE_REAL: return "Real";
case PGMMODE_PROTECTED: return "Protected";
case PGMMODE_32_BIT: return "32-bit";
case PGMMODE_PAE: return "PAE";
case PGMMODE_PAE_NX: return "PAE+NX";
case PGMMODE_AMD64: return "AMD64";
case PGMMODE_AMD64_NX: return "AMD64+NX";
case PGMMODE_NESTED: return "Nested";
case PGMMODE_EPT: return "EPT";
default: return "unknown mode value";
}
}
int PGMPhysGCPhys2CCPtrReadOnly(PVM pVM, RTGCPHYS GCPhys, void const **ppv, PPGMPAGEMAPLOCK pLock)
int PGMPhysGCPhys2CCPtrReadOnly(PVM pVM, RTGCPHYS GCPhys, void const **ppv,
PPGMPAGEMAPLOCK pLock)
{
void *pv = guest_memory()->lookup(GCPhys, 0x1000);
if (!pv) {
PDBG("unknown address pv=%p ppv=%p GCPhys=%llx", pv, ppv, GCPhys);
PERR("unknown address pv=%p ppv=%p GCPhys=%llx", pv, ppv, GCPhys);
guest_memory()->dump();
@ -526,16 +531,21 @@ int PGMPhysGCPhys2CCPtrReadOnly(PVM pVM, RTGCPHYS GCPhys, void const **ppv, PPGM
int PGMHandlerPhysicalReset(PVM, RTGCPHYS GCPhys)
{
if (!vmm_memory()->unmap_from_vm(GCPhys))
PWRN("%s: unbacked region - GCPhys %lx", __func__, GCPhys);
size_t size = 1;
if (!vmm_memory()->unmap_from_vm(GCPhys, size))
PWRN("%s: unbacked region - GCPhys %llx", __func__, GCPhys);
return VINF_SUCCESS;
}
extern "C" int MMIO2_MAPPED_SYNC(PVM pVM, RTGCPHYS GCPhys, size_t cbWrite,
void **ppv)
void **ppv, Genode::Flexpage_iterator &fli,
bool &writeable)
{
using Genode::Flexpage_iterator;
using Genode::addr_t;
/* DON'T USE normal printf in this function - corrupts unsaved UTCB !!! */
PFNPGMR3PHYSHANDLER pfnHandlerR3 = 0;
@ -546,6 +556,8 @@ extern "C" int MMIO2_MAPPED_SYNC(PVM pVM, RTGCPHYS GCPhys, size_t cbWrite,
if (!pv)
return VERR_PGM_PHYS_TLB_UNASSIGNED;
fli = Flexpage_iterator((addr_t)pv, cbWrite, GCPhys, cbWrite, GCPhys);
if (!pfnHandlerR3 && !pvUserR3) {
*ppv = pv;
/* you may map it */
@ -567,9 +579,25 @@ extern "C" int MMIO2_MAPPED_SYNC(PVM pVM, RTGCPHYS GCPhys, size_t cbWrite,
return rc;
}
Vmm::printf("%s: GCPhys=0x%lx failed - unexpected state \n",
__func__, GCPhys);
return VERR_GENERAL_FAILURE;
RTGCPHYS map_start = GCPhys;
size_t map_size = 1;
bool io = vmm_memory()->lookup_range(map_start, map_size);
Assert(io);
pv = vmm_memory()->lookup(map_start, map_size);
Assert(pv);
fli = Flexpage_iterator((addr_t)pv, map_size, map_start, map_size, map_start);
if (debug)
Vmm::printf("%s: GCPhys=0x%llx - %llx+%zx\n",
__func__, GCPhys, map_start, map_size);
*ppv = pv;
writeable = false;
return VINF_SUCCESS;
}
@ -579,8 +607,8 @@ void PGMR3Reset(PVM pVM)
for (VMCPUID i = 0; i < pVM->cCpus; i++)
{
int rc = PGMR3ChangeMode(pVM, &pVM->aCpus[i], PGMMODE_REAL);
AssertRC(rc);
// int rc = PGMR3ChangeMode(pVM, &pVM->aCpus[i], PGMMODE_REAL);
// AssertRC(rc);
}
for (VMCPUID i = 0; i < pVM->cCpus; i++)
@ -590,6 +618,8 @@ void PGMR3Reset(PVM pVM)
VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL);
VMCPU_FF_SET(pVCpu, VMCPU_FF_TLB_FLUSH);
if (!pVCpu->pgm.s.fA20Enabled)
{
pVCpu->pgm.s.fA20Enabled = true;
@ -602,7 +632,7 @@ void PGMR3Reset(PVM pVM)
}
}
PERR("clearing ram and rom areas missing !!!!!!!");
vmm_memory()->revoke_all();
}

View File

@ -0,0 +1,11 @@
+++ src/app/virtualbox/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp
@@ -536,7 +536,8 @@
pView->u32VBVAOffset = HGSMIOFFSET_VOID;
}
- pVGAState->pDrv->pfnVBVADisable (pVGAState->pDrv, uScreenId);
+ if (pVGAState->pDrv->pfnVBVADisable)
+ pVGAState->pDrv->pfnVBVADisable (pVGAState->pDrv, uScreenId);
return VINF_SUCCESS;
}

View File

@ -54,6 +54,7 @@ class Vmm_memory
RTGCPHYS vm_phys;
PFNPGMR3PHYSHANDLER pfnHandlerR3;
void *pvUserR3;
PGMPHYSHANDLERTYPE enmType;
Region(Ram_session &ram, size_t size, PPDMDEVINS pDevIns,
unsigned iRegion)
@ -122,12 +123,69 @@ class Vmm_memory
return 0;
}
void *alloc_ram(size_t cb)
void *alloc_rom(size_t cb, PPDMDEVINS pDevIns)
{
return alloc(cb, 0, 0);
return alloc(cb, pDevIns, ~0U);
}
size_t map_to_vm(PPDMDEVINS pDevIns, unsigned iRegion, RTGCPHYS GCPhys)
void *alloc_ram(size_t cb)
{
return alloc(cb, 0, ~0U);
}
bool add_handler(RTGCPHYS vm_phys, size_t size,
PFNPGMR3PHYSHANDLER pfnHandlerR3, void *pvUserR3,
PGMPHYSHANDLERTYPE enmType = PGMPHYSHANDLERTYPE_PHYSICAL_ALL)
{
Lock::Guard guard(_lock);
Region *r = _lookup_unsynchronized(vm_phys, size);
if (!r) return false;
r->enmType = enmType;
r->pfnHandlerR3 = pfnHandlerR3;
r->pvUserR3 = pvUserR3;
return true;
}
void * lookup(RTGCPHYS vm_phys, size_t size,
PFNPGMR3PHYSHANDLER *ppfnHandlerR3 = 0,
void **ppvUserR3 = 0,
PGMPHYSHANDLERTYPE *enmType = 0)
{
Lock::Guard guard(_lock);
Region *r = _lookup_unsynchronized(vm_phys, size);
if (!r) return 0;
if (enmType) *enmType = r->enmType;
if (ppfnHandlerR3) *ppfnHandlerR3 = r->pfnHandlerR3;
if (ppvUserR3) *ppvUserR3 = r->pvUserR3;
return reinterpret_cast<void *>(r->local_addr<uint8_t>() +
(vm_phys - r->vm_phys));
}
bool lookup_range(RTGCPHYS &vm_phys, size_t &size)
{
Lock::Guard guard(_lock);
Region *r = _lookup_unsynchronized(vm_phys, size);
if (!r)
return false;
vm_phys = r->vm_phys;
size = r->size();
return true;
}
size_t map_to_vm(PPDMDEVINS pDevIns, RTGCPHYS GCPhys,
unsigned iRegion = ~0U)
{
Lock::Guard guard(_lock);
@ -138,36 +196,39 @@ class Vmm_memory
return r ? r->size() : 0;
}
void add_handler(RTGCPHYS vm_phys, size_t size,
PFNPGMR3PHYSHANDLER pfnHandlerR3, void *pvUserR3)
bool unmap_from_vm(RTGCPHYS GCPhys, size_t size, bool invalidate = false)
{
Lock::Guard guard(_lock);
Region *r = _lookup_unsynchronized(vm_phys, size);
Region *r = _lookup_unsynchronized(GCPhys, size);
if (!r) return false;
if (!r) return;
bool result = revoke_from_vm(r);
r->pfnHandlerR3 = pfnHandlerR3;
r->pvUserR3 = pvUserR3;
if (invalidate)
r->vm_phys = 0ULL;
return result;
}
void * lookup(RTGCPHYS vm_phys, size_t size,
PFNPGMR3PHYSHANDLER *ppfnHandlerR3 = 0, void **ppvUserR3 = 0)
/**
* Platform specific implemented.
*/
bool revoke_from_vm(Region *r);
/**
* Revoke all memory (RAM or ROM) from VM
*/
void revoke_all()
{
Lock::Guard guard(_lock);
Region *r = _lookup_unsynchronized(vm_phys, size);
if (!r) return 0;
if (ppfnHandlerR3) *ppfnHandlerR3 = r->pfnHandlerR3;
if (ppvUserR3) *ppvUserR3 = r->pvUserR3;
return reinterpret_cast<void *>(r->local_addr<uint8_t>() +
(vm_phys - r->vm_phys));
for (Region *r = _regions.first(); r; r = r->next())
{
bool ok = revoke_from_vm(r);
Assert(ok);
}
}
bool unmap_from_vm(RTGCPHYS GCPhys);
};