In particular, the i386 patches fix an issue that was newly introduced in 7.2.10 and the LSI patches improve the reentrancy fix. The others also sounded relevant and nice to have.
Signed-off-by: Fiona Ebner <f.eb...@proxmox.com> --- ...lign-exposed-ID-registers-with-Linux.patch | 273 ++++++++++++++++++ ...4-sysregs.c-Use-S-syntax-for-id_aa64.patch | 91 ++++++ ...arget-arm-Fix-SME-full-tile-indexing.patch | 199 +++++++++++++ ...tor-move-drain_call_rcu-call-under-i.patch | 61 ++++ ...3c895a-stop-script-on-phase-mismatch.patch | 85 ++++++ ...5a-add-missing-decrement-of-reentran.patch | 38 +++ ...895a-add-timer-to-scripts-processing.patch | 173 +++++++++++ ...0012-e1000e-fix-link-state-on-resume.patch | 161 +++++++++++ ...roduce-function-to-query-MMU-indices.patch | 61 ++++ ...separate-MMU-indexes-for-32-bit-acce.patch | 130 +++++++++ ...386-fix-direction-of-32-bit-MMU-test.patch | 46 +++ ...rt-monitor_puts-in-do_inject_x86_mce.patch | 35 +++ ...ix-sign_mask-for-logical-right-shift.patch | 86 ++++++ ...-Fix-packed-virtqueue-flush-used_idx.patch | 66 +++++ ...he-CPU-model-to-kvm64-32-instead-of-.patch | 2 +- debian/patches/series | 14 + 16 files changed, 1520 insertions(+), 1 deletion(-) create mode 100644 debian/patches/extra/0005-target-arm-align-exposed-ID-registers-with-Linux.patch create mode 100644 debian/patches/extra/0006-tests-tcg-aarch64-sysregs.c-Use-S-syntax-for-id_aa64.patch create mode 100644 debian/patches/extra/0007-target-arm-Fix-SME-full-tile-indexing.patch create mode 100644 debian/patches/extra/0008-system-qdev-monitor-move-drain_call_rcu-call-under-i.patch create mode 100644 debian/patches/extra/0009-hw-scsi-lsi53c895a-stop-script-on-phase-mismatch.patch create mode 100644 debian/patches/extra/0010-hw-scsi-lsi53c895a-add-missing-decrement-of-reentran.patch create mode 100644 debian/patches/extra/0011-hw-scsi-lsi53c895a-add-timer-to-scripts-processing.patch create mode 100644 debian/patches/extra/0012-e1000e-fix-link-state-on-resume.patch create mode 100644 debian/patches/extra/0013-target-i386-introduce-function-to-query-MMU-indices.patch create mode 100644 debian/patches/extra/0014-target-i386-use-separate-MMU-indexes-for-32-bit-acce.patch create mode 100644 debian/patches/extra/0015-target-i386-fix-direction-of-32-bit-MMU-test.patch create mode 100644 debian/patches/extra/0016-target-i386-Revert-monitor_puts-in-do_inject_x86_mce.patch create mode 100644 debian/patches/extra/0017-tcg-optimize-Fix-sign_mask-for-logical-right-shift.patch create mode 100644 debian/patches/extra/0018-hw-virtio-Fix-packed-virtqueue-flush-used_idx.patch diff --git a/debian/patches/extra/0005-target-arm-align-exposed-ID-registers-with-Linux.patch b/debian/patches/extra/0005-target-arm-align-exposed-ID-registers-with-Linux.patch new file mode 100644 index 0000000..bf17182 --- /dev/null +++ b/debian/patches/extra/0005-target-arm-align-exposed-ID-registers-with-Linux.patch @@ -0,0 +1,273 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Zhuojia Shen <chaosdefinit...@hotmail.com> +Date: Wed, 10 Apr 2024 08:43:24 +0300 +Subject: [PATCH] target/arm: align exposed ID registers with Linux + +In CPUID registers exposed to userspace, some registers were missing +and some fields were not exposed. This patch aligns exposed ID +registers and their fields with what the upstream kernel currently +exposes. + +Specifically, the following new ID registers/fields are exposed to +userspace: + +ID_AA64PFR1_EL1.BT: bits 3-0 +ID_AA64PFR1_EL1.MTE: bits 11-8 +ID_AA64PFR1_EL1.SME: bits 27-24 + +ID_AA64ZFR0_EL1.SVEver: bits 3-0 +ID_AA64ZFR0_EL1.AES: bits 7-4 +ID_AA64ZFR0_EL1.BitPerm: bits 19-16 +ID_AA64ZFR0_EL1.BF16: bits 23-20 +ID_AA64ZFR0_EL1.SHA3: bits 35-32 +ID_AA64ZFR0_EL1.SM4: bits 43-40 +ID_AA64ZFR0_EL1.I8MM: bits 47-44 +ID_AA64ZFR0_EL1.F32MM: bits 55-52 +ID_AA64ZFR0_EL1.F64MM: bits 59-56 + +ID_AA64SMFR0_EL1.F32F32: bit 32 +ID_AA64SMFR0_EL1.B16F32: bit 34 +ID_AA64SMFR0_EL1.F16F32: bit 35 +ID_AA64SMFR0_EL1.I8I32: bits 39-36 +ID_AA64SMFR0_EL1.F64F64: bit 48 +ID_AA64SMFR0_EL1.I16I64: bits 55-52 +ID_AA64SMFR0_EL1.FA64: bit 63 + +ID_AA64MMFR0_EL1.ECV: bits 63-60 + +ID_AA64MMFR1_EL1.AFP: bits 47-44 + +ID_AA64MMFR2_EL1.AT: bits 35-32 + +ID_AA64ISAR0_EL1.RNDR: bits 63-60 + +ID_AA64ISAR1_EL1.FRINTTS: bits 35-32 +ID_AA64ISAR1_EL1.BF16: bits 47-44 +ID_AA64ISAR1_EL1.DGH: bits 51-48 +ID_AA64ISAR1_EL1.I8MM: bits 55-52 + +ID_AA64ISAR2_EL1.WFxT: bits 3-0 +ID_AA64ISAR2_EL1.RPRES: bits 7-4 +ID_AA64ISAR2_EL1.GPA3: bits 11-8 +ID_AA64ISAR2_EL1.APA3: bits 15-12 + +The code is also refactored to use symbolic names for ID register fields +for better readability and maintainability. + +The test case in tests/tcg/aarch64/sysregs.c is also updated to match +the intended behavior. + +Signed-off-by: Zhuojia Shen <chaosdefinit...@hotmail.com> +Message-id: ds7pr12mb6309fb585e10772928f14271ac...@ds7pr12mb6309.namprd12.prod.outlook.com +Reviewed-by: Peter Maydell <peter.mayd...@linaro.org> +[PMM: use Sn_n_Cn_Cn_n syntax to work with older assemblers +that don't recognize id_aa64isar2_el1 and id_aa64mmfr2_el1] +Signed-off-by: Peter Maydell <peter.mayd...@linaro.org> +(cherry picked from commit bc6bd20ee3538347afb750c4bd06edca4a922897) +Signed-off-by: Michael Tokarev <m...@tls.msk.ru> +(Mjt: pick this for v8.0.0-2361-g1f51573f79 + "target/arm: Fix SME full tile indexing") +--- + target/arm/helper.c | 96 +++++++++++++++++++++++++------ + tests/tcg/aarch64/Makefile.target | 7 ++- + tests/tcg/aarch64/sysregs.c | 24 ++++++-- + 3 files changed, 103 insertions(+), 24 deletions(-) + +diff --git a/target/arm/helper.c b/target/arm/helper.c +index 2e284e048c..acc0470e86 100644 +--- a/target/arm/helper.c ++++ b/target/arm/helper.c +@@ -7852,31 +7852,89 @@ void register_cp_regs_for_features(ARMCPU *cpu) + #ifdef CONFIG_USER_ONLY + static const ARMCPRegUserSpaceInfo v8_user_idregs[] = { + { .name = "ID_AA64PFR0_EL1", +- .exported_bits = 0x000f000f00ff0000, +- .fixed_bits = 0x0000000000000011 }, ++ .exported_bits = R_ID_AA64PFR0_FP_MASK | ++ R_ID_AA64PFR0_ADVSIMD_MASK | ++ R_ID_AA64PFR0_SVE_MASK | ++ R_ID_AA64PFR0_DIT_MASK, ++ .fixed_bits = (0x1u << R_ID_AA64PFR0_EL0_SHIFT) | ++ (0x1u << R_ID_AA64PFR0_EL1_SHIFT) }, + { .name = "ID_AA64PFR1_EL1", +- .exported_bits = 0x00000000000000f0 }, ++ .exported_bits = R_ID_AA64PFR1_BT_MASK | ++ R_ID_AA64PFR1_SSBS_MASK | ++ R_ID_AA64PFR1_MTE_MASK | ++ R_ID_AA64PFR1_SME_MASK }, + { .name = "ID_AA64PFR*_EL1_RESERVED", +- .is_glob = true }, +- { .name = "ID_AA64ZFR0_EL1" }, ++ .is_glob = true }, ++ { .name = "ID_AA64ZFR0_EL1", ++ .exported_bits = R_ID_AA64ZFR0_SVEVER_MASK | ++ R_ID_AA64ZFR0_AES_MASK | ++ R_ID_AA64ZFR0_BITPERM_MASK | ++ R_ID_AA64ZFR0_BFLOAT16_MASK | ++ R_ID_AA64ZFR0_SHA3_MASK | ++ R_ID_AA64ZFR0_SM4_MASK | ++ R_ID_AA64ZFR0_I8MM_MASK | ++ R_ID_AA64ZFR0_F32MM_MASK | ++ R_ID_AA64ZFR0_F64MM_MASK }, ++ { .name = "ID_AA64SMFR0_EL1", ++ .exported_bits = R_ID_AA64SMFR0_F32F32_MASK | ++ R_ID_AA64SMFR0_B16F32_MASK | ++ R_ID_AA64SMFR0_F16F32_MASK | ++ R_ID_AA64SMFR0_I8I32_MASK | ++ R_ID_AA64SMFR0_F64F64_MASK | ++ R_ID_AA64SMFR0_I16I64_MASK | ++ R_ID_AA64SMFR0_FA64_MASK }, + { .name = "ID_AA64MMFR0_EL1", +- .fixed_bits = 0x00000000ff000000 }, +- { .name = "ID_AA64MMFR1_EL1" }, ++ .exported_bits = R_ID_AA64MMFR0_ECV_MASK, ++ .fixed_bits = (0xfu << R_ID_AA64MMFR0_TGRAN64_SHIFT) | ++ (0xfu << R_ID_AA64MMFR0_TGRAN4_SHIFT) }, ++ { .name = "ID_AA64MMFR1_EL1", ++ .exported_bits = R_ID_AA64MMFR1_AFP_MASK }, ++ { .name = "ID_AA64MMFR2_EL1", ++ .exported_bits = R_ID_AA64MMFR2_AT_MASK }, + { .name = "ID_AA64MMFR*_EL1_RESERVED", +- .is_glob = true }, ++ .is_glob = true }, + { .name = "ID_AA64DFR0_EL1", +- .fixed_bits = 0x0000000000000006 }, +- { .name = "ID_AA64DFR1_EL1" }, ++ .fixed_bits = (0x6u << R_ID_AA64DFR0_DEBUGVER_SHIFT) }, ++ { .name = "ID_AA64DFR1_EL1" }, + { .name = "ID_AA64DFR*_EL1_RESERVED", +- .is_glob = true }, ++ .is_glob = true }, + { .name = "ID_AA64AFR*", +- .is_glob = true }, ++ .is_glob = true }, + { .name = "ID_AA64ISAR0_EL1", +- .exported_bits = 0x00fffffff0fffff0 }, ++ .exported_bits = R_ID_AA64ISAR0_AES_MASK | ++ R_ID_AA64ISAR0_SHA1_MASK | ++ R_ID_AA64ISAR0_SHA2_MASK | ++ R_ID_AA64ISAR0_CRC32_MASK | ++ R_ID_AA64ISAR0_ATOMIC_MASK | ++ R_ID_AA64ISAR0_RDM_MASK | ++ R_ID_AA64ISAR0_SHA3_MASK | ++ R_ID_AA64ISAR0_SM3_MASK | ++ R_ID_AA64ISAR0_SM4_MASK | ++ R_ID_AA64ISAR0_DP_MASK | ++ R_ID_AA64ISAR0_FHM_MASK | ++ R_ID_AA64ISAR0_TS_MASK | ++ R_ID_AA64ISAR0_RNDR_MASK }, + { .name = "ID_AA64ISAR1_EL1", +- .exported_bits = 0x000000f0ffffffff }, ++ .exported_bits = R_ID_AA64ISAR1_DPB_MASK | ++ R_ID_AA64ISAR1_APA_MASK | ++ R_ID_AA64ISAR1_API_MASK | ++ R_ID_AA64ISAR1_JSCVT_MASK | ++ R_ID_AA64ISAR1_FCMA_MASK | ++ R_ID_AA64ISAR1_LRCPC_MASK | ++ R_ID_AA64ISAR1_GPA_MASK | ++ R_ID_AA64ISAR1_GPI_MASK | ++ R_ID_AA64ISAR1_FRINTTS_MASK | ++ R_ID_AA64ISAR1_SB_MASK | ++ R_ID_AA64ISAR1_BF16_MASK | ++ R_ID_AA64ISAR1_DGH_MASK | ++ R_ID_AA64ISAR1_I8MM_MASK }, ++ { .name = "ID_AA64ISAR2_EL1", ++ .exported_bits = R_ID_AA64ISAR2_WFXT_MASK | ++ R_ID_AA64ISAR2_RPRES_MASK | ++ R_ID_AA64ISAR2_GPA3_MASK | ++ R_ID_AA64ISAR2_APA3_MASK }, + { .name = "ID_AA64ISAR*_EL1_RESERVED", +- .is_glob = true }, ++ .is_glob = true }, + }; + modify_arm_cp_regs(v8_idregs, v8_user_idregs); + #endif +@@ -8194,8 +8252,12 @@ void register_cp_regs_for_features(ARMCPU *cpu) + #ifdef CONFIG_USER_ONLY + static const ARMCPRegUserSpaceInfo id_v8_user_midr_cp_reginfo[] = { + { .name = "MIDR_EL1", +- .exported_bits = 0x00000000ffffffff }, +- { .name = "REVIDR_EL1" }, ++ .exported_bits = R_MIDR_EL1_REVISION_MASK | ++ R_MIDR_EL1_PARTNUM_MASK | ++ R_MIDR_EL1_ARCHITECTURE_MASK | ++ R_MIDR_EL1_VARIANT_MASK | ++ R_MIDR_EL1_IMPLEMENTER_MASK }, ++ { .name = "REVIDR_EL1" }, + }; + modify_arm_cp_regs(id_v8_midr_cp_reginfo, id_v8_user_midr_cp_reginfo); + #endif +diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target +index a72578fccb..fc6d5d824d 100644 +--- a/tests/tcg/aarch64/Makefile.target ++++ b/tests/tcg/aarch64/Makefile.target +@@ -23,7 +23,8 @@ config-cc.mak: Makefile + $(call cc-option,-march=armv8.1-a+sve2, CROSS_CC_HAS_SVE2); \ + $(call cc-option,-march=armv8.3-a, CROSS_CC_HAS_ARMV8_3); \ + $(call cc-option,-mbranch-protection=standard, CROSS_CC_HAS_ARMV8_BTI); \ +- $(call cc-option,-march=armv8.5-a+memtag, CROSS_CC_HAS_ARMV8_MTE)) 3> config-cc.mak ++ $(call cc-option,-march=armv8.5-a+memtag, CROSS_CC_HAS_ARMV8_MTE); \ ++ $(call cc-option,-march=armv9-a+sme, CROSS_CC_HAS_ARMV9_SME)) 3> config-cc.mak + -include config-cc.mak + + # Pauth Tests +@@ -53,7 +54,11 @@ endif + ifneq ($(CROSS_CC_HAS_SVE),) + # System Registers Tests + AARCH64_TESTS += sysregs ++ifneq ($(CROSS_CC_HAS_ARMV9_SME),) ++sysregs: CFLAGS+=-march=armv9-a+sme -DHAS_ARMV9_SME ++else + sysregs: CFLAGS+=-march=armv8.1-a+sve ++endif + + # SVE ioctl test + AARCH64_TESTS += sve-ioctls +diff --git a/tests/tcg/aarch64/sysregs.c b/tests/tcg/aarch64/sysregs.c +index 40cf8d2877..46b931f781 100644 +--- a/tests/tcg/aarch64/sysregs.c ++++ b/tests/tcg/aarch64/sysregs.c +@@ -22,6 +22,13 @@ + #define HWCAP_CPUID (1 << 11) + #endif + ++/* ++ * Older assemblers don't recognize newer system register names, ++ * but we can still access them by the Sn_n_Cn_Cn_n syntax. ++ */ ++#define SYS_ID_AA64ISAR2_EL1 S3_0_C0_C6_2 ++#define SYS_ID_AA64MMFR2_EL1 S3_0_C0_C7_2 ++ + int failed_bit_count; + + /* Read and print system register `id' value */ +@@ -112,18 +119,23 @@ int main(void) + * minimum valid fields - for the purposes of this check allowed + * to have non-zero values. + */ +- get_cpu_reg_check_mask(id_aa64isar0_el1, _m(00ff,ffff,f0ff,fff0)); +- get_cpu_reg_check_mask(id_aa64isar1_el1, _m(0000,00f0,ffff,ffff)); ++ get_cpu_reg_check_mask(id_aa64isar0_el1, _m(f0ff,ffff,f0ff,fff0)); ++ get_cpu_reg_check_mask(id_aa64isar1_el1, _m(00ff,f0ff,ffff,ffff)); ++ get_cpu_reg_check_mask(SYS_ID_AA64ISAR2_EL1, _m(0000,0000,0000,ffff)); + /* TGran4 & TGran64 as pegged to -1 */ +- get_cpu_reg_check_mask(id_aa64mmfr0_el1, _m(0000,0000,ff00,0000)); +- get_cpu_reg_check_zero(id_aa64mmfr1_el1); ++ get_cpu_reg_check_mask(id_aa64mmfr0_el1, _m(f000,0000,ff00,0000)); ++ get_cpu_reg_check_mask(id_aa64mmfr1_el1, _m(0000,f000,0000,0000)); ++ get_cpu_reg_check_mask(SYS_ID_AA64MMFR2_EL1, _m(0000,000f,0000,0000)); + /* EL1/EL0 reported as AA64 only */ + get_cpu_reg_check_mask(id_aa64pfr0_el1, _m(000f,000f,00ff,0011)); +- get_cpu_reg_check_mask(id_aa64pfr1_el1, _m(0000,0000,0000,00f0)); ++ get_cpu_reg_check_mask(id_aa64pfr1_el1, _m(0000,0000,0f00,0fff)); + /* all hidden, DebugVer fixed to 0x6 (ARMv8 debug architecture) */ + get_cpu_reg_check_mask(id_aa64dfr0_el1, _m(0000,0000,0000,0006)); + get_cpu_reg_check_zero(id_aa64dfr1_el1); +- get_cpu_reg_check_zero(id_aa64zfr0_el1); ++ get_cpu_reg_check_mask(id_aa64zfr0_el1, _m(0ff0,ff0f,00ff,00ff)); ++#ifdef HAS_ARMV9_SME ++ get_cpu_reg_check_mask(id_aa64smfr0_el1, _m(80f1,00fd,0000,0000)); ++#endif + + get_cpu_reg_check_zero(id_aa64afr0_el1); + get_cpu_reg_check_zero(id_aa64afr1_el1); diff --git a/debian/patches/extra/0006-tests-tcg-aarch64-sysregs.c-Use-S-syntax-for-id_aa64.patch b/debian/patches/extra/0006-tests-tcg-aarch64-sysregs.c-Use-S-syntax-for-id_aa64.patch new file mode 100644 index 0000000..b7b82bd --- /dev/null +++ b/debian/patches/extra/0006-tests-tcg-aarch64-sysregs.c-Use-S-syntax-for-id_aa64.patch @@ -0,0 +1,91 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Maydell <peter.mayd...@linaro.org> +Date: Wed, 10 Apr 2024 08:43:25 +0300 +Subject: [PATCH] tests/tcg/aarch64/sysregs.c: Use S syntax for id_aa64zfr0_el1 + and id_aa64smfr0_el1 + +Some assemblers will complain about attempts to access +id_aa64zfr0_el1 and id_aa64smfr0_el1 by name if the test +binary isn't built for the right processor type: + + /tmp/ccASXpLo.s:782: Error: selected processor does not support system register name 'id_aa64zfr0_el1' + /tmp/ccASXpLo.s:829: Error: selected processor does not support system register name 'id_aa64smfr0_el1' + +However, these registers are in the ID space and are guaranteed to +read-as-zero on older CPUs, so the access is both safe and sensible. +Switch to using the S syntax, as we already do for ID_AA64ISAR2_EL1 +and ID_AA64MMFR2_EL1. This allows us to drop the HAS_ARMV9_SME check +and the makefile machinery to adjust the CFLAGS for this test, so we +don't rely on having a sufficiently new compiler to be able to check +these registers. + +This means we're actually testing the SME ID register: no released +GCC yet recognizes -march=armv9-a+sme, so that was always skipped. +It also avoids a future problem if we try to switch the "do we have +SME support in the toolchain" check from "in the compiler" to "in the +assembler" (at which point we would otherwise run into the above +errors). + +Signed-off-by: Peter Maydell <peter.mayd...@linaro.org> +(cherry picked from commit 3dc2afeab2964b54848715b913b6c605f36be3e1) +Signed-off-by: Michael Tokarev <m...@tls.msk.ru> +(Mjt: pick this for v8.0.0-2361-g1f51573f79 + "target/arm: Fix SME full tile indexing") +--- + tests/tcg/aarch64/Makefile.target | 7 +------ + tests/tcg/aarch64/sysregs.c | 11 +++++++---- + 2 files changed, 8 insertions(+), 10 deletions(-) + +diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target +index fc6d5d824d..118d069073 100644 +--- a/tests/tcg/aarch64/Makefile.target ++++ b/tests/tcg/aarch64/Makefile.target +@@ -51,15 +51,10 @@ AARCH64_TESTS += mte-1 mte-2 mte-3 mte-4 mte-5 mte-6 mte-7 + mte-%: CFLAGS += -march=armv8.5-a+memtag + endif + +-ifneq ($(CROSS_CC_HAS_SVE),) + # System Registers Tests + AARCH64_TESTS += sysregs +-ifneq ($(CROSS_CC_HAS_ARMV9_SME),) +-sysregs: CFLAGS+=-march=armv9-a+sme -DHAS_ARMV9_SME +-else +-sysregs: CFLAGS+=-march=armv8.1-a+sve +-endif + ++ifneq ($(CROSS_CC_HAS_SVE),) + # SVE ioctl test + AARCH64_TESTS += sve-ioctls + sve-ioctls: CFLAGS+=-march=armv8.1-a+sve +diff --git a/tests/tcg/aarch64/sysregs.c b/tests/tcg/aarch64/sysregs.c +index 46b931f781..d8eb06abcf 100644 +--- a/tests/tcg/aarch64/sysregs.c ++++ b/tests/tcg/aarch64/sysregs.c +@@ -25,9 +25,14 @@ + /* + * Older assemblers don't recognize newer system register names, + * but we can still access them by the Sn_n_Cn_Cn_n syntax. ++ * This also means we don't need to specifically request that the ++ * assembler enables whatever architectural features the ID registers ++ * syntax might be gated behind. + */ + #define SYS_ID_AA64ISAR2_EL1 S3_0_C0_C6_2 + #define SYS_ID_AA64MMFR2_EL1 S3_0_C0_C7_2 ++#define SYS_ID_AA64ZFR0_EL1 S3_0_C0_C4_4 ++#define SYS_ID_AA64SMFR0_EL1 S3_0_C0_C4_5 + + int failed_bit_count; + +@@ -132,10 +137,8 @@ int main(void) + /* all hidden, DebugVer fixed to 0x6 (ARMv8 debug architecture) */ + get_cpu_reg_check_mask(id_aa64dfr0_el1, _m(0000,0000,0000,0006)); + get_cpu_reg_check_zero(id_aa64dfr1_el1); +- get_cpu_reg_check_mask(id_aa64zfr0_el1, _m(0ff0,ff0f,00ff,00ff)); +-#ifdef HAS_ARMV9_SME +- get_cpu_reg_check_mask(id_aa64smfr0_el1, _m(80f1,00fd,0000,0000)); +-#endif ++ get_cpu_reg_check_mask(SYS_ID_AA64ZFR0_EL1, _m(0ff0,ff0f,00ff,00ff)); ++ get_cpu_reg_check_mask(SYS_ID_AA64SMFR0_EL1, _m(80f1,00fd,0000,0000)); + + get_cpu_reg_check_zero(id_aa64afr0_el1); + get_cpu_reg_check_zero(id_aa64afr1_el1); diff --git a/debian/patches/extra/0007-target-arm-Fix-SME-full-tile-indexing.patch b/debian/patches/extra/0007-target-arm-Fix-SME-full-tile-indexing.patch new file mode 100644 index 0000000..228d794 --- /dev/null +++ b/debian/patches/extra/0007-target-arm-Fix-SME-full-tile-indexing.patch @@ -0,0 +1,199 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Richard Henderson <richard.hender...@linaro.org> +Date: Wed, 10 Apr 2024 08:43:26 +0300 +Subject: [PATCH] target/arm: Fix SME full tile indexing + +For the outer product set of insns, which take an entire matrix +tile as output, the argument is not a combined tile+column. +Therefore using get_tile_rowcol was incorrect, as we extracted +the tile number from itself. + +The test case relies only on assembler support for SME, since +no release of GCC recognizes -march=armv9-a+sme yet. + +Cc: qemu-sta...@nongnu.org +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1620 +Signed-off-by: Richard Henderson <richard.hender...@linaro.org> +Message-id: 20230622151201.1578522-5-richard.hender...@linaro.org +Reviewed-by: Peter Maydell <peter.mayd...@linaro.org> +[PMM: dropped now-unneeded changes to sysregs CFLAGS] +Signed-off-by: Peter Maydell <peter.mayd...@linaro.org> +(cherry picked from commit 1f51573f7925b80e79a29f87c7d9d6ead60960c0) +Signed-off-by: Michael Tokarev <m...@tls.msk.ru> +--- + target/arm/translate-sme.c | 24 ++++++--- + tests/tcg/aarch64/Makefile.target | 7 ++- + tests/tcg/aarch64/sme-outprod1.c | 83 +++++++++++++++++++++++++++++++ + 3 files changed, 107 insertions(+), 7 deletions(-) + create mode 100644 tests/tcg/aarch64/sme-outprod1.c + +diff --git a/target/arm/translate-sme.c b/target/arm/translate-sme.c +index 7b87a9df63..65f8495bdd 100644 +--- a/target/arm/translate-sme.c ++++ b/target/arm/translate-sme.c +@@ -103,6 +103,21 @@ static TCGv_ptr get_tile_rowcol(DisasContext *s, int esz, int rs, + return addr; + } + ++/* ++ * Resolve tile.size[0] to a host pointer. ++ * Used by e.g. outer product insns where we require the entire tile. ++ */ ++static TCGv_ptr get_tile(DisasContext *s, int esz, int tile) ++{ ++ TCGv_ptr addr = tcg_temp_new_ptr(); ++ int offset; ++ ++ offset = tile * sizeof(ARMVectorReg) + offsetof(CPUARMState, zarray); ++ ++ tcg_gen_addi_ptr(addr, cpu_env, offset); ++ return addr; ++} ++ + static bool trans_ZERO(DisasContext *s, arg_ZERO *a) + { + if (!dc_isar_feature(aa64_sme, s)) { +@@ -279,8 +294,7 @@ static bool do_adda(DisasContext *s, arg_adda *a, MemOp esz, + return true; + } + +- /* Sum XZR+zad to find ZAd. */ +- za = get_tile_rowcol(s, esz, 31, a->zad, false); ++ za = get_tile(s, esz, a->zad); + zn = vec_full_reg_ptr(s, a->zn); + pn = pred_full_reg_ptr(s, a->pn); + pm = pred_full_reg_ptr(s, a->pm); +@@ -310,8 +324,7 @@ static bool do_outprod(DisasContext *s, arg_op *a, MemOp esz, + return true; + } + +- /* Sum XZR+zad to find ZAd. */ +- za = get_tile_rowcol(s, esz, 31, a->zad, false); ++ za = get_tile(s, esz, a->zad); + zn = vec_full_reg_ptr(s, a->zn); + zm = vec_full_reg_ptr(s, a->zm); + pn = pred_full_reg_ptr(s, a->pn); +@@ -337,8 +350,7 @@ static bool do_outprod_fpst(DisasContext *s, arg_op *a, MemOp esz, + return true; + } + +- /* Sum XZR+zad to find ZAd. */ +- za = get_tile_rowcol(s, esz, 31, a->zad, false); ++ za = get_tile(s, esz, a->zad); + zn = vec_full_reg_ptr(s, a->zn); + zm = vec_full_reg_ptr(s, a->zm); + pn = pred_full_reg_ptr(s, a->pn); +diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target +index 118d069073..5e4ea7c998 100644 +--- a/tests/tcg/aarch64/Makefile.target ++++ b/tests/tcg/aarch64/Makefile.target +@@ -24,7 +24,7 @@ config-cc.mak: Makefile + $(call cc-option,-march=armv8.3-a, CROSS_CC_HAS_ARMV8_3); \ + $(call cc-option,-mbranch-protection=standard, CROSS_CC_HAS_ARMV8_BTI); \ + $(call cc-option,-march=armv8.5-a+memtag, CROSS_CC_HAS_ARMV8_MTE); \ +- $(call cc-option,-march=armv9-a+sme, CROSS_CC_HAS_ARMV9_SME)) 3> config-cc.mak ++ $(call cc-option,-Wa$(COMMA)-march=armv9-a+sme, CROSS_AS_HAS_ARMV9_SME)) 3> config-cc.mak + -include config-cc.mak + + # Pauth Tests +@@ -51,6 +51,11 @@ AARCH64_TESTS += mte-1 mte-2 mte-3 mte-4 mte-5 mte-6 mte-7 + mte-%: CFLAGS += -march=armv8.5-a+memtag + endif + ++# SME Tests ++ifneq ($(CROSS_AS_HAS_ARMV9_SME),) ++AARCH64_TESTS += sme-outprod1 ++endif ++ + # System Registers Tests + AARCH64_TESTS += sysregs + +diff --git a/tests/tcg/aarch64/sme-outprod1.c b/tests/tcg/aarch64/sme-outprod1.c +new file mode 100644 +index 0000000000..6e5972d75e +--- /dev/null ++++ b/tests/tcg/aarch64/sme-outprod1.c +@@ -0,0 +1,83 @@ ++/* ++ * SME outer product, 1 x 1. ++ * SPDX-License-Identifier: GPL-2.0-or-later ++ */ ++ ++#include <stdio.h> ++ ++extern void foo(float *dst); ++ ++asm( ++" .arch_extension sme\n" ++" .type foo, @function\n" ++"foo:\n" ++" stp x29, x30, [sp, -80]!\n" ++" mov x29, sp\n" ++" stp d8, d9, [sp, 16]\n" ++" stp d10, d11, [sp, 32]\n" ++" stp d12, d13, [sp, 48]\n" ++" stp d14, d15, [sp, 64]\n" ++" smstart\n" ++" ptrue p0.s, vl4\n" ++" fmov z0.s, #1.0\n" ++/* ++ * An outer product of a vector of 1.0 by itself should be a matrix of 1.0. ++ * Note that we are using tile 1 here (za1.s) rather than tile 0. ++ */ ++" zero {za}\n" ++" fmopa za1.s, p0/m, p0/m, z0.s, z0.s\n" ++/* ++ * Read the first 4x4 sub-matrix of elements from tile 1: ++ * Note that za1h should be interchangable here. ++ */ ++" mov w12, #0\n" ++" mova z0.s, p0/m, za1v.s[w12, #0]\n" ++" mova z1.s, p0/m, za1v.s[w12, #1]\n" ++" mova z2.s, p0/m, za1v.s[w12, #2]\n" ++" mova z3.s, p0/m, za1v.s[w12, #3]\n" ++/* ++ * And store them to the input pointer (dst in the C code): ++ */ ++" st1w {z0.s}, p0, [x0]\n" ++" add x0, x0, #16\n" ++" st1w {z1.s}, p0, [x0]\n" ++" add x0, x0, #16\n" ++" st1w {z2.s}, p0, [x0]\n" ++" add x0, x0, #16\n" ++" st1w {z3.s}, p0, [x0]\n" ++" smstop\n" ++" ldp d8, d9, [sp, 16]\n" ++" ldp d10, d11, [sp, 32]\n" ++" ldp d12, d13, [sp, 48]\n" ++" ldp d14, d15, [sp, 64]\n" ++" ldp x29, x30, [sp], 80\n" ++" ret\n" ++" .size foo, . - foo" ++); ++ ++int main() ++{ ++ float dst[16]; ++ int i, j; ++ ++ foo(dst); ++ ++ for (i = 0; i < 16; i++) { ++ if (dst[i] != 1.0f) { ++ break; ++ } ++ } ++ ++ if (i == 16) { ++ return 0; /* success */ ++ } ++ ++ /* failure */ ++ for (i = 0; i < 4; ++i) { ++ for (j = 0; j < 4; ++j) { ++ printf("%f ", (double)dst[i * 4 + j]); ++ } ++ printf("\n"); ++ } ++ return 1; ++} diff --git a/debian/patches/extra/0008-system-qdev-monitor-move-drain_call_rcu-call-under-i.patch b/debian/patches/extra/0008-system-qdev-monitor-move-drain_call_rcu-call-under-i.patch new file mode 100644 index 0000000..7c15a00 --- /dev/null +++ b/debian/patches/extra/0008-system-qdev-monitor-move-drain_call_rcu-call-under-i.patch @@ -0,0 +1,61 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Dmitrii Gavrilov <ds-g...@yandex-team.ru> +Date: Wed, 10 Apr 2024 08:43:28 +0300 +Subject: [PATCH] system/qdev-monitor: move drain_call_rcu call under if (!dev) + in qmp_device_add() + +Original goal of addition of drain_call_rcu to qmp_device_add was to cover +the failure case of qdev_device_add. It seems call of drain_call_rcu was +misplaced in 7bed89958bfbf40df what led to waiting for pending RCU callbacks +under happy path too. What led to overall performance degradation of +qmp_device_add. + +In this patch call of drain_call_rcu moved under handling of failure of +qdev_device_add. + +Signed-off-by: Dmitrii Gavrilov <ds-g...@yandex-team.ru> +Message-ID: <20231103105602.90475-1-ds-g...@yandex-team.ru> +Fixes: 7bed89958bf ("device_core: use drain_call_rcu in in qmp_device_add", 2020-10-12) +Cc: qemu-sta...@nongnu.org +Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> +(cherry picked from commit 012b170173bcaa14b9bc26209e0813311ac78489) +Signed-off-by: Michael Tokarev <m...@tls.msk.ru> +--- + softmmu/qdev-monitor.c | 23 +++++++++++------------ + 1 file changed, 11 insertions(+), 12 deletions(-) + +diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c +index 4b0ef65780..f4348443b0 100644 +--- a/softmmu/qdev-monitor.c ++++ b/softmmu/qdev-monitor.c +@@ -853,19 +853,18 @@ void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp) + return; + } + dev = qdev_device_add(opts, errp); +- +- /* +- * Drain all pending RCU callbacks. This is done because +- * some bus related operations can delay a device removal +- * (in this case this can happen if device is added and then +- * removed due to a configuration error) +- * to a RCU callback, but user might expect that this interface +- * will finish its job completely once qmp command returns result +- * to the user +- */ +- drain_call_rcu(); +- + if (!dev) { ++ /* ++ * Drain all pending RCU callbacks. This is done because ++ * some bus related operations can delay a device removal ++ * (in this case this can happen if device is added and then ++ * removed due to a configuration error) ++ * to a RCU callback, but user might expect that this interface ++ * will finish its job completely once qmp command returns result ++ * to the user ++ */ ++ drain_call_rcu(); ++ + qemu_opts_del(opts); + return; + } diff --git a/debian/patches/extra/0009-hw-scsi-lsi53c895a-stop-script-on-phase-mismatch.patch b/debian/patches/extra/0009-hw-scsi-lsi53c895a-stop-script-on-phase-mismatch.patch new file mode 100644 index 0000000..fc1900f --- /dev/null +++ b/debian/patches/extra/0009-hw-scsi-lsi53c895a-stop-script-on-phase-mismatch.patch @@ -0,0 +1,85 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Sven Schnelle <sv...@stackframe.org> +Date: Wed, 10 Apr 2024 08:43:29 +0300 +Subject: [PATCH] hw/scsi/lsi53c895a: stop script on phase mismatch + +Netbsd isn't happy with qemu lsi53c895a emulation: + +cd0(esiop0:0:2:0): command with tag id 0 reset +esiop0: autoconfiguration error: phase mismatch without command +esiop0: autoconfiguration error: unhandled scsi interrupt, sist=0x80 sstat1=0x0 DSA=0x23a64b1 DSP=0x50 + +This is because lsi_bad_phase() triggers a phase mismatch, which +stops SCRIPT processing. However, after returning to +lsi_command_complete(), SCRIPT is restarted with lsi_resume_script(). +Fix this by adding a return value to lsi_bad_phase(), and only resume +script processing when lsi_bad_phase() didn't trigger a host interrupt. + +Signed-off-by: Sven Schnelle <sv...@stackframe.org> +Tested-by: Helge Deller <del...@gmx.de> +Message-ID: <20240302214453.2071388-1-sv...@stackframe.org> +Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> +(cherry picked from commit a9198b3132d81a6bfc9fdbf6f3d3a514c2864674) +Signed-off-by: Michael Tokarev <m...@tls.msk.ru> +--- + hw/scsi/lsi53c895a.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c +index ca619ed564..905f5ef237 100644 +--- a/hw/scsi/lsi53c895a.c ++++ b/hw/scsi/lsi53c895a.c +@@ -570,8 +570,9 @@ static inline void lsi_set_phase(LSIState *s, int phase) + s->sstat1 = (s->sstat1 & ~PHASE_MASK) | phase; + } + +-static void lsi_bad_phase(LSIState *s, int out, int new_phase) ++static int lsi_bad_phase(LSIState *s, int out, int new_phase) + { ++ int ret = 0; + /* Trigger a phase mismatch. */ + if (s->ccntl0 & LSI_CCNTL0_ENPMJ) { + if ((s->ccntl0 & LSI_CCNTL0_PMJCTL)) { +@@ -584,8 +585,10 @@ static void lsi_bad_phase(LSIState *s, int out, int new_phase) + trace_lsi_bad_phase_interrupt(); + lsi_script_scsi_interrupt(s, LSI_SIST0_MA, 0); + lsi_stop_script(s); ++ ret = 1; + } + lsi_set_phase(s, new_phase); ++ return ret; + } + + +@@ -789,7 +792,7 @@ static int lsi_queue_req(LSIState *s, SCSIRequest *req, uint32_t len) + static void lsi_command_complete(SCSIRequest *req, size_t resid) + { + LSIState *s = LSI53C895A(req->bus->qbus.parent); +- int out; ++ int out, stop = 0; + + out = (s->sstat1 & PHASE_MASK) == PHASE_DO; + trace_lsi_command_complete(req->status); +@@ -797,7 +800,10 @@ static void lsi_command_complete(SCSIRequest *req, size_t resid) + s->command_complete = 2; + if (s->waiting && s->dbc != 0) { + /* Raise phase mismatch for short transfers. */ +- lsi_bad_phase(s, out, PHASE_ST); ++ stop = lsi_bad_phase(s, out, PHASE_ST); ++ if (stop) { ++ s->waiting = 0; ++ } + } else { + lsi_set_phase(s, PHASE_ST); + } +@@ -807,7 +813,9 @@ static void lsi_command_complete(SCSIRequest *req, size_t resid) + lsi_request_free(s, s->current); + scsi_req_unref(req); + } +- lsi_resume_script(s); ++ if (!stop) { ++ lsi_resume_script(s); ++ } + } + + /* Callback to indicate that the SCSI layer has completed a transfer. */ diff --git a/debian/patches/extra/0010-hw-scsi-lsi53c895a-add-missing-decrement-of-reentran.patch b/debian/patches/extra/0010-hw-scsi-lsi53c895a-add-missing-decrement-of-reentran.patch new file mode 100644 index 0000000..35771e2 --- /dev/null +++ b/debian/patches/extra/0010-hw-scsi-lsi53c895a-add-missing-decrement-of-reentran.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Sven Schnelle <sv...@stackframe.org> +Date: Wed, 10 Apr 2024 08:43:30 +0300 +Subject: [PATCH] hw/scsi/lsi53c895a: add missing decrement of reentrancy + counter + +When the maximum count of SCRIPTS instructions is reached, the code +stops execution and returns, but fails to decrement the reentrancy +counter. This effectively renders the SCSI controller unusable +because on next entry the reentrancy counter is still above the limit. + +This bug was seen on HP-UX 10.20 which seems to trigger SCRIPTS +loops. + +Fixes: b987718bbb ("hw/scsi/lsi53c895a: Fix reentrancy issues in the LSI controller (CVE-2023-0330)") +Signed-off-by: Sven Schnelle <sv...@stackframe.org> +Message-ID: <20240128202214.2644768-1-sv...@stackframe.org> +Reviewed-by: Thomas Huth <th...@redhat.com> +Tested-by: Helge Deller <del...@gmx.de> +Signed-off-by: Thomas Huth <th...@redhat.com> +(cherry picked from commit 8b09b7fe47082c69295a0fc0cc01b041b6385025) +Signed-off-by: Michael Tokarev <m...@tls.msk.ru> +--- + hw/scsi/lsi53c895a.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c +index 905f5ef237..c7a3964b5f 100644 +--- a/hw/scsi/lsi53c895a.c ++++ b/hw/scsi/lsi53c895a.c +@@ -1167,6 +1167,7 @@ again: + lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0); + lsi_disconnect(s); + trace_lsi_execute_script_stop(); ++ reentrancy_level--; + return; + } + insn = read_dword(s, s->dsp); diff --git a/debian/patches/extra/0011-hw-scsi-lsi53c895a-add-timer-to-scripts-processing.patch b/debian/patches/extra/0011-hw-scsi-lsi53c895a-add-timer-to-scripts-processing.patch new file mode 100644 index 0000000..32b7fe8 --- /dev/null +++ b/debian/patches/extra/0011-hw-scsi-lsi53c895a-add-timer-to-scripts-processing.patch @@ -0,0 +1,173 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Sven Schnelle <sv...@stackframe.org> +Date: Wed, 10 Apr 2024 08:43:31 +0300 +Subject: [PATCH] hw/scsi/lsi53c895a: add timer to scripts processing + +HP-UX 10.20 seems to make the lsi53c895a spinning on a memory location +under certain circumstances. As the SCSI controller and CPU are not +running at the same time this loop will never finish. After some +time, the check loop interrupts with a unexpected device disconnect. +This works, but is slow because the kernel resets the scsi controller. +Instead of signaling UDC, start a timer and exit the loop. Until the +timer fires, the CPU can process instructions which might changes the +memory location. + +The limit of instructions is also reduced because scripts running on +the SCSI processor are usually very short. This keeps the time until +the loop is exit short. + +Suggested-by: Peter Maydell <peter.mayd...@linaro.org> +Signed-off-by: Sven Schnelle <sv...@stackframe.org> +Message-ID: <20240229204407.1699260-1-sv...@stackframe.org> +Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> +(cherry picked from commit 9876359990dd4c8a48de65cf5e1c3d13e96a7f4e) +Signed-off-by: Michael Tokarev <m...@tls.msk.ru> +--- + hw/scsi/lsi53c895a.c | 43 +++++++++++++++++++++++++++++++++---------- + hw/scsi/trace-events | 2 ++ + 2 files changed, 35 insertions(+), 10 deletions(-) + +diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c +index c7a3964b5f..48c85d479c 100644 +--- a/hw/scsi/lsi53c895a.c ++++ b/hw/scsi/lsi53c895a.c +@@ -188,7 +188,7 @@ static const char *names[] = { + #define LSI_TAG_VALID (1 << 16) + + /* Maximum instructions to process. */ +-#define LSI_MAX_INSN 10000 ++#define LSI_MAX_INSN 100 + + typedef struct lsi_request { + SCSIRequest *req; +@@ -205,6 +205,7 @@ enum { + LSI_WAIT_RESELECT, /* Wait Reselect instruction has been issued */ + LSI_DMA_SCRIPTS, /* processing DMA from lsi_execute_script */ + LSI_DMA_IN_PROGRESS, /* DMA operation is in progress */ ++ LSI_WAIT_SCRIPTS, /* SCRIPTS stopped because of instruction count limit */ + }; + + enum { +@@ -224,6 +225,7 @@ struct LSIState { + MemoryRegion ram_io; + MemoryRegion io_io; + AddressSpace pci_io_as; ++ QEMUTimer *scripts_timer; + + int carry; /* ??? Should this be an a visible register somewhere? */ + int status; +@@ -415,6 +417,7 @@ static void lsi_soft_reset(LSIState *s) + s->sbr = 0; + assert(QTAILQ_EMPTY(&s->queue)); + assert(!s->current); ++ timer_del(s->scripts_timer); + } + + static int lsi_dma_40bit(LSIState *s) +@@ -1135,6 +1138,12 @@ static void lsi_wait_reselect(LSIState *s) + } + } + ++static void lsi_scripts_timer_start(LSIState *s) ++{ ++ trace_lsi_scripts_timer_start(); ++ timer_mod(s->scripts_timer, qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) + 500); ++} ++ + static void lsi_execute_script(LSIState *s) + { + PCIDevice *pci_dev = PCI_DEVICE(s); +@@ -1144,6 +1153,11 @@ static void lsi_execute_script(LSIState *s) + int insn_processed = 0; + static int reentrancy_level; + ++ if (s->waiting == LSI_WAIT_SCRIPTS) { ++ timer_del(s->scripts_timer); ++ s->waiting = LSI_NOWAIT; ++ } ++ + reentrancy_level++; + + s->istat1 |= LSI_ISTAT1_SRUN; +@@ -1151,8 +1165,8 @@ again: + /* + * Some windows drivers make the device spin waiting for a memory location + * to change. If we have executed more than LSI_MAX_INSN instructions then +- * assume this is the case and force an unexpected device disconnect. This +- * is apparently sufficient to beat the drivers into submission. ++ * assume this is the case and start a timer. Until the timer fires, the ++ * host CPU has a chance to run and change the memory location. + * + * Another issue (CVE-2023-0330) can occur if the script is programmed to + * trigger itself again and again. Avoid this problem by stopping after +@@ -1160,13 +1174,8 @@ again: + * which should be enough for all valid use cases). + */ + if (++insn_processed > LSI_MAX_INSN || reentrancy_level > 8) { +- if (!(s->sien0 & LSI_SIST0_UDC)) { +- qemu_log_mask(LOG_GUEST_ERROR, +- "lsi_scsi: inf. loop with UDC masked"); +- } +- lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0); +- lsi_disconnect(s); +- trace_lsi_execute_script_stop(); ++ s->waiting = LSI_WAIT_SCRIPTS; ++ lsi_scripts_timer_start(s); + reentrancy_level--; + return; + } +@@ -2205,6 +2214,9 @@ static int lsi_post_load(void *opaque, int version_id) + return -EINVAL; + } + ++ if (s->waiting == LSI_WAIT_SCRIPTS) { ++ lsi_scripts_timer_start(s); ++ } + return 0; + } + +@@ -2302,6 +2314,15 @@ static const struct SCSIBusInfo lsi_scsi_info = { + .cancel = lsi_request_cancelled + }; + ++static void scripts_timer_cb(void *opaque) ++{ ++ LSIState *s = opaque; ++ ++ trace_lsi_scripts_timer_triggered(); ++ s->waiting = LSI_NOWAIT; ++ lsi_execute_script(s); ++} ++ + static void lsi_scsi_realize(PCIDevice *dev, Error **errp) + { + LSIState *s = LSI53C895A(dev); +@@ -2321,6 +2342,7 @@ static void lsi_scsi_realize(PCIDevice *dev, Error **errp) + "lsi-ram", 0x2000); + memory_region_init_io(&s->io_io, OBJECT(s), &lsi_io_ops, s, + "lsi-io", 256); ++ s->scripts_timer = timer_new_us(QEMU_CLOCK_VIRTUAL, scripts_timer_cb, s); + + /* + * Since we use the address-space API to interact with ram_io, disable the +@@ -2345,6 +2367,7 @@ static void lsi_scsi_exit(PCIDevice *dev) + LSIState *s = LSI53C895A(dev); + + address_space_destroy(&s->pci_io_as); ++ timer_del(s->scripts_timer); + } + + static void lsi_class_init(ObjectClass *klass, void *data) +diff --git a/hw/scsi/trace-events b/hw/scsi/trace-events +index ab238293f0..131af99d91 100644 +--- a/hw/scsi/trace-events ++++ b/hw/scsi/trace-events +@@ -299,6 +299,8 @@ lsi_execute_script_stop(void) "SCRIPTS execution stopped" + lsi_awoken(void) "Woken by SIGP" + lsi_reg_read(const char *name, int offset, uint8_t ret) "Read reg %s 0x%x = 0x%02x" + lsi_reg_write(const char *name, int offset, uint8_t val) "Write reg %s 0x%x = 0x%02x" ++lsi_scripts_timer_triggered(void) "SCRIPTS timer triggered" ++lsi_scripts_timer_start(void) "SCRIPTS timer started" + + # virtio-scsi.c + virtio_scsi_cmd_req(int lun, uint32_t tag, uint8_t cmd) "virtio_scsi_cmd_req lun=%u tag=0x%x cmd=0x%x" diff --git a/debian/patches/extra/0012-e1000e-fix-link-state-on-resume.patch b/debian/patches/extra/0012-e1000e-fix-link-state-on-resume.patch new file mode 100644 index 0000000..b313718 --- /dev/null +++ b/debian/patches/extra/0012-e1000e-fix-link-state-on-resume.patch @@ -0,0 +1,161 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Laurent Vivier <lviv...@redhat.com> +Date: Wed, 10 Apr 2024 08:43:33 +0300 +Subject: [PATCH] e1000e: fix link state on resume + +On resume e1000e_vm_state_change() always calls e1000e_autoneg_resume() +that sets link_down to false, and thus activates the link even +if we have disabled it. + +The problem can be reproduced starting qemu in paused state (-S) and +then set the link to down. When we resume the machine the link appears +to be up. + +Reproducer: + + # qemu-system-x86_64 ... -device e1000e,netdev=netdev0,id=net0 -S + + {"execute": "qmp_capabilities" } + {"execute": "set_link", "arguments": {"name": "net0", "up": false}} + {"execute": "cont" } + +To fix the problem, merge the content of e1000e_vm_state_change() +into e1000e_core_post_load() as e1000 does. + +Buglink: https://issues.redhat.com/browse/RHEL-21867 +Fixes: 6f3fbe4ed06a ("net: Introduce e1000e device emulation") +Suggested-by: Akihiko Odaki <akihiko.od...@daynix.com> +Signed-off-by: Laurent Vivier <lviv...@redhat.com> +Signed-off-by: Jason Wang <jasow...@redhat.com> +(cherry picked from commit 4cadf10234989861398e19f3bb441d3861f3bb7c) +Signed-off-by: Michael Tokarev <m...@tls.msk.ru> +--- + hw/net/e1000e_core.c | 60 ++++++-------------------------------------- + hw/net/e1000e_core.h | 2 -- + 2 files changed, 7 insertions(+), 55 deletions(-) + +diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c +index c71d82ce1d..742f5ec800 100644 +--- a/hw/net/e1000e_core.c ++++ b/hw/net/e1000e_core.c +@@ -108,14 +108,6 @@ e1000e_intmgr_timer_resume(E1000IntrDelayTimer *timer) + } + } + +-static void +-e1000e_intmgr_timer_pause(E1000IntrDelayTimer *timer) +-{ +- if (timer->running) { +- timer_del(timer->timer); +- } +-} +- + static inline void + e1000e_intrmgr_stop_timer(E1000IntrDelayTimer *timer) + { +@@ -397,24 +389,6 @@ e1000e_intrmgr_resume(E1000ECore *core) + } + } + +-static void +-e1000e_intrmgr_pause(E1000ECore *core) +-{ +- int i; +- +- e1000e_intmgr_timer_pause(&core->radv); +- e1000e_intmgr_timer_pause(&core->rdtr); +- e1000e_intmgr_timer_pause(&core->raid); +- e1000e_intmgr_timer_pause(&core->tidv); +- e1000e_intmgr_timer_pause(&core->tadv); +- +- e1000e_intmgr_timer_pause(&core->itr); +- +- for (i = 0; i < E1000E_MSIX_VEC_NUM; i++) { +- e1000e_intmgr_timer_pause(&core->eitr[i]); +- } +-} +- + static void + e1000e_intrmgr_reset(E1000ECore *core) + { +@@ -3336,12 +3310,6 @@ e1000e_core_read(E1000ECore *core, hwaddr addr, unsigned size) + return 0; + } + +-static inline void +-e1000e_autoneg_pause(E1000ECore *core) +-{ +- timer_del(core->autoneg_timer); +-} +- + static void + e1000e_autoneg_resume(E1000ECore *core) + { +@@ -3353,22 +3321,6 @@ e1000e_autoneg_resume(E1000ECore *core) + } + } + +-static void +-e1000e_vm_state_change(void *opaque, bool running, RunState state) +-{ +- E1000ECore *core = opaque; +- +- if (running) { +- trace_e1000e_vm_state_running(); +- e1000e_intrmgr_resume(core); +- e1000e_autoneg_resume(core); +- } else { +- trace_e1000e_vm_state_stopped(); +- e1000e_autoneg_pause(core); +- e1000e_intrmgr_pause(core); +- } +-} +- + void + e1000e_core_pci_realize(E1000ECore *core, + const uint16_t *eeprom_templ, +@@ -3381,9 +3333,6 @@ e1000e_core_pci_realize(E1000ECore *core, + e1000e_autoneg_timer, core); + e1000e_intrmgr_pci_realize(core); + +- core->vmstate = +- qemu_add_vm_change_state_handler(e1000e_vm_state_change, core); +- + for (i = 0; i < E1000E_NUM_QUEUES; i++) { + net_tx_pkt_init(&core->tx[i].tx_pkt, core->owner, + E1000E_MAX_TX_FRAGS, core->has_vnet); +@@ -3408,8 +3357,6 @@ e1000e_core_pci_uninit(E1000ECore *core) + + e1000e_intrmgr_pci_unint(core); + +- qemu_del_vm_change_state_handler(core->vmstate); +- + for (i = 0; i < E1000E_NUM_QUEUES; i++) { + net_tx_pkt_reset(core->tx[i].tx_pkt); + net_tx_pkt_uninit(core->tx[i].tx_pkt); +@@ -3561,5 +3508,12 @@ e1000e_core_post_load(E1000ECore *core) + */ + nc->link_down = (core->mac[STATUS] & E1000_STATUS_LU) == 0; + ++ /* ++ * we need to restart intrmgr timers, as an older version of ++ * QEMU can have stopped them before migration ++ */ ++ e1000e_intrmgr_resume(core); ++ e1000e_autoneg_resume(core); ++ + return 0; + } +diff --git a/hw/net/e1000e_core.h b/hw/net/e1000e_core.h +index 4ddb4d2c39..f2a8ff4a33 100644 +--- a/hw/net/e1000e_core.h ++++ b/hw/net/e1000e_core.h +@@ -100,8 +100,6 @@ struct E1000Core { + E1000IntrDelayTimer eitr[E1000E_MSIX_VEC_NUM]; + bool eitr_intr_pending[E1000E_MSIX_VEC_NUM]; + +- VMChangeStateEntry *vmstate; +- + uint32_t itr_guest_value; + uint32_t eitr_guest_value[E1000E_MSIX_VEC_NUM]; + diff --git a/debian/patches/extra/0013-target-i386-introduce-function-to-query-MMU-indices.patch b/debian/patches/extra/0013-target-i386-introduce-function-to-query-MMU-indices.patch new file mode 100644 index 0000000..c97cd07 --- /dev/null +++ b/debian/patches/extra/0013-target-i386-introduce-function-to-query-MMU-indices.patch @@ -0,0 +1,61 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini <pbonz...@redhat.com> +Date: Wed, 10 Apr 2024 08:43:49 +0300 +Subject: [PATCH] target/i386: introduce function to query MMU indices + +Remove knowledge of specific MMU indexes (other than MMU_NESTED_IDX and +MMU_PHYS_IDX) from mmu_translate(). This will make it possible to split +32-bit and 64-bit MMU indexes. + +Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> +(cherry picked from commit 5f97afe2543f09160a8d123ab6e2e8c6d98fa9ce) +Signed-off-by: Michael Tokarev <m...@tls.msk.ru> +(Mjt: context fixup in target/i386/cpu.h due to other changes in that area) +--- + target/i386/cpu.h | 10 ++++++++++ + target/i386/tcg/sysemu/excp_helper.c | 4 ++-- + 2 files changed, 12 insertions(+), 2 deletions(-) + +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index 7be047ce33..f175e18768 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -2195,6 +2195,16 @@ static inline int cpu_mmu_index(CPUX86State *env, bool ifetch) + ? MMU_KNOSMAP_IDX : MMU_KSMAP_IDX; + } + ++static inline bool is_mmu_index_smap(int mmu_index) ++{ ++ return mmu_index == MMU_KSMAP_IDX; ++} ++ ++static inline bool is_mmu_index_user(int mmu_index) ++{ ++ return mmu_index == MMU_USER_IDX; ++} ++ + static inline bool is_mmu_index_32(int mmu_index) + { + assert(mmu_index < MMU_PHYS_IDX); +diff --git a/target/i386/tcg/sysemu/excp_helper.c b/target/i386/tcg/sysemu/excp_helper.c +index 5999cdedf5..553a60d976 100644 +--- a/target/i386/tcg/sysemu/excp_helper.c ++++ b/target/i386/tcg/sysemu/excp_helper.c +@@ -135,7 +135,7 @@ static bool mmu_translate(CPUX86State *env, const TranslateParams *in, + { + const target_ulong addr = in->addr; + const int pg_mode = in->pg_mode; +- const bool is_user = (in->mmu_idx == MMU_USER_IDX); ++ const bool is_user = is_mmu_index_user(in->mmu_idx); + const MMUAccessType access_type = in->access_type; + uint64_t ptep, pte, rsvd_mask; + PTETranslate pte_trans = { +@@ -355,7 +355,7 @@ do_check_protect_pse36: + } + + int prot = 0; +- if (in->mmu_idx != MMU_KSMAP_IDX || !(ptep & PG_USER_MASK)) { ++ if (!is_mmu_index_smap(in->mmu_idx) || !(ptep & PG_USER_MASK)) { + prot |= PAGE_READ; + if ((ptep & PG_RW_MASK) || !(is_user || (pg_mode & PG_MODE_WP))) { + prot |= PAGE_WRITE; diff --git a/debian/patches/extra/0014-target-i386-use-separate-MMU-indexes-for-32-bit-acce.patch b/debian/patches/extra/0014-target-i386-use-separate-MMU-indexes-for-32-bit-acce.patch new file mode 100644 index 0000000..64c042d --- /dev/null +++ b/debian/patches/extra/0014-target-i386-use-separate-MMU-indexes-for-32-bit-acce.patch @@ -0,0 +1,130 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini <pbonz...@redhat.com> +Date: Wed, 10 Apr 2024 08:43:50 +0300 +Subject: [PATCH] target/i386: use separate MMU indexes for 32-bit accesses + +Accesses from a 32-bit environment (32-bit code segment for instruction +accesses, EFER.LMA==0 for processor accesses) have to mask away the +upper 32 bits of the address. While a bit wasteful, the easiest way +to do so is to use separate MMU indexes. These days, QEMU anyway is +compiled with a fixed value for NB_MMU_MODES. Split MMU_USER_IDX, +MMU_KSMAP_IDX and MMU_KNOSMAP_IDX in two. + +Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> +(cherry picked from commit 90f641531c782c873a05895f411c05fbbbef3c49) +Signed-off-by: Michael Tokarev <m...@tls.msk.ru> +(Mjt: move changes for x86_cpu_mmu_index() to cpu_mmu_index() due to missing + v8.2.0-1030-gace0c5fe5950 "target/i386: Populate CPUClass.mmu_index" + Increase NB_MMU_MODES from 5 to 8 in target/i386/cpu-param.h due to missing + v7.2.0-2640-gffd824f3f32d "include/exec: Set default NB_MMU_MODES to 16" + v7.2.0-2647-g6787318a5d86 "target/i386: Remove NB_MMU_MODES define" + which relaxed upper limit of MMU index for i386, since this commit starts + using MMU_NESTED_IDX=7. + Thanks Zhao Liu and Paolo Bonzini for the analisys and suggestions. +) +--- + target/i386/cpu-param.h | 2 +- + target/i386/cpu.h | 44 ++++++++++++++++++++-------- + target/i386/tcg/sysemu/excp_helper.c | 3 +- + 3 files changed, 34 insertions(+), 15 deletions(-) + +diff --git a/target/i386/cpu-param.h b/target/i386/cpu-param.h +index f579b16bd2..e21e472e1e 100644 +--- a/target/i386/cpu-param.h ++++ b/target/i386/cpu-param.h +@@ -23,7 +23,7 @@ + # define TARGET_VIRT_ADDR_SPACE_BITS 32 + #endif + #define TARGET_PAGE_BITS 12 +-#define NB_MMU_MODES 5 ++#define NB_MMU_MODES 8 + + #ifndef CONFIG_USER_ONLY + # define TARGET_TB_PCREL 1 +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index f175e18768..73eee08f3f 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -2182,27 +2182,42 @@ uint64_t cpu_get_tsc(CPUX86State *env); + #define cpu_list x86_cpu_list + + /* MMU modes definitions */ +-#define MMU_KSMAP_IDX 0 +-#define MMU_USER_IDX 1 +-#define MMU_KNOSMAP_IDX 2 +-#define MMU_NESTED_IDX 3 +-#define MMU_PHYS_IDX 4 ++#define MMU_KSMAP64_IDX 0 ++#define MMU_KSMAP32_IDX 1 ++#define MMU_USER64_IDX 2 ++#define MMU_USER32_IDX 3 ++#define MMU_KNOSMAP64_IDX 4 ++#define MMU_KNOSMAP32_IDX 5 ++#define MMU_PHYS_IDX 6 ++#define MMU_NESTED_IDX 7 ++ ++#ifdef CONFIG_USER_ONLY ++#ifdef TARGET_X86_64 ++#define MMU_USER_IDX MMU_USER64_IDX ++#else ++#define MMU_USER_IDX MMU_USER32_IDX ++#endif ++#endif + + static inline int cpu_mmu_index(CPUX86State *env, bool ifetch) + { +- return (env->hflags & HF_CPL_MASK) == 3 ? MMU_USER_IDX : +- (!(env->hflags & HF_SMAP_MASK) || (env->eflags & AC_MASK)) +- ? MMU_KNOSMAP_IDX : MMU_KSMAP_IDX; ++ int mmu_index_32 = (env->hflags & HF_CS64_MASK) ? 1 : 0; ++ int mmu_index_base = ++ (env->hflags & HF_CPL_MASK) == 3 ? MMU_USER64_IDX : ++ !(env->hflags & HF_SMAP_MASK) ? MMU_KNOSMAP64_IDX : ++ (env->eflags & AC_MASK) ? MMU_KNOSMAP64_IDX : MMU_KSMAP64_IDX; ++ ++ return mmu_index_base + mmu_index_32; + } + + static inline bool is_mmu_index_smap(int mmu_index) + { +- return mmu_index == MMU_KSMAP_IDX; ++ return (mmu_index & ~1) == MMU_KSMAP64_IDX; + } + + static inline bool is_mmu_index_user(int mmu_index) + { +- return mmu_index == MMU_USER_IDX; ++ return (mmu_index & ~1) == MMU_USER64_IDX; + } + + static inline bool is_mmu_index_32(int mmu_index) +@@ -2213,9 +2228,12 @@ static inline bool is_mmu_index_32(int mmu_index) + + static inline int cpu_mmu_index_kernel(CPUX86State *env) + { +- return !(env->hflags & HF_SMAP_MASK) ? MMU_KNOSMAP_IDX : +- ((env->hflags & HF_CPL_MASK) < 3 && (env->eflags & AC_MASK)) +- ? MMU_KNOSMAP_IDX : MMU_KSMAP_IDX; ++ int mmu_index_32 = (env->hflags & HF_LMA_MASK) ? 1 : 0; ++ int mmu_index_base = ++ !(env->hflags & HF_SMAP_MASK) ? MMU_KNOSMAP64_IDX : ++ ((env->hflags & HF_CPL_MASK) < 3 && (env->eflags & AC_MASK)) ? MMU_KNOSMAP64_IDX : MMU_KSMAP64_IDX; ++ ++ return mmu_index_base + mmu_index_32; + } + + #define CC_DST (env->cc_dst) +diff --git a/target/i386/tcg/sysemu/excp_helper.c b/target/i386/tcg/sysemu/excp_helper.c +index 553a60d976..5f13252d68 100644 +--- a/target/i386/tcg/sysemu/excp_helper.c ++++ b/target/i386/tcg/sysemu/excp_helper.c +@@ -541,7 +541,8 @@ static bool get_physical_address(CPUX86State *env, vaddr addr, + if (likely(use_stage2)) { + in.cr3 = env->nested_cr3; + in.pg_mode = env->nested_pg_mode; +- in.mmu_idx = MMU_USER_IDX; ++ in.mmu_idx = ++ env->nested_pg_mode & PG_MODE_LMA ? MMU_USER64_IDX : MMU_USER32_IDX; + in.ptw_idx = MMU_PHYS_IDX; + + if (!mmu_translate(env, &in, out, err)) { diff --git a/debian/patches/extra/0015-target-i386-fix-direction-of-32-bit-MMU-test.patch b/debian/patches/extra/0015-target-i386-fix-direction-of-32-bit-MMU-test.patch new file mode 100644 index 0000000..667da4f --- /dev/null +++ b/debian/patches/extra/0015-target-i386-fix-direction-of-32-bit-MMU-test.patch @@ -0,0 +1,46 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini <pbonz...@redhat.com> +Date: Wed, 10 Apr 2024 08:43:51 +0300 +Subject: [PATCH] target/i386: fix direction of "32-bit MMU" test + +The low bit of MMU indices for x86 TCG indicates whether the processor is +in 32-bit mode and therefore linear addresses have to be masked to 32 bits. +However, the index was computed incorrectly, leading to possible conflicts +in the TLB for any address above 4G. + +Analyzed-by: Mark Cave-Ayland <mark.cave-ayl...@ilande.co.uk> +Fixes: b1661801c18 ("target/i386: Fix physical address truncation", 2024-02-28) +Fixes: 1c15f97b4f1 ("target/i386: Fix physical address truncation" in stable-7.2) +Cc: qemu-sta...@nongnu.org +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2206 +Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> +(cherry picked from commit 2cc68629a6fc198f4a972698bdd6477f883aedfb) +Signed-off-by: Michael Tokarev <m...@tls.msk.ru> +(Mjt: move changes for x86_cpu_mmu_index() to cpu_mmu_index() due to missing + v8.2.0-1030-gace0c5fe59 "target/i386: Populate CPUClass.mmu_index") +--- + target/i386/cpu.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/target/i386/cpu.h b/target/i386/cpu.h +index 73eee08f3f..326649ca99 100644 +--- a/target/i386/cpu.h ++++ b/target/i386/cpu.h +@@ -2201,7 +2201,7 @@ uint64_t cpu_get_tsc(CPUX86State *env); + + static inline int cpu_mmu_index(CPUX86State *env, bool ifetch) + { +- int mmu_index_32 = (env->hflags & HF_CS64_MASK) ? 1 : 0; ++ int mmu_index_32 = (env->hflags & HF_CS64_MASK) ? 0 : 1; + int mmu_index_base = + (env->hflags & HF_CPL_MASK) == 3 ? MMU_USER64_IDX : + !(env->hflags & HF_SMAP_MASK) ? MMU_KNOSMAP64_IDX : +@@ -2228,7 +2228,7 @@ static inline bool is_mmu_index_32(int mmu_index) + + static inline int cpu_mmu_index_kernel(CPUX86State *env) + { +- int mmu_index_32 = (env->hflags & HF_LMA_MASK) ? 1 : 0; ++ int mmu_index_32 = (env->hflags & HF_LMA_MASK) ? 0 : 1; + int mmu_index_base = + !(env->hflags & HF_SMAP_MASK) ? MMU_KNOSMAP64_IDX : + ((env->hflags & HF_CPL_MASK) < 3 && (env->eflags & AC_MASK)) ? MMU_KNOSMAP64_IDX : MMU_KSMAP64_IDX; diff --git a/debian/patches/extra/0016-target-i386-Revert-monitor_puts-in-do_inject_x86_mce.patch b/debian/patches/extra/0016-target-i386-Revert-monitor_puts-in-do_inject_x86_mce.patch new file mode 100644 index 0000000..be14c2e --- /dev/null +++ b/debian/patches/extra/0016-target-i386-Revert-monitor_puts-in-do_inject_x86_mce.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Tao Su <tao1...@linux.intel.com> +Date: Wed, 10 Apr 2024 08:43:52 +0300 +Subject: [PATCH] target/i386: Revert monitor_puts() in do_inject_x86_mce() + +monitor_puts() doesn't check the monitor pointer, but do_inject_x86_mce() +may have a parameter with NULL monitor pointer. Revert monitor_puts() in +do_inject_x86_mce() to fix, then the fact that we send the same message to +monitor and log is again more obvious. + +Fixes: bf0c50d4aa85 (monitor: expose monitor_puts to rest of code) +Reviwed-by: Xiaoyao Li <xiaoyao...@intel.com> +Reviewed-by: Markus Armbruster <arm...@redhat.com> +Signed-off-by: Tao Su <tao1...@linux.intel.com> +Message-ID: <20240320083640.523287-1-tao1...@linux.intel.com> +Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> +(cherry picked from commit 7fd226b04746f0be0b636de5097f1b42338951a0) +Signed-off-by: Michael Tokarev <m...@tls.msk.ru> +--- + target/i386/helper.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/target/i386/helper.c b/target/i386/helper.c +index 0ac2da066d..290d9d309c 100644 +--- a/target/i386/helper.c ++++ b/target/i386/helper.c +@@ -427,7 +427,7 @@ static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data) + if (need_reset) { + emit_guest_memory_failure(MEMORY_FAILURE_ACTION_RESET, ar, + recursive); +- monitor_puts(params->mon, msg); ++ monitor_printf(params->mon, "%s", msg); + qemu_log_mask(CPU_LOG_RESET, "%s\n", msg); + qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); + return; diff --git a/debian/patches/extra/0017-tcg-optimize-Fix-sign_mask-for-logical-right-shift.patch b/debian/patches/extra/0017-tcg-optimize-Fix-sign_mask-for-logical-right-shift.patch new file mode 100644 index 0000000..53ca97b --- /dev/null +++ b/debian/patches/extra/0017-tcg-optimize-Fix-sign_mask-for-logical-right-shift.patch @@ -0,0 +1,86 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Richard Henderson <richard.hender...@linaro.org> +Date: Wed, 10 Apr 2024 08:43:57 +0300 +Subject: [PATCH] tcg/optimize: Fix sign_mask for logical right-shift +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The 'sign' computation is attempting to locate the sign bit that has +been repeated, so that we can test if that bit is known zero. That +computation can be zero if there are no known sign repetitions. + +Cc: qemu-sta...@nongnu.org +Fixes: 93a967fbb57 ("tcg/optimize: Propagate sign info for shifting") +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2248 +Signed-off-by: Richard Henderson <richard.hender...@linaro.org> +Reviewed-by: Philippe Mathieu-Daudé <phi...@linaro.org> +(cherry picked from commit 2911e9b95f3bb03783ae5ca3e2494dc3b44a9161) +Signed-off-by: Michael Tokarev <m...@tls.msk.ru> +(Mjt: trivial context fixup in tests/tcg/aarch64/Makefile.target) +--- + tcg/optimize.c | 2 +- + tests/tcg/aarch64/Makefile.target | 1 + + tests/tcg/aarch64/test-2248.c | 28 ++++++++++++++++++++++++++++ + 3 files changed, 30 insertions(+), 1 deletion(-) + create mode 100644 tests/tcg/aarch64/test-2248.c + +diff --git a/tcg/optimize.c b/tcg/optimize.c +index ae081ab29c..b6f6436c74 100644 +--- a/tcg/optimize.c ++++ b/tcg/optimize.c +@@ -1907,7 +1907,7 @@ static bool fold_shift(OptContext *ctx, TCGOp *op) + * will not reduced the number of input sign repetitions. + */ + sign = (s_mask & -s_mask) >> 1; +- if (!(z_mask & sign)) { ++ if (sign && !(z_mask & sign)) { + ctx->s_mask = s_mask; + } + break; +diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target +index 5e4ea7c998..474f61bc30 100644 +--- a/tests/tcg/aarch64/Makefile.target ++++ b/tests/tcg/aarch64/Makefile.target +@@ -10,6 +10,7 @@ VPATH += $(AARCH64_SRC) + + # Base architecture tests + AARCH64_TESTS=fcvt pcalign-a64 ++AARCH64_TESTS += test-2248 + + fcvt: LDFLAGS+=-lm + +diff --git a/tests/tcg/aarch64/test-2248.c b/tests/tcg/aarch64/test-2248.c +new file mode 100644 +index 0000000000..aac2e17836 +--- /dev/null ++++ b/tests/tcg/aarch64/test-2248.c +@@ -0,0 +1,28 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++/* See https://gitlab.com/qemu-project/qemu/-/issues/2248 */ ++ ++#include <assert.h> ++ ++__attribute__((noinline)) ++long test(long x, long y, long sh) ++{ ++ long r; ++ asm("cmp %1, %2\n\t" ++ "cset x12, lt\n\t" ++ "and w11, w12, #0xff\n\t" ++ "cmp w11, #0\n\t" ++ "csetm x14, ne\n\t" ++ "lsr x13, x14, %3\n\t" ++ "sxtb %0, w13" ++ : "=r"(r) ++ : "r"(x), "r"(y), "r"(sh) ++ : "x11", "x12", "x13", "x14"); ++ return r; ++} ++ ++int main() ++{ ++ long r = test(0, 1, 2); ++ assert(r == -1); ++ return 0; ++} diff --git a/debian/patches/extra/0018-hw-virtio-Fix-packed-virtqueue-flush-used_idx.patch b/debian/patches/extra/0018-hw-virtio-Fix-packed-virtqueue-flush-used_idx.patch new file mode 100644 index 0000000..dc4c2be --- /dev/null +++ b/debian/patches/extra/0018-hw-virtio-Fix-packed-virtqueue-flush-used_idx.patch @@ -0,0 +1,66 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Wafer <wa...@jaguarmicro.com> +Date: Wed, 10 Apr 2024 08:44:02 +0300 +Subject: [PATCH] hw/virtio: Fix packed virtqueue flush used_idx +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In the event of writing many chains of descriptors, the device must +write just the id of the last buffer in the descriptor chain, skip +forward the number of descriptors in the chain, and then repeat the +operations for the rest of chains. + +Current QEMU code writes all the buffer ids consecutively, and then +skips all the buffers altogether. This is a bug, and can be reproduced +with a VirtIONet device with _F_MRG_RXBUB and without +_F_INDIRECT_DESC: + +If a virtio-net device has the VIRTIO_NET_F_MRG_RXBUF feature +but not the VIRTIO_RING_F_INDIRECT_DESC feature, +'VirtIONetQueue->rx_vq' will use the merge feature +to store data in multiple 'elems'. +The 'num_buffers' in the virtio header indicates how many elements are merged. +If the value of 'num_buffers' is greater than 1, +all the merged elements will be filled into the descriptor ring. +The 'idx' of the elements should be the value of 'vq->used_idx' plus 'ndescs'. + +Fixes: 86044b24e8 ("virtio: basic packed virtqueue support") +Acked-by: Eugenio Pérez <epere...@redhat.com> +Signed-off-by: Wafer <wa...@jaguarmicro.com> +Message-Id: <20240407015451.5228-2-wa...@jaguarmicro.com> +Reviewed-by: Michael S. Tsirkin <m...@redhat.com> +Signed-off-by: Michael S. Tsirkin <m...@redhat.com> +(cherry picked from commit 2d9a31b3c27311eca1682cb2c076d7a300441960) +Signed-off-by: Michael Tokarev <m...@tls.msk.ru> +--- + hw/virtio/virtio.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c +index b7da7f074d..e4f8ed1e63 100644 +--- a/hw/virtio/virtio.c ++++ b/hw/virtio/virtio.c +@@ -1367,12 +1367,20 @@ static void virtqueue_packed_flush(VirtQueue *vq, unsigned int count) + return; + } + ++ /* ++ * For indirect element's 'ndescs' is 1. ++ * For all other elemment's 'ndescs' is the ++ * number of descriptors chained by NEXT (as set in virtqueue_packed_pop). ++ * So When the 'elem' be filled into the descriptor ring, ++ * The 'idx' of this 'elem' shall be ++ * the value of 'vq->used_idx' plus the 'ndescs'. ++ */ ++ ndescs += vq->used_elems[0].ndescs; + for (i = 1; i < count; i++) { +- virtqueue_packed_fill_desc(vq, &vq->used_elems[i], i, false); ++ virtqueue_packed_fill_desc(vq, &vq->used_elems[i], ndescs, false); + ndescs += vq->used_elems[i].ndescs; + } + virtqueue_packed_fill_desc(vq, &vq->used_elems[0], 0, true); +- ndescs += vq->used_elems[0].ndescs; + + vq->inuse -= ndescs; + vq->used_idx += ndescs; diff --git a/debian/patches/pve/0003-PVE-Config-set-the-CPU-model-to-kvm64-32-instead-of-.patch b/debian/patches/pve/0003-PVE-Config-set-the-CPU-model-to-kvm64-32-instead-of-.patch index 07ce8dd..5b58350 100644 --- a/debian/patches/pve/0003-PVE-Config-set-the-CPU-model-to-kvm64-32-instead-of-.patch +++ b/debian/patches/pve/0003-PVE-Config-set-the-CPU-model-to-kvm64-32-instead-of-.patch @@ -10,7 +10,7 @@ Signed-off-by: Thomas Lamprecht <t.lampre...@proxmox.com> 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/i386/cpu.h b/target/i386/cpu.h -index 7be047ce33..a443d66439 100644 +index 326649ca99..24d21486bc 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -2174,9 +2174,9 @@ uint64_t cpu_get_tsc(CPUX86State *env); diff --git a/debian/patches/series b/debian/patches/series index f67a67b..f12a651 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -2,6 +2,20 @@ extra/0001-monitor-qmp-fix-race-with-clients-disconnecting-earl.patch extra/0002-init-daemonize-defuse-PID-file-resolve-error.patch extra/0003-scsi-megasas-Internal-cdbs-have-16-byte-length.patch extra/0004-ide-avoid-potential-deadlock-when-draining-during-tr.patch +extra/0005-target-arm-align-exposed-ID-registers-with-Linux.patch +extra/0006-tests-tcg-aarch64-sysregs.c-Use-S-syntax-for-id_aa64.patch +extra/0007-target-arm-Fix-SME-full-tile-indexing.patch +extra/0008-system-qdev-monitor-move-drain_call_rcu-call-under-i.patch +extra/0009-hw-scsi-lsi53c895a-stop-script-on-phase-mismatch.patch +extra/0010-hw-scsi-lsi53c895a-add-missing-decrement-of-reentran.patch +extra/0011-hw-scsi-lsi53c895a-add-timer-to-scripts-processing.patch +extra/0012-e1000e-fix-link-state-on-resume.patch +extra/0013-target-i386-introduce-function-to-query-MMU-indices.patch +extra/0014-target-i386-use-separate-MMU-indexes-for-32-bit-acce.patch +extra/0015-target-i386-fix-direction-of-32-bit-MMU-test.patch +extra/0016-target-i386-Revert-monitor_puts-in-do_inject_x86_mce.patch +extra/0017-tcg-optimize-Fix-sign_mask-for-logical-right-shift.patch +extra/0018-hw-virtio-Fix-packed-virtqueue-flush-used_idx.patch bitmap-mirror/0001-drive-mirror-add-support-for-sync-bitmap-mode-never.patch bitmap-mirror/0002-drive-mirror-add-support-for-conditional-and-always-.patch bitmap-mirror/0003-mirror-add-check-for-bitmap-mode-without-bitmap.patch -- 2.30.2 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel