All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH RFC 0/2] tests/tcg: Vector instruction tests for target/s390x
@ 2019-02-27 11:14 David Hildenbrand
  2019-02-27 11:14 ` [Qemu-devel] [PATCH RFC 1/2] tests/tcg: Allow targets to set the optimization level David Hildenbrand
  2019-02-27 11:14 ` [Qemu-devel] [PATCH RFC 2/2] tests/tcg: target/s390: Add test for VECTOR LOAD GR FROM VR ELEMENT David Hildenbrand
  0 siblings, 2 replies; 18+ messages in thread
From: David Hildenbrand @ 2019-02-27 11:14 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-s390x, Thomas Huth, Cornelia Huck, Richard Henderson,
	Alex Bennée, Philippe Mathieu-Daudé,
	David Hildenbrand

As I currently work on vector instruction support for s390x/tcg, for now
I wrote my tests for kvm-unit-tests, but tests/tcg seems to be a better fit.
The only tricky part is testing interrupt handling, but that also seems to
be possible using some signal hackery.

This is only one test to discuss if the approach make sense. These patches
only work when applied on top of:
    https://github.com/davidhildenbrand/qemu/tree/vx

David Hildenbrand (2):
  tests/tcg: Allow targets to set the optimization level
  tests/tcg: target/s390: Add test for VECTOR LOAD GR FROM VR ELEMENT

 tests/tcg/Makefile                  |  4 +--
 tests/tcg/s390x/Makefile.target     |  3 ++-
 tests/tcg/s390x/helper.h            | 28 +++++++++++++++++++++
 tests/tcg/s390x/signal_helper.inc.c | 39 +++++++++++++++++++++++++++++
 tests/tcg/s390x/vlgv.c              | 37 +++++++++++++++++++++++++++
 5 files changed, 108 insertions(+), 3 deletions(-)
 create mode 100644 tests/tcg/s390x/helper.h
 create mode 100644 tests/tcg/s390x/signal_helper.inc.c
 create mode 100644 tests/tcg/s390x/vlgv.c

-- 
2.17.2

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH RFC 1/2] tests/tcg: Allow targets to set the optimization level
  2019-02-27 11:14 [Qemu-devel] [PATCH RFC 0/2] tests/tcg: Vector instruction tests for target/s390x David Hildenbrand
@ 2019-02-27 11:14 ` David Hildenbrand
  2019-02-27 11:46   ` Alex Bennée
  2019-02-28  0:26   ` Richard Henderson
  2019-02-27 11:14 ` [Qemu-devel] [PATCH RFC 2/2] tests/tcg: target/s390: Add test for VECTOR LOAD GR FROM VR ELEMENT David Hildenbrand
  1 sibling, 2 replies; 18+ messages in thread
From: David Hildenbrand @ 2019-02-27 11:14 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-s390x, Thomas Huth, Cornelia Huck, Richard Henderson,
	Alex Bennée, Philippe Mathieu-Daudé,
	David Hildenbrand

We sometimes want basic optimizations, e.g. for constant propagation
into inlined functions.

Especially for inline asm with immediates;

static inline void some_instr(uint8_t imm)
{
    asm volatile("...", :: "i" (imm));
}

static void test()
{
    some_instr(1);
}

Which is impossible with -O0. So make -O0 the default but let
targets override it.

Signed-off-by: David Hildenbrand <david@redhat.com>
---
 tests/tcg/Makefile | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/tcg/Makefile b/tests/tcg/Makefile
index bf06415390..bd0bace0d5 100644
--- a/tests/tcg/Makefile
+++ b/tests/tcg/Makefile
@@ -47,7 +47,7 @@ skip-test = @printf "  SKIPPED %s on $(TARGET_NAME) because %s\n" $1 $2
 TESTS=
 
 # Start with a blank slate, the build targets get to add stuff first
-CFLAGS=
+CFLAGS=-O0
 QEMU_CFLAGS=
 LDFLAGS=
 
@@ -70,7 +70,7 @@ ifneq ($(TARGET_BASE_ARCH),$(TARGET_NAME))
 endif
 
 # Add the common build options
-CFLAGS+=-Wall -O0 -g -fno-strict-aliasing
+CFLAGS+=-Wall -g -fno-strict-aliasing
 ifeq ($(BUILD_STATIC),y)
 LDFLAGS+=-static
 endif
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH RFC 2/2] tests/tcg: target/s390: Add test for VECTOR LOAD GR FROM VR ELEMENT
  2019-02-27 11:14 [Qemu-devel] [PATCH RFC 0/2] tests/tcg: Vector instruction tests for target/s390x David Hildenbrand
  2019-02-27 11:14 ` [Qemu-devel] [PATCH RFC 1/2] tests/tcg: Allow targets to set the optimization level David Hildenbrand
@ 2019-02-27 11:14 ` David Hildenbrand
  2019-02-27 11:19   ` David Hildenbrand
  2019-02-27 19:37   ` David Hildenbrand
  1 sibling, 2 replies; 18+ messages in thread
From: David Hildenbrand @ 2019-02-27 11:14 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-s390x, Thomas Huth, Cornelia Huck, Richard Henderson,
	Alex Bennée, Philippe Mathieu-Daudé,
	David Hildenbrand

We want to make use of vectors, so use -march=z13. To make it compile,
use a reasonable optimization level (-O2), which seems to work just fine
with all tests.

Add some infrastructure for checking if SIGILL will be properly
triggered.

Signed-off-by: David Hildenbrand <david@redhat.com>
---
 tests/tcg/s390x/Makefile.target     |  3 ++-
 tests/tcg/s390x/helper.h            | 28 +++++++++++++++++++++
 tests/tcg/s390x/signal_helper.inc.c | 39 +++++++++++++++++++++++++++++
 tests/tcg/s390x/vlgv.c              | 37 +++++++++++++++++++++++++++
 4 files changed, 106 insertions(+), 1 deletion(-)
 create mode 100644 tests/tcg/s390x/helper.h
 create mode 100644 tests/tcg/s390x/signal_helper.inc.c
 create mode 100644 tests/tcg/s390x/vlgv.c

diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target
index 151dc075aa..d1ae755ab9 100644
--- a/tests/tcg/s390x/Makefile.target
+++ b/tests/tcg/s390x/Makefile.target
@@ -1,8 +1,9 @@
 VPATH+=$(SRC_PATH)/tests/tcg/s390x
-CFLAGS+=-march=zEC12 -m64
+CFLAGS+=-march=z13 -m64 -O2
 TESTS+=hello-s390x
 TESTS+=csst
 TESTS+=ipm
 TESTS+=exrl-trt
 TESTS+=exrl-trtr
 TESTS+=pack
