From 2df59b73e0864f021f6179f32f7ed364f6d4f38d Mon Sep 17 00:00:00 2001 From: Nico Boehr Date: Thu, 16 Dec 2021 14:16:57 +0100 Subject: s390x/css: fix PMCW invalid mask Previously, we required bits 5, 6 and 7 to be zero (0x07 == 0b111). But, as per the principles of operation, bit 5 is ignored in MSCH and bits 0, 1, 6 and 7 need to be zero. As both PMCW_FLAGS_MASK_INVALID and ioinst_schib_valid() are only used by ioinst_handle_msch(), adjust the mask accordingly. Fixes: db1c8f53bfb1 ("s390: Channel I/O basic definitions.") Signed-off-by: Nico Boehr Reviewed-by: Pierre Morel Reviewed-by: Halil Pasic Reviewed-by: Janosch Frank Reviewed-by: Cornelia Huck Message-Id: <20211216131657.1057978-1-nrb@linux.ibm.com> Signed-off-by: Thomas Huth --- include/hw/s390x/ioinst.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/hw/s390x/ioinst.h b/include/hw/s390x/ioinst.h index 3771fff..ea8d0f2 100644 --- a/include/hw/s390x/ioinst.h +++ b/include/hw/s390x/ioinst.h @@ -107,7 +107,7 @@ QEMU_BUILD_BUG_MSG(sizeof(PMCW) != 28, "size of PMCW is wrong"); #define PMCW_FLAGS_MASK_MP 0x0004 #define PMCW_FLAGS_MASK_TF 0x0002 #define PMCW_FLAGS_MASK_DNV 0x0001 -#define PMCW_FLAGS_MASK_INVALID 0x0700 +#define PMCW_FLAGS_MASK_INVALID 0xc300 #define PMCW_CHARS_MASK_ST 0x00e00000 #define PMCW_CHARS_MASK_MBFC 0x00000004 -- cgit v1.1 From 521130f267240cb1ed8fd4635496493a153281db Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Wed, 12 Jan 2022 17:50:12 +0100 Subject: target/s390x: Fix SLDA sign bit index SLDA operates on 64-bit values, so its sign bit index should be 63, not 31. Fixes: a79ba3398a0a ("target-s390: Convert SHIFT DOUBLE") Reported-by: David Hildenbrand Signed-off-by: Ilya Leoshkevich Reviewed-by: David Hildenbrand Message-Id: <20220112165016.226996-2-iii@linux.ibm.com> Signed-off-by: Thomas Huth --- target/s390x/tcg/insn-data.def | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/s390x/tcg/insn-data.def b/target/s390x/tcg/insn-data.def index f0af458..90c7530 100644 --- a/target/s390x/tcg/insn-data.def +++ b/target/s390x/tcg/insn-data.def @@ -800,7 +800,7 @@ C(0xebde, SRLK, RSY_a, DO, r3_32u, sh32, new, r1_32, srl, 0) C(0xeb0c, SRLG, RSY_a, Z, r3_o, sh64, r1, 0, srl, 0) /* SHIFT LEFT DOUBLE */ - D(0x8f00, SLDA, RS_a, Z, r1_D32, sh64, new, r1_D32, sla, 0, 31) + D(0x8f00, SLDA, RS_a, Z, r1_D32, sh64, new, r1_D32, sla, 0, 63) /* SHIFT LEFT DOUBLE LOGICAL */ C(0x8d00, SLDL, RS_a, Z, r1_D32, sh64, new, r1_D32, sll, 0) /* SHIFT RIGHT DOUBLE */ -- cgit v1.1 From 57556b28afde4b039bb12bfc274bd8df9022d946 Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Wed, 12 Jan 2022 17:50:13 +0100 Subject: target/s390x: Fix SRDA CC calculation SRDA uses r1_D32 for binding the first operand and s64 for setting CC. cout_s64() relies on o->out being the shift result, however, wout_r1_D32() clobbers it. Fix by using a temporary. Fixes: a79ba3398a0a ("target-s390: Convert SHIFT DOUBLE") Signed-off-by: Ilya Leoshkevich Reviewed-by: David Hildenbrand Message-Id: <20220112165016.226996-3-iii@linux.ibm.com> Signed-off-by: Thomas Huth --- target/s390x/tcg/translate.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c index f180853..766b4c8 100644 --- a/target/s390x/tcg/translate.c +++ b/target/s390x/tcg/translate.c @@ -5420,9 +5420,11 @@ static void wout_r1_P32(DisasContext *s, DisasOps *o) static void wout_r1_D32(DisasContext *s, DisasOps *o) { int r1 = get_field(s, r1); + TCGv_i64 t = tcg_temp_new_i64(); store_reg32_i64(r1 + 1, o->out); - tcg_gen_shri_i64(o->out, o->out, 32); - store_reg32_i64(r1, o->out); + tcg_gen_shri_i64(t, o->out, 32); + store_reg32_i64(r1, t); + tcg_temp_free_i64(t); } #define SPEC_wout_r1_D32 SPEC_r1_even -- cgit v1.1 From df103c09bc2f549d36ba6313a69c18fc003ef1ee Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Wed, 12 Jan 2022 17:50:14 +0100 Subject: target/s390x: Fix cc_calc_sla_64() missing overflows An overflow occurs for SLAG when at least one shifted bit is not equal to sign bit. Therefore, we need to check that `shift + 1` bits are neither all 0s nor all 1s. The current code checks only `shift` bits, missing some overflows. Fixes: cbe24bfa91d2 ("target-s390: Convert SHIFT, ROTATE SINGLE") Co-developed-by: David Hildenbrand Signed-off-by: Ilya Leoshkevich Reviewed-by: David Hildenbrand Message-Id: <20220112165016.226996-4-iii@linux.ibm.com> Signed-off-by: Thomas Huth --- target/s390x/tcg/cc_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/s390x/tcg/cc_helper.c b/target/s390x/tcg/cc_helper.c index c2c96c3..c9b7b0e 100644 --- a/target/s390x/tcg/cc_helper.c +++ b/target/s390x/tcg/cc_helper.c @@ -297,7 +297,7 @@ static uint32_t cc_calc_sla_32(uint32_t src, int shift) static uint32_t cc_calc_sla_64(uint64_t src, int shift) { - uint64_t mask = ((1ULL << shift) - 1ULL) << (64 - shift); + uint64_t mask = -1ULL << (63 - shift); uint64_t sign = 1ULL << 63; uint64_t match; int64_t r; -- cgit v1.1 From 6da170beda33f3e7f1d9242814acd9f428f0f0fb Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Wed, 12 Jan 2022 17:50:15 +0100 Subject: target/s390x: Fix shifting 32-bit values for more than 31 bits According to PoP, both 32- and 64-bit shifts use lowest 6 address bits. The current code special-cases 32-bit shifts to use only 5 bits, which is not correct. For example, shifting by 32 bits currently preserves the initial value, however, it's supposed zero it out instead. Fix by merging sh32 and sh64 and adapting CC calculation to shift values greater than 31. Fixes: cbe24bfa91d2 ("target-s390: Convert SHIFT, ROTATE SINGLE") Signed-off-by: Ilya Leoshkevich Reviewed-by: David Hildenbrand Message-Id: <20220112165016.226996-5-iii@linux.ibm.com> Signed-off-by: Thomas Huth --- target/s390x/cpu-dump.c | 3 +-- target/s390x/s390x-internal.h | 3 +-- target/s390x/tcg/cc_helper.c | 36 +++----------------------------- target/s390x/tcg/insn-data.def | 36 ++++++++++++++++---------------- target/s390x/tcg/translate.c | 47 ++++++++++++++++++++---------------------- 5 files changed, 45 insertions(+), 80 deletions(-) diff --git a/target/s390x/cpu-dump.c b/target/s390x/cpu-dump.c index 0f5c062..ffa9e94 100644 --- a/target/s390x/cpu-dump.c +++ b/target/s390x/cpu-dump.c @@ -121,8 +121,7 @@ const char *cc_name(enum cc_op cc_op) [CC_OP_NZ_F64] = "CC_OP_NZ_F64", [CC_OP_NZ_F128] = "CC_OP_NZ_F128", [CC_OP_ICM] = "CC_OP_ICM", - [CC_OP_SLA_32] = "CC_OP_SLA_32", - [CC_OP_SLA_64] = "CC_OP_SLA_64", + [CC_OP_SLA] = "CC_OP_SLA", [CC_OP_FLOGR] = "CC_OP_FLOGR", [CC_OP_LCBB] = "CC_OP_LCBB", [CC_OP_VC] = "CC_OP_VC", diff --git a/target/s390x/s390x-internal.h b/target/s390x/s390x-internal.h index 1a178ae..6fc8cad 100644 --- a/target/s390x/s390x-internal.h +++ b/target/s390x/s390x-internal.h @@ -193,8 +193,7 @@ enum cc_op { CC_OP_NZ_F128, /* FP dst != 0 (128bit) */ CC_OP_ICM, /* insert characters under mask */ - CC_OP_SLA_32, /* Calculate shift left signed (32bit) */ - CC_OP_SLA_64, /* Calculate shift left signed (64bit) */ + CC_OP_SLA, /* Calculate shift left signed */ CC_OP_FLOGR, /* find leftmost one */ CC_OP_LCBB, /* load count to block boundary */ CC_OP_VC, /* vector compare result */ diff --git a/target/s390x/tcg/cc_helper.c b/target/s390x/tcg/cc_helper.c index c9b7b0e..8d04097 100644 --- a/target/s390x/tcg/cc_helper.c +++ b/target/s390x/tcg/cc_helper.c @@ -268,34 +268,7 @@ static uint32_t cc_calc_icm(uint64_t mask, uint64_t val) } } -static uint32_t cc_calc_sla_32(uint32_t src, int shift) -{ - uint32_t mask = ((1U << shift) - 1U) << (32 - shift); - uint32_t sign = 1U << 31; - uint32_t match; - int32_t r; - - /* Check if the sign bit stays the same. */ - if (src & sign) { - match = mask; - } else { - match = 0; - } - if ((src & mask) != match) { - /* Overflow. */ - return 3; - } - - r = ((src << shift) & ~sign) | (src & sign); - if (r == 0) { - return 0; - } else if (r < 0) { - return 1; - } - return 2; -} - -static uint32_t cc_calc_sla_64(uint64_t src, int shift) +static uint32_t cc_calc_sla(uint64_t src, int shift) { uint64_t mask = -1ULL << (63 - shift); uint64_t sign = 1ULL << 63; @@ -459,11 +432,8 @@ static uint32_t do_calc_cc(CPUS390XState *env, uint32_t cc_op, case CC_OP_ICM: r = cc_calc_icm(src, dst); break; - case CC_OP_SLA_32: - r = cc_calc_sla_32(src, dst); - break; - case CC_OP_SLA_64: - r = cc_calc_sla_64(src, dst); + case CC_OP_SLA: + r = cc_calc_sla(src, dst); break; case CC_OP_FLOGR: r = cc_calc_flogr(dst); diff --git a/target/s390x/tcg/insn-data.def b/target/s390x/tcg/insn-data.def index 90c7530..1c3e115 100644 --- a/target/s390x/tcg/insn-data.def +++ b/target/s390x/tcg/insn-data.def @@ -747,8 +747,8 @@ C(0xb9e1, POPCNT, RRE, PC, 0, r2_o, r1, 0, popcnt, nz64) /* ROTATE LEFT SINGLE LOGICAL */ - C(0xeb1d, RLL, RSY_a, Z, r3_o, sh32, new, r1_32, rll32, 0) - C(0xeb1c, RLLG, RSY_a, Z, r3_o, sh64, r1, 0, rll64, 0) + C(0xeb1d, RLL, RSY_a, Z, r3_o, sh, new, r1_32, rll32, 0) + C(0xeb1c, RLLG, RSY_a, Z, r3_o, sh, r1, 0, rll64, 0) /* ROTATE THEN INSERT SELECTED BITS */ C(0xec55, RISBG, RIE_f, GIE, 0, r2, r1, 0, risbg, s64) @@ -784,29 +784,29 @@ C(0x0400, SPM, RR_a, Z, r1, 0, 0, 0, spm, 0) /* SHIFT LEFT SINGLE */ - D(0x8b00, SLA, RS_a, Z, r1, sh32, new, r1_32, sla, 0, 31) - D(0xebdd, SLAK, RSY_a, DO, r3, sh32, new, r1_32, sla, 0, 31) - D(0xeb0b, SLAG, RSY_a, Z, r3, sh64, r1, 0, sla, 0, 63) + D(0x8b00, SLA, RS_a, Z, r1, sh, new, r1_32, sla, 0, 31) + D(0xebdd, SLAK, RSY_a, DO, r3, sh, new, r1_32, sla, 0, 31) + D(0xeb0b, SLAG, RSY_a, Z, r3, sh, r1, 0, sla, 0, 63) /* SHIFT LEFT SINGLE LOGICAL */ - C(0x8900, SLL, RS_a, Z, r1_o, sh32, new, r1_32, sll, 0) - C(0xebdf, SLLK, RSY_a, DO, r3_o, sh32, new, r1_32, sll, 0) - C(0xeb0d, SLLG, RSY_a, Z, r3_o, sh64, r1, 0, sll, 0) + C(0x8900, SLL, RS_a, Z, r1_o, sh, new, r1_32, sll, 0) + C(0xebdf, SLLK, RSY_a, DO, r3_o, sh, new, r1_32, sll, 0) + C(0xeb0d, SLLG, RSY_a, Z, r3_o, sh, r1, 0, sll, 0) /* SHIFT RIGHT SINGLE */ - C(0x8a00, SRA, RS_a, Z, r1_32s, sh32, new, r1_32, sra, s32) - C(0xebdc, SRAK, RSY_a, DO, r3_32s, sh32, new, r1_32, sra, s32) - C(0xeb0a, SRAG, RSY_a, Z, r3_o, sh64, r1, 0, sra, s64) + C(0x8a00, SRA, RS_a, Z, r1_32s, sh, new, r1_32, sra, s32) + C(0xebdc, SRAK, RSY_a, DO, r3_32s, sh, new, r1_32, sra, s32) + C(0xeb0a, SRAG, RSY_a, Z, r3_o, sh, r1, 0, sra, s64) /* SHIFT RIGHT SINGLE LOGICAL */ - C(0x8800, SRL, RS_a, Z, r1_32u, sh32, new, r1_32, srl, 0) - C(0xebde, SRLK, RSY_a, DO, r3_32u, sh32, new, r1_32, srl, 0) - C(0xeb0c, SRLG, RSY_a, Z, r3_o, sh64, r1, 0, srl, 0) + C(0x8800, SRL, RS_a, Z, r1_32u, sh, new, r1_32, srl, 0) + C(0xebde, SRLK, RSY_a, DO, r3_32u, sh, new, r1_32, srl, 0) + C(0xeb0c, SRLG, RSY_a, Z, r3_o, sh, r1, 0, srl, 0) /* SHIFT LEFT DOUBLE */ - D(0x8f00, SLDA, RS_a, Z, r1_D32, sh64, new, r1_D32, sla, 0, 63) + D(0x8f00, SLDA, RS_a, Z, r1_D32, sh, new, r1_D32, sla, 0, 63) /* SHIFT LEFT DOUBLE LOGICAL */ - C(0x8d00, SLDL, RS_a, Z, r1_D32, sh64, new, r1_D32, sll, 0) + C(0x8d00, SLDL, RS_a, Z, r1_D32, sh, new, r1_D32, sll, 0) /* SHIFT RIGHT DOUBLE */ - C(0x8e00, SRDA, RS_a, Z, r1_D32, sh64, new, r1_D32, sra, s64) + C(0x8e00, SRDA, RS_a, Z, r1_D32, sh, new, r1_D32, sra, s64) /* SHIFT RIGHT DOUBLE LOGICAL */ - C(0x8c00, SRDL, RS_a, Z, r1_D32, sh64, new, r1_D32, srl, 0) + C(0x8c00, SRDL, RS_a, Z, r1_D32, sh, new, r1_D32, srl, 0) /* SQUARE ROOT */ F(0xb314, SQEBR, RRE, Z, 0, e2, new, e1, sqeb, 0, IF_BFP) diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c index 766b4c8..46dea73 100644 --- a/target/s390x/tcg/translate.c +++ b/target/s390x/tcg/translate.c @@ -636,8 +636,7 @@ static void gen_op_calc_cc(DisasContext *s) case CC_OP_LTUGTU_64: case CC_OP_TM_32: case CC_OP_TM_64: - case CC_OP_SLA_32: - case CC_OP_SLA_64: + case CC_OP_SLA: case CC_OP_SUBU: case CC_OP_NZ_F128: case CC_OP_VC: @@ -1178,19 +1177,6 @@ struct DisasInsn { /* ====================================================================== */ /* Miscellaneous helpers, used by several operations. */ -static void help_l2_shift(DisasContext *s, DisasOps *o, int mask) -{ - int b2 = get_field(s, b2); - int d2 = get_field(s, d2); - - if (b2 == 0) { - o->in2 = tcg_const_i64(d2 & mask); - } else { - o->in2 = get_address(s, 0, b2, d2); - tcg_gen_andi_i64(o->in2, o->in2, mask); - } -} - static DisasJumpType help_goto_direct(DisasContext *s, uint64_t dest) { if (dest == s->pc_tmp) { @@ -4113,9 +4099,18 @@ static DisasJumpType op_soc(DisasContext *s, DisasOps *o) static DisasJumpType op_sla(DisasContext *s, DisasOps *o) { + TCGv_i64 t; uint64_t sign = 1ull << s->insn->data; - enum cc_op cco = s->insn->data == 31 ? CC_OP_SLA_32 : CC_OP_SLA_64; - gen_op_update2_cc_i64(s, cco, o->in1, o->in2); + if (s->insn->data == 31) { + t = tcg_temp_new_i64(); + tcg_gen_shli_i64(t, o->in1, 32); + } else { + t = o->in1; + } + gen_op_update2_cc_i64(s, CC_OP_SLA, t, o->in2); + if (s->insn->data == 31) { + tcg_temp_free_i64(t); + } tcg_gen_shl_i64(o->out, o->in1, o->in2); /* The arithmetic left shift is curious in that it does not affect the sign bit. Copy that over from the source unchanged. */ @@ -5924,17 +5919,19 @@ static void in2_ri2(DisasContext *s, DisasOps *o) } #define SPEC_in2_ri2 0 -static void in2_sh32(DisasContext *s, DisasOps *o) +static void in2_sh(DisasContext *s, DisasOps *o) { - help_l2_shift(s, o, 31); -} -#define SPEC_in2_sh32 0 + int b2 = get_field(s, b2); + int d2 = get_field(s, d2); -static void in2_sh64(DisasContext *s, DisasOps *o) -{ - help_l2_shift(s, o, 63); + if (b2 == 0) { + o->in2 = tcg_const_i64(d2 & 0x3f); + } else { + o->in2 = get_address(s, 0, b2, d2); + tcg_gen_andi_i64(o->in2, o->in2, 0x3f); + } } -#define SPEC_in2_sh64 0 +#define SPEC_in2_sh 0 static void in2_m2_8u(DisasContext *s, DisasOps *o) { -- cgit v1.1 From f7cff0738d1bc66b530a6c200874eb86575048f4 Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Wed, 12 Jan 2022 17:50:16 +0100 Subject: tests/tcg/s390x: Test shift instructions Add a test for each shift instruction in order to to prevent regressions. Signed-off-by: Ilya Leoshkevich Acked-by: David Hildenbrand Message-Id: <20220112165016.226996-6-iii@linux.ibm.com> Signed-off-by: Thomas Huth --- tests/tcg/s390x/Makefile.target | 1 + tests/tcg/s390x/shift.c | 270 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 271 insertions(+) create mode 100644 tests/tcg/s390x/shift.c diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target index cc64dd3..1a7238b 100644 --- a/tests/tcg/s390x/Makefile.target +++ b/tests/tcg/s390x/Makefile.target @@ -9,6 +9,7 @@ TESTS+=exrl-trtr TESTS+=pack TESTS+=mvo TESTS+=mvc +TESTS+=shift TESTS+=trap TESTS+=signals-s390x diff --git a/tests/tcg/s390x/shift.c b/tests/tcg/s390x/shift.c new file mode 100644 index 0000000..29594fe --- /dev/null +++ b/tests/tcg/s390x/shift.c @@ -0,0 +1,270 @@ +#include +#include +#include + +#define DEFINE_SHIFT_SINGLE_COMMON(_name, _insn_str) \ + static uint64_t _name(uint64_t op1, uint64_t op2, uint64_t *cc) \ + { \ + asm(" sll %[cc],28\n" \ + " spm %[cc]\n" \ + " " _insn_str "\n" \ + " ipm %[cc]\n" \ + " srl %[cc],28" \ + : [op1] "+&r" (op1), \ + [cc] "+&r" (*cc) \ + : [op2] "r" (op2) \ + : "cc"); \ + return op1; \ + } +#define DEFINE_SHIFT_SINGLE_2(_insn, _offset) \ + DEFINE_SHIFT_SINGLE_COMMON(_insn ## _ ## _offset, \ + #_insn " %[op1]," #_offset "(%[op2])") +#define DEFINE_SHIFT_SINGLE_3(_insn, _offset) \ + DEFINE_SHIFT_SINGLE_COMMON(_insn ## _ ## _offset, \ + #_insn " %[op1],%[op1]," #_offset "(%[op2])") +#define DEFINE_SHIFT_DOUBLE(_insn, _offset) \ + static uint64_t _insn ## _ ## _offset(uint64_t op1, uint64_t op2, \ + uint64_t *cc) \ + { \ + uint32_t op1h = op1 >> 32; \ + uint32_t op1l = op1 & 0xffffffff; \ + register uint32_t r2 asm("2") = op1h; \ + register uint32_t r3 asm("3") = op1l; \ + \ + asm(" sll %[cc],28\n" \ + " spm %[cc]\n" \ + " " #_insn " %[r2]," #_offset "(%[op2])\n" \ + " ipm %[cc]\n" \ + " srl %[cc],28" \ + : [r2] "+&r" (r2), \ + [r3] "+&r" (r3), \ + [cc] "+&r" (*cc) \ + : [op2] "r" (op2) \ + : "cc"); \ + op1h = r2; \ + op1l = r3; \ + return (((uint64_t)op1h) << 32) | op1l; \ + } + +DEFINE_SHIFT_SINGLE_3(rll, 0x4cf3b); +DEFINE_SHIFT_SINGLE_3(rllg, 0x697c9); +DEFINE_SHIFT_SINGLE_2(sla, 0x4b0); +DEFINE_SHIFT_SINGLE_2(sla, 0xd54); +DEFINE_SHIFT_SINGLE_3(slak, 0x2832c); +DEFINE_SHIFT_SINGLE_3(slag, 0x66cc4); +DEFINE_SHIFT_SINGLE_3(slag, 0xd54); +DEFINE_SHIFT_SINGLE_2(sll, 0xd04); +DEFINE_SHIFT_SINGLE_3(sllk, 0x2699f); +DEFINE_SHIFT_SINGLE_3(sllg, 0x59df9); +DEFINE_SHIFT_SINGLE_2(sra, 0x67e); +DEFINE_SHIFT_SINGLE_3(srak, 0x60943); +DEFINE_SHIFT_SINGLE_3(srag, 0x6b048); +DEFINE_SHIFT_SINGLE_2(srl, 0x035); +DEFINE_SHIFT_SINGLE_3(srlk, 0x43dfc); +DEFINE_SHIFT_SINGLE_3(srlg, 0x27227); +DEFINE_SHIFT_DOUBLE(slda, 0x38b); +DEFINE_SHIFT_DOUBLE(sldl, 0x031); +DEFINE_SHIFT_DOUBLE(srda, 0x36f); +DEFINE_SHIFT_DOUBLE(srdl, 0x99a); + +struct shift_test { + const char *name; + uint64_t (*insn)(uint64_t, uint64_t, uint64_t *); + uint64_t op1; + uint64_t op2; + uint64_t exp_result; + uint64_t exp_cc; +}; + +static const struct shift_test tests[] = { + { + .name = "rll", + .insn = rll_0x4cf3b, + .op1 = 0xecbd589a45c248f5ull, + .op2 = 0x62e5508ccb4c99fdull, + .exp_result = 0xecbd589af545c248ull, + .exp_cc = 0, + }, + { + .name = "rllg", + .insn = rllg_0x697c9, + .op1 = 0xaa2d54c1b729f7f4ull, + .op2 = 0x5ffcf7465f5cd71full, + .exp_result = 0x29f7f4aa2d54c1b7ull, + .exp_cc = 0, + }, + { + .name = "sla-1", + .insn = sla_0x4b0, + .op1 = 0x8bf21fb67cca0e96ull, + .op2 = 0x3ddf2f53347d3030ull, + .exp_result = 0x8bf21fb600000000ull, + .exp_cc = 3, + }, + { + .name = "sla-2", + .insn = sla_0xd54, + .op1 = 0xe4faaed5def0e926ull, + .op2 = 0x18d586fab239cbeeull, + .exp_result = 0xe4faaed5fbc3a498ull, + .exp_cc = 3, + }, + { + .name = "slak", + .insn = slak_0x2832c, + .op1 = 0x7300bf78707f09f9ull, + .op2 = 0x4d193b85bb5cb39bull, + .exp_result = 0x7300bf783f84fc80ull, + .exp_cc = 3, + }, + { + .name = "slag-1", + .insn = slag_0x66cc4, + .op1 = 0xe805966de1a77762ull, + .op2 = 0x0e92953f6aa91c6bull, + .exp_result = 0xbbb1000000000000ull, + .exp_cc = 3, + }, + { + .name = "slag-2", + .insn = slag_0xd54, + .op1 = 0xdef0e92600000000ull, + .op2 = 0x18d586fab239cbeeull, + .exp_result = 0xfbc3a49800000000ull, + .exp_cc = 3, + }, + { + .name = "sll", + .insn = sll_0xd04, + .op1 = 0xb90281a3105939dfull, + .op2 = 0xb5e4df7e082e4c5eull, + .exp_result = 0xb90281a300000000ull, + .exp_cc = 0, + }, + { + .name = "sllk", + .insn = sllk_0x2699f, + .op1 = 0x777c6cf116f99557ull, + .op2 = 0xe0556cf112e5a458ull, + .exp_result = 0x777c6cf100000000ull, + .exp_cc = 0, + }, + { + .name = "sllg", + .insn = sllg_0x59df9, + .op1 = 0xcdf86cbfbc0f3557ull, + .op2 = 0x325a45acf99c6d3dull, + .exp_result = 0x55c0000000000000ull, + .exp_cc = 0, + }, + { + .name = "sra", + .insn = sra_0x67e, + .op1 = 0xb878f048d5354183ull, + .op2 = 0x9e27d13195931f79ull, + .exp_result = 0xb878f048ffffffffull, + .exp_cc = 1, + }, + { + .name = "srak", + .insn = srak_0x60943, + .op1 = 0xb6ceb5a429cedb35ull, + .op2 = 0x352354900ae34d7aull, + .exp_result = 0xb6ceb5a400000000ull, + .exp_cc = 0, + }, + { + .name = "srag", + .insn = srag_0x6b048, + .op1 = 0xd54dd4468676c63bull, + .op2 = 0x84d026db7b4dca28ull, + .exp_result = 0xffffffffffffd54dull, + .exp_cc = 1, + }, + { + .name = "srl", + .insn = srl_0x035, + .op1 = 0x09be503ef826815full, + .op2 = 0xbba8d1a0e542d5c1ull, + .exp_result = 0x9be503e00000000ull, + .exp_cc = 0, + }, + { + .name = "srlk", + .insn = srlk_0x43dfc, + .op1 = 0x540d6c8de71aee2aull, + .op2 = 0x0000000000000000ull, + .exp_result = 0x540d6c8d00000000ull, + .exp_cc = 0, + }, + { + .name = "srlg", + .insn = srlg_0x27227, + .op1 = 0x26f7123c1c447a34ull, + .op2 = 0x0000000000000000ull, + .exp_result = 0x00000000004dee24ull, + .exp_cc = 0, + }, + { + .name = "slda", + .insn = slda_0x38b, + .op1 = 0x7988f722dd5bbe7cull, + .op2 = 0x9aed3f95b4d78cc2ull, + .exp_result = 0x1ee45bab77cf8000ull, + .exp_cc = 3, + }, + { + .name = "sldl", + .insn = sldl_0x031, + .op1 = 0xaae2918dce2b049aull, + .op2 = 0x0000000000000000ull, + .exp_result = 0x0934000000000000ull, + .exp_cc = 0, + }, + { + .name = "srda", + .insn = srda_0x36f, + .op1 = 0x0cd4ed9228a50978ull, + .op2 = 0x72b046f0848b8cc9ull, + .exp_result = 0x000000000000000cull, + .exp_cc = 2, + }, + { + .name = "srdl", + .insn = srdl_0x99a, + .op1 = 0x1018611c41689a1dull, + .op2 = 0x2907e150c50ba319ull, + .exp_result = 0x0000000000000203ull, + .exp_cc = 0, + }, +}; + +int main(void) +{ + int ret = 0; + size_t i; + + for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { + uint64_t result; + uint64_t cc = 0; + + result = tests[i].insn(tests[i].op1, tests[i].op2, &cc); + if (result != tests[i].exp_result) { + fprintf(stderr, + "bad %s result:\n" + "actual = 0x%" PRIx64 "\n" + "expected = 0x%" PRIx64 "\n", + tests[i].name, result, tests[i].exp_result); + ret = 1; + } + if (cc != tests[i].exp_cc) { + fprintf(stderr, + "bad %s cc:\n" + "actual = %" PRIu64 "\n" + "expected = %" PRIu64 "\n", + tests[i].name, cc, tests[i].exp_cc); + ret = 1; + } + } + return ret; +} -- cgit v1.1 From 56e34834029c7c6862cb0095d95ad83c50485f88 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Wed, 22 Dec 2021 11:55:48 +0100 Subject: MAINTAINERS: split out s390x sections MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split out some more specialized devices etc., so that we can build smarter lists of people to be put on cc: in the future. Signed-off-by: Cornelia Huck Reviewed-by: Philippe Mathieu-Daudé Acked-by: David Hildenbrand Acked-by: Christian Borntraeger Acked-by: Thomas Huth Acked-by: Halil Pasic Acked-by: Eric Farman Message-Id: <20211222105548.356852-1-cohuck@redhat.com> Signed-off-by: Thomas Huth --- MAINTAINERS | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 74 insertions(+), 11 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 2fd74c4..793d6ed 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -297,7 +297,6 @@ M: David Hildenbrand S: Maintained F: target/s390x/ F: target/s390x/tcg -F: target/s390x/cpu_models_*.[ch] F: hw/s390x/ F: disas/s390.c F: tests/tcg/s390x/ @@ -396,16 +395,10 @@ M: Halil Pasic M: Christian Borntraeger S: Supported F: target/s390x/kvm/ -F: target/s390x/ioinst.[ch] F: target/s390x/machine.c F: target/s390x/sigp.c -F: target/s390x/cpu_features*.[ch] -F: target/s390x/cpu_models.[ch] F: hw/s390x/pv.c F: include/hw/s390x/pv.h -F: hw/intc/s390_flic.c -F: hw/intc/s390_flic_kvm.c -F: include/hw/s390x/s390_flic.h F: gdb-xml/s390*.xml T: git https://github.com/borntraeger/qemu.git s390-next L: qemu-s390x@nongnu.org @@ -1533,12 +1526,8 @@ S390 Virtio-ccw M: Halil Pasic M: Christian Borntraeger S: Supported -F: hw/char/sclp*.[hc] -F: hw/char/terminal3270.c F: hw/s390x/ F: include/hw/s390x/ -F: hw/watchdog/wdt_diag288.c -F: include/hw/watchdog/wdt_diag288.h F: configs/devices/s390x-softmmu/default.mak F: tests/avocado/machine_s390_ccw_virtio.py T: git https://github.com/borntraeger/qemu.git s390-next @@ -1563,6 +1552,37 @@ F: hw/s390x/s390-pci* F: include/hw/s390x/s390-pci* L: qemu-s390x@nongnu.org +S390 channel subsystem +M: Halil Pasic +M: Christian Borntraeger +S: Supported +F: hw/s390x/ccw-device.[ch] +F: hw/s390x/css.c +F: hw/s390x/css-bridge.c +F: include/hw/s390x/css.h +F: include/hw/s390x/css-bridge.h +F: include/hw/s390x/ioinst.h +F: target/s390x/ioinst.c +L: qemu-s390x@nongnu.org + +S390 CPU models +M: David Hildenbrand +S: Maintained +F: target/s390x/cpu_features*.[ch] +F: target/s390x/cpu_models.[ch] +L: qemu-s390x@nongnu.org + +S390 SCLP-backed devices +M: Halil Pasic +M: Christian Borntraeger +S: Supported +F: include/hw/s390x/event-facility.h +F: include/hw/s390x/sclp.h +F: hw/char/sclp*.[hc] +F: hw/s390x/event-facility.c +F: hw/s390x/sclp*.c +L: qemu-s390x@nongnu.org + X86 Machines ------------ PC @@ -1970,6 +1990,7 @@ M: Halil Pasic S: Supported F: hw/s390x/virtio-ccw*.[hc] F: hw/s390x/vhost-vsock-ccw.c +F: hw/s390x/vhost-user-fs-ccw.c T: git https://gitlab.com/cohuck/qemu.git s390-next T: git https://github.com/borntraeger/qemu.git s390-next L: qemu-s390x@nongnu.org @@ -2308,6 +2329,48 @@ F: hw/timer/mips_gictimer.c F: include/hw/intc/mips_gic.h F: include/hw/timer/mips_gictimer.h +S390 3270 device +M: Halil Pasic +M: Christian Borntraeger +S: Odd fixes +F: include/hw/s390x/3270-ccw.h +F: hw/char/terminal3270.c +F: hw/s390x/3270-ccw.c +L: qemu-s390x@nongnu.org + +S390 diag 288 watchdog +M: Halil Pasic +M: Christian Borntraeger +S: Supported +F: hw/watchdog/wdt_diag288.c +F: include/hw/watchdog/wdt_diag288.h +L: qemu-s390x@nongnu.org + +S390 storage key device +M: Halil Pasic +M: Christian Borntraeger +S: Supported +F: hw/s390x/storage-keys.h +F: hw/390x/s390-skeys*.c +L: qemu-s390x@nongnu.org + +S390 storage attribute device +M: Halil Pasic +M: Christian Borntraeger +S: Supported +F: hw/s390x/storage-attributes.h +F: hw/s390/s390-stattrib*.c +L: qemu-s390x@nongnu.org + +S390 floating interrupt controller +M: Halil Pasic +M: Christian Borntraeger +M: David Hildenbrand +S: Supported +F: hw/intc/s390_flic*.c +F: include/hw/s390x/s390_flic.h +L: qemu-s390x@nongnu.org + Subsystems ---------- Overall Audio backends -- cgit v1.1 From 6a6d3dfd6ed57d624dbbef116c8328d70d49130f Mon Sep 17 00:00:00 2001 From: Eric Farman Date: Wed, 12 Jan 2022 17:40:44 +0100 Subject: MAINTAINERS: Add myself to s390 I/O areas After the recent restructuring, I'd like to volunteer to help in some of the s390 I/O areas. Built on "[PATCH RFC v2] MAINTAINERS: split out s390x sections" Signed-off-by: Eric Farman Acked-by: Christian Borntraeger Acked-by: Halil Pasic Message-Id: <20220112164044.2210508-1-farman@linux.ibm.com> Signed-off-by: Thomas Huth --- MAINTAINERS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 793d6ed..893a556 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1525,6 +1525,7 @@ S390 Machines S390 Virtio-ccw M: Halil Pasic M: Christian Borntraeger +M: Eric Farman S: Supported F: hw/s390x/ F: include/hw/s390x/ @@ -1555,6 +1556,7 @@ L: qemu-s390x@nongnu.org S390 channel subsystem M: Halil Pasic M: Christian Borntraeger +M: Eric Farman S: Supported F: hw/s390x/ccw-device.[ch] F: hw/s390x/css.c @@ -1987,6 +1989,7 @@ T: git https://github.com/stefanha/qemu.git block virtio-ccw M: Cornelia Huck M: Halil Pasic +M: Eric Farman S: Supported F: hw/s390x/virtio-ccw*.[hc] F: hw/s390x/vhost-vsock-ccw.c -- cgit v1.1 From b2173046a64beed76715f310f98538f159276af1 Mon Sep 17 00:00:00 2001 From: Marc Hartmayer Date: Mon, 22 Nov 2021 12:29:09 +0100 Subject: s390x/ipl: support extended kernel command line size In the past s390 used a fixed command line length of 896 bytes. This has changed with the Linux commit 5ecb2da660ab ("s390: support command lines longer than 896 bytes"). There is now a parm area indicating the maximum command line size. This parm area has always been initialized to zero, so with older kernels this field would read zero and we must then assume that only 896 bytes are available. Signed-off-by: Marc Hartmayer Reviewed-by: David Hildenbrand Reviewed-by: Christian Borntraeger Acked-by: Viktor Mihajlovski Message-Id: <20211122112909.18138-1-mhartmay@linux.ibm.com> [thuth: Cosmetic fixes, and use PRIu64 instead of %lu] Signed-off-by: Thomas Huth --- hw/s390x/ipl.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c index 7ddca01..eb7fc4c 100644 --- a/hw/s390x/ipl.c +++ b/hw/s390x/ipl.c @@ -37,8 +37,9 @@ #define KERN_IMAGE_START 0x010000UL #define LINUX_MAGIC_ADDR 0x010008UL +#define KERN_PARM_AREA_SIZE_ADDR 0x010430UL #define KERN_PARM_AREA 0x010480UL -#define KERN_PARM_AREA_SIZE 0x000380UL +#define LEGACY_KERN_PARM_AREA_SIZE 0x000380UL #define INITRD_START 0x800000UL #define INITRD_PARM_START 0x010408UL #define PARMFILE_START 0x001000UL @@ -110,6 +111,21 @@ static uint64_t bios_translate_addr(void *opaque, uint64_t srcaddr) return srcaddr + dstaddr; } +static uint64_t get_max_kernel_cmdline_size(void) +{ + uint64_t *size_ptr = rom_ptr(KERN_PARM_AREA_SIZE_ADDR, sizeof(*size_ptr)); + + if (size_ptr) { + uint64_t size; + + size = be64_to_cpu(*size_ptr); + if (size) { + return size; + } + } + return LEGACY_KERN_PARM_AREA_SIZE; +} + static void s390_ipl_realize(DeviceState *dev, Error **errp) { MachineState *ms = MACHINE(qdev_get_machine()); @@ -197,10 +213,13 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp) ipl->start_addr = KERN_IMAGE_START; /* Overwrite parameters in the kernel image, which are "rom" */ if (parm_area) { - if (cmdline_size > KERN_PARM_AREA_SIZE) { + uint64_t max_cmdline_size = get_max_kernel_cmdline_size(); + + if (cmdline_size > max_cmdline_size) { error_setg(errp, - "kernel command line exceeds maximum size: %zu > %lu", - cmdline_size, KERN_PARM_AREA_SIZE); + "kernel command line exceeds maximum size:" + " %zu > %" PRIu64, + cmdline_size, max_cmdline_size); return; } -- cgit v1.1 From 59b9b5186e44a90088a91ed7a7493b03027e4f1f Mon Sep 17 00:00:00 2001 From: Eric Farman Date: Mon, 13 Dec 2021 22:09:19 +0100 Subject: s390x: sigp: Reorder the SIGP STOP code Let's wait to mark the VCPU STOPPED until the possible STORE STATUS operation is completed, so that we know the CPU is fully stopped and done doing anything. (When we also clear the possible sigp_order field for STOP orders.) Suggested-by: David Hildenbrand Signed-off-by: Eric Farman Message-Id: <20211213210919.856693-2-farman@linux.ibm.com> Reviewed-by: David Hildenbrand Signed-off-by: Thomas Huth --- target/s390x/sigp.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/target/s390x/sigp.c b/target/s390x/sigp.c index 51c7278..9dd9773 100644 --- a/target/s390x/sigp.c +++ b/target/s390x/sigp.c @@ -139,7 +139,7 @@ static void sigp_stop_and_store_status(CPUState *cs, run_on_cpu_data arg) case S390_CPU_STATE_OPERATING: cpu->env.sigp_order = SIGP_STOP_STORE_STATUS; cpu_inject_stop(cpu); - /* store will be performed in do_stop_interrup() */ + /* store will be performed in do_stop_interrupt() */ break; case S390_CPU_STATE_STOPPED: /* already stopped, just store the status */ @@ -479,13 +479,17 @@ void do_stop_interrupt(CPUS390XState *env) { S390CPU *cpu = env_archcpu(env); - if (s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu) == 0) { - qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); - } + /* + * Complete the STOP operation before exposing the CPU as + * STOPPED to the system. + */ if (cpu->env.sigp_order == SIGP_STOP_STORE_STATUS) { s390_store_status(cpu, S390_STORE_STATUS_DEF_ADDR, true); } env->sigp_order = 0; + if (s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu) == 0) { + qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); + } env->pending_int &= ~INTERRUPT_STOP; } -- cgit v1.1