Bug 310931 - s390 message-security assist (MSA) instruction extension not implemented
Summary: s390 message-security assist (MSA) instruction extension not implemented
Status: RESOLVED FIXED
Alias: None
Product: valgrind
Classification: Developer tools
Component: vex (show other bugs)
Version: 3.9.0.SVN
Platform: unspecified Linux
: NOR normal
Target Milestone: ---
Assignee: Julian Seward
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-11-30 14:45 UTC by Mark Wielaard
Modified: 2012-12-04 04:48 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mark Wielaard 2012-11-30 14:45:37 UTC
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
Comment 1 Mark Wielaard 2012-11-30 14:47:49 UTC
This is also https://bugzilla.redhat.com/show_bug.cgi?id=881893
Comment 2 Mark Wielaard 2012-11-30 23:58:52 UTC
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;
Comment 3 Florian Krohm 2012-12-01 19:36:13 UTC
(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.
Comment 4 Florian Krohm 2012-12-04 04:48:42 UTC
Fixed in valgrind r13150 / VEX r2579.