+TESTS+=vlgv
diff --git a/tests/tcg/s390x/helper.h b/tests/tcg/s390x/helper.h
new file mode 100644
index 0000000000..845b8bb504
--- /dev/null
+++ b/tests/tcg/s390x/helper.h
@@ -0,0 +1,28 @@
+#ifndef TEST_TCG_S390x_VECTOR_H
+#define TEST_TCG_S390x_VECTOR_H
+
+#include <stdint.h>
+
+#define ES_8    0
+#define ES_16   1
+#define ES_32   2
+#define ES_64   3
+#define ES_128  4
+
+typedef union S390Vector {
+    __uint128_t v;
+    uint64_t q[2];
+    uint32_t d[4];
+    uint16_t w[8];
+    uint8_t h[16];
+} S390Vector;
+
+static inline void check(const char *s, bool cond)
+{
+    if (!cond) {
+        fprintf(stderr, "Check failed: %s\n", s);
+        exit(-1);
+    }
+}
+
+#endif /* TEST_TCG_S390x_VECTOR_H */
diff --git a/tests/tcg/s390x/signal_helper.inc.c b/tests/tcg/s390x/signal_helper.inc.c
new file mode 100644
index 0000000000..5bd69ca76a
--- /dev/null
+++ b/tests/tcg/s390x/signal_helper.inc.c
@@ -0,0 +1,39 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <signal.h>
+#include <setjmp.h>
+#include "helper.h"
+
+jmp_buf jmp_env;
+
+static void sig_sigill(int sig)
+{
+    if (sig != SIGILL) {
+        check("Wrong signal received", false);
+    }
+    longjmp(jmp_env, 1);
+}
+
+#define CHECK_SIGILL(STATEMENT)                             \
+do {                                                        \
+    struct sigaction act;                                   \
+                                                            \
+    act.sa_handler = sig_sigill;                            \
+    act.sa_flags = 0;                                       \
+    if (sigaction(SIGILL, &act, NULL)) {                    \
+        check("SIGILL handler not registered", false);      \
+    }                                                       \
+                                                            \
+    if (setjmp(jmp_env) == 0) {                             \
+        STATEMENT;                                          \
+        check("SIGILL not triggered", false);               \
+    }                                                       \
+                                                            \
+    act.sa_handler = SIG_DFL;                               \
+    sigemptyset(&act.sa_mask);                              \
+    act.sa_flags = 0;                                       \
+    if (sigaction(SIGILL, &act, NULL)) {                    \
+        check("SIGILL handler not unregistered", false);    \
+    }                                                       \
+} while (0)
diff --git a/tests/tcg/s390x/vlgv.c b/tests/tcg/s390x/vlgv.c
new file mode 100644
index 0000000000..3c37ee2035
--- /dev/null
+++ b/tests/tcg/s390x/vlgv.c
@@ -0,0 +1,37 @@
+#include <stdint.h>
+#include <unistd.h>
+#include "signal_helper.inc.c"
+
+static inline void vlgv(uint64_t *r1, S390Vector *v3, const void *a2,
+                        uint8_t m4)
+{
+    asm volatile("vlgv %[r1], %[v3], 0(%[a2]), %[m4]\n"
+                 : [r1] "+d" (*r1),
+                   [v3] "+v" (v3->v)
+                 : [a2] "d" (a2),
+                   [m4] "i" (m4));
+}
+
+int main(void)
+{
+    S390Vector v3 = {
+        .q[0] = 0x0011223344556677ull,
+        .q[1] = 0x8899aabbccddeeffull,
+    };
+    uint64_t r1 = 0;
+
+    /* Directly set all ignored bits to  */
+    vlgv(&r1, &v3, (void *)(7 | ~0xf), ES_8);
+    check("8 bit", r1 == 0x77);
+    vlgv(&r1, &v3, (void *)(4 | ~0x7), ES_16);
+    check("16 bit", r1 == 0x8899);
+    vlgv(&r1, &v3, (void *)(3 | ~0x3), ES_32);
+    check("32 bit", r1 == 0xccddeeff);
+    vlgv(&r1, &v3, (void *)(1 | ~0x1), ES_64);
+    check("64 bit", r1 == 0x8899aabbccddeeffull);
+    check("v3 not modified", v3.q[0] == 0x0011223344556677ull &&
+                             v3.q[1] == 0x8899aabbccddeeffull);
+
+    CHECK_SIGILL(vlgv(&r1, &v3, NULL, ES_128));
+    return 0;
+}
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH RFC 2/2] tests/tcg: target/s390: Add test for VECTOR LOAD GR FROM VR ELEMENT
  2019-02-27 11:14 ` [Qemu-devel] [PATCH RFC 2/2] tests/tcg: target/s390: Add test for VECTOR LOAD GR FROM VR ELEMENT David Hildenbrand
@ 2019-02-27 11:19   ` David Hildenbrand
  2019-02-27 19:37   ` David Hildenbrand
  1 sibling, 0 replies; 18+ messages in thread
From: David Hildenbrand @ 2019-02-27 11:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-s390x, Thomas Huth, Cornelia Huck, Richard Henderson,
	Alex Bennée, Philippe Mathieu-Daudé

On 27.02.19 12:14, David Hildenbrand wrote:
> We want to make use of vectors, so use -march=z13. To make it compile,
> use a reasonable optimization level (-O2), which seems to work just fine
> with all tests.

Just double-checked, at least exrl-trt will need a fixup to work with -O2.

> 
> Add some infrastructure for checking if SIGILL will be properly
> triggered.
> 
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
>  tests/tcg/s390x/Makefile.target     |  3 ++-
>  tests/tcg/s390x/helper.h            | 28 +++++++++++++++++++++
>  tests/tcg/s390x/signal_helper.inc.c | 39 +++++++++++++++++++++++++++++
>  tests/tcg/s390x/vlgv.c              | 37 +++++++++++++++++++++++++++
>  4 files changed, 106 insertions(+), 1 deletion(-)
>  create mode 100644 tests/tcg/s390x/helper.h
>  create mode 100644 tests/tcg/s390x/signal_helper.inc.c
>  create mode 100644 tests/tcg/s390x/vlgv.c
> 
> diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target
> index 151dc075aa..d1ae755ab9 100644
> --- a/tests/tcg/s390x/Makefile.target
> +++ b/tests/tcg/s390x/Makefile.target
> @@ -1,8 +1,9 @@
>  VPATH+=$(SRC_PATH)/tests/tcg/s390x
> -CFLAGS+=-march=zEC12 -m64
> +CFLAGS+=-march=z13 -m64 -O2
>  TESTS+=hello-s390x
>  TESTS+=csst
>  TESTS+=ipm
>  TESTS+=exrl-trt
>  TESTS+=exrl-trtr
>  TESTS+=pack
> +TESTS+=vlgv
> diff --git a/tests/tcg/s390x/helper.h b/tests/tcg/s390x/helper.h
> new file mode 100644
> index 0000000000..845b8bb504
> --- /dev/null
> +++ b/tests/tcg/s390x/helper.h
> @@ -0,0 +1,28 @@
> +#ifndef TEST_TCG_S390x_VECTOR_H
> +#define TEST_TCG_S390x_VECTOR_H
> +
> +#include <stdint.h>
> +
> +#define ES_8    0
> +#define ES_16   1
> +#define ES_32   2
> +#define ES_64   3
> +#define ES_128  4
> +
> +typedef union S390Vector {
> +    __uint128_t v;
> +    uint64_t q[2];
> +    uint32_t d[4];
> +    uint16_t w[8];
> +    uint8_t h[16];
> +} S390Vector;
> +
> +static inline void check(const char *s, bool cond)
> +{
> +    if (!cond) {
> +        fprintf(stderr, "Check failed: %s\n", s);
> +        exit(-1);
> +    }
> +}
> +
> +#endif /* TEST_TCG_S390x_VECTOR_H */
> diff --git a/tests/tcg/s390x/signal_helper.inc.c b/tests/tcg/s390x/signal_helper.inc.c
> new file mode 100644
> index 0000000000..5bd69ca76a
> --- /dev/null
> +++ b/tests/tcg/s390x/signal_helper.inc.c
> @@ -0,0 +1,39 @@
> +#include <stdlib.h>
> +#include <stdio.h>
> +#include <stdbool.h>
> +#include <signal.h>
> +#include <setjmp.h>
> +#include "helper.h"
> +
> +jmp_buf jmp_env;
> +
> +static void sig_sigill(int sig)
> +{
> +    if (sig != SIGILL) {
> +        check("Wrong signal received", false);
> +    }
> +    longjmp(jmp_env, 1);
> +}
> +
> +#define CHECK_SIGILL(STATEMENT)                             \
> +do {                                                        \
> +    struct sigaction act;                                   \
> +                                                            \
> +    act.sa_handler = sig_sigill;                            \
> +    act.sa_flags = 0;                                       \
> +    if (sigaction(SIGILL, &act, NULL)) {                    \
> +        check("SIGILL handler not registered", false);      \
> +    }                                                       \
> +                                                            \
> +    if (setjmp(jmp_env) == 0) {                             \
> +        STATEMENT;                                          \
> +        check("SIGILL not triggered", false);               \
> +    }                                                       \
> +                                                            \
> +    act.sa_handler = SIG_DFL;                               \
> +    sigemptyset(&act.sa_mask);                              \
> +    act.sa_flags = 0;                                       \
> +    if (sigaction(SIGILL, &act, NULL)) {                    \
> +        check("SIGILL handler not unregistered", false);    \
> +    }                                                       \
> +} while (0)
> diff --git a/tests/tcg/s390x/vlgv.c b/tests/tcg/s390x/vlgv.c
> new file mode 100644
> index 0000000000..3c37ee2035
> --- /dev/null
> +++ b/tests/tcg/s390x/vlgv.c
> @@ -0,0 +1,37 @@
> +#include <stdint.h>
> +#include <unistd.h>
> +#include "signal_helper.inc.c"
> +
> +static inline void vlgv(uint64_t *r1, S390Vector *v3, const void *a2,
> +                        uint8_t m4)
> +{
> +    asm volatile("vlgv %[r1], %[v3], 0(%[a2]), %[m4]\n"
> +                 : [r1] "+d" (*r1),
> +                   [v3] "+v" (v3->v)
> +                 : [a2] "d" (a2),
> +                   [m4] "i" (m4));
> +}
> +
> +int main(void)
> +{
> +    S390Vector v3 = {
> +        .q[0] = 0x0011223344556677ull,
> +        .q[1] = 0x8899aabbccddeeffull,
> +    };
> +    uint64_t r1 = 0;
> +
> +    /* Directly set all ignored bits to  */
> +    vlgv(&r1, &v3, (void *)(7 | ~0xf), ES_8);
> +    check("8 bit", r1 == 0x77);
> +    vlgv(&r1, &v3, (void *)(4 | ~0x7), ES_16);
> +    check("16 bit", r1 == 0x8899);
> +    vlgv(&r1, &v3, (void *)(3 | ~0x3), ES_32);
> +    check("32 bit", r1 == 0xccddeeff);
> +    vlgv(&r1, &v3, (void *)(1 | ~0x1), ES_64);
> +    check("64 bit", r1 == 0x8899aabbccddeeffull);
> +    check("v3 not modified", v3.q[0] == 0x0011223344556677ull &&
> +                             v3.q[1] == 0x8899aabbccddeeffull);
> +
> +    CHECK_SIGILL(vlgv(&r1, &v3, NULL, ES_128));
> +    return 0;
> +}
> 


-- 

Thanks,

David / dhildenb

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH RFC 1/2] tests/tcg: Allow targets to set the optimization level
  2019-02-27 11:14 ` [Qemu-devel] [PATCH RFC 1/2] tests/tcg: Allow targets to set the optimization level David Hildenbrand
