When running a program that uses openssl sha1 implementation the KIMD instruction will be used and valgrind signals an illegal instruction exception. ==2345== Process terminating with default action of signal 4 (SIGILL) ==2345== Illegal opcode at address 0x51D5EDC ==2345== at 0x51D5EDC: sha1_block_data_order (sha1-s390x.s:15) ==2345== by 0x51D4F8F: SHA1_Update (md32_common.h:307) ==2345== by 0x523159F: ssleay_rand_add (md_rand.c:289) gdb says: Dump of assembler code for function sha1_block_data_order: 0x00000000051d5ec0 <+0>: larl %r1,0x532d770 <OPENSSL_s390xcap_P> 0x00000000051d5ec6 <+6>: lg %r0,0(%r1) 0x00000000051d5ecc <+12>: tmhl %r0,16384 0x00000000051d5ed0 <+16>: je 0x51d5f10 <sha1_block_data_order+80> 0x00000000051d5ed4 <+20>: lghi %r0,0 0x00000000051d5ed8 <+24>: la %r1,16(%r15) 0x00000000051d5edc <+28>: kimd %r0,%r2 => 0x00000000051d5ee0 <+32>: lg %r0,16(%r15) 0x00000000051d5ee6 <+38>: tmhh %r0,16384 0x00000000051d5eea <+42>: je 0x51d5f10 <sha1_block_data_order+80> KIMD is part of the message-security assist (MSA) instruction extension. And valgrind doesn't implement it: case 0xb93e: /* KIMD */ goto unimplemented; openssl seems to probe the cpu to see if it can use it first, so valgrind should probably mask the availability somehow. openssl detection looks as follows [crypto/s390xcap.c]: extern unsigned long OPENSSL_s390xcap_P; static sigjmp_buf ill_jmp; static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); } sigaction (SIGILL,&ill_act,&oact); /* protection against missing store-facility-list-extended */ if (sigsetjmp(ill_jmp,0) == 0) OPENSSL_s390xcap_P = OPENSSL_s390x_facilities(); else OPENSSL_s390xcap_P = 1UL<<63; sigaction (SIGILL,&oact,NULL); [crypto/s390xcpuid.S]: OPENSSL_s390x_facilities: lghi %r0,0 .long 0xb2b0f010 # stfle 16(%r15) lg %r2,16(%r15) larl %r1,OPENSSL_s390xcap_P stg %r2,0(%r1) br %r14 As a "workaround" we can "unimplement" STFLE and openssl will use the fallback code that doesn't use KIMD. --- VEX/priv/guest_s390_toIR.c (revision 2574) +++ VEX/priv/guest_s390_toIR.c (working copy) @@ -12884,8 +12884,9 @@ case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3, ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok; - case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2); - goto ok; +// case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2); +// goto ok; + case 0xb2b0: /* STFLE */ goto unimplemented; case 0xb2b1: /* STFL */ goto unimplemented; case 0xb2b2: /* LPSWE */ goto unimplemented; case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2); A better workaround would be to make the valgrind STFLE indicate that message-security assist instructions aren't available. Reproducible: Always
This is also https://bugzilla.redhat.com/show_bug.cgi?id=881893
How about the following? It works for me, but we might want to mask of some more other bits maybe for other extensions valgrind doesn't support. Index: VEX/priv/guest_s390_helpers.c =================================================================== --- VEX/priv/guest_s390_helpers.c (revision 2574) +++ VEX/priv/guest_s390_helpers.c (working copy) @@ -310,6 +310,11 @@ "srl %2,28\n" : "=m" (hoststfle), "+d"(reg0), "=d"(cc) : : "cc", "memory"); + /* None of the message-security assist (MSA) extensions are supported + under valgrind. So clear bit 17. */ + UChar *ptr = (UChar *) &hoststfle[0] + (17 >> 3); + *ptr &= ~(0x80 >> (17 & 7)); + /* Update guest register 0 with what STFLE set r0 to */ guest_state->guest_r0 = reg0;
(In reply to comment #2) > How about the following? It works for me, but we might want to mask of some > more other bits maybe for other extensions valgrind doesn't support. Thanks for the report. The STFLE helper needs to be changed such that it reports the facilities of the virtual machine. Today it reports the facilities of the host. So.. for an insn X that is only available if facility F is installed, STFLE should report that F is not installed, if X is not implemented. I'll fix it.
Fixed in valgrind r13150 / VEX r2579.