-
Bug
-
Resolution: Unresolved
-
Undefined
-
None
-
rhel-8.6.0, rhel-8.7.0, rhel-8.8.0, rhel-8.9.0
-
None
-
None
-
Moderate
-
Patch
-
rhel-sst-java
-
None
-
False
-
-
None
-
Red Hat Enterprise Linux
-
None
-
None
-
None
-
None
(gdb) bt
#0 os::ThreadCrashProtection::check_crash_protection (sig=4, thread=0x7fffa8050000)
at /usr/src/debug/java-1.8.0-openjdk-1.8.0.402.b06-2.el8.ppc64le/shenandoah-jdk8u402-b06/hotspot/src/os/posix/vm/os_posix.cpp:913
#1 0x00007fffae3f9ee4 in JVM_handle_linux_signal (sig=<optimized out>, info=0x7fffad8fbc68, ucVoid=0x7fffad8faef0, abort_if_unrecognized=<optimized out>)
at /usr/src/debug/java-1.8.0-openjdk-1.8.0.402.b06-2.el8.ppc64le/shenandoah-jdk8u402-b06/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp:181
#2 0x00007fffae3e59b4 in signalHandler (sig=<optimized out>, info=0x7fffae9ea050 <VM_Version::_features>, uc=0x7fffad8fbef0)
at /usr/src/debug/java-1.8.0-openjdk-1.8.0.402.b06-2.el8.ppc64le/shenandoah-jdk8u402-b06/hotspot/src/os/linux/vm/os_linux.cpp:4584
#3 <signal handler called>
#4 0x00007fff980002a4 in ?? ()
#5 0x00007fffae6b0bbc in VM_Version::determine_features () at /usr/src/debug/java-1.8.0-openjdk-1.8.0.402.b06-2.el8.ppc64le/shenandoah-jdk8u402-b06/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp:554
#6 0x00007fffae6b147c in VM_Version::initialize () at /usr/src/debug/java-1.8.0-openjdk-1.8.0.402.b06-2.el8.ppc64le/shenandoah-jdk8u402-b06/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp:59
#7 0x00007fffae6aec40 in VM_Version_init () at /usr/src/debug/java-1.8.0-openjdk-1.8.0.402.b06-2.el8.ppc64le/shenandoah-jdk8u402-b06/hotspot/src/share/vm/runtime/vm_version.cpp:328
#8 0x00007fffadfd94e0 in init_globals () at /usr/src/debug/java-1.8.0-openjdk-1.8.0.402.b06-2.el8.ppc64le/shenandoah-jdk8u402-b06/hotspot/src/share/vm/runtime/init.cpp:101
#9 0x00007fffae627fa4 in Threads::create_vm (args=<optimized out>, canTryAgain=0x7fffad8fe627)
(gdb) frame 5
#5 0x00007fffae6b0bbc in VM_Version::determine_features () at /usr/src/debug/java-1.8.0-openjdk-1.8.0.402.b06-2.el8.ppc64le/shenandoah-jdk8u402-b06/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp:554
554 (*test)((address)mid_of_test_area, (uint64_t)0);
(gdb) p test
$1 = (void (address, uint64_t)) 0x7fff98000280
(gdb) ptype test
type = void (address, uint64_t)(gdb) list VM_Version::determine_features
...
504 // Emit code.
505 void (*test)(address addr, uint64_t offset)=(void(address addr, uint64_t offset))(void *)a->function_entry();
506 uint32_t *code = (uint32_t *)a->pc();
507 // Don't use R0 in ldarx.
508 // Keep R3_ARG1 unmodified, it contains &field (see below).
509 // Keep R4_ARG2 unmodified, it contains offset = 0 (see below).
510 a->fsqrt(F3, F4); // code[0] -> fsqrt_m
511 a->fsqrts(F3, F4); // code[1] -> fsqrts_m
512 a->isel(R7, R5, R6, 0); // code[2] -> isel_m
513 a->ldarx_unchecked(R7, R3_ARG1, R4_ARG2, 1); // code[3] -> lxarx_m
514 a->cmpb(R7, R5, R6); // code[4] -> bcmp
515 //a->mftgpr(R7, F3); // code[5] -> mftgpr
516 a->popcntb(R7, R5); // code[6] -> popcntb
517 a->popcntw(R7, R5); // code[7] -> popcntw
518 a->fcfids(F3, F4); // code[8] -> fcfids
519 a->vand(VR0, VR0, VR0); // code[9] -> vand
520 a->lqarx_unchecked(R7, R3_ARG1, R4_ARG2, 1); // code[10] -> lqarx_m
521 a->vcipher(VR0, VR1, VR2); // code[11] -> vcipher
522 a->vpmsumb(VR0, VR1, VR2); // code[12] -> vpmsumb
523 a->mfdscr(R0); // code[13] -> mfdscr
...
(gdb) x/20i $pc-32
0x7fff98000284: fsqrts f3,f4
0x7fff98000288: isellt r7,r5,r6
0x7fff9800028c: ldarx r7,r3,r4,1
0x7fff98000290: cmpb r7,r5,r6
0x7fff98000294: popcntb r7,r5
0x7fff98000298: popcntw r7,r5
0x7fff9800029c: fcfids f3,f4
0x7fff980002a0: vand v0,v0,v0
=> 0x7fff980002a4: .long 0x7ce32229
0x7fff980002a8: vcipher v0,v1,v2
0x7fff980002ac: vpmsumb v0,v1,v2
0x7fff980002b0: mfspr r0,3
0x7fff980002b4: lxvd2x vs0,0,r3
0x7fff980002b8: vshasigmaw v0,v1,1,15
0x7fff980002bc: blr
0x7fff980002c0: dcbz 0,r3
0x7fff980002c4: blr
...
I do not have documentation for the actual instruction, but openjdk code that
added it is:
// Atomics.
LWARX_OPCODE = (31u << OPCODE_SHIFT | 20u << 1),
LDARX_OPCODE = (31u << OPCODE_SHIFT | 84u << 1),
+ LQARX_OPCODE = (31u << OPCODE_SHIFT | 276u << 1),
this should be an atomic acquire for a 128 bit memory address.
The cpu probably does not support it, the kernel does not properly emulate
it, or the arguments is not aligned.
It is indeed an unaligned memory access:
(gdb) frame 5
#5 0x00007fffae6b0bbc in VM_Version::determine_features () at /usr/src/debug/java-1.8.0-openjdk-1.8.0.402.b06-2.el8.ppc64le/shenandoah-jdk8u402-b06/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp:554
554 (*test)((address)mid_of_test_area, (uint64_t)0);
(gdb) list VM_Version::determine_features
...
491 // create test area
492 enum{{{}
{}}}; // Needs to be >=2* max cache line size (cache line size can't exceed min page size).
493 char test_area[BUFFER_SIZE];
494 char *mid_of_test_area = &test_area[BUFFER_SIZE>>1];
...
(gdb) p/x $r3
$1 = 0x7fffad8fd0d8
(gdb) p/x $r4
$2 = 0x0
(gdb) p/x $r3 & 15
$3 = 0x8
(gdb) p mid_of_test_area
$4 = 0x7fffad8fd0d8 ""
This is a bug in the openjdk code. The variable test_area should be 16 byte
aligned, or rely on a hardware or kernel trap to fix it. But for an atomic acquire
this might not be possible (trap and emulate the instruction).
The feature test code likely is only handling SIGILL, to check for features.
The fix should be the pseudo patch:
hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp:VM_Version::determine_features()()
- char test_area[BUFFER_SIZE];
+ char test_area[BUFFER_SIZE] {}attribute{} ((aligned (16)));