@ 2019-02-27 11:46   ` Alex Bennée
  2019-02-27 11:58     ` David Hildenbrand
  2019-02-27 12:42     ` David Hildenbrand
  2019-02-28  0:26   ` Richard Henderson
  1 sibling, 2 replies; 18+ messages in thread
From: Alex Bennée @ 2019-02-27 11:46 UTC (permalink / raw)
  To: David Hildenbrand
  Cc: qemu-devel, qemu-s390x, Thomas Huth, Cornelia Huck,
	Richard Henderson, Philippe Mathieu-Daudé


David Hildenbrand <david@redhat.com> writes:

> We sometimes want basic optimizations, e.g. for constant propagation
> into inlined functions.
>
> Especially for inline asm with immediates;

I agree you need this, but...

<snip>
>  # Start with a blank slate, the build targets get to add stuff first
> -CFLAGS=
> +CFLAGS=-O0
>  QEMU_CFLAGS=
>  LDFLAGS=
>
> @@ -70,7 +70,7 @@ ifneq ($(TARGET_BASE_ARCH),$(TARGET_NAME))
>  endif
>
>  # Add the common build options
> -CFLAGS+=-Wall -O0 -g -fno-strict-aliasing
> +CFLAGS+=-Wall -g -fno-strict-aliasing


You don't need to do this - we already have EXTRA_CFLAGS which will
always be at the end of the compile invocation:

  # enable vectors and optimisation to vectorise for this test
  vglv: CFLAGS+=-march=z13 -m64
  vglv: EXTRA_CFLAGS+=-O2


>  ifeq ($(BUILD_STATIC),y)
>  LDFLAGS+=-static
>  endif


--
Alex Bennée

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH RFC 1/2] tests/tcg: Allow targets to set the optimization level
  2019-02-27 11:46   ` Alex Bennée
@ 2019-02-27 11:58     ` David Hildenbrand
  2019-02-27 12:42     ` David Hildenbrand
  1 sibling, 0 replies; 18+ messages in thread
From: David Hildenbrand @ 2019-02-27 11:58 UTC (permalink / raw)
  To: Alex Bennée
  Cc: qemu-devel, qemu-s390x, Thomas Huth, Cornelia Huck,
	Richard Henderson, Philippe Mathieu-Daudé

On 27.02.19 12:46, Alex Bennée wrote:
> 
> David Hildenbrand <david@redhat.com> writes:
> 
>> We sometimes want basic optimizations, e.g. for constant propagation
>> into inlined functions.
>>
>> Especially for inline asm with immediates;
> 
> I agree you need this, but...
> 
> <snip>
>>  # Start with a blank slate, the build targets get to add stuff first
>> -CFLAGS=
>> +CFLAGS=-O0
>>  QEMU_CFLAGS=
>>  LDFLAGS=
>>
>> @@ -70,7 +70,7 @@ ifneq ($(TARGET_BASE_ARCH),$(TARGET_NAME))
>>  endif
>>
>>  # Add the common build options
>> -CFLAGS+=-Wall -O0 -g -fno-strict-aliasing
>> +CFLAGS+=-Wall -g -fno-strict-aliasing
> 
> 
> You don't need to do this - we already have EXTRA_CFLAGS which will
> always be at the end of the compile invocation:
> 
>   # enable vectors and optimisation to vectorise for this test
>   vglv: CFLAGS+=-march=z13 -m64
>   vglv: EXTRA_CFLAGS+=-O2
> 

Cool, missed that - thanks!


-- 

Thanks,

David / dhildenb

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH RFC 1/2] tests/tcg: Allow targets to set the optimization level
  2019-02-27 11:46   ` Alex Bennée
  2019-02-27 11:58     ` David Hildenbrand
@ 2019-02-27 12:42     ` David Hildenbrand
  2019-02-27 13:44       ` David Hildenbrand
  1 sibling, 1 reply; 18+ messages in thread
From: David Hildenbrand @ 2019-02-27 12:42 UTC (permalink / raw)
  To: Alex Bennée
  Cc: qemu-devel, qemu-s390x, Thomas Huth, Cornelia Huck,
	Richard Henderson, Philippe Mathieu-Daudé

On 27.02.19 12:46, Alex Bennée wrote:
> 
> David Hildenbrand <david@redhat.com> writes:
> 
>> We sometimes want basic optimizations, e.g. for constant propagation
>> into inlined functions.
>>
>> Especially for inline asm with immediates;
> 
> I agree you need this, but...
> 
> <snip>
>>  # Start with a blank slate, the build targets get to add stuff first
>> -CFLAGS=
>> +CFLAGS=-O0
>>  QEMU_CFLAGS=
>>  LDFLAGS=
>>
>> @@ -70,7 +70,7 @@ ifneq ($(TARGET_BASE_ARCH),$(TARGET_NAME))
>>  endif
>>
>>  # Add the common build options
>> -CFLAGS+=-Wall -O0 -g -fno-strict-aliasing
>> +CFLAGS+=-Wall -g -fno-strict-aliasing
> 
> 
> You don't need to do this - we already have EXTRA_CFLAGS which will
> always be at the end of the compile invocation:
> 
>   # enable vectors and optimisation to vectorise for this test
>   vglv: CFLAGS+=-march=z13 -m64
>   vglv: EXTRA_CFLAGS+=-O2

For whatever reason I can't get this to work. EXTRA_CFLAGS+=-O2 is
always silently dropped:

make SHELL='sh -x' run-tcg-tests-s390x-linux-user

+ /home/dhildenb/git/qemu/tests/docker/docker.py cc --user 100813 --cc
s390x-linux-gnu-gcc -i qemu:debian-s390x-cross -s
/home/dhildenb/git/qemu -- -march=zEC12 -m64 -Wall -O0 -g
-fno-strict-aliasing -march=z13
/home/dhildenb/git/qemu/tests/tcg/s390x/vlgv.c -o vlgv -static
/home/dhildenb/git/qemu/tests/tcg/s390x/vlgv.c: In function 'vlgv':
/home/dhildenb/git/qemu/tests/tcg/s390x/vlgv.c:8:5: warning: asm operand
3 probably doesn't match constraints
     asm volatile("vlgv %[r1], %[v3], 0(%[a2]), %[m4]\n"
     ^~~
/home/dhildenb/git/qemu/tests/tcg/s390x/vlgv.c:8:5: error: impossible
constraint in 'asm'



-- 

Thanks,

David / dhildenb

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH RFC 1/2] tests/tcg: Allow targets to set the optimization level
  2019-02-27 12:42     ` David Hildenbrand
