[pve-devel] [PATCH stable-7 qemu 2/2] pick up some extra fixes from upcoming 7.2.11

Fiona Ebner f.ebner at proxmox.com
Wed Apr 10 15:13:41 CEST 2024


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.ebner at 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 <chaosdefinition at 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 <chaosdefinition at hotmail.com>
+Message-id: DS7PR12MB6309FB585E10772928F14271ACE79 at DS7PR12MB6309.namprd12.prod.outlook.com
+Reviewed-by: Peter Maydell <peter.maydell at 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.maydell at linaro.org>
+(cherry picked from commit bc6bd20ee3538347afb750c4bd06edca4a922897)
+Signed-off-by: Michael Tokarev <mjt at 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.maydell at 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.maydell at linaro.org>
+(cherry picked from commit 3dc2afeab2964b54848715b913b6c605f36be3e1)
+Signed-off-by: Michael Tokarev <mjt at 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.henderson at 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-stable at nongnu.org
+Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1620
+Signed-off-by: Richard Henderson <richard.henderson at linaro.org>
+Message-id: 20230622151201.1578522-5-richard.henderson at linaro.org
+Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
+[PMM: dropped now-unneeded changes to sysregs CFLAGS]
+Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
+(cherry picked from commit 1f51573f7925b80e79a29f87c7d9d6ead60960c0)
+Signed-off-by: Michael Tokarev <mjt at 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-gavr at 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-gavr at yandex-team.ru>
+Message-ID: <20231103105602.90475-1-ds-gavr at yandex-team.ru>
+Fixes: 7bed89958bf ("device_core: use drain_call_rcu in in qmp_device_add", 2020-10-12)
+Cc: qemu-stable at nongnu.org
+Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
+(cherry picked from commit 012b170173bcaa14b9bc26209e0813311ac78489)
+Signed-off-by: Michael Tokarev <mjt at 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 <svens at 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 <svens at stackframe.org>
+Tested-by: Helge Deller <deller at gmx.de>
+Message-ID: <20240302214453.2071388-1-svens at stackframe.org>
+Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
+(cherry picked from commit a9198b3132d81a6bfc9fdbf6f3d3a514c2864674)
+Signed-off-by: Michael Tokarev <mjt at 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 <svens at 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 <svens at stackframe.org>
+Message-ID: <20240128202214.2644768-1-svens at stackframe.org>
+Reviewed-by: Thomas Huth <thuth at redhat.com>
+Tested-by: Helge Deller <deller at gmx.de>
+Signed-off-by: Thomas Huth <thuth at redhat.com>
+(cherry picked from commit 8b09b7fe47082c69295a0fc0cc01b041b6385025)
+Signed-off-by: Michael Tokarev <mjt at 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 <svens at 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.maydell at linaro.org>
+Signed-off-by: Sven Schnelle <svens at stackframe.org>
+Message-ID: <20240229204407.1699260-1-svens at stackframe.org>
+Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
+(cherry picked from commit 9876359990dd4c8a48de65cf5e1c3d13e96a7f4e)
+Signed-off-by: Michael Tokarev <mjt at 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 <lvivier at 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.odaki at daynix.com>
+Signed-off-by: Laurent Vivier <lvivier at redhat.com>
+Signed-off-by: Jason Wang <jasowang at redhat.com>
+(cherry picked from commit 4cadf10234989861398e19f3bb441d3861f3bb7c)
+Signed-off-by: Michael Tokarev <mjt at 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 <pbonzini at 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 <pbonzini at redhat.com>
+(cherry picked from commit 5f97afe2543f09160a8d123ab6e2e8c6d98fa9ce)
+Signed-off-by: Michael Tokarev <mjt at 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 <pbonzini at 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 <pbonzini at redhat.com>
+(cherry picked from commit 90f641531c782c873a05895f411c05fbbbef3c49)
+Signed-off-by: Michael Tokarev <mjt at 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 <pbonzini at 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-ayland at 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-stable at nongnu.org
+Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2206
+Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
+(cherry picked from commit 2cc68629a6fc198f4a972698bdd6477f883aedfb)
+Signed-off-by: Michael Tokarev <mjt at 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.su at 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.li at intel.com>
+Reviewed-by: Markus Armbruster <armbru at redhat.com>
+Signed-off-by: Tao Su <tao1.su at linux.intel.com>
+Message-ID: <20240320083640.523287-1-tao1.su at linux.intel.com>
+Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
+(cherry picked from commit 7fd226b04746f0be0b636de5097f1b42338951a0)
+Signed-off-by: Michael Tokarev <mjt at 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.henderson at 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-stable at 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.henderson at linaro.org>
+Reviewed-by: Philippe Mathieu-Daudé <philmd at linaro.org>
+(cherry picked from commit 2911e9b95f3bb03783ae5ca3e2494dc3b44a9161)
+Signed-off-by: Michael Tokarev <mjt at 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 <wafer at 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 <eperezma at redhat.com>
+Signed-off-by: Wafer <wafer at jaguarmicro.com>
+Message-Id: <20240407015451.5228-2-wafer at jaguarmicro.com>
+Reviewed-by: Michael S. Tsirkin <mst at redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
+(cherry picked from commit 2d9a31b3c27311eca1682cb2c076d7a300441960)
+Signed-off-by: Michael Tokarev <mjt at 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.lamprecht at 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





More information about the pve-devel mailing list