OpenJDK / portola / portola
changeset 54948:278600885731
8222825: ARM32 SIGILL issue on single core CPU (not supported PLDW instruction)
Reviewed-by: dholmes, dlong
author | bulasevich |
---|---|
date | Thu, 16 May 2019 18:45:30 -0400 |
parents | 9feb4852536f |
children | 7136c9ac56a7 |
files | src/hotspot/cpu/arm/arm.ad src/hotspot/cpu/arm/assembler_arm_32.hpp src/hotspot/cpu/arm/vm_version_arm.hpp src/hotspot/cpu/arm/vm_version_arm_32.cpp src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp |
diffstat | 5 files changed, 54 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/src/hotspot/cpu/arm/arm.ad Fri May 17 00:21:10 2019 +0200 +++ b/src/hotspot/cpu/arm/arm.ad Thu May 16 18:45:30 2019 -0400 @@ -4348,7 +4348,8 @@ // Prefetch instructions. // Must be safe to execute with invalid address (cannot fault). -instruct prefetchAlloc( memoryP mem ) %{ +instruct prefetchAlloc_mp( memoryP mem ) %{ + predicate(VM_Version::has_multiprocessing_extensions()); match( PrefetchAllocation mem ); ins_cost(MEMORY_REF_COST); size(4); @@ -4360,6 +4361,20 @@ ins_pipe(iload_mem); %} +instruct prefetchAlloc_sp( memoryP mem ) %{ + predicate(!VM_Version::has_multiprocessing_extensions()); + match( PrefetchAllocation mem ); + ins_cost(MEMORY_REF_COST); + size(4); + + format %{ "PLD $mem\t! Prefetch allocation" %} + ins_encode %{ + __ pld($mem$$Address); + %} + ins_pipe(iload_mem); +%} + + //----------Store Instructions------------------------------------------------- // Store Byte instruct storeB(memoryB mem, store_RegI src) %{
--- a/src/hotspot/cpu/arm/assembler_arm_32.hpp Fri May 17 00:21:10 2019 +0200 +++ b/src/hotspot/cpu/arm/assembler_arm_32.hpp Thu May 16 18:45:30 2019 -0400 @@ -434,7 +434,9 @@ } void pldw(Address addr) { - assert(VM_Version::arm_arch() >= 7 && os::is_MP(), "no pldw on this processor"); + assert(!VM_Version::is_initialized() || + (VM_Version::arm_arch() >= 7 && VM_Version::has_multiprocessing_extensions()), + "PLDW is available on ARMv7 with Multiprocessing Extensions only"); emit_int32(0xf510f000 | addr.encoding2()); }
--- a/src/hotspot/cpu/arm/vm_version_arm.hpp Fri May 17 00:21:10 2019 +0200 +++ b/src/hotspot/cpu/arm/vm_version_arm.hpp Thu May 16 18:45:30 2019 -0400 @@ -32,6 +32,7 @@ friend class JVMCIVMStructs; static bool _has_simd; + static bool _has_mp_ext; protected: // Are we done with vm version initialization @@ -47,6 +48,7 @@ vfp = 0, vfp3_32 = 1, simd = 2, + mp_ext = 3 }; enum Feature_Flag_Set { @@ -56,6 +58,7 @@ vfp_m = 1 << vfp, vfp3_32_m = 1 << vfp3_32, simd_m = 1 << simd, + mp_ext_m = 1 << mp_ext }; // The value stored by "STR PC, [addr]" instruction can be either @@ -97,6 +100,7 @@ static bool has_vfp() { return (_features & vfp_m) != 0; } static bool has_vfp3_32() { return (_features & vfp3_32_m) != 0; } static bool has_simd() { return (_features & simd_m) != 0; } + static bool has_multiprocessing_extensions() { return (_features & mp_ext_m) != 0; } static bool simd_math_is_compliant() { return false; }
--- a/src/hotspot/cpu/arm/vm_version_arm_32.cpp Fri May 17 00:21:10 2019 +0200 +++ b/src/hotspot/cpu/arm/vm_version_arm_32.cpp Thu May 16 18:45:30 2019 -0400 @@ -40,6 +40,7 @@ typedef int (*get_cpu_info_t)(); typedef bool (*check_vfp_t)(double *d); typedef bool (*check_simd_t)(); + typedef bool (*check_mp_ext_t)(int *addr); } #define __ _masm-> @@ -95,6 +96,20 @@ return start; }; + + address generate_check_mp_ext() { + StubCodeMark mark(this, "VM_Version", "check_mp_ext"); + address start = __ pc(); + + // PLDW is available with Multiprocessing Extensions only + __ pldw(Address(R0)); + // Return true if instruction caused no signals + __ mov(R0, 1); + // JVM_handle_linux_signal moves PC here if SIGILL happens + __ bx(LR); + + return start; + }; }; #undef __ @@ -103,6 +118,7 @@ extern "C" address check_vfp3_32_fault_instr; extern "C" address check_vfp_fault_instr; extern "C" address check_simd_fault_instr; +extern "C" address check_mp_ext_fault_instr; void VM_Version::early_initialize() { @@ -165,6 +181,13 @@ #endif #endif + address check_mp_ext_pc = g.generate_check_mp_ext(); + check_mp_ext_t check_mp_ext = CAST_TO_FN_PTR(check_mp_ext_t, check_mp_ext_pc); + check_mp_ext_fault_instr = (address)check_mp_ext; + int dummy_local_variable; + if (check_mp_ext(&dummy_local_variable)) { + _features |= mp_ext_m; + } if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) { warning("AES intrinsics are not available on this CPU"); @@ -247,11 +270,12 @@ && _supports_atomic_getset8 && _supports_atomic_getadd8, "C2: atomic operations must be supported"); #endif char buf[512]; - jio_snprintf(buf, sizeof(buf), "(ARMv%d)%s%s%s", + jio_snprintf(buf, sizeof(buf), "(ARMv%d)%s%s%s%s", _arm_arch, (has_vfp() ? ", vfp" : ""), (has_vfp3_32() ? ", vfp3-32" : ""), - (has_simd() ? ", simd" : "")); + (has_simd() ? ", simd" : ""), + (has_multiprocessing_extensions() ? ", mp_ext" : "")); // buf is started with ", " or is empty _features_string = os::strdup(buf);
--- a/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp Fri May 17 00:21:10 2019 +0200 +++ b/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp Thu May 16 18:45:30 2019 -0400 @@ -248,11 +248,13 @@ extern "C" address check_vfp_fault_instr; extern "C" address check_vfp3_32_fault_instr; +extern "C" address check_simd_fault_instr; +extern "C" address check_mp_ext_fault_instr; address check_vfp_fault_instr = NULL; address check_vfp3_32_fault_instr = NULL; -extern "C" address check_simd_fault_instr; address check_simd_fault_instr = NULL; +address check_mp_ext_fault_instr = NULL; // Utility functions @@ -271,7 +273,8 @@ if (sig == SIGILL && ((info->si_addr == (caddr_t)check_simd_fault_instr) || info->si_addr == (caddr_t)check_vfp_fault_instr - || info->si_addr == (caddr_t)check_vfp3_32_fault_instr)) { + || info->si_addr == (caddr_t)check_vfp3_32_fault_instr + || info->si_addr == (caddr_t)check_mp_ext_fault_instr)) { // skip faulty instruction + instruction that sets return value to // success and set return value to failure. os::Linux::ucontext_set_pc(uc, (address)info->si_addr + 8);