@ 2019-02-27 13:44       ` David Hildenbrand
  0 siblings, 0 replies; 18+ messages in thread
From: David Hildenbrand @ 2019-02-27 13:44 UTC (permalink / raw)
  To: Alex Bennée
  Cc: qemu-devel, qemu-s390x, Thomas Huth, Cornelia Huck,
	Richard Henderson, Philippe Mathieu-Daudé

On 27.02.19 13:42, David Hildenbrand wrote:
> On 27.02.19 12:46, Alex Bennée wrote:
>>
>> David Hildenbrand <david@redhat.com> writes:
>>
>>> We sometimes want basic optimizations, e.g. for constant propagation
>>> into inlined functions.
>>>
>>> Especially for inline asm with immediates;
>>
>> I agree you need this, but...
>>
>> <snip>
>>>  # Start with a blank slate, the build targets get to add stuff first
>>> -CFLAGS=
>>> +CFLAGS=-O0
>>>  QEMU_CFLAGS=
>>>  LDFLAGS=
>>>
>>> @@ -70,7 +70,7 @@ ifneq ($(TARGET_BASE_ARCH),$(TARGET_NAME))
>>>  endif
>>>
>>>  # Add the common build options
>>> -CFLAGS+=-Wall -O0 -g -fno-strict-aliasing
>>> +CFLAGS+=-Wall -g -fno-strict-aliasing
>>
>>
>> You don't need to do this - we already have EXTRA_CFLAGS which will
>> always be at the end of the compile invocation:
>>
>>   # enable vectors and optimisation to vectorise for this test
>>   vglv: CFLAGS+=-march=z13 -m64
>>   vglv: EXTRA_CFLAGS+=-O2
> 
> For whatever reason I can't get this to work. EXTRA_CFLAGS+=-O2 is
> always silently dropped:
> 
> make SHELL='sh -x' run-tcg-tests-s390x-linux-user
> 
> + /home/dhildenb/git/qemu/tests/docker/docker.py cc --user 100813 --cc
> s390x-linux-gnu-gcc -i qemu:debian-s390x-cross -s
> /home/dhildenb/git/qemu -- -march=zEC12 -m64 -Wall -O0 -g
> -fno-strict-aliasing -march=z13
> /home/dhildenb/git/qemu/tests/tcg/s390x/vlgv.c -o vlgv -static
> /home/dhildenb/git/qemu/tests/tcg/s390x/vlgv.c: In function 'vlgv':
> /home/dhildenb/git/qemu/tests/tcg/s390x/vlgv.c:8:5: warning: asm operand
> 3 probably doesn't match constraints
>      asm volatile("vlgv %[r1], %[v3], 0(%[a2]), %[m4]\n"
>      ^~~
> /home/dhildenb/git/qemu/tests/tcg/s390x/vlgv.c:8:5: error: impossible
> constraint in 'asm'
> 

vlgv: CFLAGS+=-march=z13 -O2

However works. I am very confused now. I guess this is about evaluation
order or something like that.

-- 

Thanks,

David / dhildenb

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH RFC 2/2] tests/tcg: target/s390: Add test for VECTOR LOAD GR FROM VR ELEMENT
  2019-02-27 11:14 ` [Qemu-devel] [PATCH RFC 2/2] tests/tcg: target/s390: Add test for VECTOR LOAD GR FROM VR ELEMENT David Hildenbrand
  2019-02-27 11:19   ` David Hildenbrand
@ 2019-02-27 19:37   ` David Hildenbrand
  2019-02-27 20:19     ` Alex Bennée
  2019-02-28  0:17     ` Richard Henderson
  1 sibling, 2 replies; 18+ messages in thread
From: David Hildenbrand @ 2019-02-27 19:37 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-s390x, Thomas Huth, Cornelia Huck, Richard Henderson,
	Alex Bennée, Philippe Mathieu-Daudé

On 27.02.19 12:14, David Hildenbrand wrote:
> We want to make use of vectors, so use -march=z13. To make it compile,
> use a reasonable optimization level (-O2), which seems to work just fine
> with all tests.
> 
> Add some infrastructure for checking if SIGILL will be properly
> triggered.
> 
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
>  tests/tcg/s390x/Makefile.target     |  3 ++-
>  tests/tcg/s390x/helper.h            | 28 +++++++++++++++++++++
>  tests/tcg/s390x/signal_helper.inc.c | 39 +++++++++++++++++++++++++++++
>  tests/tcg/s390x/vlgv.c              | 37 +++++++++++++++++++++++++++
>  4 files changed, 106 insertions(+), 1 deletion(-)
>  create mode 100644 tests/tcg/s390x/helper.h
>  create mode 100644 tests/tcg/s390x/signal_helper.inc.c
>  create mode 100644 tests/tcg/s390x/vlgv.c
> 
> diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target
> index 151dc075aa..d1ae755ab9 100644
> --- a/tests/tcg/s390x/Makefile.target
> +++ b/tests/tcg/s390x/Makefile.target
> @@ -1,8 +1,9 @@
>  VPATH+=$(SRC_PATH)/tests/tcg/s390x
> -CFLAGS+=-march=zEC12 -m64
> +CFLAGS+=-march=z13 -m64 -O2
>  TESTS+=hello-s390x
>  TESTS+=csst
>  TESTS+=ipm
>  TESTS+=exrl-trt
>  TESTS+=exrl-trtr
>  TESTS+=pack
> +TESTS+=vlgv
> diff --git a/tests/tcg/s390x/helper.h b/tests/tcg/s390x/helper.h
> new file mode 100644
> index 0000000000..845b8bb504
> --- /dev/null
> +++ b/tests/tcg/s390x/helper.h
> @@ -0,0 +1,28 @@
> +#ifndef TEST_TCG_S390x_VECTOR_H
> +#define TEST_TCG_S390x_VECTOR_H
> +
> +#include <stdint.h>
> +
> +#define ES_8    0
> +#define ES_16   1
> +#define ES_32   2
> +#define ES_64   3
> +#define ES_128  4
> +
> +typedef union S390Vector {
> +    __uint128_t v;
> +    uint64_t q[2];
> +    uint32_t d[4];
> +    uint16_t w[8];
> +    uint8_t h[16];
> +} S390Vector;
> +
> +static inline void check(const char *s, bool cond)
> +{
> +    if (!cond) {
> +        fprintf(stderr, "Check failed: %s\n", s);
> +        exit(-1);
> +    }
> +}
> +
> +#endif /* TEST_TCG_S390x_VECTOR_H */
> diff --git a/tests/tcg/s390x/signal_helper.inc.c b/tests/tcg/s390x/signal_helper.inc.c
> new file mode 100644
> index 0000000000..5bd69ca76a
> --- /dev/null
> +++ b/tests/tcg/s390x/signal_helper.inc.c
> @@ -0,0 +1,39 @@
> +#include <stdlib.h>
> +#include <stdio.h>
> +#include <stdbool.h>
> +#include <signal.h>
> +#include <setjmp.h>
> +#include "helper.h"
> +
> +jmp_buf jmp_env;
> +
> +static void sig_sigill(int sig)
> +{
> +    if (sig != SIGILL) {
> +        check("Wrong signal received", false);
> +    }
> +    longjmp(jmp_env, 1);
> +}
> +
> +#define CHECK_SIGILL(STATEMENT)                             \
> +do {                                                        \
> +    struct sigaction act;                                   \
> +                                                            \
> +    act.sa_handler = sig_sigill;                            \
> +    act.sa_flags = 0;                                       \
> +    if (sigaction(SIGILL, &act, NULL)) {                    \
> +        check("SIGILL handler not registered", false);      \
> +    }                                                       \
> +                                                            \
> +    if (setjmp(jmp_env) == 0) {                             \
> +        STATEMENT;                                          \
> +        check("SIGILL not triggered", false);               \
> +    }                                                       \
> +                                                            \
> +    act.sa_handler = SIG_DFL;                               \
> +    sigemptyset(&act.sa_mask);                              \
> +    act.sa_flags = 0;                                       \
> +    if (sigaction(SIGILL, &act, NULL)) {                    \
> +        check("SIGILL handler not unregistered", false);    \
> +    }                                                       \
> +} while (0)

Now this is some interesting hackery.

I changed it to

jmp_buf jmp_env;

static void sig_sigill(int sig)
{
    if (sig != SIGILL) {
        check("Wrong signal received", false);
    }
    longjmp(jmp_env, 1);
}

#define CHECK_SIGILL(STATEMENT)                  \
do {                                             \
    if (signal(SIGILL, sig_sigill) == SIG_ERR) { \
        check("SIGILL not registered", false);   \
    }                                            \
    if (setjmp(jmp_env) == 0) {                  \
        STATEMENT;                               \
        check("SIGILL not triggered", false);    \
    }                                            \
    if (signal(SIGILL, SIG_DFL) == SIG_ERR) {    \
        check("SIGILL not registered", false);   \
    }                                            \
} while (0)


However it only works once. During the second signal, QEMU decides to
set the default handler.

1. In a signal handler that signal is blocked. We leave that handler via
a longjump. So after the first signal, the signal is blocked.

2. In QEMU, we decide that synchronous signals cannot be blocked and
simply override the signal handler to default handler. So on the second
signal, we execute the default handler and not our defined handler.

Multiple ways to fix:

