2014-09-23 13:01:47 +02:00
|
|
|
/*
|
|
|
|
* \brief VirtualBox hardware-acceleration manager
|
|
|
|
* \author Norman Feske
|
|
|
|
* \date 2013-08-20
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2017-02-20 13:23:52 +01:00
|
|
|
* Copyright (C) 2013-2017 Genode Labs GmbH
|
2014-09-23 13:01:47 +02:00
|
|
|
*
|
|
|
|
* This file is distributed under the terms of the GNU General Public License
|
|
|
|
* version 2.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Genode includes */
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
#include <base/log.h>
|
2014-09-23 13:01:47 +02:00
|
|
|
|
|
|
|
/* VirtualBox includes */
|
|
|
|
#include "HMInternal.h" /* enable access to hm.s.* */
|
|
|
|
#include <VBox/vmm/hm.h>
|
|
|
|
#include <VBox/vmm/vm.h>
|
|
|
|
|
|
|
|
/* Genode's VirtualBox includes */
|
|
|
|
#include "sup.h"
|
|
|
|
|
|
|
|
|
2015-11-26 14:19:42 +01:00
|
|
|
static bool enabled_hm = true;
|
|
|
|
static bool enable_pae_nx = false;
|
|
|
|
static bool enable_64bit = false;
|
2014-09-23 13:01:47 +02:00
|
|
|
|
|
|
|
VMMR3DECL(int) HMR3Init(PVM pVM)
|
|
|
|
{
|
2015-01-14 17:31:34 +01:00
|
|
|
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);
|
|
|
|
|
2015-11-26 14:19:42 +01:00
|
|
|
/* check whether to enable long-mode bit - in 64bit host mode */
|
|
|
|
rc = CFGMR3QueryBoolDef(pCfgHM, "64bitEnabled", &enable_64bit, false);
|
|
|
|
AssertRCReturn(rc, rc);
|
|
|
|
|
2014-09-23 13:01:47 +02:00
|
|
|
/*
|
|
|
|
* We always set the fHMEnabled flag. Otherwise, the EM won't
|
|
|
|
* consult us for taking scheduling decisions. The actual switch to
|
|
|
|
* HW accelerated mode is still dependent on the result of the
|
|
|
|
* HMR3CanExecuteGuest function.
|
|
|
|
*/
|
|
|
|
pVM->fHMEnabled = true;
|
|
|
|
|
|
|
|
for (VMCPUID i = 0; i < pVM->cCpus; i++)
|
|
|
|
pVM->aCpus[i].hm.s.fActive = false;
|
|
|
|
|
|
|
|
pVM->fHMEnabledFixed = true;
|
|
|
|
|
|
|
|
return VINF_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VMMR3_INT_DECL(int) HMR3Term(PVM pVM)
|
|
|
|
{
|
|
|
|
return VINF_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VMMR3_INT_DECL(int) HMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat)
|
|
|
|
{
|
2015-01-14 17:31:34 +01:00
|
|
|
enabled_hm = pVM->hm.s.svm.fSupported || pVM->hm.s.vmx.fSupported;
|
2014-09-23 13:01:47 +02:00
|
|
|
|
2015-01-14 17:31:34 +01:00
|
|
|
if (!enabled_hm || enmWhat != VMINITCOMPLETED_RING0)
|
2014-09-23 13:01:47 +02:00
|
|
|
return VINF_SUCCESS;
|
|
|
|
|
|
|
|
int rc = SUPR3CallVMMR0Ex(pVM->pVMR0, 0 /*idCpu*/, VMMR0_DO_HM_SETUP_VM, 0, NULL);
|
|
|
|
|
|
|
|
if (rc == VINF_SUCCESS) {
|
|
|
|
CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_SEP);
|
2015-01-14 17:31:34 +01:00
|
|
|
|
|
|
|
/* nova kernel supports solely on 64bit the following features */
|
|
|
|
if (sizeof(void *) > 4 && enable_pae_nx) {
|
|
|
|
CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_PAE);
|
|
|
|
CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_NX);
|
|
|
|
}
|
2015-11-26 14:19:42 +01:00
|
|
|
if (sizeof(void *) > 4 && enable_64bit) {
|
|
|
|
CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_LONG_MODE);
|
|
|
|
CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_SYSCALL);
|
|
|
|
CPUMSetGuestCpuIdFeature(pVM, CPUMCPUIDFEATURE_LAHF);
|
|
|
|
}
|
2014-09-23 13:01:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VMMDECL(bool) HMIsEnabledNotMacro(PVM pVM)
|
|
|
|
{
|
|
|
|
Assert(pVM->fHMEnabledFixed);
|
|
|
|
return pVM->fHMEnabled;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VMMR3DECL(bool) HMR3IsVmxPreemptionTimerUsed(PVM pVM)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VMMR3DECL(bool) HMR3IsActive(PVMCPU pVCpu)
|
|
|
|
{
|
|
|
|
return pVCpu->hm.s.fActive;
|
|
|
|
}
|
|
|
|
|
|
|
|
VMM_INT_DECL(bool) HMIsLongModeAllowed(PVM pVM)
|
|
|
|
{
|
|
|
|
return HMIsEnabled(pVM) && pVM->hm.s.fAllow64BitGuests;
|
|
|
|
}
|
|
|
|
|
|
|
|
VMMR3DECL(bool) HMR3IsRescheduleRequired(PVM pVM, PCPUMCTX pCtx)
|
|
|
|
{
|
2015-01-14 17:31:34 +01:00
|
|
|
if (pVM->hm.s.vmx.fAllowUnrestricted)
|
2014-09-23 13:01:47 +02:00
|
|
|
return false;
|
|
|
|
|
2015-01-14 17:31:34 +01:00
|
|
|
return !CPUMIsGuestInPagedProtectedModeEx(pCtx);
|
2014-09-23 13:01:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VMMR3DECL(bool) HMR3IsEventPending(PVMCPU pVCpu)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VMMR3DECL(bool) HMR3CanExecuteGuest(PVM pVM, PCPUMCTX pCtx)
|
|
|
|
{
|
2015-01-14 17:31:34 +01:00
|
|
|
if (!enabled_hm)
|
|
|
|
return false;
|
|
|
|
|
2014-09-23 13:01:47 +02:00
|
|
|
PVMCPU pVCpu = VMMGetCpu(pVM);
|
|
|
|
|
2015-01-14 17:31:34 +01:00
|
|
|
if (pVM->hm.s.vmx.fAllowUnrestricted) {
|
2014-09-23 13:01:47 +02:00
|
|
|
pVCpu->hm.s.fActive = true;
|
2015-01-14 17:31:34 +01:00
|
|
|
} else
|
|
|
|
/* enable H/W acceleration in protected and paged mode only */
|
|
|
|
pVCpu->hm.s.fActive = CPUMIsGuestInPagedProtectedModeEx(pCtx);
|
2014-09-23 13:01:47 +02:00
|
|
|
|
2015-01-14 17:31:34 +01:00
|
|
|
return pVCpu->hm.s.fActive;
|
|
|
|
}
|
2014-09-23 13:01:47 +02:00
|
|
|
|
|
|
|
|
2015-01-14 17:31:34 +01:00
|
|
|
VMM_INT_DECL(int) HMFlushTLB(PVMCPU pVCpu) { return VINF_SUCCESS; }
|
2016-09-21 11:50:03 +02:00
|
|
|
|
|
|
|
|
|
|
|
void HMR3ResetCpu(PVMCPU pVCpu) { }
|