* [PATCH v2 1/3] target/s390x: Fix LPSW
2023-03-15 2:04 [PATCH v2 0/3] target/s390x: Implement Early Exception Recognition Ilya Leoshkevich
@ 2023-03-15 2:04 ` Ilya Leoshkevich
2023-03-15 8:56 ` David Hildenbrand
2023-03-15 2:04 ` [PATCH v2 2/3] target/s390x: Implement Early Exception Recognition Ilya Leoshkevich
2023-03-15 2:04 ` [PATCH v2 3/3] tests/tcg/s390x: Add PSW modification tests Ilya Leoshkevich
2 siblings, 1 reply; 6+ messages in thread
From: Ilya Leoshkevich @ 2023-03-15 2:04 UTC (permalink / raw)
To: Richard Henderson, David Hildenbrand, Thomas Huth
Cc: qemu-s390x, qemu-devel, Ilya Leoshkevich, Nina Schoetterl-Glausch
Currently LPSW does not invert the mask bit 12 and incorrectly copies
the BA bit into the address.
Fix by generating code similar to what s390_cpu_load_normal() does.
Reported-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Co-developed-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
target/s390x/tcg/translate.c | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
index 14c3896d529..2e1e7e046a6 100644
--- a/target/s390x/tcg/translate.c
+++ b/target/s390x/tcg/translate.c
@@ -2910,19 +2910,21 @@ static DisasJumpType op_lpp(DisasContext *s, DisasOps *o)
static DisasJumpType op_lpsw(DisasContext *s, DisasOps *o)
{
- TCGv_i64 t1, t2;
+ TCGv_i64 mask, addr;
per_breaking_event(s);
- t1 = tcg_temp_new_i64();
- t2 = tcg_temp_new_i64();
- tcg_gen_qemu_ld_i64(t1, o->in2, get_mem_index(s),
- MO_TEUL | MO_ALIGN_8);
- tcg_gen_addi_i64(o->in2, o->in2, 4);
- tcg_gen_qemu_ld32u(t2, o->in2, get_mem_index(s));
- /* Convert the 32-bit PSW_MASK into the 64-bit PSW_MASK. */
- tcg_gen_shli_i64(t1, t1, 32);
- gen_helper_load_psw(cpu_env, t1, t2);
+ /*
+ * Convert the short PSW into the normal PSW, similar to what
+ * s390_cpu_load_normal() does.
+ */
+ mask = tcg_temp_new_i64();
+ addr = tcg_temp_new_i64();
+ tcg_gen_qemu_ld_i64(mask, o->in2, get_mem_index(s), MO_TEUQ | MO_ALIGN_8);
+ tcg_gen_andi_i64(addr, mask, PSW_MASK_SHORT_ADDR);
+ tcg_gen_andi_i64(mask, mask, PSW_MASK_SHORT_CTRL);
+ tcg_gen_xori_i64(mask, mask, PSW_MASK_SHORTPSW);
+ gen_helper_load_psw(cpu_env, mask, addr);
return DISAS_NORETURN;
}
--
2.39.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/3] target/s390x: Fix LPSW
2023-03-15 2:04 ` [PATCH v2 1/3] target/s390x: Fix LPSW Ilya Leoshkevich
@ 2023-03-15 8:56 ` David Hildenbrand
0 siblings, 0 replies; 6+ messages in thread
From: David Hildenbrand @ 2023-03-15 8:56 UTC (permalink / raw)
To: Ilya Leoshkevich, Richard Henderson, Thomas Huth
Cc: qemu-s390x, qemu-devel, Nina Schoetterl-Glausch
On 15.03.23 03:04, Ilya Leoshkevich wrote:
> Currently LPSW does not invert the mask bit 12 and incorrectly copies
> the BA bit into the address.
>
> Fix by generating code similar to what s390_cpu_load_normal() does.
>
> Reported-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
> Co-developed-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
> ---
Reviewed-by: David Hildenbrand <david@redhat.com>
--
Thanks,
David / dhildenb
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 2/3] target/s390x: Implement Early Exception Recognition
2023-03-15 2:04 [PATCH v2 0/3] target/s390x: Implement Early Exception Recognition Ilya Leoshkevich
2023-03-15 2:04 ` [PATCH v2 1/3] target/s390x: Fix LPSW Ilya Leoshkevich
@ 2023-03-15 2:04 ` Ilya Leoshkevich
2023-03-15 8:57 ` David Hildenbrand
2023-03-15 2:04 ` [PATCH v2 3/3] tests/tcg/s390x: Add PSW modification tests Ilya Leoshkevich
2 siblings, 1 reply; 6+ messages in thread
From: Ilya Leoshkevich @ 2023-03-15 2:04 UTC (permalink / raw)
To: Richard Henderson, David Hildenbrand, Thomas Huth
Cc: qemu-s390x, qemu-devel, Ilya Leoshkevich, Nina Schoetterl-Glausch
Generate a specification exception if a reserved bit is set in the PSW
mask or if the PSW address is out of bounds dictated by the addressing
mode.
Reported-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
target/s390x/cpu.c | 26 ++++++++++++++++++++++++++
target/s390x/cpu.h | 1 +
target/s390x/tcg/excp_helper.c | 3 ++-
target/s390x/tcg/translate.c | 16 ++++++++++++++++
4 files changed, 45 insertions(+), 1 deletion(-)
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index b10a8541ff8..40fdeaa9056 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -41,6 +41,26 @@
#define CR0_RESET 0xE0UL
#define CR14_RESET 0xC2000000UL;
+#ifndef CONFIG_USER_ONLY
+static bool is_early_exception_psw(uint64_t mask, uint64_t addr)
+{
+ if (mask & PSW_MASK_RESERVED) {
+ return true;
+ }
+
+ switch (mask & (PSW_MASK_32 | PSW_MASK_64)) {
+ case 0:
+ return addr & ~0xffffffULL;
+ case PSW_MASK_32:
+ return addr & ~0x7fffffffULL;
+ case PSW_MASK_32 | PSW_MASK_64:
+ return false;
+ default: /* PSW_MASK_64 */
+ return true;
+ }
+}
+#endif
+
void s390_cpu_set_psw(CPUS390XState *env, uint64_t mask, uint64_t addr)
{
#ifndef CONFIG_USER_ONLY
@@ -57,6 +77,12 @@ void s390_cpu_set_psw(CPUS390XState *env, uint64_t mask, uint64_t addr)
env->cc_op = (mask >> 44) & 3;
#ifndef CONFIG_USER_ONLY
+ if (is_early_exception_psw(mask, addr)) {
+ env->int_pgm_ilen = 0;
+ trigger_pgm_exception(env, PGM_SPECIFICATION);
+ return;
+ }
+
if ((old_mask ^ mask) & PSW_MASK_PER) {
s390_cpu_recompute_watchpoints(env_cpu(env));
}
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 7d6d01325b2..16f63547513 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -292,6 +292,7 @@ extern const VMStateDescription vmstate_s390_cpu;
#define PSW_MASK_32 0x0000000080000000ULL
#define PSW_MASK_SHORT_ADDR 0x000000007fffffffULL
#define PSW_MASK_SHORT_CTRL 0xffffffff80000000ULL
+#define PSW_MASK_RESERVED 0xb80800fe7fffffffULL
#undef PSW_ASC_PRIMARY
#undef PSW_ASC_ACCREG
diff --git a/target/s390x/tcg/excp_helper.c b/target/s390x/tcg/excp_helper.c
index bc767f04438..a7829b1e494 100644
--- a/target/s390x/tcg/excp_helper.c
+++ b/target/s390x/tcg/excp_helper.c
@@ -212,7 +212,8 @@ static void do_program_interrupt(CPUS390XState *env)
LowCore *lowcore;
int ilen = env->int_pgm_ilen;
- assert(ilen == 2 || ilen == 4 || ilen == 6);
+ assert((env->int_pgm_code == PGM_SPECIFICATION && ilen == 0) ||
+ ilen == 2 || ilen == 4 || ilen == 6);
switch (env->int_pgm_code) {
case PGM_PER:
diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c
index 2e1e7e046a6..7832cf02a68 100644
--- a/target/s390x/tcg/translate.c
+++ b/target/s390x/tcg/translate.c
@@ -4068,9 +4068,23 @@ static DisasJumpType op_sske(DisasContext *s, DisasOps *o)
return DISAS_NEXT;
}
+static void gen_check_psw_mask(DisasContext *s)
+{
+ TCGv_i64 reserved = tcg_temp_new_i64();
+ TCGLabel *ok = gen_new_label();
+
+ tcg_gen_andi_i64(reserved, psw_mask, PSW_MASK_RESERVED);
+ tcg_gen_brcondi_i64(TCG_COND_EQ, reserved, 0, ok);
+ gen_program_exception(s, PGM_SPECIFICATION);
+ gen_set_label(ok);
+}
+
static DisasJumpType op_ssm(DisasContext *s, DisasOps *o)
{
tcg_gen_deposit_i64(psw_mask, psw_mask, o->in2, 56, 8);
+
+ gen_check_psw_mask(s);
+
/* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */
s->exit_to_mainloop = true;
return DISAS_TOO_MANY;
@@ -4331,6 +4345,8 @@ static DisasJumpType op_stnosm(DisasContext *s, DisasOps *o)
tcg_gen_ori_i64(psw_mask, psw_mask, i2 << 56);
}
+ gen_check_psw_mask(s);
+
/* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */
s->exit_to_mainloop = true;
return DISAS_TOO_MANY;
--
2.39.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2 2/3] target/s390x: Implement Early Exception Recognition
2023-03-15 2:04 ` [PATCH v2 2/3] target/s390x: Implement Early Exception Recognition Ilya Leoshkevich
@ 2023-03-15 8:57 ` David Hildenbrand
0 siblings, 0 replies; 6+ messages in thread
From: David Hildenbrand @ 2023-03-15 8:57 UTC (permalink / raw)
To: Ilya Leoshkevich, Richard Henderson, Thomas Huth
Cc: qemu-s390x, qemu-devel, Nina Schoetterl-Glausch
On 15.03.23 03:04, Ilya Leoshkevich wrote:
> Generate a specification exception if a reserved bit is set in the PSW
> mask or if the PSW address is out of bounds dictated by the addressing
> mode.
>
> Reported-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
> ---
Make sure to not drop Acks/Rbs.
Reviewed-by: David Hildenbrand <david@redhat.com>
--
Thanks,
David / dhildenb
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 3/3] tests/tcg/s390x: Add PSW modification tests
2023-03-15 2:04 [PATCH v2 0/3] target/s390x: Implement Early Exception Recognition Ilya Leoshkevich
2023-03-15 2:04 ` [PATCH v2 1/3] target/s390x: Fix LPSW Ilya Leoshkevich
2023-03-15 2:04 ` [PATCH v2 2/3] target/s390x: Implement Early Exception Recognition Ilya Leoshkevich
@ 2023-03-15 2:04 ` Ilya Leoshkevich
2 siblings, 0 replies; 6+ messages in thread
From: Ilya Leoshkevich @ 2023-03-15 2:04 UTC (permalink / raw)
To: Richard Henderson, David Hildenbrand, Thomas Huth
Cc: qemu-s390x, qemu-devel, Ilya Leoshkevich
Add several small tests that check the PSW modification instructions:
* lpsw.S checks whether LPSW works correctly in the "happy" case.
* lpswe-early.S checks whether early exceptions are recognized and
whether the correct ILC and old PSW are stored when they happen.
* ssm-early.S, stosm-early.S and exrl-ssm-early.S check the special
handling of SSM and STOSM with respect to early exceptions.
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
tests/tcg/s390x/Makefile.softmmu-target | 5 +++
tests/tcg/s390x/exrl-ssm-early.S | 43 +++++++++++++++++++++++++
tests/tcg/s390x/lpsw.S | 36 +++++++++++++++++++++
tests/tcg/s390x/lpswe-early.S | 38 ++++++++++++++++++++++
tests/tcg/s390x/ssm-early.S | 41 +++++++++++++++++++++++
tests/tcg/s390x/stosm-early.S | 41 +++++++++++++++++++++++
6 files changed, 204 insertions(+)
create mode 100644 tests/tcg/s390x/exrl-ssm-early.S
create mode 100644 tests/tcg/s390x/lpsw.S
create mode 100644 tests/tcg/s390x/lpswe-early.S
create mode 100644 tests/tcg/s390x/ssm-early.S
create mode 100644 tests/tcg/s390x/stosm-early.S
diff --git a/tests/tcg/s390x/Makefile.softmmu-target b/tests/tcg/s390x/Makefile.softmmu-target
index 725b6c598db..607f6ba21a4 100644
--- a/tests/tcg/s390x/Makefile.softmmu-target
+++ b/tests/tcg/s390x/Makefile.softmmu-target
@@ -9,3 +9,8 @@ QEMU_OPTS=-action panic=exit-failure -kernel
TESTS += unaligned-lowcore
TESTS += bal
TESTS += sam
+TESTS += lpsw
+TESTS += lpswe-early
+TESTS += ssm-early
+TESTS += stosm-early
+TESTS += exrl-ssm-early
diff --git a/tests/tcg/s390x/exrl-ssm-early.S b/tests/tcg/s390x/exrl-ssm-early.S
new file mode 100644
index 00000000000..68fbd87b3a5
--- /dev/null
+++ b/tests/tcg/s390x/exrl-ssm-early.S
@@ -0,0 +1,43 @@
+/*
+ * Test early exception recognition using EXRL + SSM.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+ .org 0x8d
+ilc:
+ .org 0x8e
+program_interruption_code:
+ .org 0x150
+program_old_psw:
+ .org 0x1D0 /* program new PSW */
+ .quad 0,pgm
+ .org 0x200 /* lowcore padding */
+
+ .globl _start
+_start:
+ exrl %r0,ssm
+expected_pswa:
+ j failure
+ssm:
+ ssm ssm_op
+
+pgm:
+ chhsi program_interruption_code,0x6 /* specification exception? */
+ jne failure
+ cli ilc,6 /* ilc for EXRL? */
+ jne failure
+ clc program_old_psw(16),expected_old_psw /* correct old PSW? */
+ jne failure
+ lpswe success_psw
+failure:
+ lpswe failure_psw
+
+ssm_op:
+ .byte 0x08 /* bit 4 set */
+ .align 8
+expected_old_psw:
+ .quad 0x0800000180000000,expected_pswa /* bit 2 set */
+success_psw:
+ .quad 0x2000000000000,0xfff /* see is_special_wait_psw() */
+failure_psw:
+ .quad 0x2000000000000,0 /* disabled wait */
diff --git a/tests/tcg/s390x/lpsw.S b/tests/tcg/s390x/lpsw.S
new file mode 100644
index 00000000000..b37dec59b73
--- /dev/null
+++ b/tests/tcg/s390x/lpsw.S
@@ -0,0 +1,36 @@
+/*
+ * Test the LPSW instruction.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+ .org 0x140
+svc_old_psw:
+ .org 0x1c0 /* supervisor call new PSW */
+ .quad 0x80000000,svc /* 31-bit mode */
+ .org 0x200 /* lowcore padding */
+
+ .globl _start
+_start:
+ lpsw short_psw
+lpsw_target:
+ svc 0
+expected_pswa:
+ j failure
+
+svc:
+ clc svc_old_psw(16),expected_psw /* correct full PSW? */
+ jne failure
+ lpswe success_psw
+failure:
+ lpswe failure_psw
+
+ .align 8
+short_psw:
+ .long 0x90001,0x80000000+lpsw_target /* problem state,
+ 64-bit mode */
+expected_psw:
+ .quad 0x1000180000000,expected_pswa /* corresponds to short_psw */
+success_psw:
+ .quad 0x2000000000000,0xfff /* see is_special_wait_psw() */
+failure_psw:
+ .quad 0x2000000000000,0 /* disabled wait */
diff --git a/tests/tcg/s390x/lpswe-early.S b/tests/tcg/s390x/lpswe-early.S
new file mode 100644
index 00000000000..90a7f213dfb
--- /dev/null
+++ b/tests/tcg/s390x/lpswe-early.S
@@ -0,0 +1,38 @@
+/*
+ * Test early exception recognition using LPSWE.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+ .org 0x8d
+ilc:
+ .org 0x8e
+program_interruption_code:
+ .org 0x150
+program_old_psw:
+ .org 0x1D0 /* program new PSW */
+ .quad 0,pgm
+ .org 0x200 /* lowcore padding */
+
+ .globl _start
+_start:
+ lpswe bad_psw
+ j failure
+
+pgm:
+ chhsi program_interruption_code,0x6 /* specification exception? */
+ jne failure
+ cli ilc,0 /* ilc zero? */
+ jne failure
+ clc program_old_psw(16),bad_psw /* correct old PSW? */
+ jne failure
+ lpswe success_psw
+failure:
+ lpswe failure_psw
+
+ .align 8
+bad_psw:
+ .quad 0x8000000000000000,0xfedcba9876543210 /* bit 0 set */
+success_psw:
+ .quad 0x2000000000000,0xfff /* see is_special_wait_psw() */
+failure_psw:
+ .quad 0x2000000000000,0 /* disabled wait */
diff --git a/tests/tcg/s390x/ssm-early.S b/tests/tcg/s390x/ssm-early.S
new file mode 100644
index 00000000000..6dfe40c597b
--- /dev/null
+++ b/tests/tcg/s390x/ssm-early.S
@@ -0,0 +1,41 @@
+/*
+ * Test early exception recognition using SSM.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+ .org 0x8d
+ilc:
+ .org 0x8e
+program_interruption_code:
+ .org 0x150
+program_old_psw:
+ .org 0x1D0 /* program new PSW */
+ .quad 0,pgm
+ .org 0x200 /* lowcore padding */
+
+ .globl _start
+_start:
+ ssm ssm_op
+expected_pswa:
+ j failure
+
+pgm:
+ chhsi program_interruption_code,0x6 /* specification exception? */
+ jne failure
+ cli ilc,4 /* ilc for SSM? */
+ jne failure
+ clc program_old_psw(16),expected_old_psw /* correct old PSW? */
+ jne failure
+ lpswe success_psw
+failure:
+ lpswe failure_psw
+
+ssm_op:
+ .byte 0x20 /* bit 2 set */
+ .align 8
+expected_old_psw:
+ .quad 0x2000000180000000,expected_pswa /* bit 2 set */
+success_psw:
+ .quad 0x2000000000000,0xfff /* see is_special_wait_psw() */
+failure_psw:
+ .quad 0x2000000000000,0 /* disabled wait */
diff --git a/tests/tcg/s390x/stosm-early.S b/tests/tcg/s390x/stosm-early.S
new file mode 100644
index 00000000000..0689924f3a4
--- /dev/null
+++ b/tests/tcg/s390x/stosm-early.S
@@ -0,0 +1,41 @@
+/*
+ * Test early exception recognition using STOSM.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+ .org 0x8d
+ilc:
+ .org 0x8e
+program_interruption_code:
+ .org 0x150
+program_old_psw:
+ .org 0x1D0 /* program new PSW */
+ .quad 0,pgm
+ .org 0x200 /* lowcore padding */
+
+ .globl _start
+_start:
+ stosm ssm_op,0x10 /* bit 3 set */
+expected_pswa:
+ j failure
+
+pgm:
+ chhsi program_interruption_code,0x6 /* specification exception? */
+ jne failure
+ cli ilc,4 /* ilc for STOSM? */
+ jne failure
+ clc program_old_psw(16),expected_old_psw /* correct old PSW? */
+ jne failure
+ lpswe success_psw
+failure:
+ lpswe failure_psw
+
+ssm_op:
+ .byte 0
+ .align 8
+expected_old_psw:
+ .quad 0x1000000180000000,expected_pswa /* bit 3 set */
+success_psw:
+ .quad 0x2000000000000,0xfff /* see is_special_wait_psw() */
+failure_psw:
+ .quad 0x2000000000000,0 /* disabled wait */
--
2.39.2
^ permalink raw reply related [flat|nested] 6+ messages in thread