1. We have to manually unblock the signal in that hackery above.
2. In QEMU, don't block synchronous signals.
3. In QEMU, don't set the signal handler to the default handler in case
a synchronous signal is blocked.


Trying to run the test on a real s390x linux indicates that 1. should be
the right approach.

[linux1@redhat-kvm ~]$ ./vge
Illegal instruction (core dumped)

-- 

Thanks,

David / dhildenb

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH RFC 2/2] tests/tcg: target/s390: Add test for VECTOR LOAD GR FROM VR ELEMENT
  2019-02-27 19:37   ` David Hildenbrand
@ 2019-02-27 20:19     ` Alex Bennée
  2019-02-27 20:20       ` David Hildenbrand
  2019-02-28  0:17     ` Richard Henderson
  1 sibling, 1 reply; 18+ messages in thread
From: Alex Bennée @ 2019-02-27 20:19 UTC (permalink / raw)
  To: David Hildenbrand
  Cc: qemu-devel, qemu-s390x, Thomas Huth, Cornelia Huck,
	Richard Henderson, Philippe Mathieu-Daudé


David Hildenbrand <david@redhat.com> writes:

> On 27.02.19 12:14, David Hildenbrand wrote:
>> We want to make use of vectors, so use -march=z13. To make it compile,
>> use a reasonable optimization level (-O2), which seems to work just fine
>> with all tests.
>>
>> Add some infrastructure for checking if SIGILL will be properly
>> triggered.
>>
>> Signed-off-by: David Hildenbrand <david@redhat.com>
>> ---
>>  tests/tcg/s390x/Makefile.target     |  3 ++-
>>  tests/tcg/s390x/helper.h            | 28 +++++++++++++++++++++
>>  tests/tcg/s390x/signal_helper.inc.c | 39 +++++++++++++++++++++++++++++
>>  tests/tcg/s390x/vlgv.c              | 37 +++++++++++++++++++++++++++
>>  4 files changed, 106 insertions(+), 1 deletion(-)
>>  create mode 100644 tests/tcg/s390x/helper.h
>>  create mode 100644 tests/tcg/s390x/signal_helper.inc.c
>>  create mode 100644 tests/tcg/s390x/vlgv.c
>>
>> diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target
>> index 151dc075aa..d1ae755ab9 100644
>> --- a/tests/tcg/s390x/Makefile.target
>> +++ b/tests/tcg/s390x/Makefile.target
>> @@ -1,8 +1,9 @@
>>  VPATH+=$(SRC_PATH)/tests/tcg/s390x
>> -CFLAGS+=-march=zEC12 -m64
>> +CFLAGS+=-march=z13 -m64 -O2
>>  TESTS+=hello-s390x
>>  TESTS+=csst
>>  TESTS+=ipm
>>  TESTS+=exrl-trt
>>  TESTS+=exrl-trtr
>>  TESTS+=pack
>> +TESTS+=vlgv
>> diff --git a/tests/tcg/s390x/helper.h b/tests/tcg/s390x/helper.h
>> new file mode 100644
>> index 0000000000..845b8bb504
>> --- /dev/null
>> +++ b/tests/tcg/s390x/helper.h
>> @@ -0,0 +1,28 @@
>> +#ifndef TEST_TCG_S390x_VECTOR_H
>> +#define TEST_TCG_S390x_VECTOR_H
>> +
>> +#include <stdint.h>
>> +
>> +#define ES_8    0
>> +#define ES_16   1
>> +#define ES_32   2
>> +#define ES_64   3
>> +#define ES_128  4
>> +
>> +typedef union S390Vector {
>> +    __uint128_t v;
>> +    uint64_t q[2];
>> +    uint32_t d[4];
>> +    uint16_t w[8];
>> +    uint8_t h[16];
>> +} S390Vector;
>> +
>> +static inline void check(const char *s, bool cond)
>> +{
>> +    if (!cond) {
>> +        fprintf(stderr, "Check failed: %s\n", s);
>> +        exit(-1);
>> +    }
>> +}
>> +
>> +#endif /* TEST_TCG_S390x_VECTOR_H */
>> diff --git a/tests/tcg/s390x/signal_helper.inc.c b/tests/tcg/s390x/signal_helper.inc.c
>> new file mode 100644
>> index 0000000000..5bd69ca76a
>> --- /dev/null
>> +++ b/tests/tcg/s390x/signal_helper.inc.c
>> @@ -0,0 +1,39 @@
>> +#include <stdlib.h>
>> +#include <stdio.h>
>> +#include <stdbool.h>
>> +#include <signal.h>
>> +#include <setjmp.h>
>> +#include "helper.h"
>> +
>> +jmp_buf jmp_env;
>> +
>> +static void sig_sigill(int sig)
>> +{
>> +    if (sig != SIGILL) {
>> +        check("Wrong signal received", false);
>> +    }
>> +    longjmp(jmp_env, 1);
>> +}
>> +
>> +#define CHECK_SIGILL(STATEMENT)                             \
>> +do {                                                        \
>> +    struct sigaction act;                                   \
>> +                                                            \
>> +    act.sa_handler = sig_sigill;                            \
>> +    act.sa_flags = 0;                                       \
>> +    if (sigaction(SIGILL, &act, NULL)) {                    \
>> +        check("SIGILL handler not registered", false);      \
>> +    }                                                       \
>> +                                                            \
>> +    if (setjmp(jmp_env) == 0) {                             \
>> +        STATEMENT;                                          \
>> +        check("SIGILL not triggered", false);               \
>> +    }                                                       \
>> +                                                            \
>> +    act.sa_handler = SIG_DFL;                               \
>> +    sigemptyset(&act.sa_mask);                              \
>> +    act.sa_flags = 0;                                       \
>> +    if (sigaction(SIGILL, &act, NULL)) {                    \
>> +        check("SIGILL handler not unregistered", false);    \
>> +    }                                                       \
>> +} while (0)
>
> Now this is some interesting hackery.
>
> I changed it to
>
> jmp_buf jmp_env;
>
> static void sig_sigill(int sig)
> {
>     if (sig != SIGILL) {
>         check("Wrong signal received", false);
>     }
>     longjmp(jmp_env, 1);
> }
>
> #define CHECK_SIGILL(STATEMENT)                  \
> do {                                             \
>     if (signal(SIGILL, sig_sigill) == SIG_ERR) { \
>         check("SIGILL not registered", false);   \
>     }                                            \
>     if (setjmp(jmp_env) == 0) {                  \
>         STATEMENT;                               \
>         check("SIGILL not triggered", false);    \
>     }                                            \
>     if (signal(SIGILL, SIG_DFL) == SIG_ERR) {    \
>         check("SIGILL not registered", false);   \
>     }                                            \
> } while (0)
>
>
> However it only works once. During the second signal, QEMU decides to
> set the default handler.
>
> 1. In a signal handler that signal is blocked. We leave that handler via
> a longjump. So after the first signal, the signal is blocked.
>
> 2. In QEMU, we decide that synchronous signals cannot be blocked and
> simply override the signal handler to default handler. So on the second
> signal, we execute the default handler and not our defined handler.
>
> Multiple ways to fix:
>
> 1. We have to manually unblock the signal in that hackery above.
> 2. In QEMU, don't block synchronous signals.
> 3. In QEMU, don't set the signal handler to the default handler in case
> a synchronous signal is blocked.


This all seems a little over-engineered. This is a single-threaded test
so what's wrong with a couple of flags:

bool should_get_sigill;

and the handler doing:

if (!should_get_sigill) {
   unexpected_sigills++;
}

Tests don't have to be pretty, just reliable.

>
>
> Trying to run the test on a real s390x linux indicates that 1. should be
> the right approach.
>
> [linux1@redhat-kvm ~]$ ./vge
> Illegal instruction (core dumped)


