diff options
author | Stefan Hajnoczi <stefanha@redhat.com> | 2023-11-08 20:34:36 +0800 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2023-11-08 20:34:36 +0800 |
commit | 44ad47b75877e10a750adb17174539ddfeae3963 (patch) | |
tree | bb685924339d26f4f2f1d6f9186a56314161f719 | |
parent | ed1d873caa93fde443b14369309cdd4366d4ca08 (diff) | |
parent | 3e19fbc0c51a62d0c021e1ae768da0df64855927 (diff) | |
download | qemu-44ad47b75877e10a750adb17174539ddfeae3963.zip qemu-44ad47b75877e10a750adb17174539ddfeae3963.tar.gz qemu-44ad47b75877e10a750adb17174539ddfeae3963.tar.bz2 |
Merge tag 'pull-request-2023-11-07' of https://gitlab.com/thuth/qemu into staging
* Fix s390x CPU reconfiguration information in the SCLP facility map
* Fix condition code problem in the CLC and LAALG instruction
* Fix ordering of the new s390x topology list entries
* Add some more files to the MAINTAINERS file
* Allow newer versions of Tesseract in the m68k nextcube test
# -----BEGIN PGP SIGNATURE-----
#
# iQJFBAABCAAvFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmVKgksRHHRodXRoQHJl
# ZGhhdC5jb20ACgkQLtnXdP5wLbWIHg//TM3JOpsMEqHKlUKqOJH02mFQrK6H7LG0
# BC56FG7T+/mpYs1NTG92t8nCK03C2ZCweQWD7ZulRJAjPhZv+TF5bJEForivU7+k
# PKEshz9xKCWn2YGyNnf2LA06J1JkF215+KlReOoxwSgj1cPlHfBLQ0DtxmpJJZ1G
# h5p4d26BbSlwR58HrFWTlhgJMPenl59BETUGIK1FklBxunmZeeijddfniAhOT44y
# i0u9/H9KCg3tkwBROUy+42QV+ef32kz/yvi5RmYQI5W7PixO4sxH6MYduOjshsu9
# wK70f8EOwiZV6lFxqmbV7vxFeNnp5IuaVU7PMBoAkwZqLw99mSFy1+1BabCuL5b+
# 3iUTiD4UW48MYwE2Ua6Lit4kpfjhwcp/UYz6pIk6TCBQX6LfzO+nj+rod0GdIpyZ
# 4Lwm7jBtpTlYkGrsMvpA/qcidOtqPA1lmBTNlY1hFodQF6KWtyObn0w5AM80xeeU
# /mGxQDz97Bpz7LKZvhu+k38jaWvnJFnl3jF1zet88CYL9YL+YI/k1KjhFafCXb0V
# 38Xpt5JTWxyLSh2B3gx0OpokX5bftvW9GlLix0HqL7c23uYwR2Bq+Rd6I8SAlk4C
# uJq6gqP8IFBFHfgbmyqf/fyd/eHxm7J1voIdy9PZyxZ1JYT9A7yu56qV6SJYwCpr
# aARwui/Dm4o=
# =y+cC
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 08 Nov 2023 02:30:35 HKT
# gpg: using RSA key 27B88847EEE0250118F3EAB92ED9D774FE702DB5
# gpg: issuer "thuth@redhat.com"
# gpg: Good signature from "Thomas Huth <th.huth@gmx.de>" [full]
# gpg: aka "Thomas Huth <thuth@redhat.com>" [full]
# gpg: aka "Thomas Huth <huth@tuxfamily.org>" [full]
# gpg: aka "Thomas Huth <th.huth@posteo.de>" [unknown]
# Primary key fingerprint: 27B8 8847 EEE0 2501 18F3 EAB9 2ED9 D774 FE70 2DB5
* tag 'pull-request-2023-11-07' of https://gitlab.com/thuth/qemu:
target/s390x/cpu topology: Fix ordering and creation of TLEs
tests/tcg/s390x: Test ADD LOGICAL WITH CARRY
tests/tcg/s390x: Test LAALG with negative cc_src
target/s390x: Fix LAALG not updating cc_src
tests/tcg/s390x: Test CLC with inaccessible second operand
target/s390x: Fix CLC corrupting cc_src
target/s390x/cpu_models: Use 'first_cpu' in s390_get_feat_block()
s390/sclp: fix SCLP facility map
tests/avocado: Allow newer versions of tesseract in the nextcube test
MAINTAINERS: Add artist.c to the hppa machine section
MAINTAINERS: Add the virtio-gpu documentation to the corresponding section
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
-rw-r--r-- | MAINTAINERS | 2 | ||||
-rw-r--r-- | include/hw/s390x/sclp.h | 4 | ||||
-rw-r--r-- | target/s390x/cpu_models.c | 6 | ||||
-rw-r--r-- | target/s390x/kvm/stsi-topology.c | 8 | ||||
-rw-r--r-- | target/s390x/tcg/insn-data.h.inc | 2 | ||||
-rw-r--r-- | target/s390x/tcg/translate.c | 26 | ||||
-rw-r--r-- | tests/avocado/machine_m68k_nextcube.py | 15 | ||||
-rw-r--r-- | tests/avocado/tesseract_utils.py | 4 | ||||
-rw-r--r-- | tests/tcg/s390x/Makefile.target | 3 | ||||
-rw-r--r-- | tests/tcg/s390x/add-logical-with-carry.c | 156 | ||||
-rw-r--r-- | tests/tcg/s390x/clc.c | 48 | ||||
-rw-r--r-- | tests/tcg/s390x/laalg.c | 27 |
12 files changed, 271 insertions, 30 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index cb3ac62..934ab90 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1194,6 +1194,7 @@ M: Richard Henderson <richard.henderson@linaro.org> R: Helge Deller <deller@gmx.de> S: Odd Fixes F: configs/devices/hppa-softmmu/default.mak +F: hw/display/artist.c F: hw/hppa/ F: hw/input/lasips2.c F: hw/net/*i82596* @@ -2496,6 +2497,7 @@ S: Odd Fixes F: hw/display/virtio-gpu* F: hw/display/virtio-vga.* F: include/hw/virtio/virtio-gpu.h +F: docs/system/devices/virtio-gpu.rst vhost-user-blk M: Raphael Norwitz <raphael.norwitz@nutanix.com> diff --git a/include/hw/s390x/sclp.h b/include/hw/s390x/sclp.h index e229b81..b405a38 100644 --- a/include/hw/s390x/sclp.h +++ b/include/hw/s390x/sclp.h @@ -38,10 +38,8 @@ #define MAX_STORAGE_INCREMENTS 1020 /* CPU hotplug SCLP codes */ -#define SCLP_HAS_CPU_INFO 0x0C00000000000000ULL +#define SCLP_HAS_CPU_INFO 0x0800000000000000ULL #define SCLP_CMDW_READ_CPU_INFO 0x00010001 -#define SCLP_CMDW_CONFIGURE_CPU 0x00110001 -#define SCLP_CMDW_DECONFIGURE_CPU 0x00100001 /* SCLP PCI codes */ #define SCLP_HAS_IOA_RECONFIG 0x0000000040000000ULL diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c index 5c455d0..a63d990 100644 --- a/target/s390x/cpu_models.c +++ b/target/s390x/cpu_models.c @@ -196,11 +196,7 @@ uint32_t s390_get_ibc_val(void) void s390_get_feat_block(S390FeatType type, uint8_t *data) { - static S390CPU *cpu; - - if (!cpu) { - cpu = S390_CPU(qemu_get_cpu(0)); - } + S390CPU *cpu = S390_CPU(first_cpu); if (!cpu || !cpu->model) { return; diff --git a/target/s390x/kvm/stsi-topology.c b/target/s390x/kvm/stsi-topology.c index efd2aa7..c8d6389 100644 --- a/target/s390x/kvm/stsi-topology.c +++ b/target/s390x/kvm/stsi-topology.c @@ -210,6 +210,9 @@ static S390TopologyId s390_topology_from_cpu(S390CPU *cpu) static int s390_topology_id_cmp(const S390TopologyId *l, const S390TopologyId *r) { + int l_polarization = l->vertical ? l->entitlement : 0; + int r_polarization = r->vertical ? r->entitlement : 0; + /* * lexical order, compare less significant values only if more significant * ones are equal @@ -219,9 +222,8 @@ static int s390_topology_id_cmp(const S390TopologyId *l, l->book - r->book ?: l->socket - r->socket ?: l->type - r->type ?: - /* logic is inverted for the next three */ - r->vertical - l->vertical ?: - r->entitlement - l->entitlement ?: + /* logic is inverted for the next two */ + r_polarization - l_polarization ?: r->dedicated - l->dedicated ?: l->origin - r->origin; } diff --git a/target/s390x/tcg/insn-data.h.inc b/target/s390x/tcg/insn-data.h.inc index 0bfd88d..2f07f39 100644 --- a/target/s390x/tcg/insn-data.h.inc +++ b/target/s390x/tcg/insn-data.h.inc @@ -442,7 +442,7 @@ D(0xebe8, LAAG, RSY_a, ILA, r3, a2, new, in2_r1, laa, adds64, MO_TEUQ) /* LOAD AND ADD LOGICAL */ D(0xebfa, LAAL, RSY_a, ILA, r3_32u, a2, new, in2_r1_32, laa, addu32, MO_TEUL) - D(0xebea, LAALG, RSY_a, ILA, r3, a2, new, in2_r1, laa, addu64, MO_TEUQ) + D(0xebea, LAALG, RSY_a, ILA, r3, a2, new, in2_r1, laa_addu64, addu64, MO_TEUQ) /* LOAD AND AND */ D(0xebf4, LAN, RSY_a, ILA, r3_32s, a2, new, in2_r1_32, lan, nz32, MO_TESL) D(0xebe4, LANG, RSY_a, ILA, r3, a2, new, in2_r1, lan, nz64, MO_TEUQ) diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c index 4bae150..62ab2be 100644 --- a/target/s390x/tcg/translate.c +++ b/target/s390x/tcg/translate.c @@ -2007,6 +2007,7 @@ static DisasJumpType op_cksm(DisasContext *s, DisasOps *o) static DisasJumpType op_clc(DisasContext *s, DisasOps *o) { int l = get_field(s, l1); + TCGv_i64 src; TCGv_i32 vl; MemOp mop; @@ -2016,9 +2017,11 @@ static DisasJumpType op_clc(DisasContext *s, DisasOps *o) case 4: case 8: mop = ctz32(l + 1) | MO_TE; - tcg_gen_qemu_ld_tl(cc_src, o->addr1, get_mem_index(s), mop); + /* Do not update cc_src yet: loading cc_dst may cause an exception. */ + src = tcg_temp_new_i64(); + tcg_gen_qemu_ld_tl(src, o->addr1, get_mem_index(s), mop); tcg_gen_qemu_ld_tl(cc_dst, o->in2, get_mem_index(s), mop); - gen_op_update2_cc_i64(s, CC_OP_LTUGTU_64, cc_src, cc_dst); + gen_op_update2_cc_i64(s, CC_OP_LTUGTU_64, src, cc_dst); return DISAS_NEXT; default: vl = tcg_constant_i32(l); @@ -2674,17 +2677,32 @@ static DisasJumpType op_kxb(DisasContext *s, DisasOps *o) return DISAS_NEXT; } -static DisasJumpType op_laa(DisasContext *s, DisasOps *o) +static DisasJumpType help_laa(DisasContext *s, DisasOps *o, bool addu64) { /* The real output is indeed the original value in memory; recompute the addition for the computation of CC. */ tcg_gen_atomic_fetch_add_i64(o->in2, o->in2, o->in1, get_mem_index(s), s->insn->data | MO_ALIGN); /* However, we need to recompute the addition for setting CC. */ - tcg_gen_add_i64(o->out, o->in1, o->in2); + if (addu64) { + tcg_gen_movi_i64(cc_src, 0); + tcg_gen_add2_i64(o->out, cc_src, o->in1, cc_src, o->in2, cc_src); + } else { + tcg_gen_add_i64(o->out, o->in1, o->in2); + } return DISAS_NEXT; } +static DisasJumpType op_laa(DisasContext *s, DisasOps *o) +{ + return help_laa(s, o, false); +} + +static DisasJumpType op_laa_addu64(DisasContext *s, DisasOps *o) +{ + return help_laa(s, o, true); +} + static DisasJumpType op_lan(DisasContext *s, DisasOps *o) { /* The real output is indeed the original value in memory; diff --git a/tests/avocado/machine_m68k_nextcube.py b/tests/avocado/machine_m68k_nextcube.py index f1205d7..1f3c883 100644 --- a/tests/avocado/machine_m68k_nextcube.py +++ b/tests/avocado/machine_m68k_nextcube.py @@ -55,25 +55,16 @@ class NextCubeMachine(QemuSystemTest): self.assertEqual(width, 1120) self.assertEqual(height, 832) - @skipUnless(tesseract_available(3), 'tesseract v3 OCR tool not available') - def test_bootrom_framebuffer_ocr_with_tesseract_v3(self): - screenshot_path = os.path.join(self.workdir, "dump.ppm") - self.check_bootrom_framebuffer(screenshot_path) - lines = tesseract_ocr(screenshot_path, tesseract_version=3) - text = '\n'.join(lines) - self.assertIn('Backplane', text) - self.assertIn('Ethernet address', text) - # Tesseract 4 adds a new OCR engine based on LSTM neural networks. The # new version is faster and more accurate than version 3. The drawback is # that it is still alpha-level software. - @skipUnless(tesseract_available(4), 'tesseract v4 OCR tool not available') - def test_bootrom_framebuffer_ocr_with_tesseract_v4(self): + @skipUnless(tesseract_available(4), 'tesseract OCR tool not available') + def test_bootrom_framebuffer_ocr_with_tesseract(self): screenshot_path = os.path.join(self.workdir, "dump.ppm") self.check_bootrom_framebuffer(screenshot_path) lines = tesseract_ocr(screenshot_path, tesseract_version=4) text = '\n'.join(lines) - self.assertIn('Testing the FPU, SCC', text) + self.assertIn('Testing the FPU', text) self.assertIn('System test failed. Error code', text) self.assertIn('Boot command', text) self.assertIn('Next>', text) diff --git a/tests/avocado/tesseract_utils.py b/tests/avocado/tesseract_utils.py index 72cd9ab..476f528 100644 --- a/tests/avocado/tesseract_utils.py +++ b/tests/avocado/tesseract_utils.py @@ -21,13 +21,13 @@ def tesseract_available(expected_version): version = res.stdout_text.split()[1] except IndexError: version = res.stderr_text.split()[1] - return int(version.split('.')[0]) == expected_version + return int(version.split('.')[0]) >= expected_version match = re.match(r'tesseract\s(\d)', res) if match is None: return False # now this is guaranteed to be a digit - return int(match.groups()[0]) == expected_version + return int(match.groups()[0]) >= expected_version def tesseract_ocr(image_path, tesseract_args='', tesseract_version=3): diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target index 826f0a1..0e670f3 100644 --- a/tests/tcg/s390x/Makefile.target +++ b/tests/tcg/s390x/Makefile.target @@ -41,6 +41,9 @@ TESTS+=larl TESTS+=mdeb TESTS+=cgebra TESTS+=clgebr +TESTS+=clc +TESTS+=laalg +TESTS+=add-logical-with-carry cdsg: CFLAGS+=-pthread cdsg: LDFLAGS+=-pthread diff --git a/tests/tcg/s390x/add-logical-with-carry.c b/tests/tcg/s390x/add-logical-with-carry.c new file mode 100644 index 0000000..d982f8a --- /dev/null +++ b/tests/tcg/s390x/add-logical-with-carry.c @@ -0,0 +1,156 @@ +/* + * Test ADD LOGICAL WITH CARRY instructions. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#include <stdio.h> +#include <stdlib.h> + +static const struct test { + const char *name; + unsigned long values[3]; + unsigned long exp_sum; + int exp_cc; +} tests[] = { + /* + * Each test starts with CC 0 and executes two chained ADD LOGICAL WITH + * CARRY instructions on three input values. The values must be compatible + * with both 32- and 64-bit test functions. + */ + + /* NAME VALUES EXP_SUM EXP_CC */ + { "cc0->cc0", {0, 0, 0}, 0, 0, }, + { "cc0->cc1", {0, 0, 42}, 42, 1, }, + /* cc0->cc2 is not possible */ + /* cc0->cc3 is not possible */ + /* cc1->cc0 is not possible */ + { "cc1->cc1", {-3, 1, 1}, -1, 1, }, + { "cc1->cc2", {-3, 1, 2}, 0, 2, }, + { "cc1->cc3", {-3, 1, -1}, -3, 3, }, + /* cc2->cc0 is not possible */ + { "cc2->cc1", {-1, 1, 1}, 2, 1, }, + { "cc2->cc2", {-1, 1, -1}, 0, 2, }, + /* cc2->cc3 is not possible */ + /* cc3->cc0 is not possible */ + { "cc3->cc1", {-1, 2, 1}, 3, 1, }, + { "cc3->cc2", {-1, 2, -2}, 0, 2, }, + { "cc3->cc3", {-1, 2, -1}, 1, 3, }, +}; + +/* Test ALCR (register variant) followed by ALC (memory variant). */ +static unsigned long test32rm(unsigned long a, unsigned long b, + unsigned long c, int *cc) +{ + unsigned int a32 = a, b32 = b, c32 = c; + + asm("xr %[cc],%[cc]\n" + "alcr %[a],%[b]\n" + "alc %[a],%[c]\n" + "ipm %[cc]" + : [a] "+&r" (a32), [cc] "+&r" (*cc) + : [b] "r" (b32), [c] "T" (c32) + : "cc"); + *cc >>= 28; + + return (int)a32; +} + +/* Test ALC (memory variant) followed by ALCR (register variant). */ +static unsigned long test32mr(unsigned long a, unsigned long b, + unsigned long c, int *cc) +{ + unsigned int a32 = a, b32 = b, c32 = c; + + asm("xr %[cc],%[cc]\n" + "alc %[a],%[b]\n" + "alcr %[c],%[a]\n" + "ipm %[cc]" + : [a] "+&r" (a32), [c] "+&r" (c32), [cc] "+&r" (*cc) + : [b] "T" (b32) + : "cc"); + *cc >>= 28; + + return (int)c32; +} + +/* Test ALCGR (register variant) followed by ALCG (memory variant). */ +static unsigned long test64rm(unsigned long a, unsigned long b, + unsigned long c, int *cc) +{ + asm("xr %[cc],%[cc]\n" + "alcgr %[a],%[b]\n" + "alcg %[a],%[c]\n" + "ipm %[cc]" + : [a] "+&r" (a), [cc] "+&r" (*cc) + : [b] "r" (b), [c] "T" (c) + : "cc"); + *cc >>= 28; + return a; +} + +/* Test ALCG (memory variant) followed by ALCGR (register variant). */ +static unsigned long test64mr(unsigned long a, unsigned long b, + unsigned long c, int *cc) +{ + asm("xr %[cc],%[cc]\n" + "alcg %[a],%[b]\n" + "alcgr %[c],%[a]\n" + "ipm %[cc]" + : [a] "+&r" (a), [c] "+&r" (c), [cc] "+&r" (*cc) + : [b] "T" (b) + : "cc"); + *cc >>= 28; + return c; +} + +static const struct test_func { + const char *name; + unsigned long (*ptr)(unsigned long, unsigned long, unsigned long, int *); +} test_funcs[] = { + { "test32rm", test32rm }, + { "test32mr", test32mr }, + { "test64rm", test64rm }, + { "test64mr", test64mr }, +}; + +static const struct test_perm { + const char *name; + size_t a_idx, b_idx, c_idx; +} test_perms[] = { + { "a, b, c", 0, 1, 2 }, + { "b, a, c", 1, 0, 2 }, +}; + +int main(void) +{ + unsigned long a, b, c, sum; + int result = EXIT_SUCCESS; + const struct test_func *f; + const struct test_perm *p; + size_t i, j, k; + const struct test *t; + int cc; + + for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { + t = &tests[i]; + for (j = 0; j < sizeof(test_funcs) / sizeof(test_funcs[0]); j++) { + f = &test_funcs[j]; + for (k = 0; k < sizeof(test_perms) / sizeof(test_perms[0]); k++) { + p = &test_perms[k]; + a = t->values[p->a_idx]; + b = t->values[p->b_idx]; + c = t->values[p->c_idx]; + sum = f->ptr(a, b, c, &cc); + if (sum != t->exp_sum || cc != t->exp_cc) { + fprintf(stderr, + "[ FAILED ] %s %s(0x%lx, 0x%lx, 0x%lx) returned 0x%lx cc %d, expected 0x%lx cc %d\n", + t->name, f->name, a, b, c, sum, cc, + t->exp_sum, t->exp_cc); + result = EXIT_FAILURE; + } + } + } + } + + return result; +} diff --git a/tests/tcg/s390x/clc.c b/tests/tcg/s390x/clc.c new file mode 100644 index 0000000..e14189b --- /dev/null +++ b/tests/tcg/s390x/clc.c @@ -0,0 +1,48 @@ +/* + * Test the CLC instruction. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#include <assert.h> +#include <signal.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +static void handle_sigsegv(int sig, siginfo_t *info, void *ucontext) +{ + mcontext_t *mcontext = &((ucontext_t *)ucontext)->uc_mcontext; + if (mcontext->gregs[0] != 600) { + write(STDERR_FILENO, "bad r0\n", 7); + _exit(EXIT_FAILURE); + } + if (((mcontext->psw.mask >> 44) & 3) != 1) { + write(STDERR_FILENO, "bad cc\n", 7); + _exit(EXIT_FAILURE); + } + _exit(EXIT_SUCCESS); +} + +int main(void) +{ + register unsigned long r0 asm("r0"); + unsigned long mem = 42, rhs = 500; + struct sigaction act; + int err; + + memset(&act, 0, sizeof(act)); + act.sa_sigaction = handle_sigsegv; + act.sa_flags = SA_SIGINFO; + err = sigaction(SIGSEGV, &act, NULL); + assert(err == 0); + + r0 = 100; + asm("algr %[r0],%[rhs]\n" + "clc 0(8,%[mem]),0(0)\n" /* The 2nd operand will cause a SEGV. */ + : [r0] "+r" (r0) + : [mem] "r" (&mem) + , [rhs] "r" (rhs) + : "cc", "memory"); + + return EXIT_FAILURE; +} diff --git a/tests/tcg/s390x/laalg.c b/tests/tcg/s390x/laalg.c new file mode 100644 index 0000000..797d168 --- /dev/null +++ b/tests/tcg/s390x/laalg.c @@ -0,0 +1,27 @@ +/* + * Test the LAALG instruction. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#include <assert.h> +#include <stdlib.h> + +int main(void) +{ + unsigned long cc = 0, op1, op2 = 40, op3 = 2; + + asm("slgfi %[cc],1\n" /* Set cc_src = -1. */ + "laalg %[op1],%[op3],%[op2]\n" + "ipm %[cc]" + : [cc] "+r" (cc) + , [op1] "=r" (op1) + , [op2] "+T" (op2) + : [op3] "r" (op3) + : "cc"); + + assert(cc == 0xffffffff10ffffff); + assert(op1 == 40); + assert(op2 == 42); + + return EXIT_SUCCESS; +} |