1650 if (PrefetchFieldsAhead > 0) { 1651 log->print_cr("PrefetchFieldsAhead %d", (int) PrefetchFieldsAhead); 1652 } 1653 if (ContendedPaddingWidth > 0) { 1654 log->print_cr("ContendedPaddingWidth %d", (int) ContendedPaddingWidth); 1655 } 1656 } 1657 #endif // !PRODUCT 1658 } 1659 1660 void VM_Version::print_platform_virtualization_info(outputStream* st) { 1661 VirtualizationType vrt = VM_Version::get_detected_virtualization(); 1662 if (vrt == XenHVM) { 1663 st->print_cr("Xen hardware-assisted virtualization detected"); 1664 } else if (vrt == KVM) { 1665 st->print_cr("KVM virtualization detected"); 1666 } else if (vrt == VMWare) { 1667 st->print_cr("VMWare virtualization detected"); 1668 VirtualizationSupport::print_virtualization_info(st); 1669 } else if (vrt == HyperV) { 1670 st->print_cr("HyperV virtualization detected"); 1671 } 1672 } 1673 1674 void VM_Version::check_virt_cpuid(uint32_t idx, uint32_t *regs) { 1675 // TODO support 32 bit 1676 #if defined(_LP64) 1677 #if defined(_MSC_VER) 1678 // Allocate space for the code 1679 const int code_size = 100; 1680 ResourceMark rm; 1681 CodeBuffer cb("detect_virt", code_size, 0); 1682 MacroAssembler* a = new MacroAssembler(&cb); 1683 address code = a->pc(); 1684 void (*test)(uint32_t idx, uint32_t *regs) = (void(*)(uint32_t idx, uint32_t *regs))code; 1685 1686 a->movq(r9, rbx); // save nonvolatile register 1687 1688 // next line would not work on 32-bit 1689 a->movq(rax, c_rarg0 /* rcx */); 1690 a->movq(r8, c_rarg1 /* rdx */); 1691 a->cpuid(); 1692 a->movl(Address(r8, 0), rax); 1693 a->movl(Address(r8, 4), rbx); 1694 a->movl(Address(r8, 8), rcx); 1695 a->movl(Address(r8, 12), rdx); 1696 1697 a->movq(rbx, r9); // restore nonvolatile register 1698 a->ret(0); 1699 1700 uint32_t *code_end = (uint32_t *)a->pc(); 1701 a->flush(); 1702 1703 // execute code 1704 (*test)(idx, regs); 1705 #elif defined(__GNUC__) 1706 __asm__ volatile ( 1707 " cpuid;" 1708 " mov %%eax,(%1);" 1709 " mov %%ebx,4(%1);" 1710 " mov %%ecx,8(%1);" 1711 " mov %%edx,12(%1);" 1712 : "+a" (idx) 1713 : "S" (regs) 1714 : "ebx", "ecx", "edx", "memory" ); 1715 #endif 1716 #endif 1717 } 1718 1719 1720 bool VM_Version::use_biased_locking() { 1721 #if INCLUDE_RTM_OPT 1722 // RTM locking is most useful when there is high lock contention and 1723 // low data contention. With high lock contention the lock is usually 1724 // inflated and biased locking is not suitable for that case. 1725 // RTM locking code requires that biased locking is off. 1726 // Note: we can't switch off UseBiasedLocking in get_processor_features() 1727 // because it is used by Thread::allocate() which is called before 1728 // VM_Version::initialize(). 1729 if (UseRTMLocking && UseBiasedLocking) { 1730 if (FLAG_IS_DEFAULT(UseBiasedLocking)) { 1731 FLAG_SET_DEFAULT(UseBiasedLocking, false); 1732 } else { 1733 warning("Biased locking is not supported with RTM locking; ignoring UseBiasedLocking flag." ); 1734 UseBiasedLocking = false; 1735 } 1736 } 1800 // If we are running on another intel machine not recognized in the table, we are okay. 1801 return false; 1802 } 1803 } 1804 1805 // On Xen, the cpuid instruction returns 1806 // eax / registers[0]: Version of Xen 1807 // ebx / registers[1]: chars 'XenV' 1808 // ecx / registers[2]: chars 'MMXe' 1809 // edx / registers[3]: chars 'nVMM' 1810 // 1811 // On KVM / VMWare / MS Hyper-V, the cpuid instruction returns 1812 // ebx / registers[1]: chars 'KVMK' / 'VMwa' / 'Micr' 1813 // ecx / registers[2]: chars 'VMKV' / 'reVM' / 'osof' 1814 // edx / registers[3]: chars 'M' / 'ware' / 't Hv' 1815 // 1816 // more information : 1817 // https://kb.vmware.com/s/article/1009458 1818 // 1819 void VM_Version::check_virtualizations() { 1820 #if defined(_LP64) 1821 uint32_t registers[4]; 1822 char signature[13]; 1823 uint32_t base; 1824 signature[12] = '\0'; 1825 memset((void*)registers, 0, 4*sizeof(uint32_t)); 1826 1827 for (base = 0x40000000; base < 0x40010000; base += 0x100) { 1828 check_virt_cpuid(base, registers); 1829 1830 *(uint32_t *)(signature + 0) = registers[1]; 1831 *(uint32_t *)(signature + 4) = registers[2]; 1832 *(uint32_t *)(signature + 8) = registers[3]; 1833 1834 if (strncmp("VMwareVMware", signature, 12) == 0) { 1835 Abstract_VM_Version::_detected_virtualization = VMWare; 1836 // check for extended metrics from guestlib 1837 VirtualizationSupport::initialize(); 1838 } 1839 1840 if (strncmp("Microsoft Hv", signature, 12) == 0) { 1841 Abstract_VM_Version::_detected_virtualization = HyperV; 1842 } 1843 1844 if (strncmp("KVMKVMKVM", signature, 9) == 0) { 1845 Abstract_VM_Version::_detected_virtualization = KVM; 1846 } 1847 1848 if (strncmp("XenVMMXenVMM", signature, 12) == 0) { 1849 Abstract_VM_Version::_detected_virtualization = XenHVM; 1850 } 1851 } 1852 #endif 1853 } 1854 1855 void VM_Version::initialize() { 1856 ResourceMark rm; 1857 // Making this stub must be FIRST use of assembler 1858 1859 stub_blob = BufferBlob::create("get_cpu_info_stub", stub_size); 1860 if (stub_blob == NULL) { 1861 vm_exit_during_initialization("Unable to allocate get_cpu_info_stub"); 1862 } 1863 CodeBuffer c(stub_blob); 1864 VM_Version_StubGenerator g(&c); 1865 get_cpu_info_stub = CAST_TO_FN_PTR(get_cpu_info_stub_t, 1866 g.generate_get_cpu_info()); 1867 1868 get_processor_features(); 1869 1870 LP64_ONLY(Assembler::precompute_instructions();) 1871 1872 if (cpu_family() > 4) { // it supports CPUID 1873 check_virtualizations(); 1874 } 1875 } | 1650 if (PrefetchFieldsAhead > 0) { 1651 log->print_cr("PrefetchFieldsAhead %d", (int) PrefetchFieldsAhead); 1652 } 1653 if (ContendedPaddingWidth > 0) { 1654 log->print_cr("ContendedPaddingWidth %d", (int) ContendedPaddingWidth); 1655 } 1656 } 1657 #endif // !PRODUCT 1658 } 1659 1660 void VM_Version::print_platform_virtualization_info(outputStream* st) { 1661 VirtualizationType vrt = VM_Version::get_detected_virtualization(); 1662 if (vrt == XenHVM) { 1663 st->print_cr("Xen hardware-assisted virtualization detected"); 1664 } else if (vrt == KVM) { 1665 st->print_cr("KVM virtualization detected"); 1666 } else if (vrt == VMWare) { 1667 st->print_cr("VMWare virtualization detected"); 1668 VirtualizationSupport::print_virtualization_info(st); 1669 } else if (vrt == HyperV) { 1670 st->print_cr("Hyper-V virtualization detected"); 1671 } else if (vrt == HyperVRole) { 1672 st->print_cr("Hyper-V role detected"); 1673 } 1674 } 1675 1676 void VM_Version::check_virt_cpuid(uint32_t *regs) { 1677 // Allocate space for the code 1678 const int code_size = 100; 1679 ResourceMark rm; 1680 CodeBuffer cb("detect_virt", code_size, 0); 1681 MacroAssembler* a = new MacroAssembler(&cb); 1682 void (*test)(uint32_t *regs) = (void(*)(uint32_t *regs))a->pc(); 1683 1684 // save nonvolatile register 1685 a->push(rbx); 1686 #ifdef _WINDOWS 1687 a->push(rsi); // RSI is nonvolatile register for Windows 1688 #endif 1689 1690 // Copy 1st argument to SI 1691 #ifdef _LP64 1692 a->movptr(rsi, c_rarg0); 1693 #else 1694 int ofs = 8; // return address + EBX 1695 #ifdef _WINDOWS 1696 ofs += 4; // ESI 1697 #endif 1698 a->movptr(rsi, Address(rsp, ofs)); 1699 #endif 1700 1701 a->movl(rax, 0x40000000); 1702 1703 a->cpuid(); 1704 1705 a->movl(Address(rsi, 0), rax); 1706 a->movl(Address(rsi, 4), rbx); 1707 a->movl(Address(rsi, 8), rcx); 1708 a->movl(Address(rsi, 12), rdx); 1709 1710 // restore nonvolatile register 1711 #ifdef _WINDOWS 1712 a->pop(rsi); 1713 #endif 1714 a->pop(rbx); 1715 1716 a->ret(0); 1717 1718 a->flush(); 1719 1720 // execute code 1721 test(regs); 1722 } 1723 1724 1725 bool VM_Version::use_biased_locking() { 1726 #if INCLUDE_RTM_OPT 1727 // RTM locking is most useful when there is high lock contention and 1728 // low data contention. With high lock contention the lock is usually 1729 // inflated and biased locking is not suitable for that case. 1730 // RTM locking code requires that biased locking is off. 1731 // Note: we can't switch off UseBiasedLocking in get_processor_features() 1732 // because it is used by Thread::allocate() which is called before 1733 // VM_Version::initialize(). 1734 if (UseRTMLocking && UseBiasedLocking) { 1735 if (FLAG_IS_DEFAULT(UseBiasedLocking)) { 1736 FLAG_SET_DEFAULT(UseBiasedLocking, false); 1737 } else { 1738 warning("Biased locking is not supported with RTM locking; ignoring UseBiasedLocking flag." ); 1739 UseBiasedLocking = false; 1740 } 1741 } 1805 // If we are running on another intel machine not recognized in the table, we are okay. 1806 return false; 1807 } 1808 } 1809 1810 // On Xen, the cpuid instruction returns 1811 // eax / registers[0]: Version of Xen 1812 // ebx / registers[1]: chars 'XenV' 1813 // ecx / registers[2]: chars 'MMXe' 1814 // edx / registers[3]: chars 'nVMM' 1815 // 1816 // On KVM / VMWare / MS Hyper-V, the cpuid instruction returns 1817 // ebx / registers[1]: chars 'KVMK' / 'VMwa' / 'Micr' 1818 // ecx / registers[2]: chars 'VMKV' / 'reVM' / 'osof' 1819 // edx / registers[3]: chars 'M' / 'ware' / 't Hv' 1820 // 1821 // more information : 1822 // https://kb.vmware.com/s/article/1009458 1823 // 1824 void VM_Version::check_virtualizations() { 1825 uint32_t registers[4] = {0}; 1826 char signature[13] = {0}; 1827 1828 check_virt_cpuid(registers); 1829 memcpy(signature, ®isters[1], 12); 1830 1831 if (strncmp("VMwareVMware", signature, 12) == 0) { 1832 Abstract_VM_Version::_detected_virtualization = VMWare; 1833 // check for extended metrics from guestlib 1834 VirtualizationSupport::initialize(); 1835 } else if (strncmp("Microsoft Hv", signature, 12) == 0) { 1836 #ifdef _WINDOWS 1837 Abstract_VM_Version::_detected_virtualization = is_in_VM() ? HyperV : HyperVRole; 1838 #else 1839 Abstract_VM_Version::_detected_virtualization = HyperV; 1840 #endif 1841 } else if (strncmp("KVMKVMKVM", signature, 9) == 0) { 1842 Abstract_VM_Version::_detected_virtualization = KVM; 1843 } else if (strncmp("XenVMMXenVMM", signature, 12) == 0) { 1844 Abstract_VM_Version::_detected_virtualization = XenHVM; 1845 } 1846 } 1847 1848 void VM_Version::initialize() { 1849 ResourceMark rm; 1850 // Making this stub must be FIRST use of assembler 1851 1852 stub_blob = BufferBlob::create("get_cpu_info_stub", stub_size); 1853 if (stub_blob == NULL) { 1854 vm_exit_during_initialization("Unable to allocate get_cpu_info_stub"); 1855 } 1856 CodeBuffer c(stub_blob); 1857 VM_Version_StubGenerator g(&c); 1858 get_cpu_info_stub = CAST_TO_FN_PTR(get_cpu_info_stub_t, 1859 g.generate_get_cpu_info()); 1860 1861 get_processor_features(); 1862 1863 LP64_ONLY(Assembler::precompute_instructions();) 1864 1865 if (VM_Version::supports_hv()) { // Supports hypervisor 1866 check_virtualizations(); 1867 } 1868 } |