/* $Id$ */
/** @file
* HM - All contexts.
*/
/*
* Copyright (C) 2006-2014 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#include "HMInternal.h"
#include <iprt/asm-amd64-x86.h>
/**
*
* @retval @c true if used.
* @retval @c false if software virtualization (raw-mode) is used.
* @param pVM The cross context VM structure.
* @sa HMIsEnabled, HMR3IsEnabled
* @internal
*/
{
return pVM->fHMEnabled;
}
/**
* Queues a page for invalidation
*
* @returns VBox status code.
* @param pVCpu Pointer to the VMCPU.
* @param GCVirt Page to invalidate
*/
{
/* Nothing to do if a TLB flush is already pending */
return;
#if 1
#else
/* Be very careful when activating this code! */
else
#endif
}
/**
* Invalidates a guest page
*
* @returns VBox status code.
* @param pVCpu Pointer to the VMCPU.
* @param GCVirt Page to invalidate
*/
{
#ifdef IN_RING0
#else
return VINF_SUCCESS;
#endif
}
/**
* Flushes the guest TLB.
*
* @returns VBox status code.
* @param pVCpu Pointer to the VMCPU.
*/
{
LogFlow(("HMFlushTLB\n"));
return VINF_SUCCESS;
}
#ifdef IN_RING0
/**
* Dummy RTMpOnSpecific handler since RTMpPokeCpu couldn't be used.
*
*/
{
return;
}
/**
* Wrapper for RTMpPokeCpu to deal with VERR_NOT_SUPPORTED.
*/
{
/* Not implemented on some platforms (Darwin, Linux kernel < 2.6.19); fall
back to a less efficient implementation (broadcast). */
if (rc == VERR_NOT_SUPPORTED)
{
/* synchronous. */
}
else
{
if (rc == VINF_SUCCESS)
else
/** @todo If more than one CPU is going to be poked, we could optimize this
* operation by poking them first and wait afterwards. Would require
* recording who to poke and their current cWorldSwitchExits values,
* that's something not suitable for stack... So, pVCpu->hm.s.something
* then. */
/* Spin until the VCPU has switched back (poking is async). */
ASMNopPause();
if (rc == VINF_SUCCESS)
else
}
}
#endif /* IN_RING0 */
#ifndef IN_RC
/**
* Poke an EMT so it can perform the appropriate TLB shootdowns.
*
* @param pVCpu The handle of the virtual CPU to poke.
* @param fAccountFlushStat Whether to account the call to
* StatTlbShootdownFlush or StatTlbShootdown.
*/
{
{
if (fAccountFlushStat)
else
#ifdef IN_RING0
if (idHostCpu != NIL_RTCPUID)
#else
#endif
}
else
}
/**
* Invalidates a guest page on all VCPUs.
*
* @returns VBox status code.
* @param pVM Pointer to the VM.
* @param GCVirt Page to invalidate
*/
{
{
/* Nothing to do if a TLB flush is already pending; the VCPU should
have already been poked if it were active. */
continue;
else
{
}
}
return VINF_SUCCESS;
}
/**
* Flush the TLBs of all VCPUs.
*
* @returns VBox status code.
* @param pVM Pointer to the VM.
*/
{
{
/* Nothing to do if a TLB flush is already pending; the VCPU should
have already been poked if it were active. */
{
}
}
return VINF_SUCCESS;
}
#endif /* !IN_RC */
/**
* Checks if nested paging is enabled.
*
* @returns true if nested paging is active, false otherwise.
* @param pVM Pointer to the VM.
*
* @remarks Works before hmR3InitFinalizeR0.
*/
{
}
/**
* Checks if both nested paging and unhampered guest execution are enabled.
*
* The almost complete guest execution in harware is only applicable to VT-x.
*
* @returns true if we have both enabled, otherwise false.
* @param pVM Pointer to the VM.
*
* @remarks Works before hmR3InitFinalizeR0.
*/
{
return HMIsEnabled(pVM)
}
/**
* Checks if this VM is long-mode capable.
*
* @returns true if long mode is allowed, false otherwise.
* @param pUVM The user mode VM handle.
*/
{
}
/**
* Checks if MSR bitmaps are available. It is assumed that when it's available
* it will be used as well.
*
* @returns true if MSR bitmaps are available, false otherwise.
* @param pVM Pointer to the VM.
*/
{
if (HMIsEnabled(pVM))
{
return true;
{
return true;
}
}
return false;
}
/**
*
* @returns shadow paging mode
* @param pVM Pointer to the VM.
*/
{
return PGMMODE_NESTED;
return PGMMODE_EPT;
}
/**
* Invalidates a guest page by physical address
*
* NOTE: Assumes the current instruction references this physical page though a virtual address!!
*
* @returns VBox status code.
* @param pVM Pointer to the VM.
* @param GCPhys Page to invalidate
*/
{
if (!HMIsNestedPagingActive(pVM))
return VINF_SUCCESS;
#ifdef IN_RING0
{
{
{
/** @todo r=ramshankar: Intel does not support flushing by guest physical
* address either. See comment in VMXR0InvalidatePhysPage(). Fix this. */
}
else
{
}
}
return VINF_SUCCESS;
}
/* AMD-V doesn't support invalidation with guest physical addresses; see
comment in SVMR0InvalidatePhysPage. */
#else
#endif
return VINF_SUCCESS;
}
/**
* Checks if an interrupt event is currently pending.
*
* @returns Interrupt event pending state.
* @param pVM Pointer to the VM.
*/
{
}
/**
* Return the PAE PDPE entries.
*
* @returns Pointer to the PAE PDPE array.
* @param pVCpu Pointer to the VMCPU.
*/
{
}
/**
* Checks if the current AMD CPU is subject to erratum 170 "In SVM mode,
* incorrect code bytes may be fetched after a world-switch".
*
* @param pu32Family Where to store the CPU family (can be NULL).
* @param pu32Model Where to store the CPU model (can be NULL).
* @param pu32Stepping Where to store the CPU stepping (can be NULL).
* @returns true if the erratum applies, false otherwise.
*/
VMM_INT_DECL(int) HMAmdIsSubjectToErratum170(uint32_t *pu32Family, uint32_t *pu32Model, uint32_t *pu32Stepping)
{
/*
* Erratum 170 which requires a forced TLB flush for each world switch:
* See AMD spec. "Revision Guide for AMD NPT Family 0Fh Processors".
*
* All BH-G1/2 and DH-G1/2 models include a fix:
* Athlon X2: 0x6b 1/2
* 0x68 1/2
* Athlon 64: 0x7f 1
* 0x6f 2
* Sempron: 0x7f 1/2
* 0x6f 2
* 0x6c 2
* 0x7c 2
* Turion 64: 0x68 2
*/
bool fErratumApplies = false;
if ( u32Family == 0xf
{
fErratumApplies = true;
}
if (pu32Family)
*pu32Family = u32Family;
if (pu32Model)
if (pu32Stepping)
return fErratumApplies;
}
/**
* Sets or clears the single instruction flag.
*
* When set, HM will try its best to return to ring-3 after executing a single
* instruction. This can be used for debugging. See also
* EMR3HmSingleInstruction.
*
* @returns The old flag state.
* @param pVCpu Pointer to the cross context CPU structure of
* the calling EMT.
* @param fEnable The new flag state.
*/
{
return fOld;
}
/**
* Notifies HM that paravirtualized hypercalls are now enabled.
*
* @param pVCpu Pointer to the VMCPU.
*/
{
}
/**
* Notifies HM that paravirtualized hypercalls are now disabled.
*
* @param pVCpu Pointer to the VMCPU.
*/
{
}
/**
* Notifies HM that GIM provider wants to trap #UD.
*
* @param pVCpu Pointer to the VMCPU.
*/
{
}
/**
* Notifies HM that GIM provider no longer wants to trap #UD.
*
* @param pVCpu Pointer to the VMCPU.
*/
{
}