8188857: [s390]: CPU feature detection incomplete

Reviewed-by: mdoerr
This commit is contained in:
Lutz Schmidt 2017-10-09 11:51:20 +02:00
parent 75a4bdf218
commit ccbba3fe48
3 changed files with 33 additions and 4 deletions

View file

@ -706,12 +706,13 @@ void VM_Version::determine_features() {
Label getCPUFEATURES; // fcode = -1 (cache) Label getCPUFEATURES; // fcode = -1 (cache)
Label getCIPHERFEATURES; // fcode = -2 (cipher) Label getCIPHERFEATURES; // fcode = -2 (cipher)
Label getMSGDIGESTFEATURES; // fcode = -3 (SHA) Label getMSGDIGESTFEATURES; // fcode = -3 (SHA)
Label getVECTORFEATURES; // fcode = -4 (OS support for vector instructions)
Label checkLongDispFast; Label checkLongDispFast;
Label noLongDisp; Label noLongDisp;
Label posDisp, negDisp; Label posDisp, negDisp;
Label errRTN; Label errRTN;
a->z_ltgfr(Z_R0, Z_ARG2); // Buf len to r0 and test. a->z_ltgfr(Z_R0, Z_ARG2); // Buf len to r0 and test.
a->z_brl(getFEATURES); // negative -> Get machine features. a->z_brl(getFEATURES); // negative -> Get machine features not covered by facility list.
a->z_brz(checkLongDispFast); // zero -> Check for high-speed Long Displacement Facility. a->z_brz(checkLongDispFast); // zero -> Check for high-speed Long Displacement Facility.
a->z_aghi(Z_R0, -1); a->z_aghi(Z_R0, -1);
a->z_stfle(0, Z_ARG1); a->z_stfle(0, Z_ARG1);
@ -736,6 +737,8 @@ void VM_Version::determine_features() {
a->z_bre(getCIPHERFEATURES); a->z_bre(getCIPHERFEATURES);
a->z_cghi(Z_R0, -3); // -3: Extract detailed crypto capabilities (msg digest instructions). a->z_cghi(Z_R0, -3); // -3: Extract detailed crypto capabilities (msg digest instructions).
a->z_bre(getMSGDIGESTFEATURES); a->z_bre(getMSGDIGESTFEATURES);
a->z_cghi(Z_R0, -4); // -4: Verify vector instruction availability (OS support).
a->z_bre(getVECTORFEATURES);
a->z_xgr(Z_RET, Z_RET); // Not a valid function code. a->z_xgr(Z_RET, Z_RET); // Not a valid function code.
a->z_br(Z_R14); // Return "operation aborted". a->z_br(Z_R14); // Return "operation aborted".
@ -766,6 +769,11 @@ void VM_Version::determine_features() {
a->z_ecag(Z_RET,Z_R0,0,Z_ARG3); // Extract information as requested by Z_ARG1 contents. a->z_ecag(Z_RET,Z_R0,0,Z_ARG3); // Extract information as requested by Z_ARG1 contents.
a->z_br(Z_R14); a->z_br(Z_R14);
// Use a vector instruction to verify OS support. Will fail with SIGFPE if OS support is missing.
a->bind(getVECTORFEATURES);
a->z_vtm(Z_V0,Z_V0); // non-destructive vector instruction. Will cause SIGFPE if not supported.
a->z_br(Z_R14);
// Check the performance of the Long Displacement Facility, i.e. find out if we are running on z900 or newer. // Check the performance of the Long Displacement Facility, i.e. find out if we are running on z900 or newer.
a->bind(checkLongDispFast); a->bind(checkLongDispFast);
a->z_llill(Z_R0, 0xffff); // preset #iterations a->z_llill(Z_R0, 0xffff); // preset #iterations
@ -962,6 +970,19 @@ void VM_Version::determine_features() {
_nfeatures = 0; _nfeatures = 0;
} }
if (has_VectorFacility()) {
// Verify that feature can actually be used. OS support required.
call_getFeatures(buffer, -4, 0);
if (printVerbose) {
ttyLocker ttyl;
if (has_VectorFacility()) {
tty->print_cr(" Vector Facility has been verified to be supported by OS");
} else {
tty->print_cr(" Vector Facility has been disabled - not supported by OS");
}
}
}
// Extract Crypto Facility details. // Extract Crypto Facility details.
if (has_Crypto()) { if (has_Crypto()) {
// Get cipher features. // Get cipher features.

View file

@ -473,6 +473,8 @@ class VM_Version: public Abstract_VM_Version {
static void set_has_CryptoExt5() { _features[0] |= CryptoExtension5Mask; } static void set_has_CryptoExt5() { _features[0] |= CryptoExtension5Mask; }
static void set_has_VectorFacility() { _features[2] |= VectorFacilityMask; } static void set_has_VectorFacility() { _features[2] |= VectorFacilityMask; }
static void reset_has_VectorFacility() { _features[2] &= ~VectorFacilityMask; }
// Assembler testing. // Assembler testing.
static void allow_all(); static void allow_all();
static void revert(); static void revert();

View file

@ -448,11 +448,17 @@ JVM_handle_linux_signal(int sig,
} }
else { // thread->thread_state() != _thread_in_Java else { // thread->thread_state() != _thread_in_Java
if (sig == SIGILL && VM_Version::is_determine_features_test_running()) { if ((sig == SIGILL) && VM_Version::is_determine_features_test_running()) {
// SIGILL must be caused by VM_Version::determine_features(). // SIGILL must be caused by VM_Version::determine_features()
// when attempting to execute a non-existing instruction.
//*(int *) (pc-6)=0; // Patch instruction to 0 to indicate that it causes a SIGILL. //*(int *) (pc-6)=0; // Patch instruction to 0 to indicate that it causes a SIGILL.
// Flushing of icache is not necessary. // Flushing of icache is not necessary.
stub = pc; // Continue with next instruction. stub = pc; // Continue with next instruction.
} else if ((sig == SIGFPE) && VM_Version::is_determine_features_test_running()) {
// SIGFPE is known to be caused by trying to execute a vector instruction
// when the vector facility is installed, but operating system support is missing.
VM_Version::reset_has_VectorFacility();
stub = pc; // Continue with next instruction.
} else if (thread->thread_state() == _thread_in_vm && } else if (thread->thread_state() == _thread_in_vm &&
sig == SIGBUS && thread->doing_unsafe_access()) { sig == SIGBUS && thread->doing_unsafe_access()) {
// We don't really need a stub here! Just set the pending exeption and // We don't really need a stub here! Just set the pending exeption and