parent
d86380d744
commit
417199ea64
|
@ -23,7 +23,7 @@
|
||||||
<HardwareVirtEx enabled="true"/>
|
<HardwareVirtEx enabled="true"/>
|
||||||
<HardwareVirtExNestedPaging enabled="true"/>
|
<HardwareVirtExNestedPaging enabled="true"/>
|
||||||
<HardwareVirtExVPID enabled="true"/>
|
<HardwareVirtExVPID enabled="true"/>
|
||||||
<HardwareVirtExUX enabled="true"/>
|
<HardwareVirtExUX enabled="false"/>
|
||||||
<PAE enabled="false"/>
|
<PAE enabled="false"/>
|
||||||
<LongMode enabled="false"/>
|
<LongMode enabled="false"/>
|
||||||
<HardwareVirtExLargePages enabled="false"/>
|
<HardwareVirtExLargePages enabled="false"/>
|
||||||
|
|
|
@ -23,11 +23,23 @@
|
||||||
#include "sup.h"
|
#include "sup.h"
|
||||||
|
|
||||||
|
|
||||||
static bool enabled = true;
|
static bool enabled_hm = true;
|
||||||
|
static bool enable_pae_nx = false;
|
||||||
|
|
||||||
VMMR3DECL(int) HMR3Init(PVM pVM)
|
VMMR3DECL(int) HMR3Init(PVM pVM)
|
||||||
{
|
{
|
||||||
|
PCFGMNODE pCfgHM = CFGMR3GetChild(CFGMR3GetRoot(pVM), "HM/");
|
||||||
|
|
||||||
|
/* check whether to stay for non-paged modi in recompiler */
|
||||||
|
int rc = CFGMR3QueryBoolDef(pCfgHM, "EnableUX",
|
||||||
|
&pVM->hm.s.vmx.fAllowUnrestricted, true);
|
||||||
|
AssertRCReturn(rc, rc);
|
||||||
|
|
||||||
|
/* check whether to enable pae and nx bit - in 64bit host mode */
|
||||||
|
rc = CFGMR3QueryBoolDef(CFGMR3GetRoot(pVM), "EnablePAE", &enable_pae_nx,
|
||||||
|
false);
|
||||||
|
AssertRCReturn(rc, rc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We always set the fHMEnabled flag. Otherwise, the EM won't
|
* We always set the fHMEnabled flag. Otherwise, the EM won't
|
||||||
* consult us for taking scheduling decisions. The actual switch to
|
* consult us for taking scheduling decisions. The actual switch to
|
||||||
|
@ -53,15 +65,21 @@ VMMR3_INT_DECL(int) HMR3Term(PVM pVM)
|
||||||
|
|
||||||
VMMR3_INT_DECL(int) HMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat)
|
VMMR3_INT_DECL(int) HMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat)
|
||||||
{
|
{
|
||||||
enabled = pVM->hm.s.svm.fSupported || pVM->hm.s.vmx.fSupported;
|
enabled_hm = pVM->hm.s.svm.fSupported || pVM->hm.s.vmx.fSupported;
|
||||||
|
|
||||||
if (!enabled || enmWhat != VMINITCOMPLETED_RING0)
|
if (!enabled_hm || enmWhat != VMINITCOMPLETED_RING0)
|
||||||
return VINF_SUCCESS;
|
return VINF_SUCCESS;
|
||||||
|
|
||||||
int rc = SUPR3CallVMMR0Ex(pVM->pVMR0, 0 /*idCpu*/, VMMR0_DO_HM_SETUP_VM, 0, NULL);
|
int rc = SUPR3CallVMMR0Ex(pVM->pVMR0, 0 /*idCpu*/, VMMR0_DO_HM_SETUP_VM, 0, NULL);
|
||||||
|
|
||||||
if (rc == VINF_SUCCESS) {
|
if (rc == VINF_SUCCESS) {
|
||||||
CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_SEP);
|
CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_SEP);
|
||||||
|
|
||||||
|
/* nova kernel supports solely on 64bit the following features */
|
||||||
|
if (sizeof(void *) > 4 && enable_pae_nx) {
|
||||||
|
CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_PAE);
|
||||||
|
CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_NX);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -94,16 +112,10 @@ VMM_INT_DECL(bool) HMIsLongModeAllowed(PVM pVM)
|
||||||
|
|
||||||
VMMR3DECL(bool) HMR3IsRescheduleRequired(PVM pVM, PCPUMCTX pCtx)
|
VMMR3DECL(bool) HMR3IsRescheduleRequired(PVM pVM, PCPUMCTX pCtx)
|
||||||
{
|
{
|
||||||
/* no re-schedule on AMD-V required - just works */
|
if (pVM->hm.s.vmx.fAllowUnrestricted)
|
||||||
/*
|
|
||||||
if (pVM->hm.s.svm.fSupported)
|
|
||||||
return false;
|
return false;
|
||||||
*/
|
|
||||||
bool reschedule = !CPUMIsGuestInPagedProtectedModeEx(pCtx);
|
|
||||||
|
|
||||||
// PLOG("reschedule %u %u %lx", reschedule, HMR3CanExecuteGuest(pVM, pCtx), pCtx->cr0);
|
return !CPUMIsGuestInPagedProtectedModeEx(pCtx);
|
||||||
|
|
||||||
return reschedule;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -116,30 +128,19 @@ VMMR3DECL(bool) HMR3IsEventPending(PVMCPU pVCpu)
|
||||||
|
|
||||||
VMMR3DECL(bool) HMR3CanExecuteGuest(PVM pVM, PCPUMCTX pCtx)
|
VMMR3DECL(bool) HMR3CanExecuteGuest(PVM pVM, PCPUMCTX pCtx)
|
||||||
{
|
{
|
||||||
PVMCPU pVCpu = VMMGetCpu(pVM);
|
if (!enabled_hm)
|
||||||
|
|
||||||
/* AMD-V just works */
|
|
||||||
/*
|
|
||||||
if (pVM->hm.s.svm.fSupported) {
|
|
||||||
pVCpu->hm.s.fActive = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if (!enabled)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* enable H/W acceleration in protected mode only */
|
PVMCPU pVCpu = VMMGetCpu(pVM);
|
||||||
bool res = (pCtx->cr0 & 1) && (pCtx->cr0 & 0x80000000);
|
|
||||||
/*
|
|
||||||
static bool on = false;
|
|
||||||
|
|
||||||
if (res)
|
if (pVM->hm.s.vmx.fAllowUnrestricted) {
|
||||||
on = true;
|
pVCpu->hm.s.fActive = true;
|
||||||
|
} else
|
||||||
|
/* enable H/W acceleration in protected and paged mode only */
|
||||||
|
pVCpu->hm.s.fActive = CPUMIsGuestInPagedProtectedModeEx(pCtx);
|
||||||
|
|
||||||
if (on)
|
return pVCpu->hm.s.fActive;
|
||||||
PLOG("executeguest %lx -> %x", pCtx->cr0, res);
|
|
||||||
*/
|
|
||||||
pVCpu->hm.s.fActive = res;
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VMM_INT_DECL(int) HMFlushTLB(PVMCPU pVCpu) { return VINF_SUCCESS; }
|
||||||
|
|
|
@ -111,6 +111,7 @@ extern "C" char *getenv(const char *name)
|
||||||
// "+rem_run.e.l.f"
|
// "+rem_run.e.l.f"
|
||||||
// "+pgm.e.l.f"
|
// "+pgm.e.l.f"
|
||||||
"+pdm"
|
"+pdm"
|
||||||
|
// "+cpum.e.l.f"
|
||||||
// "+dev_pcnet.e.l.f"
|
// "+dev_pcnet.e.l.f"
|
||||||
// "+dev_pic.e.l.f"
|
// "+dev_pic.e.l.f"
|
||||||
// "+dev_apic.e.l.f"
|
// "+dev_apic.e.l.f"
|
||||||
|
|
|
@ -350,6 +350,9 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher<pthread>
|
||||||
utcb->gdtr.limit = pCtx->gdtr.cbGdt;
|
utcb->gdtr.limit = pCtx->gdtr.cbGdt;
|
||||||
utcb->gdtr.base = pCtx->gdtr.pGdt;
|
utcb->gdtr.base = pCtx->gdtr.pGdt;
|
||||||
|
|
||||||
|
utcb->mtd |= Mtd::EFER;
|
||||||
|
utcb->write_efer(CPUMGetGuestEFER(pVCpu));
|
||||||
|
|
||||||
Assert(!(VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)));
|
Assert(!(VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -392,6 +395,8 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher<pthread>
|
||||||
pCtx->gdtr.pGdt != utcb->gdtr.base)
|
pCtx->gdtr.pGdt != utcb->gdtr.base)
|
||||||
CPUMSetGuestGDTR(pVCpu, utcb->gdtr.base, utcb->gdtr.limit);
|
CPUMSetGuestGDTR(pVCpu, utcb->gdtr.base, utcb->gdtr.limit);
|
||||||
|
|
||||||
|
CPUMSetGuestEFER(pVCpu, utcb->read_efer());
|
||||||
|
|
||||||
if (pCtx->cr0 != utcb->cr0)
|
if (pCtx->cr0 != utcb->cr0)
|
||||||
CPUMSetGuestCR0(pVCpu, utcb->cr0);
|
CPUMSetGuestCR0(pVCpu, utcb->cr0);
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ class Vcpu_handler_svm : public Vcpu_handler
|
||||||
if (utcb->qual[0] & 0x4) {
|
if (utcb->qual[0] & 0x4) {
|
||||||
unsigned ctrl0 = utcb->ctrl[0];
|
unsigned ctrl0 = utcb->ctrl[0];
|
||||||
|
|
||||||
PERR("invalid gueststate");
|
Vmm::printf("invalid gueststate\n");
|
||||||
|
|
||||||
utcb->ctrl[0] = ctrl0;
|
utcb->ctrl[0] = ctrl0;
|
||||||
utcb->ctrl[1] = 0;
|
utcb->ctrl[1] = 0;
|
||||||
|
|
|
@ -135,6 +135,8 @@ class Vcpu_handler_vmx : public Vcpu_handler
|
||||||
&This::_vmx_default> (exc_base, Mtd::ALL | Mtd::FPU);
|
&This::_vmx_default> (exc_base, Mtd::ALL | Mtd::FPU);
|
||||||
register_handler<VMX_EXIT_INT_WINDOW, This,
|
register_handler<VMX_EXIT_INT_WINDOW, This,
|
||||||
&This::_vmx_irqwin> (exc_base, Mtd::ALL | Mtd::FPU);
|
&This::_vmx_irqwin> (exc_base, Mtd::ALL | Mtd::FPU);
|
||||||
|
register_handler<VMX_EXIT_TASK_SWITCH, This,
|
||||||
|
&This::_vmx_default> (exc_base, Mtd::ALL | Mtd::FPU);
|
||||||
register_handler<VMX_EXIT_CPUID, This,
|
register_handler<VMX_EXIT_CPUID, This,
|
||||||
&This::_vmx_default> (exc_base, Mtd::ALL | Mtd::FPU);
|
&This::_vmx_default> (exc_base, Mtd::ALL | Mtd::FPU);
|
||||||
register_handler<VMX_EXIT_HLT, This,
|
register_handler<VMX_EXIT_HLT, This,
|
||||||
|
|
|
@ -122,8 +122,6 @@ static inline bool vmx_load_state(Nova::Utcb * utcb, VM * pVM, PVMCPU pVCpu)
|
||||||
|
|
||||||
/* tr */
|
/* tr */
|
||||||
Assert(pCtx->tr.Attr.u & X86_SEL_TYPE_SYS_TSS_BUSY_MASK);
|
Assert(pCtx->tr.Attr.u & X86_SEL_TYPE_SYS_TSS_BUSY_MASK);
|
||||||
Assert(!CPUMIsGuestInRealModeEx(pCtx));
|
|
||||||
|
|
||||||
{
|
{
|
||||||
utcb->mtd |= Nova::Mtd::TR;
|
utcb->mtd |= Nova::Mtd::TR;
|
||||||
|
|
||||||
|
|
|
@ -521,7 +521,8 @@ bool PGMPhysIsA20Enabled(PVMCPU pVCpu)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PGMR3PhysWriteU8(PVM pVM, RTGCPHYS GCPhys, uint8_t value)
|
template <typename T>
|
||||||
|
static void PGMR3PhysWrite(PVM pVM, RTGCPHYS GCPhys, T value)
|
||||||
{
|
{
|
||||||
VM_ASSERT_EMT(pVM);
|
VM_ASSERT_EMT(pVM);
|
||||||
|
|
||||||
|
@ -536,62 +537,41 @@ void PGMR3PhysWriteU8(PVM pVM, RTGCPHYS GCPhys, uint8_t value)
|
||||||
(Genode::uint64_t)GCPhys);
|
(Genode::uint64_t)GCPhys);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* sanity check */
|
||||||
void * pvx = vmm_memory()->lookup(GCPhys, sizeof(value));
|
void * pvx = vmm_memory()->lookup(GCPhys, sizeof(value));
|
||||||
Assert(!pvx);
|
Assert(!pvx);
|
||||||
|
|
||||||
*reinterpret_cast<uint8_t *>(pv) = value;
|
*reinterpret_cast<T *>(pv) = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PGMR3PhysWriteU8(PVM pVM, RTGCPHYS GCPhys, uint8_t value)
|
||||||
|
{
|
||||||
|
PGMR3PhysWrite(pVM, GCPhys, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PGMR3PhysWriteU16(PVM pVM, RTGCPHYS GCPhys, uint16_t value)
|
void PGMR3PhysWriteU16(PVM pVM, RTGCPHYS GCPhys, uint16_t value)
|
||||||
{
|
{
|
||||||
VM_ASSERT_EMT(pVM);
|
PGMR3PhysWrite(pVM, GCPhys, value);
|
||||||
|
|
||||||
void *pv = guest_memory()->lookup(GCPhys, sizeof(value));
|
|
||||||
|
|
||||||
if (verbose_debug)
|
|
||||||
PDBG("%s: GCPhys=0x%llx cb=0x%zx pv=%p",
|
|
||||||
__func__, (Genode::uint64_t)GCPhys, sizeof(value), pv);
|
|
||||||
|
|
||||||
if (!pv) {
|
|
||||||
PERR("%s: invalid write attempt phy=%llx", __func__,
|
|
||||||
(Genode::uint64_t)GCPhys);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
void * pvx = vmm_memory()->lookup(GCPhys, sizeof(value));
|
|
||||||
Assert(!pvx);
|
|
||||||
|
|
||||||
*reinterpret_cast<uint16_t *>(pv) = value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PGMR3PhysWriteU32(PVM pVM, RTGCPHYS GCPhys, uint32_t value)
|
void PGMR3PhysWriteU32(PVM pVM, RTGCPHYS GCPhys, uint32_t value)
|
||||||
{
|
{
|
||||||
void *pv = guest_memory()->lookup(GCPhys, sizeof(value));
|
PGMR3PhysWrite(pVM, GCPhys, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static T PGMR3PhysRead(PVM pVM, RTGCPHYS GCPhys)
|
||||||
|
{
|
||||||
|
void *pv = guest_memory()->lookup(GCPhys, sizeof(T));
|
||||||
|
|
||||||
if (verbose_debug)
|
if (verbose_debug)
|
||||||
PDBG("%s: GCPhys=0x%llx cb=0x%zx pv=%p",
|
PDBG("%s: GCPhys=0x%llx cb=0x%zx pv=%p",
|
||||||
__func__, (Genode::uint64_t)GCPhys, sizeof(value), pv);
|
__func__, (Genode::uint64_t)GCPhys, sizeof(T), pv);
|
||||||
|
|
||||||
if (!pv) {
|
|
||||||
PERR("%s: invalid write attempt phy=%llx", __func__,
|
|
||||||
(Genode::uint64_t)GCPhys);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
void * pvx = vmm_memory()->lookup(GCPhys, sizeof(value));
|
|
||||||
Assert(!pvx);
|
|
||||||
|
|
||||||
*reinterpret_cast<uint32_t *>(pv) = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t PGMR3PhysReadU32(PVM pVM, RTGCPHYS GCPhys)
|
|
||||||
{
|
|
||||||
void *pv = guest_memory()->lookup(GCPhys, 4);
|
|
||||||
|
|
||||||
if (verbose_debug)
|
|
||||||
PDBG("%s: GCPhys=0x%llx cb=0x%x pv=%p",
|
|
||||||
__func__, (Genode::uint64_t)GCPhys, 4, pv);
|
|
||||||
|
|
||||||
if (!pv) {
|
if (!pv) {
|
||||||
PERR("%s: invalid read attempt phys=%llx", __func__,
|
PERR("%s: invalid read attempt phys=%llx", __func__,
|
||||||
|
@ -599,10 +579,23 @@ uint32_t PGMR3PhysReadU32(PVM pVM, RTGCPHYS GCPhys)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void * pvx = vmm_memory()->lookup(GCPhys, 4);
|
/* sanity check */
|
||||||
|
void * pvx = vmm_memory()->lookup(GCPhys, sizeof(T));
|
||||||
Assert(!pvx);
|
Assert(!pvx);
|
||||||
|
|
||||||
return *reinterpret_cast<uint32_t *>(pv);
|
return *reinterpret_cast<T *>(pv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint64_t PGMR3PhysReadU64(PVM pVM, RTGCPHYS GCPhys)
|
||||||
|
{
|
||||||
|
return PGMR3PhysRead<uint64_t>(pVM, GCPhys);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t PGMR3PhysReadU32(PVM pVM, RTGCPHYS GCPhys)
|
||||||
|
{
|
||||||
|
return PGMR3PhysRead<uint32_t>(pVM, GCPhys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -764,3 +757,11 @@ VMMDECL(bool) PGMIsLockOwner(PVM pVM)
|
||||||
{
|
{
|
||||||
return PDMCritSectIsOwner(&pVM->pgm.s.CritSectX);
|
return PDMCritSectIsOwner(&pVM->pgm.s.CritSectX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VMM_INT_DECL(void) PGMNotifyNxeChanged(PVMCPU pVCpu, bool fNxe)
|
||||||
|
{
|
||||||
|
if (verbose)
|
||||||
|
PINF("%s - not implemented - %p", __func__,
|
||||||
|
__builtin_return_address(0));
|
||||||
|
}
|
||||||
|
|
|
@ -40,7 +40,6 @@ DUMMY(DBGFR3StackWalkNext)
|
||||||
DUMMY(DBGFR3StackWalkEnd)
|
DUMMY(DBGFR3StackWalkEnd)
|
||||||
|
|
||||||
DUMMY(HMInvalidatePage)
|
DUMMY(HMInvalidatePage)
|
||||||
DUMMY(HMFlushTLB)
|
|
||||||
DUMMY(HMR3EmulateIoBlock)
|
DUMMY(HMR3EmulateIoBlock)
|
||||||
DUMMY(HMR3PatchTprInstr)
|
DUMMY(HMR3PatchTprInstr)
|
||||||
DUMMY(HMR3CheckError)
|
DUMMY(HMR3CheckError)
|
||||||
|
@ -64,7 +63,6 @@ DUMMY(PDMR3LdrGetInterfaceSymbols)
|
||||||
DUMMY(PDMR3LdrQueryRCModFromPC)
|
DUMMY(PDMR3LdrQueryRCModFromPC)
|
||||||
DUMMY(PDMCritSectBothFF)
|
DUMMY(PDMCritSectBothFF)
|
||||||
|
|
||||||
DUMMY(PGMNotifyNxeChanged)
|
|
||||||
DUMMY(PGMPhysGCPtr2GCPhys)
|
DUMMY(PGMPhysGCPtr2GCPhys)
|
||||||
DUMMY(PGMPhysSimpleReadGCPhys)
|
DUMMY(PGMPhysSimpleReadGCPhys)
|
||||||
DUMMY(PGMPhysSimpleReadGCPtr)
|
DUMMY(PGMPhysSimpleReadGCPtr)
|
||||||
|
@ -91,7 +89,6 @@ DUMMY(PGMR3PhysGCPhys2CCPtrExternal)
|
||||||
DUMMY(PGMR3PhysGCPhys2CCPtrReadOnlyExternal)
|
DUMMY(PGMR3PhysGCPhys2CCPtrReadOnlyExternal)
|
||||||
DUMMY(PGMR3PhysMMIO2MapKernel)
|
DUMMY(PGMR3PhysMMIO2MapKernel)
|
||||||
DUMMY(PGMR3PhysReadU16)
|
DUMMY(PGMR3PhysReadU16)
|
||||||
DUMMY(PGMR3PhysReadU64)
|
|
||||||
DUMMY(PGMR3PhysRomProtect)
|
DUMMY(PGMR3PhysRomProtect)
|
||||||
|
|
||||||
DUMMY(PGMPrefetchPage)
|
DUMMY(PGMPrefetchPage)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user