< prev index next >

src/hotspot/cpu/x86/vm_version_x86.cpp

Print this page




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 }


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 *regs) {



1675   // Allocate space for the code
1676   const int code_size = 100;
1677   ResourceMark rm;
1678   CodeBuffer cb("detect_virt", code_size, 0);
1679   MacroAssembler* a = new MacroAssembler(&cb);
1680   address code = a->pc();
1681   void (*test)(uint32_t *regs) = (void(*)(uint32_t *regs))code;
1682 
1683   a->movq(r9, rbx); // save nonvolatile register
1684 
1685   // next line would not work on 32-bit
1686   a->movl(rax, 0x40000000);
1687   a->movptr(r8, c_rarg0 /* rcx */);
1688   a->cpuid();
1689   a->movl(Address(r8,  0), rax);
1690   a->movl(Address(r8,  4), rbx);
1691   a->movl(Address(r8,  8), rcx);
1692   a->movl(Address(r8, 12), rdx);
1693 
1694   a->movq(rbx, r9); // restore nonvolatile register
1695   a->ret(0);
1696 
1697   uint32_t *code_end = (uint32_t *)a->pc();
1698   a->flush();
1699 
1700   // execute code
1701   (*test)(regs);












1702 }
1703 
1704 
1705 bool VM_Version::use_biased_locking() {
1706 #if INCLUDE_RTM_OPT
1707   // RTM locking is most useful when there is high lock contention and
1708   // low data contention.  With high lock contention the lock is usually
1709   // inflated and biased locking is not suitable for that case.
1710   // RTM locking code requires that biased locking is off.
1711   // Note: we can't switch off UseBiasedLocking in get_processor_features()
1712   // because it is used by Thread::allocate() which is called before
1713   // VM_Version::initialize().
1714   if (UseRTMLocking && UseBiasedLocking) {
1715     if (FLAG_IS_DEFAULT(UseBiasedLocking)) {
1716       FLAG_SET_DEFAULT(UseBiasedLocking, false);
1717     } else {
1718       warning("Biased locking is not supported with RTM locking; ignoring UseBiasedLocking flag." );
1719       UseBiasedLocking = false;
1720     }
1721   }


1785     // If we are running on another intel machine not recognized in the table, we are okay.
1786     return false;
1787   }
1788 }
1789 
1790 // On Xen, the cpuid instruction returns
1791 //  eax / registers[0]: Version of Xen
1792 //  ebx / registers[1]: chars 'XenV'
1793 //  ecx / registers[2]: chars 'MMXe'
1794 //  edx / registers[3]: chars 'nVMM'
1795 //
1796 // On KVM / VMWare / MS Hyper-V, the cpuid instruction returns
1797 //  ebx / registers[1]: chars 'KVMK' / 'VMwa' / 'Micr'
1798 //  ecx / registers[2]: chars 'VMKV' / 'reVM' / 'osof'
1799 //  edx / registers[3]: chars 'M'    / 'ware' / 't Hv'
1800 //
1801 // more information :
1802 // https://kb.vmware.com/s/article/1009458
1803 //
1804 void VM_Version::check_virtualizations() {
1805   uint32_t registers[4] = {0};
1806   char signature[13] = {0};
1807 
1808   check_virt_cpuid(registers);
1809   memcpy(signature, &registers[1], 12);








1810 
1811   if (strncmp("VMwareVMware", signature, 12) == 0) {
1812     Abstract_VM_Version::_detected_virtualization = VMWare;
1813     // check for extended metrics from guestlib
1814     VirtualizationSupport::initialize();
1815   } else if (strncmp("Microsoft Hv", signature, 12) == 0) {
1816 #ifdef _WINDOWS
1817     if (is_in_VM()) {
1818       Abstract_VM_Version::_detected_virtualization = HyperV;
1819     }
1820 #else
1821     Abstract_VM_Version::_detected_virtualization = HyperV;
1822 #endif
1823   } else if (strncmp("KVMKVMKVM", signature, 9) == 0) {
1824     Abstract_VM_Version::_detected_virtualization = KVM;
1825   } else if (strncmp("XenVMMXenVMM", signature, 12) == 0) {


1826     Abstract_VM_Version::_detected_virtualization = XenHVM;
1827   }


1828 }
1829 
1830 void VM_Version::initialize() {
1831   ResourceMark rm;
1832   // Making this stub must be FIRST use of assembler
1833 
1834   stub_blob = BufferBlob::create("get_cpu_info_stub", stub_size);
1835   if (stub_blob == NULL) {
1836     vm_exit_during_initialization("Unable to allocate get_cpu_info_stub");
1837   }
1838   CodeBuffer c(stub_blob);
1839   VM_Version_StubGenerator g(&c);
1840   get_cpu_info_stub = CAST_TO_FN_PTR(get_cpu_info_stub_t,
1841                                      g.generate_get_cpu_info());
1842 
1843   get_processor_features();
1844 
1845   LP64_ONLY(Assembler::precompute_instructions();)
1846 
1847   if (VM_Version::supports_hv()) { // Supports hypervisor
1848     check_virtualizations();
1849   }
1850 }
< prev index next >