--
Alex Bennée

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH RFC 2/2] tests/tcg: target/s390: Add test for VECTOR LOAD GR FROM VR ELEMENT
  2019-02-27 20:19     ` Alex Bennée
@ 2019-02-27 20:20       ` David Hildenbrand
  2019-02-27 21:40         ` Alex Bennée
  0 siblings, 1 reply; 18+ messages in thread
From: David Hildenbrand @ 2019-02-27 20:20 UTC (permalink / raw)
  To: Alex Bennée
  Cc: qemu-devel, qemu-s390x, Thomas Huth, Cornelia Huck,
	Richard Henderson, Philippe Mathieu-Daudé

On 27.02.19 21:19, Alex Bennée wrote:
> 
> David Hildenbrand <david@redhat.com> writes:
> 
>> On 27.02.19 12:14, David Hildenbrand wrote:
>>> We want to make use of vectors, so use -march=z13. To make it compile,
>>> use a reasonable optimization level (-O2), which seems to work just fine
>>> with all tests.
>>>
>>> Add some infrastructure for checking if SIGILL will be properly
>>> triggered.
>>>
>>> Signed-off-by: David Hildenbrand <david@redhat.com>
>>> ---
>>>  tests/tcg/s390x/Makefile.target     |  3 ++-
>>>  tests/tcg/s390x/helper.h            | 28 +++++++++++++++++++++
>>>  tests/tcg/s390x/signal_helper.inc.c | 39 +++++++++++++++++++++++++++++
>>>  tests/tcg/s390x/vlgv.c              | 37 +++++++++++++++++++++++++++
>>>  4 files changed, 106 insertions(+), 1 deletion(-)
>>>  create mode 100644 tests/tcg/s390x/helper.h
>>>  create mode 100644 tests/tcg/s390x/signal_helper.inc.c
>>>  create mode 100644 tests/tcg/s390x/vlgv.c
>>>
>>> diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target
>>> index 151dc075aa..d1ae755ab9 100644
>>> --- a/tests/tcg/s390x/Makefile.target
>>> +++ b/tests/tcg/s390x/Makefile.target
>>> @@ -1,8 +1,9 @@
>>>  VPATH+=$(SRC_PATH)/tests/tcg/s390x
>>> -CFLAGS+=-march=zEC12 -m64
>>> +CFLAGS+=-march=z13 -m64 -O2
>>>  TESTS+=hello-s390x
>>>  TESTS+=csst
>>>  TESTS+=ipm
>>>  TESTS+=exrl-trt
>>>  TESTS+=exrl-trtr
>>>  TESTS+=pack
>>> +TESTS+=vlgv
>>> diff --git a/tests/tcg/s390x/helper.h b/tests/tcg/s390x/helper.h
>>> new file mode 100644
>>> index 0000000000..845b8bb504
>>> --- /dev/null
>>> +++ b/tests/tcg/s390x/helper.h
>>> @@ -0,0 +1,28 @@
>>> +#ifndef TEST_TCG_S390x_VECTOR_H
>>> +#define TEST_TCG_S390x_VECTOR_H
>>> +
>>> +#include <stdint.h>
>>> +
>>> +#define ES_8    0
>>> +#define ES_16   1
>>> +#define ES_32   2
>>> +#define ES_64   3
>>> +#define ES_128  4
>>> +
>>> +typedef union S390Vector {
>>> +    __uint128_t v;
>>> +    uint64_t q[2];
>>> +    uint32_t d[4];
>>> +    uint16_t w[8];
>>> +    uint8_t h[16];
>>> +} S390Vector;
>>> +
>>> +static inline void check(const char *s, bool cond)
>>> +{
>>> +    if (!cond) {
>>> +        fprintf(stderr, "Check failed: %s\n", s);
>>> +        exit(-1);
>>> +    }
>>> +}
>>> +
>>> +#endif /* TEST_TCG_S390x_VECTOR_H */
>>> diff --git a/tests/tcg/s390x/signal_helper.inc.c b/tests/tcg/s390x/signal_helper.inc.c
>>> new file mode 100644
>>> index 0000000000..5bd69ca76a
>>> --- /dev/null
>>> +++ b/tests/tcg/s390x/signal_helper.inc.c
>>> @@ -0,0 +1,39 @@
>>> +#include <stdlib.h>
>>> +#include <stdio.h>
>>> +#include <stdbool.h>
>>> +#include <signal.h>
>>> +#include <setjmp.h>
>>> +#include "helper.h"
>>> +
>>> +jmp_buf jmp_env;
>>> +
>>> +static void sig_sigill(int sig)
>>> +{
>>> +    if (sig != SIGILL) {
>>> +        check("Wrong signal received", false);
>>> +    }
>>> +    longjmp(jmp_env, 1);
>>> +}
>>> +
>>> +#define CHECK_SIGILL(STATEMENT)                             \
>>> +do {                                                        \
>>> +    struct sigaction act;                                   \
>>> +                                                            \
>>> +    act.sa_handler = sig_sigill;                            \
>>> +    act.sa_flags = 0;                                       \
>>> +    if (sigaction(SIGILL, &act, NULL)) {                    \
>>> +        check("SIGILL handler not registered", false);      \
>>> +    }                                                       \
>>> +                                                            \
>>> +    if (setjmp(jmp_env) == 0) {                             \
>>> +        STATEMENT;                                          \
>>> +        check("SIGILL not triggered", false);               \
>>> +    }                                                       \
>>> +                                                            \
>>> +    act.sa_handler = SIG_DFL;                               \
>>> +    sigemptyset(&act.sa_mask);                              \
>>> +    act.sa_flags = 0;                                       \
>>> +    if (sigaction(SIGILL, &act, NULL)) {                    \
>>> +        check("SIGILL handler not unregistered", false);    \
>>> +    }                                                       \
>>> +} while (0)
>>
>> Now this is some interesting hackery.
>>
>> I changed it to
>>
>> jmp_buf jmp_env;
>>
>> static void sig_sigill(int sig)
>> {
>>     if (sig != SIGILL) {
>>         check("Wrong signal received", false);
>>     }
>>     longjmp(jmp_env, 1);
>> }
>>
>> #define CHECK_SIGILL(STATEMENT)                  \
>> do {                                             \
>>     if (signal(SIGILL, sig_sigill) == SIG_ERR) { \
>>         check("SIGILL not registered", false);   \
>>     }                                            \
>>     if (setjmp(jmp_env) == 0) {                  \
>>         STATEMENT;                               \
>>         check("SIGILL not triggered", false);    \
>>     }                                            \
>>     if (signal(SIGILL, SIG_DFL) == SIG_ERR) {    \
>>         check("SIGILL not registered", false);   \
>>     }                                            \
>> } while (0)
>>
>>
>> However it only works once. During the second signal, QEMU decides to
>> set the default handler.
>>
>> 1. In a signal handler that signal is blocked. We leave that handler via
>> a longjump. So after the first signal, the signal is blocked.
>>
>> 2. In QEMU, we decide that synchronous signals cannot be blocked and
>> simply override the signal handler to default handler. So on the second
>> signal, we execute the default handler and not our defined handler.
>>
>> Multiple ways to fix:
>>
>> 1. We have to manually unblock the signal in that hackery above.
>> 2. In QEMU, don't block synchronous signals.
>> 3. In QEMU, don't set the signal handler to the default handler in case
>> a synchronous signal is blocked.
> 
> 
> This all seems a little over-engineered. This is a single-threaded test
> so what's wrong with a couple of flags:

I have to jump over the actual broken instruction and want to avoid
patching it. Otherwise I'll loop forever ...


-- 

Thanks,

David / dhildenb

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH RFC 2/2] tests/tcg: target/s390: Add test for VECTOR LOAD GR FROM VR ELEMENT
  2019-02-27 20:20       ` David Hildenbrand
@ 2019-02-27 21:40         ` Alex Bennée
  2019-02-28  0:24           ` Richard Henderson
  0 siblings, 1 reply; 18+ messages in thread
From: Alex Bennée @ 2019-02-27 21:40 UTC (permalink / raw)
  To: David Hildenbrand
  Cc: qemu-devel, qemu-s390x, Thomas Huth, Cornelia Huck,
	Richard Henderson, Philippe Mathieu-Daudé


David Hildenbrand <david@redhat.com> writes:

