< prev index next >

src/hotspot/cpu/x86/vm_version_x86.cpp

Print this page




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, &registers[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 }
< prev index next >