1 /*
2 * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2015, 2020, Red Hat Inc. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26 #include "pauth_aarch64.hpp"
27 #include "register_aarch64.hpp"
28 #include "runtime/arguments.hpp"
29 #include "runtime/globals_extension.hpp"
30 #include "runtime/java.hpp"
31 #include "runtime/os.inline.hpp"
32 #include "runtime/vm_version.hpp"
33 #include "utilities/formatBuffer.hpp"
34 #include "utilities/macros.hpp"
35
36 int VM_Version::_cpu;
37 int VM_Version::_model;
38 int VM_Version::_model2;
39 int VM_Version::_variant;
40 int VM_Version::_revision;
41 int VM_Version::_stepping;
42
43 int VM_Version::_zva_length;
44 int VM_Version::_dcache_line_size;
45 int VM_Version::_icache_line_size;
46 int VM_Version::_initial_sve_vector_length;
47 int VM_Version::_max_supported_sve_vector_length;
48 bool VM_Version::_rop_protection;
49 uintptr_t VM_Version::_pac_mask;
50
51 SpinWait VM_Version::_spin_wait;
52
53 static SpinWait get_spin_wait_desc() {
54 if (strcmp(OnSpinWaitInst, "nop") == 0) {
55 return SpinWait(SpinWait::NOP, OnSpinWaitInstCount);
56 } else if (strcmp(OnSpinWaitInst, "isb") == 0) {
57 return SpinWait(SpinWait::ISB, OnSpinWaitInstCount);
58 } else if (strcmp(OnSpinWaitInst, "yield") == 0) {
59 return SpinWait(SpinWait::YIELD, OnSpinWaitInstCount);
60 } else if (strcmp(OnSpinWaitInst, "none") != 0) {
61 vm_exit_during_initialization("The options for OnSpinWaitInst are nop, isb, yield, and none", OnSpinWaitInst);
62 }
63
64 if (!FLAG_IS_DEFAULT(OnSpinWaitInstCount) && OnSpinWaitInstCount > 0) {
65 vm_exit_during_initialization("OnSpinWaitInstCount cannot be used for OnSpinWaitInst 'none'");
66 }
67
68 return SpinWait{};
69 }
70
71 void VM_Version::initialize() {
72 _supports_atomic_getset4 = true;
73 _supports_atomic_getadd4 = true;
74 _supports_atomic_getset8 = true;
75 _supports_atomic_getadd8 = true;
76
77 get_os_cpu_info();
78
79 int dcache_line = VM_Version::dcache_line_size();
80
81 // Limit AllocatePrefetchDistance so that it does not exceed the
82 // static constraint of 512 defined in runtime/globals.hpp.
83 if (FLAG_IS_DEFAULT(AllocatePrefetchDistance))
84 FLAG_SET_DEFAULT(AllocatePrefetchDistance, MIN2(512, 3*dcache_line));
85
86 if (FLAG_IS_DEFAULT(AllocatePrefetchStepSize))
87 FLAG_SET_DEFAULT(AllocatePrefetchStepSize, dcache_line);
88 if (FLAG_IS_DEFAULT(PrefetchScanIntervalInBytes))
89 FLAG_SET_DEFAULT(PrefetchScanIntervalInBytes, 3*dcache_line);
90 if (FLAG_IS_DEFAULT(PrefetchCopyIntervalInBytes))
91 FLAG_SET_DEFAULT(PrefetchCopyIntervalInBytes, 3*dcache_line);
92 if (FLAG_IS_DEFAULT(SoftwarePrefetchHintDistance))
93 FLAG_SET_DEFAULT(SoftwarePrefetchHintDistance, 3*dcache_line);
94
95 if (PrefetchCopyIntervalInBytes != -1 &&
96 ((PrefetchCopyIntervalInBytes & 7) || (PrefetchCopyIntervalInBytes >= 32768))) {
97 warning("PrefetchCopyIntervalInBytes must be -1, or a multiple of 8 and < 32768");
98 PrefetchCopyIntervalInBytes &= ~7;
99 if (PrefetchCopyIntervalInBytes >= 32768)
100 PrefetchCopyIntervalInBytes = 32760;
101 }
102
103 if (AllocatePrefetchDistance != -1 && (AllocatePrefetchDistance & 7)) {
104 warning("AllocatePrefetchDistance must be multiple of 8");
105 AllocatePrefetchDistance &= ~7;
106 }
107
108 if (AllocatePrefetchStepSize & 7) {
109 warning("AllocatePrefetchStepSize must be multiple of 8");
110 AllocatePrefetchStepSize &= ~7;
111 }
112
113 if (SoftwarePrefetchHintDistance != -1 &&
114 (SoftwarePrefetchHintDistance & 7)) {
115 warning("SoftwarePrefetchHintDistance must be -1, or a multiple of 8");
116 SoftwarePrefetchHintDistance &= ~7;
117 }
118
119 if (FLAG_IS_DEFAULT(ContendedPaddingWidth) && (dcache_line > ContendedPaddingWidth)) {
120 ContendedPaddingWidth = dcache_line;
121 }
122
123 if (os::supports_map_sync()) {
124 // if dcpop is available publish data cache line flush size via
125 // generic field, otherwise let if default to zero thereby
126 // disabling writeback
127 if (VM_Version::supports_dcpop()) {
128 _data_cache_line_flush_size = dcache_line;
129 }
130 }
131
132 // Enable vendor specific features
133
134 // Ampere eMAG
135 if (_cpu == CPU_AMCC && (_model == CPU_MODEL_EMAG) && (_variant == 0x3)) {
136 if (FLAG_IS_DEFAULT(AvoidUnalignedAccesses)) {
137 FLAG_SET_DEFAULT(AvoidUnalignedAccesses, true);
138 }
139 if (FLAG_IS_DEFAULT(UseSIMDForMemoryOps)) {
140 FLAG_SET_DEFAULT(UseSIMDForMemoryOps, true);
141 }
142 if (FLAG_IS_DEFAULT(UseSIMDForArrayEquals)) {
143 FLAG_SET_DEFAULT(UseSIMDForArrayEquals, !(_revision == 1 || _revision == 2));
144 }
145 }
146
147 // Ampere CPUs
148 if (_cpu == CPU_AMPERE && ((_model == CPU_MODEL_AMPERE_1) ||
149 (_model == CPU_MODEL_AMPERE_1A) ||
150 (_model == CPU_MODEL_AMPERE_1B))) {
151 if (FLAG_IS_DEFAULT(UseSIMDForMemoryOps)) {
152 FLAG_SET_DEFAULT(UseSIMDForMemoryOps, true);
153 }
154 if (FLAG_IS_DEFAULT(OnSpinWaitInst)) {
155 FLAG_SET_DEFAULT(OnSpinWaitInst, "isb");
156 }
157 if (FLAG_IS_DEFAULT(OnSpinWaitInstCount)) {
158 FLAG_SET_DEFAULT(OnSpinWaitInstCount, 2);
159 }
160 if (FLAG_IS_DEFAULT(CodeEntryAlignment) &&
161 (_model == CPU_MODEL_AMPERE_1A || _model == CPU_MODEL_AMPERE_1B)) {
162 FLAG_SET_DEFAULT(CodeEntryAlignment, 32);
163 }
164 if (FLAG_IS_DEFAULT(AlwaysMergeDMB)) {
165 FLAG_SET_DEFAULT(AlwaysMergeDMB, false);
166 }
167 }
168
169 // ThunderX
170 if (_cpu == CPU_CAVIUM && (_model == 0xA1)) {
171 guarantee(_variant != 0, "Pre-release hardware no longer supported.");
172 if (FLAG_IS_DEFAULT(AvoidUnalignedAccesses)) {
173 FLAG_SET_DEFAULT(AvoidUnalignedAccesses, true);
174 }
175 if (FLAG_IS_DEFAULT(UseSIMDForMemoryOps)) {
176 FLAG_SET_DEFAULT(UseSIMDForMemoryOps, (_variant > 0));
177 }
178 if (FLAG_IS_DEFAULT(UseSIMDForArrayEquals)) {
179 FLAG_SET_DEFAULT(UseSIMDForArrayEquals, false);
180 }
181 }
182
183 // ThunderX2
184 if ((_cpu == CPU_CAVIUM && (_model == 0xAF)) ||
185 (_cpu == CPU_BROADCOM && (_model == 0x516))) {
186 if (FLAG_IS_DEFAULT(AvoidUnalignedAccesses)) {
187 FLAG_SET_DEFAULT(AvoidUnalignedAccesses, true);
188 }
189 if (FLAG_IS_DEFAULT(UseSIMDForMemoryOps)) {
190 FLAG_SET_DEFAULT(UseSIMDForMemoryOps, true);
191 }
192 }
193
194 // HiSilicon TSV110
195 if (_cpu == CPU_HISILICON && _model == 0xd01) {
196 if (FLAG_IS_DEFAULT(AvoidUnalignedAccesses)) {
197 FLAG_SET_DEFAULT(AvoidUnalignedAccesses, true);
198 }
199 if (FLAG_IS_DEFAULT(UseSIMDForMemoryOps)) {
200 FLAG_SET_DEFAULT(UseSIMDForMemoryOps, true);
201 }
202 }
203
204 // Cortex A53
205 if (_cpu == CPU_ARM && model_is(0xd03)) {
206 _features |= CPU_A53MAC;
207 if (FLAG_IS_DEFAULT(UseSIMDForArrayEquals)) {
208 FLAG_SET_DEFAULT(UseSIMDForArrayEquals, false);
209 }
210 }
211
212 // Cortex A73
213 if (_cpu == CPU_ARM && model_is(0xd09)) {
214 if (FLAG_IS_DEFAULT(SoftwarePrefetchHintDistance)) {
215 FLAG_SET_DEFAULT(SoftwarePrefetchHintDistance, -1);
216 }
217 // A73 is faster with short-and-easy-for-speculative-execution-loop
218 if (FLAG_IS_DEFAULT(UseSimpleArrayEquals)) {
219 FLAG_SET_DEFAULT(UseSimpleArrayEquals, true);
220 }
221 }
222
223 // Neoverse
224 // N1: 0xd0c
225 // N2: 0xd49
226 // V1: 0xd40
227 // V2: 0xd4f
228 if (_cpu == CPU_ARM && (model_is(0xd0c) || model_is(0xd49) ||
229 model_is(0xd40) || model_is(0xd4f))) {
230 if (FLAG_IS_DEFAULT(UseSIMDForMemoryOps)) {
231 FLAG_SET_DEFAULT(UseSIMDForMemoryOps, true);
232 }
233
234 if (FLAG_IS_DEFAULT(OnSpinWaitInst)) {
235 FLAG_SET_DEFAULT(OnSpinWaitInst, "isb");
236 }
237
238 if (FLAG_IS_DEFAULT(OnSpinWaitInstCount)) {
239 FLAG_SET_DEFAULT(OnSpinWaitInstCount, 1);
240 }
241 if (FLAG_IS_DEFAULT(AlwaysMergeDMB)) {
242 FLAG_SET_DEFAULT(AlwaysMergeDMB, false);
243 }
244 }
245
246 if (_features & (CPU_FP | CPU_ASIMD)) {
247 if (FLAG_IS_DEFAULT(UseSignumIntrinsic)) {
248 FLAG_SET_DEFAULT(UseSignumIntrinsic, true);
249 }
250 }
251
252 if (FLAG_IS_DEFAULT(UseCRC32)) {
253 UseCRC32 = VM_Version::supports_crc32();
254 }
255
256 if (UseCRC32 && !VM_Version::supports_crc32()) {
257 warning("UseCRC32 specified, but not supported on this CPU");
258 FLAG_SET_DEFAULT(UseCRC32, false);
259 }
260
261 // Neoverse
262 // V1: 0xd40
263 // V2: 0xd4f
264 if (_cpu == CPU_ARM && (model_is(0xd40) || model_is(0xd4f))) {
265 if (FLAG_IS_DEFAULT(UseCryptoPmullForCRC32)) {
266 FLAG_SET_DEFAULT(UseCryptoPmullForCRC32, true);
267 }
268 if (FLAG_IS_DEFAULT(CodeEntryAlignment)) {
269 FLAG_SET_DEFAULT(CodeEntryAlignment, 32);
270 }
271 }
272
273 if (UseCryptoPmullForCRC32 && (!VM_Version::supports_pmull() || !VM_Version::supports_sha3() || !VM_Version::supports_crc32())) {
274 warning("UseCryptoPmullForCRC32 specified, but not supported on this CPU");
275 FLAG_SET_DEFAULT(UseCryptoPmullForCRC32, false);
276 }
277
278 if (FLAG_IS_DEFAULT(UseAdler32Intrinsics)) {
279 FLAG_SET_DEFAULT(UseAdler32Intrinsics, true);
280 }
281
282 if (UseVectorizedMismatchIntrinsic) {
283 warning("UseVectorizedMismatchIntrinsic specified, but not available on this CPU.");
284 FLAG_SET_DEFAULT(UseVectorizedMismatchIntrinsic, false);
285 }
286
287 if (VM_Version::supports_lse()) {
288 if (FLAG_IS_DEFAULT(UseLSE))
289 FLAG_SET_DEFAULT(UseLSE, true);
290 } else {
291 if (UseLSE) {
292 warning("UseLSE specified, but not supported on this CPU");
293 FLAG_SET_DEFAULT(UseLSE, false);
294 }
295 }
296
297 if (VM_Version::supports_aes()) {
298 UseAES = UseAES || FLAG_IS_DEFAULT(UseAES);
299 UseAESIntrinsics =
300 UseAESIntrinsics || (UseAES && FLAG_IS_DEFAULT(UseAESIntrinsics));
301 if (UseAESIntrinsics && !UseAES) {
302 warning("UseAESIntrinsics enabled, but UseAES not, enabling");
303 UseAES = true;
304 }
305 if (FLAG_IS_DEFAULT(UseAESCTRIntrinsics)) {
306 FLAG_SET_DEFAULT(UseAESCTRIntrinsics, true);
307 }
308 } else {
309 if (UseAES) {
310 warning("AES instructions are not available on this CPU");
311 FLAG_SET_DEFAULT(UseAES, false);
312 }
313 if (UseAESIntrinsics) {
314 warning("AES intrinsics are not available on this CPU");
315 FLAG_SET_DEFAULT(UseAESIntrinsics, false);
316 }
317 if (UseAESCTRIntrinsics) {
318 warning("AES/CTR intrinsics are not available on this CPU");
319 FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false);
320 }
321 }
322
323
324 if (FLAG_IS_DEFAULT(UseCRC32Intrinsics)) {
325 UseCRC32Intrinsics = true;
326 }
327
328 if (VM_Version::supports_crc32()) {
329 if (FLAG_IS_DEFAULT(UseCRC32CIntrinsics)) {
330 FLAG_SET_DEFAULT(UseCRC32CIntrinsics, true);
331 }
332 } else if (UseCRC32CIntrinsics) {
333 warning("CRC32C is not available on the CPU");
334 FLAG_SET_DEFAULT(UseCRC32CIntrinsics, false);
335 }
336
337 if (FLAG_IS_DEFAULT(UseFMA)) {
338 FLAG_SET_DEFAULT(UseFMA, true);
339 }
340
341 if (FLAG_IS_DEFAULT(UseMD5Intrinsics)) {
342 UseMD5Intrinsics = true;
343 }
344
345 if (VM_Version::supports_sha1() || VM_Version::supports_sha256() ||
346 VM_Version::supports_sha3() || VM_Version::supports_sha512()) {
347 if (FLAG_IS_DEFAULT(UseSHA)) {
348 FLAG_SET_DEFAULT(UseSHA, true);
349 }
350 } else if (UseSHA) {
351 warning("SHA instructions are not available on this CPU");
352 FLAG_SET_DEFAULT(UseSHA, false);
353 }
354
355 if (UseSHA && VM_Version::supports_sha1()) {
356 if (FLAG_IS_DEFAULT(UseSHA1Intrinsics)) {
357 FLAG_SET_DEFAULT(UseSHA1Intrinsics, true);
358 }
359 } else if (UseSHA1Intrinsics) {
360 warning("Intrinsics for SHA-1 crypto hash functions not available on this CPU.");
361 FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
362 }
363
364 if (UseSHA && VM_Version::supports_sha256()) {
365 if (FLAG_IS_DEFAULT(UseSHA256Intrinsics)) {
366 FLAG_SET_DEFAULT(UseSHA256Intrinsics, true);
367 }
368 } else if (UseSHA256Intrinsics) {
369 warning("Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU.");
370 FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
371 }
372
373 if (UseSHA && VM_Version::supports_sha3()) {
374 // Auto-enable UseSHA3Intrinsics on hardware with performance benefit.
375 // Note that the evaluation of UseSHA3Intrinsics shows better performance
376 // on Apple silicon but worse performance on Neoverse V1 and N2.
377 if (_cpu == CPU_APPLE) { // Apple silicon
378 if (FLAG_IS_DEFAULT(UseSHA3Intrinsics)) {
379 FLAG_SET_DEFAULT(UseSHA3Intrinsics, true);
380 }
381 }
382 } else if (UseSHA3Intrinsics && UseSIMDForSHA3Intrinsic) {
383 warning("Intrinsics for SHA3-224, SHA3-256, SHA3-384 and SHA3-512 crypto hash functions not available on this CPU.");
384 FLAG_SET_DEFAULT(UseSHA3Intrinsics, false);
385 }
386
387 if (UseSHA && VM_Version::supports_sha512()) {
388 if (FLAG_IS_DEFAULT(UseSHA512Intrinsics)) {
389 FLAG_SET_DEFAULT(UseSHA512Intrinsics, true);
390 }
391 } else if (UseSHA512Intrinsics) {
392 warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU.");
393 FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
394 }
395
396 if (!(UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA3Intrinsics || UseSHA512Intrinsics)) {
397 FLAG_SET_DEFAULT(UseSHA, false);
398 }
399
400 if (VM_Version::supports_pmull()) {
401 if (FLAG_IS_DEFAULT(UseGHASHIntrinsics)) {
402 FLAG_SET_DEFAULT(UseGHASHIntrinsics, true);
403 }
404 } else if (UseGHASHIntrinsics) {
405 warning("GHASH intrinsics are not available on this CPU");
406 FLAG_SET_DEFAULT(UseGHASHIntrinsics, false);
407 }
408
409 if (_features & CPU_ASIMD) {
410 if (FLAG_IS_DEFAULT(UseChaCha20Intrinsics)) {
411 UseChaCha20Intrinsics = true;
412 }
413 } else if (UseChaCha20Intrinsics) {
414 if (!FLAG_IS_DEFAULT(UseChaCha20Intrinsics)) {
415 warning("ChaCha20 intrinsic requires ASIMD instructions");
416 }
417 FLAG_SET_DEFAULT(UseChaCha20Intrinsics, false);
418 }
419
420 if (_features & CPU_ASIMD) {
421 if (FLAG_IS_DEFAULT(UseKyberIntrinsics)) {
422 UseKyberIntrinsics = true;
423 }
424 } else if (UseKyberIntrinsics) {
425 if (!FLAG_IS_DEFAULT(UseKyberIntrinsics)) {
426 warning("Kyber intrinsics require ASIMD instructions");
427 }
428 FLAG_SET_DEFAULT(UseKyberIntrinsics, false);
429 }
430
431 if (_features & CPU_ASIMD) {
432 if (FLAG_IS_DEFAULT(UseDilithiumIntrinsics)) {
433 UseDilithiumIntrinsics = true;
434 }
435 } else if (UseDilithiumIntrinsics) {
436 if (!FLAG_IS_DEFAULT(UseDilithiumIntrinsics)) {
437 warning("Dilithium intrinsics require ASIMD instructions");
438 }
439 FLAG_SET_DEFAULT(UseDilithiumIntrinsics, false);
440 }
441
442 if (FLAG_IS_DEFAULT(UseBASE64Intrinsics)) {
443 UseBASE64Intrinsics = true;
444 }
445
446 if (is_zva_enabled()) {
447 if (FLAG_IS_DEFAULT(UseBlockZeroing)) {
448 FLAG_SET_DEFAULT(UseBlockZeroing, true);
449 }
450 if (FLAG_IS_DEFAULT(BlockZeroingLowLimit)) {
451 FLAG_SET_DEFAULT(BlockZeroingLowLimit, 4 * VM_Version::zva_length());
452 }
453 } else if (UseBlockZeroing) {
454 warning("DC ZVA is not available on this CPU");
455 FLAG_SET_DEFAULT(UseBlockZeroing, false);
456 }
457
458 if (VM_Version::supports_sve2()) {
459 if (FLAG_IS_DEFAULT(UseSVE)) {
460 FLAG_SET_DEFAULT(UseSVE, 2);
461 }
462 } else if (VM_Version::supports_sve()) {
463 if (FLAG_IS_DEFAULT(UseSVE)) {
464 FLAG_SET_DEFAULT(UseSVE, 1);
465 } else if (UseSVE > 1) {
466 warning("SVE2 specified, but not supported on current CPU. Using SVE.");
467 FLAG_SET_DEFAULT(UseSVE, 1);
468 }
469 } else if (UseSVE > 0) {
470 warning("UseSVE specified, but not supported on current CPU. Disabling SVE.");
471 FLAG_SET_DEFAULT(UseSVE, 0);
472 }
473
474 if (UseSVE > 0) {
475 int vl = get_current_sve_vector_length();
476 if (vl < 0) {
477 warning("Unable to get SVE vector length on this system. "
478 "Disabling SVE. Specify -XX:UseSVE=0 to shun this warning.");
479 FLAG_SET_DEFAULT(UseSVE, 0);
480 } else if ((vl == 0) || ((vl % FloatRegister::sve_vl_min) != 0) || !is_power_of_2(vl)) {
481 warning("Detected SVE vector length (%d) should be a power of two and a multiple of %d. "
482 "Disabling SVE. Specify -XX:UseSVE=0 to shun this warning.",
483 vl, FloatRegister::sve_vl_min);
484 FLAG_SET_DEFAULT(UseSVE, 0);
485 } else {
486 _initial_sve_vector_length = vl;
487 }
488 }
489
490 // This machine allows unaligned memory accesses
491 if (FLAG_IS_DEFAULT(UseUnalignedAccesses)) {
492 FLAG_SET_DEFAULT(UseUnalignedAccesses, true);
493 }
494
495 if (FLAG_IS_DEFAULT(UsePopCountInstruction)) {
496 FLAG_SET_DEFAULT(UsePopCountInstruction, true);
497 }
498
499 if (!UsePopCountInstruction) {
500 warning("UsePopCountInstruction is always enabled on this CPU");
501 UsePopCountInstruction = true;
502 }
503
504 if (UseBranchProtection == nullptr || strcmp(UseBranchProtection, "none") == 0) {
505 _rop_protection = false;
506 } else if (strcmp(UseBranchProtection, "standard") == 0 ||
507 strcmp(UseBranchProtection, "pac-ret") == 0) {
508 _rop_protection = false;
509 // Enable ROP-protection if
510 // 1) this code has been built with branch-protection and
511 // 2) the CPU/OS supports it
512 #ifdef __ARM_FEATURE_PAC_DEFAULT
513 if (!VM_Version::supports_paca()) {
514 // Disable PAC to prevent illegal instruction crashes.
515 warning("ROP-protection specified, but not supported on this CPU. Disabling ROP-protection.");
516 } else {
517 _rop_protection = true;
518 }
519 #else
520 warning("ROP-protection specified, but this VM was built without ROP-protection support. Disabling ROP-protection.");
521 #endif
522 } else {
523 vm_exit_during_initialization(err_msg("Unsupported UseBranchProtection: %s", UseBranchProtection));
524 }
525
526 if (_rop_protection == true) {
527 // Determine the mask of address bits used for PAC. Clear bit 55 of
528 // the input to make it look like a user address.
529 _pac_mask = (uintptr_t)pauth_strip_pointer((address)~(UINT64_C(1) << 55));
530 }
531
532 #ifdef COMPILER2
533 if (FLAG_IS_DEFAULT(UseMultiplyToLenIntrinsic)) {
534 UseMultiplyToLenIntrinsic = true;
535 }
536
537 if (FLAG_IS_DEFAULT(UseSquareToLenIntrinsic)) {
538 UseSquareToLenIntrinsic = true;
539 }
540
541 if (FLAG_IS_DEFAULT(UseMulAddIntrinsic)) {
542 UseMulAddIntrinsic = true;
543 }
544
545 if (FLAG_IS_DEFAULT(UseMontgomeryMultiplyIntrinsic)) {
546 UseMontgomeryMultiplyIntrinsic = true;
547 }
548 if (FLAG_IS_DEFAULT(UseMontgomerySquareIntrinsic)) {
549 UseMontgomerySquareIntrinsic = true;
550 }
551
552 if (UseSVE > 0) {
553 if (FLAG_IS_DEFAULT(MaxVectorSize)) {
554 MaxVectorSize = _initial_sve_vector_length;
555 } else if (MaxVectorSize < FloatRegister::sve_vl_min) {
556 warning("SVE does not support vector length less than %d bytes. Disabling SVE.",
557 FloatRegister::sve_vl_min);
558 UseSVE = 0;
559 } else if (!((MaxVectorSize % FloatRegister::sve_vl_min) == 0 && is_power_of_2(MaxVectorSize))) {
560 vm_exit_during_initialization(err_msg("Unsupported MaxVectorSize: %d", (int)MaxVectorSize));
561 }
562
563 if (UseSVE > 0) {
564 // Acquire the largest supported vector length of this machine
565 _max_supported_sve_vector_length = set_and_get_current_sve_vector_length(FloatRegister::sve_vl_max);
566
567 if (MaxVectorSize != _max_supported_sve_vector_length) {
568 int new_vl = set_and_get_current_sve_vector_length(MaxVectorSize);
569 if (new_vl < 0) {
570 vm_exit_during_initialization(
571 err_msg("Current system does not support SVE vector length for MaxVectorSize: %d",
572 (int)MaxVectorSize));
573 } else if (new_vl != MaxVectorSize) {
574 warning("Current system only supports max SVE vector length %d. Set MaxVectorSize to %d",
575 new_vl, new_vl);
576 }
577 MaxVectorSize = new_vl;
578 }
579 _initial_sve_vector_length = MaxVectorSize;
580 }
581 }
582
583 if (UseSVE == 0) { // NEON
584 int min_vector_size = 8;
585 int max_vector_size = FloatRegister::neon_vl;
586 if (!FLAG_IS_DEFAULT(MaxVectorSize)) {
587 if (!is_power_of_2(MaxVectorSize)) {
588 vm_exit_during_initialization(err_msg("Unsupported MaxVectorSize: %d", (int)MaxVectorSize));
589 } else if (MaxVectorSize < min_vector_size) {
590 warning("MaxVectorSize must be at least %i on this platform", min_vector_size);
591 FLAG_SET_DEFAULT(MaxVectorSize, min_vector_size);
592 } else if (MaxVectorSize > max_vector_size) {
593 warning("MaxVectorSize must be at most %i on this platform", max_vector_size);
594 FLAG_SET_DEFAULT(MaxVectorSize, max_vector_size);
595 }
596 } else {
597 FLAG_SET_DEFAULT(MaxVectorSize, FloatRegister::neon_vl);
598 }
599 }
600
601 int inline_size = (UseSVE > 0 && MaxVectorSize >= FloatRegister::sve_vl_min) ? MaxVectorSize : 0;
602 if (FLAG_IS_DEFAULT(ArrayOperationPartialInlineSize)) {
603 FLAG_SET_DEFAULT(ArrayOperationPartialInlineSize, inline_size);
604 } else if (ArrayOperationPartialInlineSize != 0 && ArrayOperationPartialInlineSize != inline_size) {
605 warning("Setting ArrayOperationPartialInlineSize to %d", inline_size);
606 ArrayOperationPartialInlineSize = inline_size;
607 }
608
609 if (FLAG_IS_DEFAULT(OptoScheduling)) {
610 OptoScheduling = true;
611 }
612
613 if (FLAG_IS_DEFAULT(AlignVector)) {
614 AlignVector = AvoidUnalignedAccesses;
615 }
616
617 if (FLAG_IS_DEFAULT(UsePoly1305Intrinsics)) {
618 FLAG_SET_DEFAULT(UsePoly1305Intrinsics, true);
619 }
620
621 if (FLAG_IS_DEFAULT(UseVectorizedHashCodeIntrinsic)) {
622 FLAG_SET_DEFAULT(UseVectorizedHashCodeIntrinsic, true);
623 }
624 #endif
625
626 _spin_wait = get_spin_wait_desc();
627
628 check_virtualizations();
629
630 // Sync SVE related CPU features with flags
631 if (UseSVE < 2) {
632 _features &= ~CPU_SVE2;
633 _features &= ~CPU_SVEBITPERM;
634 }
635 if (UseSVE < 1) {
636 _features &= ~CPU_SVE;
637 }
638
639 // Construct the "features" string
640 char buf[512];
641 int buf_used_len = os::snprintf_checked(buf, sizeof(buf), "0x%02x:0x%x:0x%03x:%d", _cpu, _variant, _model, _revision);
642 if (_model2) {
643 os::snprintf_checked(buf + buf_used_len, sizeof(buf) - buf_used_len, "(0x%03x)", _model2);
644 }
645 size_t features_offset = strnlen(buf, sizeof(buf));
646 #define ADD_FEATURE_IF_SUPPORTED(id, name, bit) \
647 do { \
648 if (VM_Version::supports_##name()) strcat(buf, ", " #name); \
649 } while(0);
650 CPU_FEATURE_FLAGS(ADD_FEATURE_IF_SUPPORTED)
651 #undef ADD_FEATURE_IF_SUPPORTED
652
653 _cpu_info_string = os::strdup(buf);
654
655 _features_string = extract_features_string(_cpu_info_string,
656 strnlen(_cpu_info_string, sizeof(buf)),
657 features_offset);
658 }
659
660 #if defined(LINUX)
661 static bool check_info_file(const char* fpath,
662 const char* virt1, VirtualizationType vt1,
663 const char* virt2, VirtualizationType vt2) {
664 char line[500];
665 FILE* fp = os::fopen(fpath, "r");
666 if (fp == nullptr) {
667 return false;
668 }
669 while (fgets(line, sizeof(line), fp) != nullptr) {
670 if (strcasestr(line, virt1) != nullptr) {
671 Abstract_VM_Version::_detected_virtualization = vt1;
672 fclose(fp);
673 return true;
674 }
675 if (virt2 != nullptr && strcasestr(line, virt2) != nullptr) {
676 Abstract_VM_Version::_detected_virtualization = vt2;
677 fclose(fp);
678 return true;
679 }
680 }
681 fclose(fp);
682 return false;
683 }
684 #endif
685
686 void VM_Version::check_virtualizations() {
687 #if defined(LINUX)
688 const char* pname_file = "/sys/devices/virtual/dmi/id/product_name";
689 const char* tname_file = "/sys/hypervisor/type";
690 if (check_info_file(pname_file, "KVM", KVM, "VMWare", VMWare)) {
691 return;
692 }
693 check_info_file(tname_file, "Xen", XenPVHVM, nullptr, NoDetectedVirtualization);
694 #endif
695 }
696
697 void VM_Version::print_platform_virtualization_info(outputStream* st) {
698 #if defined(LINUX)
699 VirtualizationType vrt = VM_Version::get_detected_virtualization();
700 if (vrt == KVM) {
701 st->print_cr("KVM virtualization detected");
702 } else if (vrt == VMWare) {
703 st->print_cr("VMWare virtualization detected");
704 } else if (vrt == XenPVHVM) {
705 st->print_cr("Xen virtualization detected");
706 }
707 #endif
708 }
709
710 void VM_Version::initialize_cpu_information(void) {
711 // do nothing if cpu info has been initialized
712 if (_initialized) {
713 return;
714 }
715
716 _no_of_cores = os::processor_count();
717 _no_of_threads = _no_of_cores;
718 _no_of_sockets = _no_of_cores;
719 snprintf(_cpu_name, CPU_TYPE_DESC_BUF_SIZE - 1, "AArch64");
720
721 int desc_len = snprintf(_cpu_desc, CPU_DETAILED_DESC_BUF_SIZE, "AArch64 ");
722 get_compatible_board(_cpu_desc + desc_len, CPU_DETAILED_DESC_BUF_SIZE - desc_len);
723 desc_len = (int)strlen(_cpu_desc);
724 snprintf(_cpu_desc + desc_len, CPU_DETAILED_DESC_BUF_SIZE - desc_len, " %s", _cpu_info_string);
725
726 _initialized = true;
727 }