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