> On 27.02.19 21:19, Alex Bennée wrote:
>>
>> David Hildenbrand <david@redhat.com> writes:
>>
>>> On 27.02.19 12:14, David Hildenbrand wrote:
>>>> We want to make use of vectors, so use -march=z13. To make it compile,
>>>> use a reasonable optimization level (-O2), which seems to work just fine
>>>> with all tests.
>>>>
>>>> Add some infrastructure for checking if SIGILL will be properly
>>>> triggered.
>>>>
>>>> Signed-off-by: David Hildenbrand <david@redhat.com>
>>>> ---
>>>>  tests/tcg/s390x/Makefile.target     |  3 ++-
>>>>  tests/tcg/s390x/helper.h            | 28 +++++++++++++++++++++
>>>>  tests/tcg/s390x/signal_helper.inc.c | 39 +++++++++++++++++++++++++++++
>>>>  tests/tcg/s390x/vlgv.c              | 37 +++++++++++++++++++++++++++
>>>>  4 files changed, 106 insertions(+), 1 deletion(-)
>>>>  create mode 100644 tests/tcg/s390x/helper.h
>>>>  create mode 100644 tests/tcg/s390x/signal_helper.inc.c
>>>>  create mode 100644 tests/tcg/s390x/vlgv.c
>>>>
>>>> diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target
>>>> index 151dc075aa..d1ae755ab9 100644
>>>> --- a/tests/tcg/s390x/Makefile.target
>>>> +++ b/tests/tcg/s390x/Makefile.target
>>>> @@ -1,8 +1,9 @@
>>>>  VPATH+=$(SRC_PATH)/tests/tcg/s390x
>>>> -CFLAGS+=-march=zEC12 -m64
>>>> +CFLAGS+=-march=z13 -m64 -O2
>>>>  TESTS+=hello-s390x
>>>>  TESTS+=csst
>>>>  TESTS+=ipm
>>>>  TESTS+=exrl-trt
>>>>  TESTS+=exrl-trtr
>>>>  TESTS+=pack
>>>> +TESTS+=vlgv
>>>> diff --git a/tests/tcg/s390x/helper.h b/tests/tcg/s390x/helper.h
>>>> new file mode 100644
>>>> index 0000000000..845b8bb504
>>>> --- /dev/null
>>>> +++ b/tests/tcg/s390x/helper.h
>>>> @@ -0,0 +1,28 @@
>>>> +#ifndef TEST_TCG_S390x_VECTOR_H
>>>> +#define TEST_TCG_S390x_VECTOR_H
>>>> +
>>>> +#include <stdint.h>
>>>> +
>>>> +#define ES_8    0
>>>> +#define ES_16   1
>>>> +#define ES_32   2
>>>> +#define ES_64   3
>>>> +#define ES_128  4
>>>> +
>>>> +typedef union S390Vector {
>>>> +    __uint128_t v;
>>>> +    uint64_t q[2];
>>>> +    uint32_t d[4];
>>>> +    uint16_t w[8];
>>>> +    uint8_t h[16];
>>>> +} S390Vector;
>>>> +
>>>> +static inline void check(const char *s, bool cond)
>>>> +{
>>>> +    if (!cond) {
>>>> +        fprintf(stderr, "Check failed: %s\n", s);
>>>> +        exit(-1);
>>>> +    }
>>>> +}
>>>> +
>>>> +#endif /* TEST_TCG_S390x_VECTOR_H */
>>>> diff --git a/tests/tcg/s390x/signal_helper.inc.c b/tests/tcg/s390x/signal_helper.inc.c
>>>> new file mode 100644
>>>> index 0000000000..5bd69ca76a
>>>> --- /dev/null
>>>> +++ b/tests/tcg/s390x/signal_helper.inc.c
>>>> @@ -0,0 +1,39 @@
>>>> +#include <stdlib.h>
>>>> +#include <stdio.h>
>>>> +#include <stdbool.h>
>>>> +#include <signal.h>
>>>> +#include <setjmp.h>
>>>> +#include "helper.h"
>>>> +
>>>> +jmp_buf jmp_env;
>>>> +
>>>> +static void sig_sigill(int sig)
>>>> +{
>>>> +    if (sig != SIGILL) {
>>>> +        check("Wrong signal received", false);
>>>> +    }
>>>> +    longjmp(jmp_env, 1);
>>>> +}
>>>> +
>>>> +#define CHECK_SIGILL(STATEMENT)                             \
>>>> +do {                                                        \
>>>> +    struct sigaction act;                                   \
>>>> +                                                            \
>>>> +    act.sa_handler = sig_sigill;                            \
>>>> +    act.sa_flags = 0;                                       \
>>>> +    if (sigaction(SIGILL, &act, NULL)) {                    \
>>>> +        check("SIGILL handler not registered", false);      \
>>>> +    }                                                       \
>>>> +                                                            \
>>>> +    if (setjmp(jmp_env) == 0) {                             \
>>>> +        STATEMENT;                                          \
>>>> +        check("SIGILL not triggered", false);               \
>>>> +    }                                                       \
>>>> +                                                            \
>>>> +    act.sa_handler = SIG_DFL;                               \
>>>> +    sigemptyset(&act.sa_mask);                              \
>>>> +    act.sa_flags = 0;                                       \
>>>> +    if (sigaction(SIGILL, &act, NULL)) {                    \
>>>> +        check("SIGILL handler not unregistered", false);    \
>>>> +    }                                                       \
>>>> +} while (0)
>>>
>>> Now this is some interesting hackery.
>>>
>>> I changed it to
>>>
>>> jmp_buf jmp_env;
>>>
>>> static void sig_sigill(int sig)
>>> {
>>>     if (sig != SIGILL) {
>>>         check("Wrong signal received", false);
>>>     }
>>>     longjmp(jmp_env, 1);
>>> }
>>>
>>> #define CHECK_SIGILL(STATEMENT)                  \
>>> do {                                             \
>>>     if (signal(SIGILL, sig_sigill) == SIG_ERR) { \
>>>         check("SIGILL not registered", false);   \
>>>     }                                            \
>>>     if (setjmp(jmp_env) == 0) {                  \
>>>         STATEMENT;                               \
>>>         check("SIGILL not triggered", false);    \
>>>     }                                            \
>>>     if (signal(SIGILL, SIG_DFL) == SIG_ERR) {    \
>>>         check("SIGILL not registered", false);   \
>>>     }                                            \
>>> } while (0)
>>>
>>>
>>> However it only works once. During the second signal, QEMU decides to
>>> set the default handler.
>>>
>>> 1. In a signal handler that signal is blocked. We leave that handler via
>>> a longjump. So after the first signal, the signal is blocked.
>>>
>>> 2. In QEMU, we decide that synchronous signals cannot be blocked and
>>> simply override the signal handler to default handler. So on the second
>>> signal, we execute the default handler and not our defined handler.
>>>
>>> Multiple ways to fix:
>>>
>>> 1. We have to manually unblock the signal in that hackery above.
>>> 2. In QEMU, don't block synchronous signals.
>>> 3. In QEMU, don't set the signal handler to the default handler in case
>>> a synchronous signal is blocked.
>>
>>
>> This all seems a little over-engineered. This is a single-threaded test
>> so what's wrong with a couple of flags:
>
> I have to jump over the actual broken instruction and want to avoid
> patching it. Otherwise I'll loop forever ...

So from:

  Subject: [PATCH  v2 6/6] tests/tcg/aarch64: userspace system register test
  Date: Tue,  5 Feb 2019 19:02:24 +0000
  Message-Id: <20190205190224.2198-7-alex.bennee@linaro.org>

Where I had to do something similar:

  bool should_fail;
  int should_fail_count;
  int should_not_fail_count;
  uintptr_t failed_pc[10];

  void sigill_handler(int signo, siginfo_t *si, void *data)
  {
      ucontext_t *uc = (ucontext_t *)data;

      if (should_fail) {
          should_fail_count++;
      } else {
          uintptr_t pc = (uintptr_t) uc->uc_mcontext.pc;
          failed_pc[should_not_fail_count++] =  pc;
      }
      uc->uc_mcontext.pc += 4;
  }

But that does depend on arch making pc hackable:

  /* Hook in a SIGILL handler */
  memset(&sa, 0, sizeof(struct sigaction));
  sa.sa_flags = SA_SIGINFO;
  sa.sa_sigaction = &sigill_handler;
  sigemptyset(&sa.sa_mask);

And crucially have nice regular sized instructions. Is that not an option?

--
Alex Bennée

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH RFC 2/2] tests/tcg: target/s390: Add test for VECTOR LOAD GR FROM VR ELEMENT
  2019-02-27 19:37   ` David Hildenbrand
  2019-02-27 20:19     ` Alex Bennée
@ 2019-02-28  0:17     ` Richard Henderson
  2019-02-28  7:14       ` David Hildenbrand
  1 sibling, 1 reply; 18+ messages in thread
From: Richard Henderson @ 2019-02-28  0:17 UTC (permalink / raw)
  To: David Hildenbrand, qemu-devel
  Cc: qemu-s390x, Thomas Huth, Cornelia Huck, Alex Bennée,
	Philippe Mathieu-Daudé

On 2/27/19 11:37 AM, David Hildenbrand wrote:
> #define CHECK_SIGILL(STATEMENT)                  \
> do {                                             \
>     if (signal(SIGILL, sig_sigill) == SIG_ERR) { \
>         check("SIGILL not registered", false);   \
>     }                                            \
>     if (setjmp(jmp_env) == 0) {                  \
>         STATEMENT;                               \
>         check("SIGILL not triggered", false);    \
>     }                                            \
>     if (signal(SIGILL, SIG_DFL) == SIG_ERR) {    \
>         check("SIGILL not registered", false);   \
>     }                                            \
> } while (0)
> 
> 
> However it only works once. During the second signal, QEMU decides to
> set the default handler.
> 
> 1. In a signal handler that signal is blocked. We leave that handler via
> a longjump. So after the first signal, the signal is blocked.

