1 /*
2 * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
1556 log->print_cr(" at distance %d, one line of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchStepSize);
1557 }
1558 }
1559
1560 if (PrefetchCopyIntervalInBytes > 0) {
1561 log->print_cr("PrefetchCopyIntervalInBytes %d", (int) PrefetchCopyIntervalInBytes);
1562 }
1563 if (PrefetchScanIntervalInBytes > 0) {
1564 log->print_cr("PrefetchScanIntervalInBytes %d", (int) PrefetchScanIntervalInBytes);
1565 }
1566 if (PrefetchFieldsAhead > 0) {
1567 log->print_cr("PrefetchFieldsAhead %d", (int) PrefetchFieldsAhead);
1568 }
1569 if (ContendedPaddingWidth > 0) {
1570 log->print_cr("ContendedPaddingWidth %d", (int) ContendedPaddingWidth);
1571 }
1572 }
1573 #endif // !PRODUCT
1574 }
1575
1576 void VM_Version::print_platform_virtualization_info(outputStream* st) {
1577 VirtualizationType vrt = VM_Version::get_detected_virtualization();
1578 if (vrt == XenHVM) {
1579 st->print_cr("Xen hardware-assisted virtualization detected");
1580 } else if (vrt == KVM) {
1581 st->print_cr("KVM virtualization detected");
1582 } else if (vrt == VMWare) {
1583 st->print_cr("VMWare virtualization detected");
1584 } else if (vrt == HyperV) {
1585 st->print_cr("HyperV virtualization detected");
1586 }
1587 }
1588
1589 void VM_Version::check_virt_cpuid(uint32_t idx, uint32_t *regs) {
1590 // TODO support 32 bit
1591 #if defined(_LP64)
1592 #if defined(_MSC_VER)
1593 // Allocate space for the code
1594 const int code_size = 100;
1595 ResourceMark rm;
1596 CodeBuffer cb("detect_virt", code_size, 0);
1597 MacroAssembler* a = new MacroAssembler(&cb);
1598 address code = a->pc();
1599 void (*test)(uint32_t idx, uint32_t *regs) = (void(*)(uint32_t idx, uint32_t *regs))code;
1600
1601 a->movq(r9, rbx); // save nonvolatile register
1602
1603 // next line would not work on 32-bit
1604 a->movq(rax, c_rarg0 /* rcx */);
1605 a->movq(r8, c_rarg1 /* rdx */);
1606 a->cpuid();
1607 a->movl(Address(r8, 0), rax);
1608 a->movl(Address(r8, 4), rbx);
1609 a->movl(Address(r8, 8), rcx);
1610 a->movl(Address(r8, 12), rdx);
1611
1612 a->movq(rbx, r9); // restore nonvolatile register
1613 a->ret(0);
1614
1615 uint32_t *code_end = (uint32_t *)a->pc();
1616 a->flush();
1617
1618 // execute code
1619 (*test)(idx, regs);
1620 #elif defined(__GNUC__)
1621 __asm__ volatile (
1622 " cpuid;"
1623 " mov %%eax,(%1);"
1624 " mov %%ebx,4(%1);"
1625 " mov %%ecx,8(%1);"
1626 " mov %%edx,12(%1);"
1627 : "+a" (idx)
1628 : "S" (regs)
1629 : "ebx", "ecx", "edx", "memory" );
1630 #endif
1631 #endif
1632 }
1633
1634
1635 bool VM_Version::use_biased_locking() {
1636 #if INCLUDE_RTM_OPT
1637 // RTM locking is most useful when there is high lock contention and
1638 // low data contention. With high lock contention the lock is usually
1639 // inflated and biased locking is not suitable for that case.
1640 // RTM locking code requires that biased locking is off.
1641 // Note: we can't switch off UseBiasedLocking in get_processor_features()
1642 // because it is used by Thread::allocate() which is called before
1643 // VM_Version::initialize().
1644 if (UseRTMLocking && UseBiasedLocking) {
1645 if (FLAG_IS_DEFAULT(UseBiasedLocking)) {
1646 FLAG_SET_DEFAULT(UseBiasedLocking, false);
1647 } else {
1648 warning("Biased locking is not supported with RTM locking; ignoring UseBiasedLocking flag." );
1649 UseBiasedLocking = false;
1650 }
1651 }
1652 #endif
1653 return UseBiasedLocking;
1654 }
1655
1656 // On Xen, the cpuid instruction returns
1657 // eax / registers[0]: Version of Xen
1658 // ebx / registers[1]: chars 'XenV'
1659 // ecx / registers[2]: chars 'MMXe'
1660 // edx / registers[3]: chars 'nVMM'
1661 //
1662 // On KVM / VMWare / MS Hyper-V, the cpuid instruction returns
1663 // ebx / registers[1]: chars 'KVMK' / 'VMwa' / 'Micr'
1664 // ecx / registers[2]: chars 'VMKV' / 'reVM' / 'osof'
1665 // edx / registers[3]: chars 'M' / 'ware' / 't Hv'
1666 //
1667 // more information :
1668 // https://kb.vmware.com/s/article/1009458
1669 //
1670 void VM_Version::check_virtualizations() {
1671 #if defined(_LP64)
1672 uint32_t registers[4];
1673 char signature[13];
1674 uint32_t base;
1675 signature[12] = '\0';
1676 memset((void*)registers, 0, 4*sizeof(uint32_t));
1677
1678 for (base = 0x40000000; base < 0x40010000; base += 0x100) {
1679 check_virt_cpuid(base, registers);
1680
1681 *(uint32_t *)(signature + 0) = registers[1];
1682 *(uint32_t *)(signature + 4) = registers[2];
1683 *(uint32_t *)(signature + 8) = registers[3];
1684
1685 if (strncmp("VMwareVMware", signature, 12) == 0) {
1686 Abstract_VM_Version::_detected_virtualization = VMWare;
1687 }
1688
1689 if (strncmp("Microsoft Hv", signature, 12) == 0) {
1690 Abstract_VM_Version::_detected_virtualization = HyperV;
1691 }
1692
1693 if (strncmp("KVMKVMKVM", signature, 9) == 0) {
1694 Abstract_VM_Version::_detected_virtualization = KVM;
1695 }
1696
1697 if (strncmp("XenVMMXenVMM", signature, 12) == 0) {
1698 Abstract_VM_Version::_detected_virtualization = XenHVM;
1699 }
1700 }
1701 #endif
1702 }
1703
1704 void VM_Version::initialize() {
1705 ResourceMark rm;
1706 // Making this stub must be FIRST use of assembler
1707
1708 stub_blob = BufferBlob::create("get_cpu_info_stub", stub_size);
1709 if (stub_blob == NULL) {
1710 vm_exit_during_initialization("Unable to allocate get_cpu_info_stub");
1711 }
1712 CodeBuffer c(stub_blob);
1713 VM_Version_StubGenerator g(&c);
1714 get_cpu_info_stub = CAST_TO_FN_PTR(get_cpu_info_stub_t,
1715 g.generate_get_cpu_info());
1716
1717 get_processor_features();
1718 if (cpu_family() > 4) { // it supports CPUID
1719 check_virtualizations();
1720 }
1721 }
|
1 /*
2 * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
1556 log->print_cr(" at distance %d, one line of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchStepSize);
1557 }
1558 }
1559
1560 if (PrefetchCopyIntervalInBytes > 0) {
1561 log->print_cr("PrefetchCopyIntervalInBytes %d", (int) PrefetchCopyIntervalInBytes);
1562 }
1563 if (PrefetchScanIntervalInBytes > 0) {
1564 log->print_cr("PrefetchScanIntervalInBytes %d", (int) PrefetchScanIntervalInBytes);
1565 }
1566 if (PrefetchFieldsAhead > 0) {
1567 log->print_cr("PrefetchFieldsAhead %d", (int) PrefetchFieldsAhead);
1568 }
1569 if (ContendedPaddingWidth > 0) {
1570 log->print_cr("ContendedPaddingWidth %d", (int) ContendedPaddingWidth);
1571 }
1572 }
1573 #endif // !PRODUCT
1574 }
1575
1576 bool VM_Version::use_biased_locking() {
1577 #if INCLUDE_RTM_OPT
1578 // RTM locking is most useful when there is high lock contention and
1579 // low data contention. With high lock contention the lock is usually
1580 // inflated and biased locking is not suitable for that case.
1581 // RTM locking code requires that biased locking is off.
1582 // Note: we can't switch off UseBiasedLocking in get_processor_features()
1583 // because it is used by Thread::allocate() which is called before
1584 // VM_Version::initialize().
1585 if (UseRTMLocking && UseBiasedLocking) {
1586 if (FLAG_IS_DEFAULT(UseBiasedLocking)) {
1587 FLAG_SET_DEFAULT(UseBiasedLocking, false);
1588 } else {
1589 warning("Biased locking is not supported with RTM locking; ignoring UseBiasedLocking flag." );
1590 UseBiasedLocking = false;
1591 }
1592 }
1593 #endif
1594 return UseBiasedLocking;
1595 }
1596
1597 void VM_Version::initialize() {
1598 ResourceMark rm;
1599 // Making this stub must be FIRST use of assembler
1600
1601 stub_blob = BufferBlob::create("get_cpu_info_stub", stub_size);
1602 if (stub_blob == NULL) {
1603 vm_exit_during_initialization("Unable to allocate get_cpu_info_stub");
1604 }
1605 CodeBuffer c(stub_blob);
1606 VM_Version_StubGenerator g(&c);
1607 get_cpu_info_stub = CAST_TO_FN_PTR(get_cpu_info_stub_t,
1608 g.generate_get_cpu_info());
1609
1610 get_processor_features();
1611 }
|