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

Reply via email to