Changeset 47436 in vbox
- Timestamp:
- Jul 27, 2013 6:20:24 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/hm_vmx.h
r47322 r47436 31 31 #include <iprt/x86.h> 32 32 #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 33 50 34 51 /** @defgroup grp_vmx vmx Types and Definitions … … 1555 1572 * @param pVMXOn Physical address of VMXON structure 1556 1573 */ 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) 1558 1575 DECLASM(int) VMXEnable(RTHCPHYS pVMXOn); 1559 1576 #else 1560 1577 DECLINLINE(int) VMXEnable(RTHCPHYS pVMXOn) 1561 1578 { 1579 # if RT_INLINE_ASM_GNU_STYLE 1562 1580 int rc = VINF_SUCCESS; 1563 # if RT_INLINE_ASM_GNU_STYLE1564 1581 __asm__ __volatile__ ( 1565 1582 "push %3 \n\t" … … 1580 1597 :"memory" 1581 1598 ); 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 1582 1607 # else 1608 int rc = VINF_SUCCESS; 1583 1609 __asm 1584 1610 { … … 1601 1627 } 1602 1628 # endif 1603 return rc;1604 1629 } 1605 1630 #endif … … 1609 1634 * Executes VMXOFF 1610 1635 */ 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) 1612 1637 DECLASM(void) VMXDisable(void); 1613 1638 #else … … 1618 1643 ".byte 0x0F, 0x01, 0xC4 # VMXOFF \n\t" 1619 1644 ); 1645 1646 # elif VMX_USE_MSC_INTRINSICS 1647 __vmx_off(); 1648 1620 1649 # else 1621 1650 __asm … … 1636 1665 * @param pVMCS Physical address of VM control structure 1637 1666 */ 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) 1639 1668 DECLASM(int) VMXClearVMCS(RTHCPHYS pVMCS); 1640 1669 #else 1641 1670 DECLINLINE(int) VMXClearVMCS(RTHCPHYS pVMCS) 1642 1671 { 1672 # if RT_INLINE_ASM_GNU_STYLE 1643 1673 int rc = VINF_SUCCESS; 1644 # if RT_INLINE_ASM_GNU_STYLE1645 1674 __asm__ __volatile__ ( 1646 1675 "push %3 \n\t" … … 1657 1686 :"memory" 1658 1687 ); 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 1659 1696 # else 1697 int rc = VINF_SUCCESS; 1660 1698 __asm 1661 1699 { … … 1672 1710 add esp, 8 1673 1711 } 1712 return rc; 1674 1713 # endif 1675 return rc;1676 1714 } 1677 1715 #endif … … 1684 1722 * @param pVMCS Physical address of VMCS structure 1685 1723 */ 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) 1687 1725 DECLASM(int) VMXActivateVMCS(RTHCPHYS pVMCS); 1688 1726 #else 1689 1727 DECLINLINE(int) VMXActivateVMCS(RTHCPHYS pVMCS) 1690 1728 { 1729 # if RT_INLINE_ASM_GNU_STYLE 1691 1730 int rc = VINF_SUCCESS; 1692 # if RT_INLINE_ASM_GNU_STYLE1693 1731 __asm__ __volatile__ ( 1694 1732 "push %3 \n\t" … … 1704 1742 "ir"((uint32_t)(pVMCS >> 32)) /* this will not work with -fomit-frame-pointer */ 1705 1743 ); 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 1706 1752 # else 1753 int rc = VINF_SUCCESS; 1707 1754 __asm 1708 1755 { … … 1719 1766 add esp, 8 1720 1767 } 1768 return rc; 1721 1769 # endif 1722 return rc;1723 1770 } 1724 1771 #endif … … 1739 1786 * @param u32Val 32 bits value 1740 1787 */ 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) 1742 1789 DECLASM(int) VMXWriteVmcs32(uint32_t idxField, uint32_t u32Val); 1743 1790 #else 1744 1791 DECLINLINE(int) VMXWriteVmcs32(uint32_t idxField, uint32_t u32Val) 1745 1792 { 1793 # if RT_INLINE_ASM_GNU_STYLE 1746 1794 int rc = VINF_SUCCESS; 1747 # if RT_INLINE_ASM_GNU_STYLE1748 1795 __asm__ __volatile__ ( 1749 1796 ".byte 0x0F, 0x79, 0xC2 # VMWRITE eax, edx \n\t" … … 1760 1807 "d"(u32Val) 1761 1808 ); 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; 1763 1819 __asm 1764 1820 { … … 1779 1835 add esp, 4 1780 1836 } 1837 return rc; 1781 1838 # endif 1782 return rc;1783 1839 } 1784 1840 #endif … … 1791 1847 * @param u64Val 16, 32 or 64 bits value 1792 1848 */ 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 1794 1851 DECLASM(int) VMXWriteVmcs64(uint32_t idxField, uint64_t u64Val); 1852 # else /* VMX_USE_MSC_INTRINSICS */ 1853 DECLINLINE(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 */ 1795 1861 #else 1862 # define VMXWriteVmcs64(idxField, u64Val) VMXWriteVmcs64Ex(pVCpu, idxField, u64Val) /** @todo dead ugly, picking up pVCpu like this */ 1796 1863 VMMR0DECL(int) VMXWriteVmcs64Ex(PVMCPU pVCpu, uint32_t idxField, uint64_t u64Val); 1797 1798 #define VMXWriteVmcs64(idxField, u64Val) VMXWriteVmcs64Ex(pVCpu, idxField, u64Val)1799 1864 #endif 1800 1865 1801 1866 #ifdef VBOX_WITH_OLD_VTX_CODE 1802 # if HC_ARCH_BITS == 641867 # if ARCH_BITS == 64 1803 1868 # define VMXWriteVmcs VMXWriteVmcs64 1804 1869 # else … … 1813 1878 VMXWriteVmcs64(idxField, u64Val) \ 1814 1879 : VMXWriteVmcs32(idxField, u64Val) 1815 # elif HC_ARCH_BITS == 321880 # elif ARCH_BITS == 32 1816 1881 # define VMXWriteVmcsHstN VMXWriteVmcs32 1817 1882 # define VMXWriteVmcsGstN(idxField, u64Val) VMXWriteVmcs64Ex(pVCpu, idxField, u64Val) 1818 # else /* HC_ARCH_BITS == 64 */1883 # else /* ARCH_BITS == 64 */ 1819 1884 # define VMXWriteVmcsHstN VMXWriteVmcs64 1820 1885 # define VMXWriteVmcsGstN VMXWriteVmcs64 … … 1846 1911 * @param pData Ptr to store VM field value 1847 1912 */ 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) 1849 1914 DECLASM(int) VMXReadVmcs32(uint32_t idxField, uint32_t *pData); 1850 1915 #else 1851 1916 DECLINLINE(int) VMXReadVmcs32(uint32_t idxField, uint32_t *pData) 1852 1917 { 1918 # if RT_INLINE_ASM_GNU_STYLE 1853 1919 int rc = VINF_SUCCESS; 1854 # if RT_INLINE_ASM_GNU_STYLE1855 1920 __asm__ __volatile__ ( 1856 1921 "movl $"RT_XSTR(VINF_SUCCESS)", %0 \n\t" … … 1868 1933 "d"(0) 1869 1934 ); 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; 1871 1952 __asm 1872 1953 { … … 1889 1970 the_end: 1890 1971 } 1972 return rc; 1891 1973 # endif 1892 return rc;1893 1974 } 1894 1975 #endif … … 1901 1982 * @param pData Ptr to store VM field value 1902 1983 */ 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) 1904 1985 DECLASM(int) VMXReadVmcs64(uint32_t idxField, uint64_t *pData); 1905 1986 #else 1906 1987 DECLINLINE(int) VMXReadVmcs64(uint32_t idxField, uint64_t *pData) 1907 1988 { 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 1908 2005 int rc; 1909 1910 2006 uint32_t val_hi, val; 1911 2007 rc = VMXReadVmcs32(idxField, &val); … … 1914 2010 *pData = RT_MAKE_U64(val, val_hi); 1915 2011 return rc; 2012 2013 # else 2014 # error "Shouldn't be here..." 2015 # endif 1916 2016 } 1917 2017 #endif 1918 2018 1919 2019 #ifdef VBOX_WITH_OLD_VTX_CODE 1920 # if HC_ARCH_BITS == 642020 # if ARCH_BITS == 64 1921 2021 # define VMXReadVmcsField VMXReadVmcs64 1922 2022 # else … … 1932 2032 DECLINLINE(uint32_t) VMXGetLastError(void) 1933 2033 { 1934 #if HC_ARCH_BITS == 642034 #if ARCH_BITS == 64 1935 2035 uint64_t uLastError = 0; 1936 2036 int rc = VMXReadVmcs64(VMX_VMCS32_RO_VM_INSTR_ERROR, &uLastError);
Note:
See TracChangeset
for help on using the changeset viewer.