And this is why we use sigaction not signal.

You can set action.sa_flags |= SA_RESETHAND to avoid needing the explicit reset
(or leave it clear to avoid the reset action that you are seeing).

You can set action.sa_flags |= SA_NODEFER to avoid having the signal added to
the signal mask of the thread, to avoid neeing to use sigsetjmp/siglongjmp.  Or
you can just use sigsetjmp/siglongjmp.  ;-)


r~

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH RFC 2/2] tests/tcg: target/s390: Add test for VECTOR LOAD GR FROM VR ELEMENT
  2019-02-27 21:40         ` Alex Bennée
@ 2019-02-28  0:24           ` Richard Henderson
  2019-02-28  7:11             ` David Hildenbrand
  0 siblings, 1 reply; 18+ messages in thread
From: Richard Henderson @ 2019-02-28  0:24 UTC (permalink / raw)
  To: Alex Bennée, David Hildenbrand
  Cc: qemu-devel, qemu-s390x, Thomas Huth, Cornelia Huck,
	Philippe Mathieu-Daudé

On 2/27/19 1:40 PM, Alex Bennée wrote:
> And crucially have nice regular sized instructions. Is that not an option?

s390 insns are {2,4,6} bytes.  I don't think that there's an easy way to pick
out the hw status codes that would give the ilen of the faulting insn.


r~

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH RFC 1/2] tests/tcg: Allow targets to set the optimization level
  2019-02-27 11:14 ` [Qemu-devel] [PATCH RFC 1/2] tests/tcg: Allow targets to set the optimization level David Hildenbrand
  2019-02-27 11:46   ` Alex Bennée
@ 2019-02-28  0:26   ` Richard Henderson
  1 sibling, 0 replies; 18+ messages in thread
From: Richard Henderson @ 2019-02-28  0:26 UTC (permalink / raw)
  To: David Hildenbrand, qemu-devel
  Cc: Thomas Huth, Cornelia Huck, Philippe Mathieu-Daudé,
	qemu-s390x, Alex Bennée, Richard Henderson

On 2/27/19 3:14 AM, David Hildenbrand wrote:
> Especially for inline asm with immediates;
> 
> static inline void some_instr(uint8_t imm)
> {
>     asm volatile("...", :: "i" (imm));
> }
> 
> static void test()
> {
>     some_instr(1);
> }

FWIW, __attribute__((always_inline)) should work even with -O0.


r~

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH RFC 2/2] tests/tcg: target/s390: Add test for VECTOR LOAD GR FROM VR ELEMENT
  2019-02-28  0:24           ` Richard Henderson
@ 2019-02-28  7:11             ` David Hildenbrand
  0 siblings, 0 replies; 18+ messages in thread
From: David Hildenbrand @ 2019-02-28  7:11 UTC (permalink / raw)
  To: Richard Henderson, Alex Bennée
  Cc: qemu-devel, qemu-s390x, Thomas Huth, Cornelia Huck,
	Philippe Mathieu-Daudé

On 28.02.19 01:24, Richard Henderson wrote:
> On 2/27/19 1:40 PM, Alex Bennée wrote:
>> And crucially have nice regular sized instructions. Is that not an option?
> 
> s390 insns are {2,4,6} bytes.  I don't think that there's an easy way to pick
> out the hw status codes that would give the ilen of the faulting insn.
> 

We would have to read the faulting instruction to determine based on the
two leftmost bits the ilen. But I don't consider that approach much
cleaner compared to signal + setjmp (signal + sigsetjmp after I fixed it
;) )

Thanks for the pointer though, Alex

> 
> r~
> 


-- 

Thanks,

David / dhildenb

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH RFC 2/2] tests/tcg: target/s390: Add test for VECTOR LOAD GR FROM VR ELEMENT
  2019-02-28  0:17     ` Richard Henderson
@ 2019-02-28  7:14       ` David Hildenbrand
  2019-02-28 17:39         ` Richard Henderson
  0 siblings, 1 reply; 18+ messages in thread
From: David Hildenbrand @ 2019-02-28  7:14 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: qemu-s390x, Thomas Huth, Cornelia Huck, Alex Bennée,
	Philippe Mathieu-Daudé

On 28.02.19 01:17, Richard Henderson wrote:
> On 2/27/19 11:37 AM, David Hildenbrand wrote:
>> #define CHECK_SIGILL(STATEMENT)                  \
>> do {                                             \
>>     if (signal(SIGILL, sig_sigill) == SIG_ERR) { \
>>         check("SIGILL not registered", false);   \
>>     }                                            \
>>     if (setjmp(jmp_env) == 0) {                  \
>>         STATEMENT;                               \
>>         check("SIGILL not triggered", false);    \
>>     }                                            \
>>     if (signal(SIGILL, SIG_DFL) == SIG_ERR) {    \
>>         check("SIGILL not registered", false);   \
>>     }                                            \
>> } while (0)
>>
>>
>> However it only works once. During the second signal, QEMU decides to
>> set the default handler.
>>
>> 1. In a signal handler that signal is blocked. We leave that handler via
>> a longjump. So after the first signal, the signal is blocked.
> 
> And this is why we use sigaction not signal.
> 
> You can set action.sa_flags |= SA_RESETHAND to avoid needing the explicit reset
> (or leave it clear to avoid the reset action that you are seeing).
> 
> You can set action.sa_flags |= SA_NODEFER to avoid having the signal added to
> the signal mask of the thread, to avoid neeing to use sigsetjmp/siglongjmp.  Or
> you can just use sigsetjmp/siglongjmp.  ;-)

You might tell at this point that it is my first time hacking on signals
and I already learned a lot, thanks ;)

I guess signal + sigsetjmp/siglongjmp is the one with the smalles LOC?
Will give it a try.

BTW: I got the idea of using setjml/longjmp from
tests/tcg/multiarch/linux-test.c - we're also not caring about blocked
signals there, but I guess it doesn't matter as we trigger SISEGV only once.

-- 

Thanks,

David / dhildenb

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH RFC 2/2] tests/tcg: target/s390: Add test for VECTOR LOAD GR FROM VR ELEMENT
  2019-02-28  7:14       ` David Hildenbrand
@ 2019-02-28 17:39         ` Richard Henderson
  0 siblings, 0 replies; 18+ messages in thread
From: Richard Henderson @ 2019-02-28 17:39 UTC (permalink / raw)
  To: David Hildenbrand, qemu-devel
  Cc: qemu-s390x, Thomas Huth, Cornelia Huck, Alex Bennée,
	Philippe Mathieu-Daudé

On 2/27/19 11:14 PM, David Hildenbrand wrote:
> I guess signal + sigsetjmp/siglongjmp is the one with the smalles LOC?
> Will give it a try.

I suppose it depends on how you write it.

    struct sigaction sa = {
        .sa_mask = SA_RESETHAND | SA_NODEFER,
        .sa_handler = sig_sigill,
    };
    check("SIGILL not registered", sigaction(SIGILL, &sa, NULL) == 0);

is 5 lines to the 6 you currently use for registering and unregistering the
signal handler.  ;-)


r~

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2019-02-28 17:39 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-27 11:14 [Qemu-devel] [PATCH RFC 0/2] tests/tcg: Vector instruction tests for target/s390x David Hildenbrand
2019-02-27 11:14 ` [Qemu-devel] [PATCH RFC 1/2] tests/tcg: Allow targets to set the optimization level David Hildenbrand
2019-02-27 11:46   ` Alex Bennée
2019-02-27 11:58     ` David Hildenbrand
2019-02-27 12:42     ` David Hildenbrand
2019-02-27 13:44       ` David Hildenbrand
2019-02-28  0:26   ` Richard Henderson
2019-02-27 11:14 ` [Qemu-devel] [PATCH RFC 2/2] tests/tcg: target/s390: Add test for VECTOR LOAD GR FROM VR ELEMENT David Hildenbrand
2019-02-27 11:19   ` David Hildenbrand
2019-02-27 19:37   ` David Hildenbrand
2019-02-27 20:19     ` Alex Bennée
2019-02-27 20:20       ` David Hildenbrand
2019-02-27 21:40         ` Alex Bennée
2019-02-28  0:24           ` Richard Henderson
2019-02-28  7:11             ` David Hildenbrand
2019-02-28  0:17     ` Richard Henderson
2019-02-28  7:14       ` David Hildenbrand
2019-02-28 17:39         ` Richard Henderson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.