< prev index next >

src/cpu/x86/vm/vm_version_x86.cpp

Print this page
rev 9054 : 8219241: Provide basic virtualization related info in the hs_error file on linux/windows x86_64
Reviewed-by: dholmes, mdoerr
   1 /*
   2  * Copyright (c) 1997, 2014, 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  *


1075         tty->print_cr(" at distance %d, one line of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchStepSize);
1076       }
1077     }
1078 
1079     if (PrefetchCopyIntervalInBytes > 0) {
1080       tty->print_cr("PrefetchCopyIntervalInBytes %d", (int) PrefetchCopyIntervalInBytes);
1081     }
1082     if (PrefetchScanIntervalInBytes > 0) {
1083       tty->print_cr("PrefetchScanIntervalInBytes %d", (int) PrefetchScanIntervalInBytes);
1084     }
1085     if (PrefetchFieldsAhead > 0) {
1086       tty->print_cr("PrefetchFieldsAhead %d", (int) PrefetchFieldsAhead);
1087     }
1088     if (ContendedPaddingWidth > 0) {
1089       tty->print_cr("ContendedPaddingWidth %d", (int) ContendedPaddingWidth);
1090     }
1091   }
1092 #endif // !PRODUCT
1093 }
1094 



























































1095 bool VM_Version::use_biased_locking() {
1096 #if INCLUDE_RTM_OPT
1097   // RTM locking is most useful when there is high lock contention and
1098   // low data contention.  With high lock contention the lock is usually
1099   // inflated and biased locking is not suitable for that case.
1100   // RTM locking code requires that biased locking is off.
1101   // Note: we can't switch off UseBiasedLocking in get_processor_features()
1102   // because it is used by Thread::allocate() which is called before
1103   // VM_Version::initialize().
1104   if (UseRTMLocking && UseBiasedLocking) {
1105     if (FLAG_IS_DEFAULT(UseBiasedLocking)) {
1106       FLAG_SET_DEFAULT(UseBiasedLocking, false);
1107     } else {
1108       warning("Biased locking is not supported with RTM locking; ignoring UseBiasedLocking flag." );
1109       UseBiasedLocking = false;
1110     }
1111   }
1112 #endif
1113   return UseBiasedLocking;
1114 }
1115 
















































1116 void VM_Version::initialize() {
1117   ResourceMark rm;
1118   // Making this stub must be FIRST use of assembler
1119 
1120   stub_blob = BufferBlob::create("get_cpu_info_stub", stub_size);
1121   if (stub_blob == NULL) {
1122     vm_exit_during_initialization("Unable to allocate get_cpu_info_stub");
1123   }
1124   CodeBuffer c(stub_blob);
1125   VM_Version_StubGenerator g(&c);
1126   get_cpu_info_stub = CAST_TO_FN_PTR(get_cpu_info_stub_t,
1127                                      g.generate_get_cpu_info());
1128 
1129   get_processor_features();



1130 }
   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  *


1075         tty->print_cr(" at distance %d, one line of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchStepSize);
1076       }
1077     }
1078 
1079     if (PrefetchCopyIntervalInBytes > 0) {
1080       tty->print_cr("PrefetchCopyIntervalInBytes %d", (int) PrefetchCopyIntervalInBytes);
1081     }
1082     if (PrefetchScanIntervalInBytes > 0) {
1083       tty->print_cr("PrefetchScanIntervalInBytes %d", (int) PrefetchScanIntervalInBytes);
1084     }
1085     if (PrefetchFieldsAhead > 0) {
1086       tty->print_cr("PrefetchFieldsAhead %d", (int) PrefetchFieldsAhead);
1087     }
1088     if (ContendedPaddingWidth > 0) {
1089       tty->print_cr("ContendedPaddingWidth %d", (int) ContendedPaddingWidth);
1090     }
1091   }
1092 #endif // !PRODUCT
1093 }
1094 
1095 void VM_Version::print_platform_virtualization_info(outputStream* st) {
1096   VirtualizationType vrt = VM_Version::get_detected_virtualization();
1097   if (vrt == XenHVM) {
1098     st->print_cr("Xen hardware-assisted virtualization detected");
1099   } else if (vrt == KVM) {
1100     st->print_cr("KVM virtualization detected");
1101   } else if (vrt == VMWare) {
1102     st->print_cr("VMWare virtualization detected");
1103   } else if (vrt == HyperV) {
1104     st->print_cr("HyperV virtualization detected");
1105   }
1106 }
1107 
1108 void VM_Version::check_virt_cpuid(uint32_t idx, uint32_t *regs) {
1109 // TODO support 32 bit
1110 #if defined(_LP64)
1111 #if defined(_MSC_VER)
1112   // Allocate space for the code
1113   const int code_size = 100;
1114   ResourceMark rm;
1115   CodeBuffer cb("detect_virt", code_size, 0);
1116   MacroAssembler* a = new MacroAssembler(&cb);
1117   address code = a->pc();
1118   void (*test)(uint32_t idx, uint32_t *regs) = (void(*)(uint32_t idx, uint32_t *regs))code;
1119 
1120   a->movq(r9, rbx); // save nonvolatile register
1121 
1122   // next line would not work on 32-bit
1123   a->movq(rax, c_rarg0 /* rcx */);
1124   a->movq(r8, c_rarg1 /* rdx */);
1125   a->cpuid();
1126   a->movl(Address(r8,  0), rax);
1127   a->movl(Address(r8,  4), rbx);
1128   a->movl(Address(r8,  8), rcx);
1129   a->movl(Address(r8, 12), rdx);
1130 
1131   a->movq(rbx, r9); // restore nonvolatile register
1132   a->ret(0);
1133 
1134   uint32_t *code_end = (uint32_t *)a->pc();
1135   a->flush();
1136 
1137   // execute code
1138   (*test)(idx, regs);
1139 #elif defined(__GNUC__)
1140   __asm__ volatile (
1141      "        cpuid;"
1142      "        mov %%eax,(%1);"
1143      "        mov %%ebx,4(%1);"
1144      "        mov %%ecx,8(%1);"
1145      "        mov %%edx,12(%1);"
1146      : "+a" (idx)
1147      : "S" (regs)
1148      : "ebx", "ecx", "edx", "memory" );
1149 #endif
1150 #endif
1151 }
1152 
1153 
1154 bool VM_Version::use_biased_locking() {
1155 #if INCLUDE_RTM_OPT
1156   // RTM locking is most useful when there is high lock contention and
1157   // low data contention.  With high lock contention the lock is usually
1158   // inflated and biased locking is not suitable for that case.
1159   // RTM locking code requires that biased locking is off.
1160   // Note: we can't switch off UseBiasedLocking in get_processor_features()
1161   // because it is used by Thread::allocate() which is called before
1162   // VM_Version::initialize().
1163   if (UseRTMLocking && UseBiasedLocking) {
1164     if (FLAG_IS_DEFAULT(UseBiasedLocking)) {
1165       FLAG_SET_DEFAULT(UseBiasedLocking, false);
1166     } else {
1167       warning("Biased locking is not supported with RTM locking; ignoring UseBiasedLocking flag." );
1168       UseBiasedLocking = false;
1169     }
1170   }
1171 #endif
1172   return UseBiasedLocking;
1173 }
1174 
1175 // On Xen, the cpuid instruction returns
1176 //  eax / registers[0]: Version of Xen
1177 //  ebx / registers[1]: chars 'XenV'
1178 //  ecx / registers[2]: chars 'MMXe'
1179 //  edx / registers[3]: chars 'nVMM'
1180 //
1181 // On KVM / VMWare / MS Hyper-V, the cpuid instruction returns
1182 //  ebx / registers[1]: chars 'KVMK' / 'VMwa' / 'Micr'
1183 //  ecx / registers[2]: chars 'VMKV' / 'reVM' / 'osof'
1184 //  edx / registers[3]: chars 'M'    / 'ware' / 't Hv'
1185 //
1186 // more information :
1187 // https://kb.vmware.com/s/article/1009458
1188 //
1189 void VM_Version::check_virtualizations() {
1190 #if defined(_LP64)
1191   uint32_t registers[4];
1192   char signature[13];
1193   uint32_t base;
1194   signature[12] = '\0';
1195   memset((void*)registers, 0, 4*sizeof(uint32_t));
1196 
1197   for (base = 0x40000000; base < 0x40010000; base += 0x100) {
1198     check_virt_cpuid(base, registers);
1199 
1200     *(uint32_t *)(signature + 0) = registers[1];
1201     *(uint32_t *)(signature + 4) = registers[2];
1202     *(uint32_t *)(signature + 8) = registers[3];
1203 
1204     if (strncmp("VMwareVMware", signature, 12) == 0) {
1205       Abstract_VM_Version::_detected_virtualization = VMWare;
1206     }
1207 
1208     if (strncmp("Microsoft Hv", signature, 12) == 0) {
1209       Abstract_VM_Version::_detected_virtualization = HyperV;
1210     }
1211 
1212     if (strncmp("KVMKVMKVM", signature, 9) == 0) {
1213       Abstract_VM_Version::_detected_virtualization = KVM;
1214     }
1215 
1216     if (strncmp("XenVMMXenVMM", signature, 12) == 0) {
1217       Abstract_VM_Version::_detected_virtualization = XenHVM;
1218     }
1219   }
1220 #endif
1221 }
1222 
1223 void VM_Version::initialize() {
1224   ResourceMark rm;
1225   // Making this stub must be FIRST use of assembler
1226 
1227   stub_blob = BufferBlob::create("get_cpu_info_stub", stub_size);
1228   if (stub_blob == NULL) {
1229     vm_exit_during_initialization("Unable to allocate get_cpu_info_stub");
1230   }
1231   CodeBuffer c(stub_blob);
1232   VM_Version_StubGenerator g(&c);
1233   get_cpu_info_stub = CAST_TO_FN_PTR(get_cpu_info_stub_t,
1234                                      g.generate_get_cpu_info());
1235 
1236   get_processor_features();
1237   if (cpu_family() > 4) { // it supports CPUID
1238     check_virtualizations();
1239   }
1240 }
< prev index next >