On Fri, 2023-08-04 at 11:58 +0200, Claudio Fontana wrote:
> On 8/4/23 11:20, Thomas Huth wrote:
> > On 04/08/2023 11.00, Claudio Fontana wrote:
> > > Hi,
> > > 
> > > On 7/21/23 11:08, Claudio Fontana wrote:
> > > > 
> > > > Hello Cornelia, Richard,
> > > > 
> > > > I had some strange behavior in an s390x TCG VM that I am
> > > > debugging,
> > > > 
> > > > and configured latest upstream QEMU with --enable-debug --
> > > > enable-debug-tcg
> > > > 
> > > > and I am running the qemu binary with -d unimp,guest_errors .
> > > > 
> > > > I get:
> > > > 
> > > > /usr/bin/qemu-system-s390x -nodefaults -no-reboot -nographic -
> > > > vga none -cpu qemu -d unimp,guest_errors -object rng-
> > > > random,filename=/dev/random,id=rng0 -device virtio-rng-
> > > > ccw,rng=rng0 -runas qemu -net none -kernel /var/tmp/boot/kernel
> > > > -initrd /var/tmp/boot/initrd -append root=/dev/disk/by-
> > > > id/virtio-0 rootfstype=ext3
> > > > rootflags=data=writeback,nobarrier,commit=150,noatime
> > > > elevator=noop nmi_watchdog=0 rw oops=panic panic=1 quiet
> > > > elevator=noop console=hvc0 init=build -m 2048 -drive
> > > > file=/var/tmp/img,format=raw,if=none,id=disk,cache=unsafe -
> > > > device virtio-blk-ccw,drive=disk,serial=0 -drive
> > > > file=/var/tmp/swap,format=raw,if=none,id=swap,cache=unsafe -
> > > > device virtio-blk-ccw,drive=swap,serial=1 -device virtio-
> > > > serial-ccw -device virtconsole,chardev=virtiocon0 -chardev
> > > > stdio,id=virtiocon0 -chardev
> > > > socket,id=monitor,server=on,wait=off,path=/var/tmp/img.qemu/mon
> > > > itor -mon chardev=monitor,mode=readline -smp 8
> > > > 
> > > > unimplemented opcode 0xb9ab
> > > > unimplemented opcode 0xb2af
> > > > 
> > > 
> > > ...
> > > 
> > > > Since I have some strange misbehavior at runtime, with
> > > > processes dying with segfaults and the guest kernel
> > > > complaining:
> > > > 
> > > >   [ 2269s] [ 2243.901667][ T8318] User process fault:
> > > > interruption code 0011 ilc:2 in libc.so.6[3ff87a80000+1c9000]
> > > >   [ 2269s] [ 2243.904433][ T8318] Failing address:
> > > > 000002aa0f73f000 TEID: 000002aa0f73f800
> > > >   [ 2269s] [ 2243.904952][ T8318] Fault in primary space mode
> > > > while using user ASCE.
> > > >   [ 2269s] [ 2243.905405][ T8318] AS:00000000057841c7
> > > > R3:0000000001fdc007 S:000000000398c000 P:0000000000000400
> > > > 
> > > 
> > > I am analyzing this problem further, now that the assertions have
> > > been solved.
> > > 
> > > I seem to have found an issue that manifests as a wrong return
> > > value from glibc's
> > > 
> > > __strstr_arch13
> > > 
> > > found in glibc/sysdeps/s390/strstr-arch13.S, which ends up in
> > > libc.so
> > > 
> > > Based on my tests, I could not trigger this issue on baremetal, I
> > > could only see it when run under TCG.
> > > 
> > > The workload here is the testsuite of the swig package:
> > > 
> > > git clone https://github.com/swig/swig.git
> > > 
> > > https://github.com/swig/swig/releases/tag/v4.1.1
> > > https://github.com/swig/swig/commit/77323a0f07562b7d90d36181697a72a909b9519a
> > > 
> > > The error presents itself as a return of strstr with a match past
> > > the end of the terminating NUL character of the string.
> > > 
> > > Here is the test I am doing to showcase it: I implemented a
> > > simple strstr as follows:
> > > 
> > > --------
> > > 
> > > static char *strstr_simple(const char *haystack, const char
> > > *needle)
> > > {
> > >    /*
> > >     * This function return a pointer to the beginning of the
> > > located substring, or NULL if the substring is not found.
> > >     * If needle is the empty string, the return value is always
> > > haystack itself.
> > >     */
> > >    int i, j;
> > > 
> > >    if (needle == NULL || haystack == NULL) {
> > >      return NULL;
> > >    }
> > >    if (needle[0] == 0) {
> > >      return (char *)haystack;
> > >    }
> > >    for (i = 0; haystack[i] != 0; i++) {
> > >      for (j = 0; haystack[i + j] != 0 && needle[j] != 0; j++) {
> > >        if (needle[j] != haystack[i + j]) {
> > >          break;
> > >        }
> > >      }
> > >      if (needle[j] == 0) {
> > >        return (char *)haystack + i;
> > >      }
> > >    }
> > >    return NULL;
> > > }
> > > 
> > > 
> > > --------
> > > 
> > > and then I have a wrapper that compares the results of this
> > > simple implementation with what comes from regular strstr,
> > > where I made sure that the strstr_ifunc results in
> > > __strstr_arch13:
> > > 
> > > char *strstr_w(const char *haystack, const char *needle)
> > > {
> > >    char *rv1 = strstr(haystack, needle);
> > >    char *rv2 = strstr_simple(haystack, needle);
> > >    if (rv1 != rv2) {
> > >      printf("haystack: %p \"%s\"\n"
> > >             "needle: %p \"%s\"\n"
> > >             "rv1: %p\n"
> > >             "rv2: %p\n",
> > >             (void*)haystack, haystack,
> > >             (void*)needle, needle,
> > >             (void*)rv1, (void*)rv2);
> > >      assert(0);
> > >    }
> > >    return rv1;
> > > }
> > > 
> > > --------
> > > 
> > > 
> > > After building swig with compilation flags: -m64 -march=z14 -
> > > mtune=z15
> > > 
> > > and running even a minimal test like:
> > > 
> > > $ cd Examples/perl5/simple
> > > $ export SWIG_LIB=../../../Lib
> > > $ ../../../swig -perl5 -o example.c.wrap example.i
> > > 
> > > I get:
> > > 
> > > haystack: 0x2aa2a2488f0 "        "363:operator< ignored" "
> > > needle: 0x2aa2961bc8c " ^A"
> > > rv1: 0x2aa2a24891e
> > > rv2: (nil)
> > > swig: DOH/copy.c:120: strstr_w: Assertion `0' failed.
> > > Aborted
> > > 
> > > As you can see here strstr returns a match where there is none,
> > > and what is even worse, the pointer 0x2aa2a24891e is past the end
> > > of the string (0x2aa2a248910).
> > > 
> > > This causes the successive code (that relies on valid strstr
> > > results) to memmove a negative value of bytes, which ends up
> > > hitting the end of the heap for the process, causing the segfault
> > > originally encountered.
> > > 
> > > I can make the issue disappear for example by forcing the
> > > strstr_ifunc to choose __GI_strstr instead of __strstr_arch13.
> > > 
> > > Maybe something going wrong in the vector string search
> > > emulation, something rings a bell?
> > > 
> > > Let me know if there is something I can provide that could help
> > > investigate further.
> > 
> > Could you maybe get a disassembly of your __strstr_arch13 function,
> > so we 
> > could see which vector instructions are in there?
> > 
> >   Thomas
> 
> Here it is:
> 
> 000000000002ac70 <__strstr_arch13>:
>    2ac70:       e7 10 30 00 60 27       lcbb    %r1,0(%r3),6
>    2ac76:       a7 14 00 c6             jo      2ae02
> <__strstr_arch13+0x192>
>    2ac7a:       e7 20 30 00 68 06       vl      %v18,0(%r3),6
>    2ac80:       e7 32 20 20 0e 81       vfenezb %v19,%v18,%v18
>    2ac86:       e7 43 00 07 04 21       vlgvb   %r4,%v19,7
>    2ac8c:       a7 59 00 11             lghi    %r5,17
>    2ac90:       ec 48 e0 00 00 fc       cgibe   %r4,0,0(%r14)
>    2ac96:       c2 4e 00 00 00 09       clgfi   %r4,9
>    2ac9c:       c0 24 00 04 70 42       jgh     b8d20 <__GI_strstr>
>    2aca2:       b9 09 00 54             sgr     %r5,%r4
>    2aca6:       e7 10 20 00 60 27       lcbb    %r1,0(%r2),6
>    2acac:       a7 14 00 96             jo      2add8
> <__strstr_arch13+0x168>
>    2acb0:       e7 00 20 00 08 06       vl      %v16,0(%r2)
>    2acb6:       e7 40 20 20 3f 8b       vstrszb %v20,%v16,%v18,%v19
>    2acbc:       a7 74 00 33             jne     2ad22
> <__strstr_arch13+0xb2>
>    2acc0:       e7 10 20 10 60 27       lcbb    %r1,16(%r2),6
>    2acc6:       a7 14 00 87             jo      2add4
> <__strstr_arch13+0x164>
>    2acca:       e7 00 20 10 08 06       vl      %v16,16(%r2)
>    2acd0:       e7 40 20 20 3f 8b       vstrszb %v20,%v16,%v18,%v19
>    2acd6:       a7 74 00 24             jne     2ad1e
> <__strstr_arch13+0xae>
>    2acda:       e7 10 20 20 60 27       lcbb    %r1,32(%r2),6
>    2ace0:       a7 14 00 78             jo      2add0
> <__strstr_arch13+0x160>
>    2ace4:       e7 00 20 20 08 06       vl      %v16,32(%r2)
>    2acea:       e7 40 20 20 3f 8b       vstrszb %v20,%v16,%v18,%v19
>    2acf0:       a7 74 00 15             jne     2ad1a
> <__strstr_arch13+0xaa>
>    2acf4:       e7 10 20 30 60 27       lcbb    %r1,48(%r2),6
>    2acfa:       a7 14 00 69             jo      2adcc
> <__strstr_arch13+0x15c>
>    2acfe:       e7 00 20 30 08 06       vl      %v16,48(%r2)
>    2ad04:       e7 40 20 20 3f 8b       vstrszb %v20,%v16,%v18,%v19
>    2ad0a:       a7 74 00 06             jne     2ad16
> <__strstr_arch13+0xa6>
>    2ad0e:       41 20 20 40             la      %r2,64(%r2)
>    2ad12:       a7 f4 ff ca             j       2aca6
> <__strstr_arch13+0x36>
>    2ad16:       41 20 20 10             la      %r2,16(%r2)
>    2ad1a:       41 20 20 10             la      %r2,16(%r2)
>    2ad1e:       41 20 20 10             la      %r2,16(%r2)
>    2ad22:       a7 24 00 4f             jh      2adc0
> <__strstr_arch13+0x150>
>    2ad26:       a7 44 00 4a             jl      2adba
> <__strstr_arch13+0x14a>
>    2ad2a:       e7 15 20 00 60 27       lcbb    %r1,0(%r5,%r2),6
>    2ad30:       41 25 20 00             la      %r2,0(%r5,%r2)
>    2ad34:       a7 14 00 52             jo      2add8
> <__strstr_arch13+0x168>
>    2ad38:       e7 00 20 00 08 06       vl      %v16,0(%r2)
>    2ad3e:       e7 40 20 20 3f 8b       vstrszb %v20,%v16,%v18,%v19
>    2ad44:       a7 24 00 3e             jh      2adc0
> <__strstr_arch13+0x150>
>    2ad48:       a7 44 00 39             jl      2adba
> <__strstr_arch13+0x14a>
>    2ad4c:       41 25 20 00             la      %r2,0(%r5,%r2)
>    2ad50:       a7 84 ff ab             je      2aca6
> <__strstr_arch13+0x36>
>    2ad54:       e7 10 20 00 60 27       lcbb    %r1,0(%r2),6
>    2ad5a:       a7 14 00 3f             jo      2add8
> <__strstr_arch13+0x168>
>    2ad5e:       e7 00 20 00 08 06       vl      %v16,0(%r2)
>    2ad64:       e7 40 20 20 3f 8b       vstrszb %v20,%v16,%v18,%v19
>    2ad6a:       a7 24 00 2b             jh      2adc0
> <__strstr_arch13+0x150>
>    2ad6e:       a7 44 00 26             jl      2adba
> <__strstr_arch13+0x14a>
>    2ad72:       41 25 20 00             la      %r2,0(%r5,%r2)
>    2ad76:       a7 84 ff 98             je      2aca6
> <__strstr_arch13+0x36>
>    2ad7a:       e7 10 20 00 60 27       lcbb    %r1,0(%r2),6
>    2ad80:       a7 14 00 2c             jo      2add8
> <__strstr_arch13+0x168>
>    2ad84:       e7 00 20 00 08 06       vl      %v16,0(%r2)
>    2ad8a:       e7 40 20 20 3f 8b       vstrszb %v20,%v16,%v18,%v19
>    2ad90:       a7 24 00 18             jh      2adc0
> <__strstr_arch13+0x150>
>    2ad94:       a7 44 00 13             jl      2adba
> <__strstr_arch13+0x14a>
>    2ad98:       41 25 20 00             la      %r2,0(%r5,%r2)
>    2ad9c:       a7 84 ff 85             je      2aca6
> <__strstr_arch13+0x36>
>    2ada0:       e7 10 20 00 60 27       lcbb    %r1,0(%r2),6
>    2ada6:       a7 14 00 19             jo      2add8
> <__strstr_arch13+0x168>
>    2adaa:       e7 00 20 00 08 06       vl      %v16,0(%r2)
>    2adb0:       e7 40 20 20 3f 8b       vstrszb %v20,%v16,%v18,%v19
>    2adb6:       a7 f4 ff c7             j       2ad44
> <__strstr_arch13+0xd4>
>    2adba:       a7 29 00 00             lghi    %r2,0
>    2adbe:       07 fe                   br      %r14
>    2adc0:       e7 44 00 07 04 21       vlgvb   %r4,%v20,7
>    2adc6:       41 24 20 00             la      %r2,0(%r4,%r2)
>    2adca:       07 fe                   br      %r14
>    2adcc:       41 20 20 10             la      %r2,16(%r2)
>    2add0:       41 20 20 10             la      %r2,16(%r2)
>    2add4:       41 20 20 10             la      %r2,16(%r2)
>    2add8:       a7 1a ff ff             ahi     %r1,-1
>    2addc:       e7 01 20 00 08 37       vll     %v16,%r1,0(%r2)
>    2ade2:       e7 51 00 07 08 22       vlvgb   %v21,%r1,7
>    2ade8:       e7 10 00 20 0e 81       vfenezb %v17,%v16,%v16
>    2adee:       e7 15 00 00 0c d9       veclb   %v17,%v21
>    2adf4:       a7 c4 ff 61             jle     2acb6
> <__strstr_arch13+0x46>
>    2adf8:       e7 00 20 00 08 06       vl      %v16,0(%r2)
>    2adfe:       a7 f4 ff 5c             j       2acb6
> <__strstr_arch13+0x46>
>    2ae02:       a7 1a ff ff             ahi     %r1,-1
>    2ae06:       e7 21 30 00 08 37       vll     %v18,%r1,0(%r3)
>    2ae0c:       e7 51 00 07 08 22       vlvgb   %v21,%r1,7
>    2ae12:       e7 32 20 20 0e 81       vfenezb %v19,%v18,%v18
>    2ae18:       e7 35 00 00 0c d9       veclb   %v19,%v21
>    2ae1e:       a7 c4 ff 34             jle     2ac86
> <__strstr_arch13+0x16>
>    2ae22:       e7 20 30 00 08 06       vl      %v18,0(%r3)
>    2ae28:       e7 32 20 20 0e 81       vfenezb %v19,%v18,%v18
>    2ae2e:       a7 f4 ff 2c             j       2ac86
> <__strstr_arch13+0x16>

Thanks! I did some trace comparisons, and I can see that vstrszb
sometimes produces a CC that is different from the one from the real
hardware. I'll dig into this further and hopefully come up with a
patch.

Reply via email to