VirtualBox

Changeset 47436 in vbox


Ignore:
Timestamp:
Jul 27, 2013 6:20:24 PM (11 years ago)
Author:
vboxsync
Message:

hmvmx.h: Use MSC vmx_* intrinsics.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/hm_vmx.h

    r47322 r47436  
    3131#include <iprt/x86.h>
    3232#include <iprt/assert.h>
     33
     34/* In Visual C++ versions prior to 2012, the vmx intrinsics are only available
     35   when targeting AMD64. */
     36#if RT_INLINE_ASM_USES_INTRIN >= 16 && defined(RT_ARCH_AMD64)
     37# include <intrin.h>
     38/* We always want them as intrinsics, no functions. */
     39# pragma intrinsic(__vmx_on)
     40# pragma intrinsic(__vmx_off)
     41# pragma intrinsic(__vmx_vmclear)
     42# pragma intrinsic(__vmx_vmptrld)
     43# pragma intrinsic(__vmx_vmread)
     44# pragma intrinsic(__vmx_vmwrite)
     45# define VMX_USE_MSC_INTRINSICS 1
     46#else
     47# define VMX_USE_MSC_INTRINSICS 0
     48#endif
     49
    3350
    3451/** @defgroup grp_vmx   vmx Types and Definitions
     
    15551572 * @param   pVMXOn      Physical address of VMXON structure
    15561573 */
    1557 #if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
     1574#if ((RT_INLINE_ASM_EXTERNAL || !defined(RT_ARCH_X86)) && !VMX_USE_MSC_INTRINSICS) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
    15581575DECLASM(int) VMXEnable(RTHCPHYS pVMXOn);
    15591576#else
    15601577DECLINLINE(int) VMXEnable(RTHCPHYS pVMXOn)
    15611578{
     1579# if RT_INLINE_ASM_GNU_STYLE
    15621580    int rc = VINF_SUCCESS;
    1563 # if RT_INLINE_ASM_GNU_STYLE
    15641581    __asm__ __volatile__ (
    15651582       "push     %3                                             \n\t"
     
    15801597       :"memory"
    15811598       );
     1599    return rc;
     1600
     1601# elif VMX_USE_MSC_INTRINSICS
     1602    unsigned char rcMsc = __vmx_on(&pVMXOn);
     1603    if (RT_LIKELY(rcMsc == 0))
     1604        return VINF_SUCCESS;
     1605    return rcMsc == 2 ? VERR_VMX_INVALID_VMXON_PTR : VERR_VMX_VMXON_FAILED;
     1606
    15821607# else
     1608    int rc = VINF_SUCCESS;
    15831609    __asm
    15841610    {
     
    16011627    }
    16021628# endif
    1603     return rc;
    16041629}
    16051630#endif
     
    16091634 * Executes VMXOFF
    16101635 */
    1611 #if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
     1636#if ((RT_INLINE_ASM_EXTERNAL || !defined(RT_ARCH_X86)) && !VMX_USE_MSC_INTRINSICS) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
    16121637DECLASM(void) VMXDisable(void);
    16131638#else
     
    16181643       ".byte 0x0F, 0x01, 0xC4  # VMXOFF                        \n\t"
    16191644       );
     1645
     1646# elif VMX_USE_MSC_INTRINSICS
     1647    __vmx_off();
     1648
    16201649# else
    16211650    __asm
     
    16361665 * @param   pVMCS       Physical address of VM control structure
    16371666 */
    1638 #if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
     1667#if ((RT_INLINE_ASM_EXTERNAL || !defined(RT_ARCH_X86)) && !VMX_USE_MSC_INTRINSICS) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
    16391668DECLASM(int) VMXClearVMCS(RTHCPHYS pVMCS);
    16401669#else
    16411670DECLINLINE(int) VMXClearVMCS(RTHCPHYS pVMCS)
    16421671{
     1672# if RT_INLINE_ASM_GNU_STYLE
    16431673    int rc = VINF_SUCCESS;
    1644 # if RT_INLINE_ASM_GNU_STYLE
    16451674    __asm__ __volatile__ (
    16461675       "push    %3                                              \n\t"
     
    16571686       :"memory"
    16581687       );
     1688    return rc;
     1689
     1690# elif VMX_USE_MSC_INTRINSICS
     1691    unsigned char rcMsc = __vmx_vmclear(&pVMCS);
     1692    if (RT_LIKELY(rcMsc == 0))
     1693        return VINF_SUCCESS;
     1694    return VERR_VMX_INVALID_VMCS_PTR;
     1695
    16591696# else
     1697    int rc = VINF_SUCCESS;
    16601698    __asm
    16611699    {
     
    16721710        add     esp, 8
    16731711    }
     1712    return rc;
    16741713# endif
    1675     return rc;
    16761714}
    16771715#endif
     
    16841722 * @param   pVMCS       Physical address of VMCS structure
    16851723 */
    1686 #if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
     1724#if ((RT_INLINE_ASM_EXTERNAL || !defined(RT_ARCH_X86)) && !VMX_USE_MSC_INTRINSICS) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
    16871725DECLASM(int) VMXActivateVMCS(RTHCPHYS pVMCS);
    16881726#else
    16891727DECLINLINE(int) VMXActivateVMCS(RTHCPHYS pVMCS)
    16901728{
     1729# if RT_INLINE_ASM_GNU_STYLE
    16911730    int rc = VINF_SUCCESS;
    1692 # if RT_INLINE_ASM_GNU_STYLE
    16931731    __asm__ __volatile__ (
    16941732       "push    %3                                              \n\t"
     
    17041742        "ir"((uint32_t)(pVMCS >> 32)) /* this will not work with -fomit-frame-pointer */
    17051743       );
     1744    return rc;
     1745
     1746# elif VMX_USE_MSC_INTRINSICS
     1747    unsigned char rcMsc = __vmx_vmptrld(&pVMCS);
     1748    if (RT_LIKELY(rcMsc == 0))
     1749        return VINF_SUCCESS;
     1750    return VERR_VMX_INVALID_VMCS_PTR;
     1751
    17061752# else
     1753    int rc = VINF_SUCCESS;
    17071754    __asm
    17081755    {
     
    17191766        add     esp, 8
    17201767    }
     1768    return rc;
    17211769# endif
    1722     return rc;
    17231770}
    17241771#endif
     
    17391786 * @param   u32Val          32 bits value
    17401787 */
    1741 #if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
     1788#if ((RT_INLINE_ASM_EXTERNAL || !defined(RT_ARCH_X86)) && !VMX_USE_MSC_INTRINSICS) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
    17421789DECLASM(int) VMXWriteVmcs32(uint32_t idxField, uint32_t u32Val);
    17431790#else
    17441791DECLINLINE(int) VMXWriteVmcs32(uint32_t idxField, uint32_t u32Val)
    17451792{
     1793# if RT_INLINE_ASM_GNU_STYLE
    17461794    int rc = VINF_SUCCESS;
    1747 # if RT_INLINE_ASM_GNU_STYLE
    17481795    __asm__ __volatile__ (
    17491796       ".byte  0x0F, 0x79, 0xC2        # VMWRITE eax, edx       \n\t"
     
    17601807        "d"(u32Val)
    17611808       );
    1762 # else
     1809    return rc;
     1810
     1811# elif VMX_USE_MSC_INTRINSICS
     1812     unsigned char rcMsc = __vmx_vmwrite(idxField, u32Val);
     1813     if (RT_LIKELY(rcMsc == 0))
     1814         return VINF_SUCCESS;
     1815     return rcMsc == 2 ? VERR_VMX_INVALID_VMCS_PTR : VERR_VMX_INVALID_VMCS_FIELD;
     1816
     1817#else
     1818    int rc = VINF_SUCCESS;
    17631819    __asm
    17641820    {
     
    17791835        add    esp, 4
    17801836    }
     1837    return rc;
    17811838# endif
    1782     return rc;
    17831839}
    17841840#endif
     
    17911847 * @param   u64Val          16, 32 or 64 bits value
    17921848 */
    1793 #if HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
     1849#if !defined(RT_ARCH_X86) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
     1850# if !VMX_USE_MSC_INTRINSICS || ARCH_BITS != 64
    17941851DECLASM(int) VMXWriteVmcs64(uint32_t idxField, uint64_t u64Val);
     1852# else  /* VMX_USE_MSC_INTRINSICS */
     1853DECLINLINE(int) VMXWriteVmcs64(uint32_t idxField, uint64_t u64Val)
     1854{
     1855    unsigned char rcMsc = __vmx_vmwrite(idxField, u64Val);
     1856    if (RT_LIKELY(rcMsc == 0))
     1857        return VINF_SUCCESS;
     1858    return rcMsc == 2 ? VERR_VMX_INVALID_VMCS_PTR : VERR_VMX_INVALID_VMCS_FIELD;
     1859}
     1860# endif /* VMX_USE_MSC_INTRINSICS */
    17951861#else
     1862# define VMXWriteVmcs64(idxField, u64Val)    VMXWriteVmcs64Ex(pVCpu, idxField, u64Val) /** @todo dead ugly, picking up pVCpu like this */
    17961863VMMR0DECL(int) VMXWriteVmcs64Ex(PVMCPU pVCpu, uint32_t idxField, uint64_t u64Val);
    1797 
    1798 #define VMXWriteVmcs64(idxField, u64Val)    VMXWriteVmcs64Ex(pVCpu, idxField, u64Val)
    17991864#endif
    18001865
    18011866#ifdef VBOX_WITH_OLD_VTX_CODE
    1802 # if HC_ARCH_BITS == 64
     1867# if ARCH_BITS == 64
    18031868#  define VMXWriteVmcs VMXWriteVmcs64
    18041869# else
     
    18131878                                                   VMXWriteVmcs64(idxField, u64Val)               \
    18141879                                                 : VMXWriteVmcs32(idxField, u64Val)
    1815 # elif HC_ARCH_BITS == 32
     1880# elif ARCH_BITS == 32
    18161881#  define VMXWriteVmcsHstN                       VMXWriteVmcs32
    18171882#  define VMXWriteVmcsGstN(idxField, u64Val)     VMXWriteVmcs64Ex(pVCpu, idxField, u64Val)
    1818 # else  /* HC_ARCH_BITS == 64 */
     1883# else  /* ARCH_BITS == 64 */
    18191884#  define VMXWriteVmcsHstN                       VMXWriteVmcs64
    18201885#  define VMXWriteVmcsGstN                       VMXWriteVmcs64
     
    18461911 * @param   pData           Ptr to store VM field value
    18471912 */
    1848 #if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
     1913#if ((RT_INLINE_ASM_EXTERNAL || !defined(RT_ARCH_X86)) && !VMX_USE_MSC_INTRINSICS) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
    18491914DECLASM(int) VMXReadVmcs32(uint32_t idxField, uint32_t *pData);
    18501915#else
    18511916DECLINLINE(int) VMXReadVmcs32(uint32_t idxField, uint32_t *pData)
    18521917{
     1918# if RT_INLINE_ASM_GNU_STYLE
    18531919    int rc = VINF_SUCCESS;
    1854 # if RT_INLINE_ASM_GNU_STYLE
    18551920    __asm__ __volatile__ (
    18561921       "movl   $"RT_XSTR(VINF_SUCCESS)", %0                      \n\t"
     
    18681933        "d"(0)
    18691934       );
    1870 # else
     1935    return rc;
     1936
     1937# elif VMX_USE_MSC_INTRINSICS
     1938    unsigned char rcMsc;
     1939#  if ARCH_BITS == 32
     1940    rcMsc = __vmx_vmread(idxField, pData);
     1941#  else
     1942    uint64_t u64Tmp;
     1943    rcMsc = __vmx_vmread(idxField, &u64Tmp);
     1944    *pData = (uint32_t)u64Tmp;
     1945#  endif
     1946    if (RT_LIKELY(rcMsc == 0))
     1947        return VINF_SUCCESS;
     1948    return rcMsc == 2 ? VERR_VMX_INVALID_VMCS_PTR : VERR_VMX_INVALID_VMCS_FIELD;
     1949
     1950#else
     1951    int rc = VINF_SUCCESS;
    18711952    __asm
    18721953    {
     
    18891970the_end:
    18901971    }
     1972    return rc;
    18911973# endif
    1892     return rc;
    18931974}
    18941975#endif
     
    19011982 * @param   pData           Ptr to store VM field value
    19021983 */
    1903 #if HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
     1984#if (!defined(RT_ARCH_X86) && !VMX_USE_MSC_INTRINSICS) || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
    19041985DECLASM(int) VMXReadVmcs64(uint32_t idxField, uint64_t *pData);
    19051986#else
    19061987DECLINLINE(int) VMXReadVmcs64(uint32_t idxField, uint64_t *pData)
    19071988{
     1989# if VMX_USE_MSC_INTRINSICS
     1990    unsigned char rcMsc;
     1991#  if ARCH_BITS == 32
     1992    size_t        uLow;
     1993    size_t        uHigh;
     1994    rcMsc  = __vmx_vmread(idxField, &uLow);
     1995    rcMsc |= __vmx_vmread(idxField + 1, &uHigh);
     1996    *pData = RT_MAKE_U64(uLow, uHigh);
     1997# else
     1998    rcMsc = __vmx_vmread(idxField, pData);
     1999# endif
     2000    if (RT_LIKELY(rcMsc == 0))
     2001        return VINF_SUCCESS;
     2002    return rcMsc == 2 ? VERR_VMX_INVALID_VMCS_PTR : VERR_VMX_INVALID_VMCS_FIELD;
     2003
     2004# elif ARCH_BITS == 32
    19082005    int rc;
    1909 
    19102006    uint32_t val_hi, val;
    19112007    rc  = VMXReadVmcs32(idxField, &val);
     
    19142010    *pData = RT_MAKE_U64(val, val_hi);
    19152011    return rc;
     2012
     2013# else
     2014#  error "Shouldn't be here..."
     2015# endif
    19162016}
    19172017#endif
    19182018
    19192019#ifdef VBOX_WITH_OLD_VTX_CODE
    1920 # if HC_ARCH_BITS == 64
     2020# if ARCH_BITS == 64
    19212021#  define VMXReadVmcsField VMXReadVmcs64
    19222022# else
     
    19322032DECLINLINE(uint32_t) VMXGetLastError(void)
    19332033{
    1934 #if HC_ARCH_BITS == 64
     2034#if ARCH_BITS == 64
    19352035    uint64_t uLastError = 0;
    19362036    int rc = VMXReadVmcs64(VMX_VMCS32_RO_VM_INSTR_ERROR, &uLastError);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette