From 40f2c987836819d193058c5fe5e0d95e8e2a62b8 Mon Sep 17 00:00:00 2001 From: Jiabo Feng Date: Fri, 21 Feb 2025 15:08:43 +0800 Subject: [PATCH] QEMU update to version 8.2.0-29: - target/i386: csv: Support inject secret for CSV3 guest only if the extension is enabled - target/i386: csv: Support load kernel hashes for CSV3 guest only if the extension is enabled - target/i386: csv: Request to set private memory of CSV3 guest if the extension is enabled - target/i386: kvm: Support to get and enable extensions for Hygon CoCo guest - qapi/qom,target/i386: csv-guest: Introduce secret-header-file=str and secret-file=str options - bakcend: VirtCCA:resolve hugepage memory waste issue in vhost-user scenario - parallels: fix ext_off assertion failure due to overflow - backends/cryptodev-vhost-user: Fix local_error leaks - hw/usb/hcd-ehci: Fix debug printf format string - target/riscv/vector_helper.c: fix 'vmvr_v' memcpy endianess - target/riscv/vector_helper.c: optimize loops in ldst helpers - target/riscv/vector_helper.c: set vstart = 0 in GEN_VEXT_VSLIDEUP_VX() - target/hexagon: don't look for static glib - virtio-net: Fix network stall at the host side waiting for kick - Add if condition to avoid assertion failed error in blockdev_init - target/arm: Use float_status copy in sme_fmopa_s - target/arm: take HSTR traps of cp15 accesses to EL2, not EL1 - target/arm: Reinstate "vfp" property on AArch32 CPUs - target/i386/cpu: Fix notes for CPU models - target/arm: LDAPR should honour SCTLR_ELx.nAA - target/riscv: Avoid bad shift in riscv_cpu_do_interrupt() - hvf: remove unused but set variable - hw/misc/nrf51_rng: Don't use BIT_MASK() when we mean BIT() - Avoid taking address of out-of-bounds array index - target/arm: Fix VCMLA Dd, Dn, Dm[idx] - target/arm: Fix UMOPA/UMOPS of 16-bit values - target/arm: Fix SVE/SME gross MTE suppression checks - target/arm: Fix nregs computation in do_{ld,st}_zpa - crypto: fix error check on gcry_md_open - Change vmstate_cpuhp_sts vmstateDescription version_id - hw/pci: Remove unused pci_irq_pulse() method - hw/intc: Don't clear pending bits on IRQ lowering - target/arm: Drop user-only special case in sve_stN_r - migration: Ensure vmstate_save() sets errp - target/i386: fix hang when using slow path for ptw_setl - contrib/plugins: add compat for g_memdup2 - hw/audio/hda: fix memory leak on audio setup - crypto: perform runtime check for hash/hmac support in gcrypt - target/arm: Fix incorrect aa64_tidcp1 feature check - target/arm: fix exception syndrome for AArch32 bkpt insn - target/arm: Don't get MDCR_EL2 in pmu_counter_enabled() before checking ARM_FEATURE_PMU - linux-user: Print tid not pid with strace - target/arm: Fix A64 scalar SQSHRN and SQRSHRN - target/arm: Don't assert for 128-bit tile accesses when SVL is 128 - hw/timer/exynos4210_mct: fix possible int overflow - target/arm: Avoid shifts by -1 in tszimm_shr() and tszimm_shl() - hw/audio/virtio-snd: Always use little endian audio format - target/riscv: Fix vcompress with rvv_ta_all_1s - usb-hub: Fix handling port power control messages Signed-off-by: Jiabo Feng (cherry picked from commit d4a20b24ff377fd07fcbf2b72eecaf07a3ac4cc0) --- ...-to-avoid-assertion-failed-error-in-.patch | 26 ++ ...address-of-out-of-bounds-array-index.patch | 39 ++ ...puhp_sts-vmstateDescription-version_.patch | 30 ++ ...dev-vhost-user-Fix-local_error-leaks.patch | 41 +++ ...resolve-hugepage-memory-waste-issue-.patch | 320 +++++++++++++++++ ...rib-plugins-add-compat-for-g_memdup2.patch | 62 ++++ crypto-fix-error-check-on-gcry_md_open.patch | 44 +++ ...untime-check-for-hash-hmac-support-i.patch | 48 +++ hvf-remove-unused-but-set-variable.patch | 57 +++ ...o-hda-fix-memory-leak-on-audio-setup.patch | 85 +++++ ...snd-Always-use-little-endian-audio-f.patch | 42 +++ ...t-clear-pending-bits-on-IRQ-lowering.patch | 39 ++ ...g-Don-t-use-BIT_MASK-when-we-mean-BI.patch | 70 ++++ ...i-Remove-unused-pci_irq_pulse-method.patch | 46 +++ ...os4210_mct-fix-possible-int-overflow.patch | 36 ++ ...-ehci-Fix-debug-printf-format-string.patch | 40 +++ ...x-user-Print-tid-not-pid-with-strace.patch | 36 ++ migration-Ensure-vmstate_save-sets-errp.patch | 85 +++++ ...t_off-assertion-failure-due-to-overf.patch | 47 +++ ...i386-csv-guest-Introduce-secret-head.patch | 220 ++++++++++++ qemu.spec | 102 +++++- ...-shifts-by-1-in-tszimm_shr-and-tszim.patch | 66 ++++ ...-assert-for-128-bit-tile-accesses-wh.patch | 61 ++++ ...-get-MDCR_EL2-in-pmu_counter_enabled.patch | 68 ++++ ...-user-only-special-case-in-sve_stN_r.patch | 43 +++ ...rm-Fix-A64-scalar-SQSHRN-and-SQRSHRN.patch | 53 +++ ...SVE-SME-gross-MTE-suppression-checks.patch | 87 +++++ ...arm-Fix-UMOPA-UMOPS-of-16-bit-values.patch | 63 ++++ target-arm-Fix-VCMLA-Dd-Dn-Dm-idx.patch | 47 +++ ...-incorrect-aa64_tidcp1-feature-check.patch | 39 ++ ...-nregs-computation-in-do_-ld-st-_zpa.patch | 83 +++++ ...rm-LDAPR-should-honour-SCTLR_ELx.nAA.patch | 56 +++ ...instate-vfp-property-on-AArch32-CPUs.patch | 44 +++ ...Use-float_status-copy-in-sme_fmopa_s.patch | 47 +++ ...xception-syndrome-for-AArch32-bkpt-i.patch | 91 +++++ ...HSTR-traps-of-cp15-accesses-to-EL2-n.patch | 42 +++ ...t-hexagon-don-t-look-for-static-glib.patch | 47 +++ ...et-i386-cpu-Fix-notes-for-CPU-models.patch | 41 +++ ...Request-to-set-private-memory-of-CSV.patch | 149 ++++++++ ...Support-inject-secret-for-CSV3-guest.patch | 43 +++ ...Support-load-kernel-hashes-for-CSV3-.patch | 40 +++ ...hang-when-using-slow-path-for-ptw_se.patch | 59 +++ ...Support-to-get-and-enable-extensions.patch | 105 ++++++ ...id-bad-shift-in-riscv_cpu_do_interru.patch | 62 ++++ ...scv-Fix-vcompress-with-rvv_ta_all_1s.patch | 39 ++ ...tor_helper.c-fix-vmvr_v-memcpy-endia.patch | 49 +++ ...tor_helper.c-optimize-loops-in-ldst-.patch | 56 +++ ...tor_helper.c-set-vstart-0-in-GEN_VEX.patch | 37 ++ ...handling-port-power-control-messages.patch | 39 ++ ...etwork-stall-at-the-host-side-waitin.patch | 339 ++++++++++++++++++ 50 files changed, 3509 insertions(+), 1 deletion(-) create mode 100644 Add-if-condition-to-avoid-assertion-failed-error-in-.patch create mode 100644 Avoid-taking-address-of-out-of-bounds-array-index.patch create mode 100644 Change-vmstate_cpuhp_sts-vmstateDescription-version_.patch create mode 100644 backends-cryptodev-vhost-user-Fix-local_error-leaks.patch create mode 100644 bakcend-VirtCCA-resolve-hugepage-memory-waste-issue-.patch create mode 100644 contrib-plugins-add-compat-for-g_memdup2.patch create mode 100644 crypto-fix-error-check-on-gcry_md_open.patch create mode 100644 crypto-perform-runtime-check-for-hash-hmac-support-i.patch create mode 100644 hvf-remove-unused-but-set-variable.patch create mode 100644 hw-audio-hda-fix-memory-leak-on-audio-setup.patch create mode 100644 hw-audio-virtio-snd-Always-use-little-endian-audio-f.patch create mode 100644 hw-intc-Don-t-clear-pending-bits-on-IRQ-lowering.patch create mode 100644 hw-misc-nrf51_rng-Don-t-use-BIT_MASK-when-we-mean-BI.patch create mode 100644 hw-pci-Remove-unused-pci_irq_pulse-method.patch create mode 100644 hw-timer-exynos4210_mct-fix-possible-int-overflow.patch create mode 100644 hw-usb-hcd-ehci-Fix-debug-printf-format-string.patch create mode 100644 linux-user-Print-tid-not-pid-with-strace.patch create mode 100644 migration-Ensure-vmstate_save-sets-errp.patch create mode 100644 parallels-fix-ext_off-assertion-failure-due-to-overf.patch create mode 100644 qapi-qom-target-i386-csv-guest-Introduce-secret-head.patch create mode 100644 target-arm-Avoid-shifts-by-1-in-tszimm_shr-and-tszim.patch create mode 100644 target-arm-Don-t-assert-for-128-bit-tile-accesses-wh.patch create mode 100644 target-arm-Don-t-get-MDCR_EL2-in-pmu_counter_enabled.patch create mode 100644 target-arm-Drop-user-only-special-case-in-sve_stN_r.patch create mode 100644 target-arm-Fix-A64-scalar-SQSHRN-and-SQRSHRN.patch create mode 100644 target-arm-Fix-SVE-SME-gross-MTE-suppression-checks.patch create mode 100644 target-arm-Fix-UMOPA-UMOPS-of-16-bit-values.patch create mode 100644 target-arm-Fix-VCMLA-Dd-Dn-Dm-idx.patch create mode 100644 target-arm-Fix-incorrect-aa64_tidcp1-feature-check.patch create mode 100644 target-arm-Fix-nregs-computation-in-do_-ld-st-_zpa.patch create mode 100644 target-arm-LDAPR-should-honour-SCTLR_ELx.nAA.patch create mode 100644 target-arm-Reinstate-vfp-property-on-AArch32-CPUs.patch create mode 100644 target-arm-Use-float_status-copy-in-sme_fmopa_s.patch create mode 100644 target-arm-fix-exception-syndrome-for-AArch32-bkpt-i.patch create mode 100644 target-arm-take-HSTR-traps-of-cp15-accesses-to-EL2-n.patch create mode 100644 target-hexagon-don-t-look-for-static-glib.patch create mode 100644 target-i386-cpu-Fix-notes-for-CPU-models.patch create mode 100644 target-i386-csv-Request-to-set-private-memory-of-CSV.patch create mode 100644 target-i386-csv-Support-inject-secret-for-CSV3-guest.patch create mode 100644 target-i386-csv-Support-load-kernel-hashes-for-CSV3-.patch create mode 100644 target-i386-fix-hang-when-using-slow-path-for-ptw_se.patch create mode 100644 target-i386-kvm-Support-to-get-and-enable-extensions.patch create mode 100644 target-riscv-Avoid-bad-shift-in-riscv_cpu_do_interru.patch create mode 100644 target-riscv-Fix-vcompress-with-rvv_ta_all_1s.patch create mode 100644 target-riscv-vector_helper.c-fix-vmvr_v-memcpy-endia.patch create mode 100644 target-riscv-vector_helper.c-optimize-loops-in-ldst-.patch create mode 100644 target-riscv-vector_helper.c-set-vstart-0-in-GEN_VEX.patch create mode 100644 usb-hub-Fix-handling-port-power-control-messages.patch create mode 100644 virtio-net-Fix-network-stall-at-the-host-side-waitin.patch diff --git a/Add-if-condition-to-avoid-assertion-failed-error-in-.patch b/Add-if-condition-to-avoid-assertion-failed-error-in-.patch new file mode 100644 index 0000000..cded962 --- /dev/null +++ b/Add-if-condition-to-avoid-assertion-failed-error-in-.patch @@ -0,0 +1,26 @@ +From b78860242162ab5ef1e73973eeca36e0261bfeb5 Mon Sep 17 00:00:00 2001 +From: xiaoyuliang +Date: Wed, 21 Aug 2024 11:26:41 +0800 +Subject: [PATCH] Add if condition to avoid assertion failed error in + blockdev_init + +--- + blockdev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/blockdev.c b/blockdev.c +index bc7a947dea..d2fe5c361c 100644 +--- a/blockdev.c ++++ b/blockdev.c +@@ -588,7 +588,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, + + read_only = qemu_opt_get_bool(opts, BDRV_OPT_READ_ONLY, false); + +- if (!file || !*file) { ++ if ((!file || !*file) && qdict_size(bs_opts) == 2) { + cache = qdict_get_try_str(bs_opts, BDRV_OPT_CACHE_NO_FLUSH); + if (cache && !strcmp(cache, "on")) { + bdrv_flags |= BDRV_O_NO_FLUSH; +-- +2.41.0.windows.1 + diff --git a/Avoid-taking-address-of-out-of-bounds-array-index.patch b/Avoid-taking-address-of-out-of-bounds-array-index.patch new file mode 100644 index 0000000..54b034a --- /dev/null +++ b/Avoid-taking-address-of-out-of-bounds-array-index.patch @@ -0,0 +1,39 @@ +From 8ac5c38a54d407b363d6633eb01806b0e9aaa15e Mon Sep 17 00:00:00 2001 +From: yinxiuxiu +Date: Fri, 22 Nov 2024 14:45:09 +0800 +Subject: [PATCH] Avoid taking address of out-of-bounds array index + +Signed-off-by: yinxiuxiu +--- + hw/intc/openpic.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/hw/intc/openpic.c b/hw/intc/openpic.c +index 0f99b77a17..d74ec11af4 100644 +--- a/hw/intc/openpic.c ++++ b/hw/intc/openpic.c +@@ -1031,13 +1031,14 @@ static void openpic_cpu_write_internal(void *opaque, hwaddr addr, + s_IRQ = IRQ_get_next(opp, &dst->servicing); + /* Check queued interrupts. */ + n_IRQ = IRQ_get_next(opp, &dst->raised); +- src = &opp->src[n_IRQ]; +- if (n_IRQ != -1 && +- (s_IRQ == -1 || +- IVPR_PRIORITY(src->ivpr) > dst->servicing.priority)) { +- DPRINTF("Raise OpenPIC INT output cpu %d irq %d", +- idx, n_IRQ); +- qemu_irq_raise(opp->dst[idx].irqs[OPENPIC_OUTPUT_INT]); ++ if (n_IRQ != -1) { ++ src = &opp->src[n_IRQ]; ++ if (s_IRQ == -1 || ++ IVPR_PRIORITY(src->ivpr) > dst->servicing.priority) { ++ DPRINTF("Raise OpenPIC INT output cpu %d irq %d", ++ idx, n_IRQ); ++ qemu_irq_raise(opp->dst[idx].irqs[OPENPIC_OUTPUT_INT]); ++ } + } + break; + default: +-- +2.41.0.windows.1 + diff --git a/Change-vmstate_cpuhp_sts-vmstateDescription-version_.patch b/Change-vmstate_cpuhp_sts-vmstateDescription-version_.patch new file mode 100644 index 0000000..164bf17 --- /dev/null +++ b/Change-vmstate_cpuhp_sts-vmstateDescription-version_.patch @@ -0,0 +1,30 @@ +From 0fc0686798aba89c4d4d94f7e0c8e513cfc473b1 Mon Sep 17 00:00:00 2001 +From: lijunwei +Date: Fri, 22 Nov 2024 17:09:17 +0800 +Subject: [PATCH] Change vmstate_cpuhp_sts vmstateDescription version_id + + fix live migration failed error message: + "qemu-kvm: Missing section footer for 0000:00:01.3/piix4_pm" + change vmstate_cpuhp_sts vmstateDescription version_id + + Signed-off-by: lijunwei +--- + hw/acpi/cpu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c +index 292e1daca2..4ab27ac66e 100644 +--- a/hw/acpi/cpu.c ++++ b/hw/acpi/cpu.c +@@ -316,7 +316,7 @@ void acpi_cpu_unplug_cb(CPUHotplugState *cpu_st, + + static const VMStateDescription vmstate_cpuhp_sts = { + .name = "CPU hotplug device state", +- .version_id = 1, ++ .version_id = 2, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_BOOL(is_inserting, AcpiCpuStatus), +-- +2.41.0.windows.1 + diff --git a/backends-cryptodev-vhost-user-Fix-local_error-leaks.patch b/backends-cryptodev-vhost-user-Fix-local_error-leaks.patch new file mode 100644 index 0000000..c5c1a4c --- /dev/null +++ b/backends-cryptodev-vhost-user-Fix-local_error-leaks.patch @@ -0,0 +1,41 @@ +From c5a859ec02af99574dfac2e5cfab9570345eb2e4 Mon Sep 17 00:00:00 2001 +From: qihao_yewu +Date: Wed, 5 Feb 2025 08:04:10 -0500 +Subject: [PATCH] backends/cryptodev-vhost-user: Fix local_error leaks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cheery-pick from 78b0c15a563ac4be5afb0375602ca0a3adc6c442 + +Do not propagate error to the upper, directly output the error +to avoid leaks. + +Fixes: 2fda101de07 ("virtio-crypto: Support asynchronous mode") +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2714 +Signed-off-by: Gabriel Barrantes +Reviewed-by: zhenwei pi +Message-Id: +Signed-off-by: Philippe Mathieu-Daudé +Signed-off-by: qihao_yewu +--- + backends/cryptodev-vhost-user.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/backends/cryptodev-vhost-user.c b/backends/cryptodev-vhost-user.c +index c3283ba84a..b8e95ca8b4 100644 +--- a/backends/cryptodev-vhost-user.c ++++ b/backends/cryptodev-vhost-user.c +@@ -281,8 +281,7 @@ static int cryptodev_vhost_user_create_session( + break; + + default: +- error_setg(&local_error, "Unsupported opcode :%" PRIu32 "", +- sess_info->op_code); ++ error_report("Unsupported opcode :%" PRIu32 "", sess_info->op_code); + return -VIRTIO_CRYPTO_NOTSUPP; + } + +-- +2.41.0.windows.1 + diff --git a/bakcend-VirtCCA-resolve-hugepage-memory-waste-issue-.patch b/bakcend-VirtCCA-resolve-hugepage-memory-waste-issue-.patch new file mode 100644 index 0000000..25ee218 --- /dev/null +++ b/bakcend-VirtCCA-resolve-hugepage-memory-waste-issue-.patch @@ -0,0 +1,320 @@ +From da6ee14de85b4e619eedfbe3a6cac3f09d948589 Mon Sep 17 00:00:00 2001 +From: nonce <2774337358@qq.com> +Date: Thu, 23 Jan 2025 21:03:10 +0800 +Subject: [PATCH] bakcend: VirtCCA:resolve hugepage memory waste issue in + vhost-user scenario + +VirtCCA is based on SWIOTLB to implement virtio and will only allocate +Bounce Buffer in the lower address range below 4GB. Therefore, the +backend hugepages memory allocated above 4GB will not be used, resulting +in significant waste. + +New address space and memory region are added to manage the backend +hugepages memory corresponding to the GPA below 4GB, and there are +shared with the vhostuser backend. + +Signed-off-by: nonce0_0 <2774337358@qq.com> +--- + backends/hostmem-file.c | 85 +++++++++++++++++++++++++++++++++++ + hw/core/numa.c | 20 +++++++++ + hw/virtio/vhost.c | 8 +++- + include/exec/address-spaces.h | 3 ++ + include/exec/cpu-common.h | 1 + + include/exec/memory.h | 11 +++++ + system/physmem.c | 17 +++++++ + system/vl.c | 9 ++++ + 8 files changed, 153 insertions(+), 1 deletion(-) + +diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c +index 361d4a8103..891fe4ac4a 100644 +--- a/backends/hostmem-file.c ++++ b/backends/hostmem-file.c +@@ -20,9 +20,13 @@ + #include "qom/object.h" + #include "qapi/visitor.h" + #include "qapi/qapi-visit-common.h" ++#include "sysemu/kvm.h" ++#include "exec/address-spaces.h" + + OBJECT_DECLARE_SIMPLE_TYPE(HostMemoryBackendFile, MEMORY_BACKEND_FILE) + ++bool virtcca_shared_hugepage_mapped = false; ++uint64_t virtcca_cvm_ram_size = 0; + + struct HostMemoryBackendFile { + HostMemoryBackend parent_obj; +@@ -36,6 +40,83 @@ struct HostMemoryBackendFile { + OnOffAuto rom; + }; + ++/* Parse the path of the hugepages memory file used for memory sharing */ ++static int virtcca_parse_share_mem_path(char *src, char *dst) ++{ ++ int ret = 0; ++ char src_copy[PATH_MAX]; ++ char *token = NULL; ++ char *last_dir = NULL; ++ char *second_last_dir = NULL; ++ static const char delimiter[] = "/"; ++ ++ if (src == NULL || dst == NULL || ++ strlen(src) == 0 || strlen(src) > PATH_MAX - 1) { ++ error_report("Invalid input: NULL pointer or invalid string length."); ++ return -1; ++ } ++ ++ strcpy(src_copy, src); ++ token = strtok(src_copy, delimiter); ++ ++ /* Iterate over the path segments to find the second-to-last directory */ ++ while (token != NULL) { ++ second_last_dir = last_dir; ++ last_dir = token; ++ token = strtok(NULL, delimiter); ++ } ++ ++ /* Check if the second-to-last directory is found */ ++ if (second_last_dir == NULL) { ++ error_report("Invalid path: second-to-last directory not found."); ++ return -1; ++ } ++ ++ /* ++ * Construct the share memory path by appending the extracted domain name ++ * to the hugepages memory filesystem prefix ++ */ ++ ret = snprintf(dst, PATH_MAX, "/dev/hugepages/libvirt/qemu/%s", ++ second_last_dir); ++ ++ if (ret < 0 || ret >= PATH_MAX) { ++ error_report("Error: snprintf failed to construct the share mem path"); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++/* ++ * Create a hugepage memory region in the virtcca scenario ++ * for sharing with process like vhost-user and others. ++ */ ++static void ++virtcca_shared_backend_memory_alloc(char *mem_path, uint32_t ram_flags, Error **errp) ++{ ++ char dst[PATH_MAX]; ++ uint64_t size = virtcca_cvm_ram_size; ++ ++ if (virtcca_parse_share_mem_path(mem_path, dst)) { ++ error_report("parse virtcca share memory path failed"); ++ exit(1); ++ } ++ if (virtcca_cvm_ram_size >= VIRTCCA_SHARED_HUGEPAGE_MAX_SIZE) { ++ size = VIRTCCA_SHARED_HUGEPAGE_MAX_SIZE; ++ } ++ ++ virtcca_shared_hugepage = g_new(MemoryRegion, 1); ++ memory_region_init_ram_from_file(virtcca_shared_hugepage, NULL, ++ "virtcca_shared_hugepage", size, ++ VIRTCCA_SHARED_HUGEPAGE_ALIGN, ++ ram_flags, dst, 0, errp); ++ if (*errp) { ++ error_reportf_err(*errp, "cannot init RamBlock for virtcca_shared_hugepage: "); ++ exit(1); ++ } ++ virtcca_shared_hugepage_mapped = true; ++} ++ + static void + file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp) + { +@@ -90,6 +171,10 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp) + backend->size, fb->align, ram_flags, + fb->mem_path, fb->offset, errp); + g_free(name); ++ ++ if (virtcca_cvm_enabled() && backend->share && !virtcca_shared_hugepage_mapped) { ++ virtcca_shared_backend_memory_alloc(fb->mem_path, ram_flags, errp); ++ } + #endif + } + +diff --git a/hw/core/numa.c b/hw/core/numa.c +index f08956ddb0..e7c48dab61 100644 +--- a/hw/core/numa.c ++++ b/hw/core/numa.c +@@ -42,6 +42,8 @@ + #include "qemu/option.h" + #include "qemu/config-file.h" + #include "qemu/cutils.h" ++#include "exec/address-spaces.h" ++#include "sysemu/kvm.h" + + QemuOptsList qemu_numa_opts = { + .name = "numa", +@@ -641,6 +643,21 @@ static void numa_init_memdev_container(MachineState *ms, MemoryRegion *ram) + } + } + ++/* ++ * Add virtcca_shared_hugepage as a sub-MR to the root MR of address space ++ * address_space_memory and address_space_virtcca_shared_memory. ++ */ ++static void virtcca_shared_memory_configuration(MachineState *ms) ++{ ++ MemoryRegion *alias_mr = g_new(MemoryRegion, 1); ++ ++ memory_region_add_subregion_overlap(ms->ram, 0, virtcca_shared_hugepage, 1); ++ memory_region_init_alias(alias_mr, NULL, "alias-mr", virtcca_shared_hugepage, ++ 0, int128_get64(virtcca_shared_hugepage->size)); ++ memory_region_add_subregion(address_space_virtcca_shared_memory.root, ++ VIRTCCA_GPA_START, alias_mr); ++} ++ + void numa_complete_configuration(MachineState *ms) + { + int i; +@@ -711,6 +728,9 @@ void numa_complete_configuration(MachineState *ms) + memory_region_init(ms->ram, OBJECT(ms), mc->default_ram_id, + ms->ram_size); + numa_init_memdev_container(ms, ms->ram); ++ if (virtcca_cvm_enabled() && virtcca_shared_hugepage->ram_block) { ++ virtcca_shared_memory_configuration(ms); ++ } + } + /* QEMU needs at least all unique node pair distances to build + * the whole NUMA distance table. QEMU treats the distance table +diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c +index d29075aa04..8b95558013 100644 +--- a/hw/virtio/vhost.c ++++ b/hw/virtio/vhost.c +@@ -30,6 +30,7 @@ + #include "sysemu/dma.h" + #include "trace.h" + #include "qapi/qapi-commands-migration.h" ++#include "sysemu/kvm.h" + + /* enabled until disconnected backend stabilizes */ + #define _VHOST_DEBUG 1 +@@ -1616,7 +1617,12 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque, + hdev->log_size = 0; + hdev->log_enabled = false; + hdev->started = false; +- memory_listener_register(&hdev->memory_listener, &address_space_memory); ++ if (virtcca_cvm_enabled()) { ++ memory_listener_register(&hdev->memory_listener, ++ &address_space_virtcca_shared_memory); ++ } else { ++ memory_listener_register(&hdev->memory_listener, &address_space_memory); ++ } + QLIST_INSERT_HEAD(&vhost_devices, hdev, entry); + + /* +diff --git a/include/exec/address-spaces.h b/include/exec/address-spaces.h +index 0d0aa61d68..4518b5da86 100644 +--- a/include/exec/address-spaces.h ++++ b/include/exec/address-spaces.h +@@ -33,6 +33,9 @@ MemoryRegion *get_system_io(void); + + extern AddressSpace address_space_memory; + extern AddressSpace address_space_io; ++extern AddressSpace address_space_virtcca_shared_memory; ++ ++extern MemoryRegion *virtcca_shared_hugepage; + + #endif + +diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h +index c7fd30d5b9..d21d9990ad 100644 +--- a/include/exec/cpu-common.h ++++ b/include/exec/cpu-common.h +@@ -28,6 +28,7 @@ typedef uint64_t vaddr; + + void cpu_exec_init_all(void); + void cpu_exec_step_atomic(CPUState *cpu); ++void virtcca_shared_memory_address_space_init(void); + + /* Using intptr_t ensures that qemu_*_page_mask is sign-extended even + * when intptr_t is 32-bit and we are aligning a long long. +diff --git a/include/exec/memory.h b/include/exec/memory.h +index 542c9da918..33778f5c64 100644 +--- a/include/exec/memory.h ++++ b/include/exec/memory.h +@@ -243,6 +243,17 @@ typedef struct IOMMUTLBEvent { + /* RAM FD is opened read-only */ + #define RAM_READONLY_FD (1 << 11) + ++/* The GPA range of the VirtCCA bounce buffer is from 1GB to 4GB. */ ++#define VIRTCCA_SHARED_HUGEPAGE_MAX_SIZE 0xc0000000ULL ++ ++/* The VirtCCA shared hugepage memory granularity is 1GB */ ++#define VIRTCCA_SHARED_HUGEPAGE_ALIGN 0x40000000ULL ++ ++/* The GPA starting address of the VirtCCA CVM is 1GB */ ++#define VIRTCCA_GPA_START 0x40000000ULL ++ ++extern uint64_t virtcca_cvm_ram_size; ++ + static inline void iommu_notifier_init(IOMMUNotifier *n, IOMMUNotify fn, + IOMMUNotifierFlag flags, + hwaddr start, hwaddr end, +diff --git a/system/physmem.c b/system/physmem.c +index 250f315bc8..8f4be2d131 100644 +--- a/system/physmem.c ++++ b/system/physmem.c +@@ -89,9 +89,17 @@ RAMList ram_list = { .blocks = QLIST_HEAD_INITIALIZER(ram_list.blocks) }; + + static MemoryRegion *system_memory; + static MemoryRegion *system_io; ++static MemoryRegion *virtcca_shared_memory; ++ ++/* ++ * Serves as the sub-MR of the root MR (virtcca_shared_memory) ++ * and is associated with the RAMBlock. ++ */ ++MemoryRegion *virtcca_shared_hugepage; + + AddressSpace address_space_io; + AddressSpace address_space_memory; ++AddressSpace address_space_virtcca_shared_memory; + + static MemoryRegion io_mem_unassigned; + +@@ -2586,6 +2594,15 @@ static void memory_map_init(void) + address_space_init(&address_space_io, system_io, "I/O"); + } + ++void virtcca_shared_memory_address_space_init(void) ++{ ++ virtcca_shared_memory = g_malloc(sizeof(*virtcca_shared_memory)); ++ memory_region_init(virtcca_shared_memory, NULL, ++ "virtcca_shared_memory", UINT64_MAX); ++ address_space_init(&address_space_virtcca_shared_memory, ++ virtcca_shared_memory, "virtcca_shared_memory"); ++} ++ + MemoryRegion *get_system_memory(void) + { + return system_memory; +diff --git a/system/vl.c b/system/vl.c +index a1e5e68773..7c10cd1337 100644 +--- a/system/vl.c ++++ b/system/vl.c +@@ -3784,6 +3784,15 @@ void qemu_init(int argc, char **argv) + configure_accelerators(argv[0]); + phase_advance(PHASE_ACCEL_CREATED); + ++ /* ++ * Must run after kvm_init completes, as virtcca_cvm_enabled() ++ * depends on initialization performed in kvm_init. ++ */ ++ if (virtcca_cvm_enabled()) { ++ virtcca_cvm_ram_size = current_machine->ram_size; ++ virtcca_shared_memory_address_space_init(); ++ } ++ + /* + * Beware, QOM objects created before this point miss global and + * compat properties. +-- +2.41.0.windows.1 + diff --git a/contrib-plugins-add-compat-for-g_memdup2.patch b/contrib-plugins-add-compat-for-g_memdup2.patch new file mode 100644 index 0000000..8e8b866 --- /dev/null +++ b/contrib-plugins-add-compat-for-g_memdup2.patch @@ -0,0 +1,62 @@ +From 84321dcfb4ec3d08984e7680c8efad80907bde84 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Alex=20Benn=C3=A9e?= +Date: Mon, 29 Jul 2024 15:44:13 +0100 +Subject: [PATCH] contrib/plugins: add compat for g_memdup2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We were premature if bumping this because some of our builds are still +on older glibs. Just copy the compat handler for now and we can remove +it later. + +Fixes: ee293103b0 (plugins: update lockstep to use g_memdup2) +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2161 +Reviewed-by: Philippe Mathieu-Daudé +Signed-off-by: Alex Bennée +Message-Id: <20240729144414.830369-14-alex.bennee@linaro.org> +(cherry picked from commit 44e794896759236885f6d30d1f6b9b8b76355d52) +Signed-off-by: zhujun2 +--- + contrib/plugins/lockstep.c | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + +diff --git a/contrib/plugins/lockstep.c b/contrib/plugins/lockstep.c +index 237543b43a..0c6f060183 100644 +--- a/contrib/plugins/lockstep.c ++++ b/contrib/plugins/lockstep.c +@@ -100,6 +100,31 @@ static void plugin_exit(qemu_plugin_id_t id, void *p) + plugin_cleanup(id); + } + ++/* ++ * g_memdup has been deprecated in Glib since 2.68 and ++ * will complain about it if you try to use it. However until ++ * glib_req_ver for QEMU is bumped we make a copy of the glib-compat ++ * handler. ++ */ ++static inline gpointer g_memdup2_qemu(gconstpointer mem, gsize byte_size) ++{ ++#if GLIB_CHECK_VERSION(2, 68, 0) ++ return g_memdup2(mem, byte_size); ++#else ++ gpointer new_mem; ++ ++ if (mem && byte_size != 0) { ++ new_mem = g_malloc(byte_size); ++ memcpy(new_mem, mem, byte_size); ++ } else { ++ new_mem = NULL; ++ } ++ ++ return new_mem; ++#endif ++} ++#define g_memdup2(m, s) g_memdup2_qemu(m, s) ++ + static void report_divergance(ExecState *us, ExecState *them) + { + DivergeState divrec = { log, 0 }; +-- +2.41.0.windows.1 + diff --git a/crypto-fix-error-check-on-gcry_md_open.patch b/crypto-fix-error-check-on-gcry_md_open.patch new file mode 100644 index 0000000..a1e10e6 --- /dev/null +++ b/crypto-fix-error-check-on-gcry_md_open.patch @@ -0,0 +1,44 @@ +From 0029172c2c57c18d6aef61070c2471f40de6bb45 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Wed, 30 Oct 2024 10:08:12 +0000 +Subject: [PATCH] crypto: fix error check on gcry_md_open +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Gcrypt does not return negative values on error, it returns non-zero +values. This caused QEMU not to detect failure to open an unsupported +hash, resulting in a later crash trying to use a NULL context. + +Reviewed-by: Philippe Mathieu-Daudé +Signed-off-by: Daniel P. Berrangé +Signed-off-by: cheliequan +--- + crypto/hash-gcrypt.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/crypto/hash-gcrypt.c b/crypto/hash-gcrypt.c +index d3bdfe5633..bf5d7ff9ba 100644 +--- a/crypto/hash-gcrypt.c ++++ b/crypto/hash-gcrypt.c +@@ -56,7 +56,7 @@ qcrypto_gcrypt_hash_bytesv(QCryptoHashAlgorithm alg, + size_t *resultlen, + Error **errp) + { +- int i, ret; ++ gcry_error_t ret; + gcry_md_hd_t md; + unsigned char *digest; + +@@ -69,7 +69,7 @@ qcrypto_gcrypt_hash_bytesv(QCryptoHashAlgorithm alg, + + ret = gcry_md_open(&md, qcrypto_hash_alg_map[alg], 0); + +- if (ret < 0) { ++ if (ret != 0) { + error_setg(errp, + "Unable to initialize hash algorithm: %s", + gcry_strerror(ret)); +-- +2.41.0.windows.1 + diff --git a/crypto-perform-runtime-check-for-hash-hmac-support-i.patch b/crypto-perform-runtime-check-for-hash-hmac-support-i.patch new file mode 100644 index 0000000..f153a1d --- /dev/null +++ b/crypto-perform-runtime-check-for-hash-hmac-support-i.patch @@ -0,0 +1,48 @@ +From 17d589becc1a66934e55a4e2efffdd3876d56130 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Wed, 30 Oct 2024 10:09:30 +0000 +Subject: [PATCH] crypto: perform runtime check for hash/hmac support in gcrypt +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +gcrypto has the ability to dynamically disable hash/hmac algorithms +at runtime, so QEMU must perform a runtime check. + +Reviewed-by: Philippe Mathieu-Daudé +Signed-off-by: Daniel P. Berrangé +Signed-off-by: cheliequan +--- + crypto/hash-gcrypt.c | 2 +- + crypto/hmac-gcrypt.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/crypto/hash-gcrypt.c b/crypto/hash-gcrypt.c +index d3bdfe5633..2b6dbd97bb 100644 +--- a/crypto/hash-gcrypt.c ++++ b/crypto/hash-gcrypt.c +@@ -42,7 +42,7 @@ gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg) + { + if (alg < G_N_ELEMENTS(qcrypto_hash_alg_map) && + qcrypto_hash_alg_map[alg] != GCRY_MD_NONE) { +- return true; ++ return gcry_md_test_algo(qcrypto_hash_alg_map[alg]) == 0; + } + return false; + } +diff --git a/crypto/hmac-gcrypt.c b/crypto/hmac-gcrypt.c +index 888afb86ed..15926fccfa 100644 +--- a/crypto/hmac-gcrypt.c ++++ b/crypto/hmac-gcrypt.c +@@ -40,7 +40,7 @@ bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg) + { + if (alg < G_N_ELEMENTS(qcrypto_hmac_alg_map) && + qcrypto_hmac_alg_map[alg] != GCRY_MAC_NONE) { +- return true; ++ return gcry_mac_test_algo(qcrypto_hmac_alg_map[alg]) == 0; + } + + return false; +-- +2.41.0.windows.1 + diff --git a/hvf-remove-unused-but-set-variable.patch b/hvf-remove-unused-but-set-variable.patch new file mode 100644 index 0000000..8d42024 --- /dev/null +++ b/hvf-remove-unused-but-set-variable.patch @@ -0,0 +1,57 @@ +From 885c1bf512582757f9d7e2e360701f72a9d6e95f Mon Sep 17 00:00:00 2001 +From: Zhang Jiao +Date: Thu, 12 Dec 2024 11:27:23 +0800 +Subject: [PATCH] hvf: remove unused but set variable + +cheery-pick from 19d542cc0bce0b3641e80444374f9ffd8294a15b + +fixes associated warning when building on MacOS. + +Signed-off-by: Pierrick Bouvier +Link: https://lore.kernel.org/r/20241023182922.1040964-1-pierrick.bouvier@linaro.org +Signed-off-by: Paolo Bonzini +Signed-off-by: Zhang Jiao +--- + target/i386/hvf/x86_task.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/target/i386/hvf/x86_task.c b/target/i386/hvf/x86_task.c +index f09bfbdda5..cdea2ea69d 100644 +--- a/target/i386/hvf/x86_task.c ++++ b/target/i386/hvf/x86_task.c +@@ -122,7 +122,6 @@ void vmx_handle_task_switch(CPUState *cpu, x68_segment_selector tss_sel, int rea + load_regs(cpu); + + struct x86_segment_descriptor curr_tss_desc, next_tss_desc; +- int ret; + x68_segment_selector old_tss_sel = vmx_read_segment_selector(cpu, R_TR); + uint64_t old_tss_base = vmx_read_segment_base(cpu, R_TR); + uint32_t desc_limit; +@@ -138,7 +137,7 @@ void vmx_handle_task_switch(CPUState *cpu, x68_segment_selector tss_sel, int rea + if (reason == TSR_IDT_GATE && gate_valid) { + int dpl; + +- ret = x86_read_call_gate(cpu, &task_gate_desc, gate); ++ x86_read_call_gate(cpu, &task_gate_desc, gate); + + dpl = task_gate_desc.dpl; + x68_segment_selector cs = vmx_read_segment_selector(cpu, R_CS); +@@ -167,11 +166,12 @@ void vmx_handle_task_switch(CPUState *cpu, x68_segment_selector tss_sel, int rea + x86_write_segment_descriptor(cpu, &next_tss_desc, tss_sel); + } + +- if (next_tss_desc.type & 8) +- ret = task_switch_32(cpu, tss_sel, old_tss_sel, old_tss_base, &next_tss_desc); +- else ++ if (next_tss_desc.type & 8) { ++ task_switch_32(cpu, tss_sel, old_tss_sel, old_tss_base, &next_tss_desc); ++ } else { + //ret = task_switch_16(cpu, tss_sel, old_tss_sel, old_tss_base, &next_tss_desc); + VM_PANIC("task_switch_16"); ++ } + + macvm_set_cr0(cpu->accel->fd, rvmcs(cpu->accel->fd, VMCS_GUEST_CR0) | + CR0_TS_MASK); +-- +2.41.0.windows.1 + diff --git a/hw-audio-hda-fix-memory-leak-on-audio-setup.patch b/hw-audio-hda-fix-memory-leak-on-audio-setup.patch new file mode 100644 index 0000000..de45fe9 --- /dev/null +++ b/hw-audio-hda-fix-memory-leak-on-audio-setup.patch @@ -0,0 +1,85 @@ +From ecca2052693cc2a91459ac418bface2f1e635c88 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Thu, 14 Nov 2024 13:53:18 +0100 +Subject: [PATCH] hw/audio/hda: fix memory leak on audio setup +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When SET_STREAM_FORMAT is called, the st->buft timer is overwritten, thus +causing a memory leak. This was originally fixed in commit 816139ae6a5 +("hw/audio/hda: fix memory leak on audio setup", 2024-11-14) but that +caused the audio to break in SPICE. + +Fortunately, a simpler fix is possible. The timer only needs to be +reset, because the callback is always the same (st->output is set at +realize time in hda_audio_init); call to timer_new_ns overkill. Replace +it with timer_del and only initialize the timer once; for simplicity, +do it even if use_timer is false. + +An even simpler fix would be to free the old time in hda_audio_setup(). +However, it seems better to place the initialization of the timer close +to that of st->ouput. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Paolo Bonzini +Reviewed-by: Michael Tokarev +Message-ID: <20241114125318.1707590-3-pbonzini@redhat.com> +Signed-off-by: Philippe Mathieu-Daudé +(cherry picked from commit 626b39006d2f9b1378a04cb88a2187bb852cb055) +Signed-off-by: zhujun2 +--- + hw/audio/hda-codec.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/hw/audio/hda-codec.c b/hw/audio/hda-codec.c +index 19f401cabe..ac908e56c6 100644 +--- a/hw/audio/hda-codec.c ++++ b/hw/audio/hda-codec.c +@@ -487,8 +487,7 @@ static void hda_audio_setup(HDAAudioStream *st) + if (st->output) { + if (use_timer) { + cb = hda_audio_output_cb; +- st->buft = timer_new_ns(QEMU_CLOCK_VIRTUAL, +- hda_audio_output_timer, st); ++ timer_del(st->buft); + } else { + cb = hda_audio_compat_output_cb; + } +@@ -497,8 +496,7 @@ static void hda_audio_setup(HDAAudioStream *st) + } else { + if (use_timer) { + cb = hda_audio_input_cb; +- st->buft = timer_new_ns(QEMU_CLOCK_VIRTUAL, +- hda_audio_input_timer, st); ++ timer_del(st->buft); + } else { + cb = hda_audio_compat_input_cb; + } +@@ -726,8 +724,12 @@ static void hda_audio_init(HDACodecDevice *hda, + st->gain_right = QEMU_HDA_AMP_STEPS; + st->compat_bpos = sizeof(st->compat_buf); + st->output = true; ++ st->buft = timer_new_ns(QEMU_CLOCK_VIRTUAL, ++ hda_audio_output_timer, st); + } else { + st->output = false; ++ st->buft = timer_new_ns(QEMU_CLOCK_VIRTUAL, ++ hda_audio_input_timer, st); + } + st->format = AC_FMT_TYPE_PCM | AC_FMT_BITS_16 | + (1 << AC_FMT_CHAN_SHIFT); +@@ -750,9 +752,7 @@ static void hda_audio_exit(HDACodecDevice *hda) + if (st->node == NULL) { + continue; + } +- if (a->use_timer) { +- timer_free(st->buft); +- } ++ timer_free(st->buft); + if (st->output) { + AUD_close_out(&a->card, st->voice.out); + } else { +-- +2.41.0.windows.1 + diff --git a/hw-audio-virtio-snd-Always-use-little-endian-audio-f.patch b/hw-audio-virtio-snd-Always-use-little-endian-audio-f.patch new file mode 100644 index 0000000..0932b2d --- /dev/null +++ b/hw-audio-virtio-snd-Always-use-little-endian-audio-f.patch @@ -0,0 +1,42 @@ +From 482808a35957c10d9eb4264492a8e11a2ba749c1 Mon Sep 17 00:00:00 2001 +From: gubin +Date: Fri, 22 Nov 2024 17:49:38 +0800 +Subject: [PATCH] hw/audio/virtio-snd: Always use little endian audio format +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cherry-pick from a276ec8e2632c9015d0f9b4e47194e4e91dfa8bb + +The VIRTIO Sound Device conforms with the Virtio spec v1.2, +thus only use little endianness. + +Remove the suspicious target_words_bigendian() noticed during +code review. + +Cc: qemu-stable@nongnu.org +Fixes: eb9ad377bb ("virtio-sound: handle control messages and streams") +Signed-off-by: Philippe Mathieu-Daudé +Reviewed-by: Michael S. Tsirkin +Message-Id: <20240422211830.25606-1-philmd@linaro.org> +Signed-off-by: gubin +--- + hw/audio/virtio-snd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c +index 817fdcd910..9f7a69e408 100644 +--- a/hw/audio/virtio-snd.c ++++ b/hw/audio/virtio-snd.c +@@ -377,7 +377,7 @@ static void virtio_snd_get_qemu_audsettings(audsettings *as, + as->nchannels = MIN(AUDIO_MAX_CHANNELS, params->channels); + as->fmt = virtio_snd_get_qemu_format(params->format); + as->freq = virtio_snd_get_qemu_freq(params->rate); +- as->endianness = target_words_bigendian() ? 1 : 0; ++ as->endianness = 0; /* Conforming to VIRTIO 1.0: always little endian. */ + } + + /* +-- +2.41.0.windows.1 + diff --git a/hw-intc-Don-t-clear-pending-bits-on-IRQ-lowering.patch b/hw-intc-Don-t-clear-pending-bits-on-IRQ-lowering.patch new file mode 100644 index 0000000..cf78d7e --- /dev/null +++ b/hw-intc-Don-t-clear-pending-bits-on-IRQ-lowering.patch @@ -0,0 +1,39 @@ +From b44fc9f3fc91363c55f6ba739f6c09222f979d88 Mon Sep 17 00:00:00 2001 +From: Sergey Makarov +Date: Wed, 18 Sep 2024 17:02:29 +0300 +Subject: [PATCH] hw/intc: Don't clear pending bits on IRQ lowering + +According to PLIC specification (chapter 5), there +is only one case, when interrupt is claimed. Fix +PLIC controller to match this behavior. + +Signed-off-by: Sergey Makarov +Reviewed-by: Alistair Francis +Message-ID: <20240918140229.124329-3-s.makarov@syntacore.com> +Signed-off-by: Alistair Francis +(cherry picked from commit a84be2baa9eca8bc500f866ad943b8f63dc99adf) +Signed-off-by: zhujun2 +--- + hw/intc/sifive_plic.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c +index 5522ede2cf..e5de52bc44 100644 +--- a/hw/intc/sifive_plic.c ++++ b/hw/intc/sifive_plic.c +@@ -349,8 +349,10 @@ static void sifive_plic_irq_request(void *opaque, int irq, int level) + { + SiFivePLICState *s = opaque; + +- sifive_plic_set_pending(s, irq, level > 0); +- sifive_plic_update(s); ++ if (level > 0) { ++ sifive_plic_set_pending(s, irq, true); ++ sifive_plic_update(s); ++ } + } + + static void sifive_plic_realize(DeviceState *dev, Error **errp) +-- +2.41.0.windows.1 + diff --git a/hw-misc-nrf51_rng-Don-t-use-BIT_MASK-when-we-mean-BI.patch b/hw-misc-nrf51_rng-Don-t-use-BIT_MASK-when-we-mean-BI.patch new file mode 100644 index 0000000..4920571 --- /dev/null +++ b/hw-misc-nrf51_rng-Don-t-use-BIT_MASK-when-we-mean-BI.patch @@ -0,0 +1,70 @@ +From e6b4460566522f1a9d608217bcb1534bf6709cab Mon Sep 17 00:00:00 2001 +From: Zhang Jiao +Date: Thu, 12 Dec 2024 12:16:01 +0800 +Subject: [PATCH] hw/misc/nrf51_rng: Don't use BIT_MASK() when we mean BIT() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cheery-pick from a29a9776407e68c5560687e07828925bda710150 + +The BIT_MASK() macro from bitops.h provides the mask of a bit +within a particular word of a multi-word bit array; it is intended +to be used with its counterpart BIT_WORD() that gives the index +of the word in the array. + +In nrf51_rng we are using it for cases where we have a bit number +that we know is the index of a bit within a single word (in fact, it +happens that all the bit numbers we pass to it are zero). This +happens to give the right answer, but the macro that actually +does the job we want here is BIT(). + +Use BIT() instead of BIT_MASK(). + +Signed-off-by: Peter Maydell +Reviewed-by: Philippe Mathieu-Daudé +Message-ID: <20241108135644.4007151-1-peter.maydell@linaro.org> +Signed-off-by: Philippe Mathieu-Daudé +Signed-off-by: Zhang Jiao +--- + hw/misc/nrf51_rng.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/hw/misc/nrf51_rng.c b/hw/misc/nrf51_rng.c +index fc86e1b697..e911b3a3a3 100644 +--- a/hw/misc/nrf51_rng.c ++++ b/hw/misc/nrf51_rng.c +@@ -107,25 +107,25 @@ static void rng_write(void *opaque, hwaddr offset, + break; + case NRF51_RNG_REG_SHORTS: + s->shortcut_stop_on_valrdy = +- (value & BIT_MASK(NRF51_RNG_REG_SHORTS_VALRDY_STOP)) ? 1 : 0; ++ (value & BIT(NRF51_RNG_REG_SHORTS_VALRDY_STOP)) ? 1 : 0; + break; + case NRF51_RNG_REG_INTEN: + s->interrupt_enabled = +- (value & BIT_MASK(NRF51_RNG_REG_INTEN_VALRDY)) ? 1 : 0; ++ (value & BIT(NRF51_RNG_REG_INTEN_VALRDY)) ? 1 : 0; + break; + case NRF51_RNG_REG_INTENSET: +- if (value & BIT_MASK(NRF51_RNG_REG_INTEN_VALRDY)) { ++ if (value & BIT(NRF51_RNG_REG_INTEN_VALRDY)) { + s->interrupt_enabled = 1; + } + break; + case NRF51_RNG_REG_INTENCLR: +- if (value & BIT_MASK(NRF51_RNG_REG_INTEN_VALRDY)) { ++ if (value & BIT(NRF51_RNG_REG_INTEN_VALRDY)) { + s->interrupt_enabled = 0; + } + break; + case NRF51_RNG_REG_CONFIG: + s->filter_enabled = +- (value & BIT_MASK(NRF51_RNG_REG_CONFIG_DECEN)) ? 1 : 0; ++ (value & BIT(NRF51_RNG_REG_CONFIG_DECEN)) ? 1 : 0; + break; + + default: +-- +2.41.0.windows.1 + diff --git a/hw-pci-Remove-unused-pci_irq_pulse-method.patch b/hw-pci-Remove-unused-pci_irq_pulse-method.patch new file mode 100644 index 0000000..69baa9e --- /dev/null +++ b/hw-pci-Remove-unused-pci_irq_pulse-method.patch @@ -0,0 +1,46 @@ +From d1b98e84eeec0b94403fb716bef41080f6bee3b3 Mon Sep 17 00:00:00 2001 +From: Zhang Jiao +Date: Thu, 12 Dec 2024 10:31:47 +0800 +Subject: [PATCH] hw/pci: Remove unused pci_irq_pulse() method +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cheery-pick from ef45f46f382a5e2c41c39c71fd3364cff4f41bf5 + +Last use of pci_irq_pulse() was removed 7 years ago in commit +5e9aa92eb1 ("hw/block: Fix pin-based interrupt behaviour of NVMe"). + +Signed-off-by: Philippe Mathieu-Daudé +Reviewed-by: Thomas Huth +Message-ID: <20241122103418.539-1-philmd@linaro.org> +Signed-off-by: Thomas Huth +Signed-off-by: Zhang Jiao +--- + include/hw/pci/pci.h | 10 ---------- + 1 file changed, 10 deletions(-) + +diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h +index 7cf7b5619a..cee0cf7460 100644 +--- a/include/hw/pci/pci.h ++++ b/include/hw/pci/pci.h +@@ -632,16 +632,6 @@ static inline void pci_irq_deassert(PCIDevice *pci_dev) + pci_set_irq(pci_dev, 0); + } + +-/* +- * FIXME: PCI does not work this way. +- * All the callers to this method should be fixed. +- */ +-static inline void pci_irq_pulse(PCIDevice *pci_dev) +-{ +- pci_irq_assert(pci_dev); +- pci_irq_deassert(pci_dev); +-} +- + MSIMessage pci_get_msi_message(PCIDevice *dev, int vector); + void pci_set_power(PCIDevice *pci_dev, bool state); + +-- +2.41.0.windows.1 + diff --git a/hw-timer-exynos4210_mct-fix-possible-int-overflow.patch b/hw-timer-exynos4210_mct-fix-possible-int-overflow.patch new file mode 100644 index 0000000..d1c4a33 --- /dev/null +++ b/hw-timer-exynos4210_mct-fix-possible-int-overflow.patch @@ -0,0 +1,36 @@ +From d0076c906a96019c0fe12be78e5ab21eaf15e69e Mon Sep 17 00:00:00 2001 +From: qihao_yewu +Date: Mon, 25 Nov 2024 04:48:16 -0500 +Subject: [PATCH] hw/timer/exynos4210_mct: fix possible int overflow + +cheery-pick from c5d36da7ec62e4c72a72a437057fb6072cf0d6ab + +The product "icnto * s->tcntb" may overflow uint32_t. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Signed-off-by: Dmitry Frolov +Message-id: 20241106083801.219578-2-frolov@swemel.ru +Reviewed-by: Peter Maydell +Signed-off-by: Peter Maydell +Signed-off-by: qihao_yewu +--- + hw/timer/exynos4210_mct.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/timer/exynos4210_mct.c b/hw/timer/exynos4210_mct.c +index 446bbd2b96..6f47bfe2c2 100644 +--- a/hw/timer/exynos4210_mct.c ++++ b/hw/timer/exynos4210_mct.c +@@ -815,7 +815,7 @@ static uint32_t exynos4210_ltick_cnt_get_cnto(struct tick_timer *s) + /* Both are counting */ + icnto = remain / s->tcntb; + if (icnto) { +- tcnto = remain % (icnto * s->tcntb); ++ tcnto = remain % ((uint64_t)icnto * s->tcntb); + } else { + tcnto = remain % s->tcntb; + } +-- +2.41.0.windows.1 + diff --git a/hw-usb-hcd-ehci-Fix-debug-printf-format-string.patch b/hw-usb-hcd-ehci-Fix-debug-printf-format-string.patch new file mode 100644 index 0000000..709f2a5 --- /dev/null +++ b/hw-usb-hcd-ehci-Fix-debug-printf-format-string.patch @@ -0,0 +1,40 @@ +From 4ca8ac93bd2c328c80841540b3b5e297ff24d3c9 Mon Sep 17 00:00:00 2001 +From: qihao_yewu +Date: Wed, 5 Feb 2025 06:02:50 -0500 +Subject: [PATCH] hw/usb/hcd-ehci: Fix debug printf format string +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cheery-pick from a40b5f32867294b7c855d2e4b98a4c2d32b3be28 + +The variable is uint64_t so needs %PRIu64 instead of %d. + +Fixes: 3ae7eb88c47 ("ehci: fix overflow in frame timer code") +Signed-off-by: BALATON Zoltan +Reviewed-by: Peter Maydell +Reviewed-by: Philippe Mathieu-Daudé +Message-ID: <20250124124713.64F8C4E6031@zero.eik.bme.hu> +Signed-off-by: Philippe Mathieu-Daudé +Signed-off-by: qihao_yewu +--- + hw/usb/hcd-ehci.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c +index 7b093acd98..fa8c7af5c8 100644 +--- a/hw/usb/hcd-ehci.c ++++ b/hw/usb/hcd-ehci.c +@@ -2287,7 +2287,8 @@ static void ehci_work_bh(void *opaque) + ehci_update_frindex(ehci, skipped_uframes); + ehci->last_run_ns += UFRAME_TIMER_NS * skipped_uframes; + uframes -= skipped_uframes; +- DPRINTF("WARNING - EHCI skipped %d uframes\n", skipped_uframes); ++ DPRINTF("WARNING - EHCI skipped %"PRIu64" uframes\n", ++ skipped_uframes); + } + + for (i = 0; i < uframes; i++) { +-- +2.41.0.windows.1 + diff --git a/linux-user-Print-tid-not-pid-with-strace.patch b/linux-user-Print-tid-not-pid-with-strace.patch new file mode 100644 index 0000000..1c60527 --- /dev/null +++ b/linux-user-Print-tid-not-pid-with-strace.patch @@ -0,0 +1,36 @@ +From 2f37362de1d971cc90c35405705bfa22a33f6cd8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?J=2E=20Neusch=C3=A4fer?= +Date: Wed, 20 Nov 2024 14:20:24 -0600 +Subject: [PATCH] linux-user: Print tid not pid with strace +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This aligns with strace, and is very useful when tracing multi-threaded +programs. The result is the same in single-threaded programs. + +Signed-off-by: J. Neuschäfer +Message-Id: 20241024-strace-v1-1-56c4161431cd@gmx.net +[rth: Use TaskState.ts_tid via get_task_state()] +Signed-off-by: Richard Henderson +Signed-off-by: Zhongrui Tang +--- + linux-user/strace.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/linux-user/strace.c b/linux-user/strace.c +index cf26e55264..ac9177ebe4 100644 +--- a/linux-user/strace.c ++++ b/linux-user/strace.c +@@ -4176,7 +4176,7 @@ print_syscall(CPUArchState *cpu_env, int num, + if (!f) { + return; + } +- fprintf(f, "%d ", getpid()); ++ fprintf(f, "%d ", get_task_state(env_cpu(cpu_env))->ts_tid); + + for (i = 0; i < nsyscalls; i++) { + if (scnames[i].nr == num) { +-- +2.41.0.windows.1 + diff --git a/migration-Ensure-vmstate_save-sets-errp.patch b/migration-Ensure-vmstate_save-sets-errp.patch new file mode 100644 index 0000000..e35e2c2 --- /dev/null +++ b/migration-Ensure-vmstate_save-sets-errp.patch @@ -0,0 +1,85 @@ +From 72aa575da11b3a897eeaae926802c50dc8ff7a84 Mon Sep 17 00:00:00 2001 +From: Hanna Czenczek +Date: Tue, 15 Oct 2024 19:04:37 +0200 +Subject: [PATCH] migration: Ensure vmstate_save() sets errp + +migration/savevm.c contains some calls to vmstate_save() that are +followed by migrate_set_error() if the integer return value indicates an +error. migrate_set_error() requires that the `Error *` object passed to +it is set. Therefore, vmstate_save() is assumed to always set *errp on +error. + +Right now, that assumption is not met: vmstate_save_state_v() (called +internally by vmstate_save()) will not set *errp if +vmstate_subsection_save() or vmsd->post_save() fail. Fix that by adding +an *errp parameter to vmstate_subsection_save(), and by generating a +generic error in case post_save() fails (as is already done for +pre_save()). + +Without this patch, qemu will crash after vmstate_subsection_save() or +post_save() have failed inside of a vmstate_save() call (unless +migrate_set_error() then happen to discard the new error because +s->error is already set). This happens e.g. when receiving the state +from a virtio-fs back-end (virtiofsd) fails. + +Signed-off-by: Hanna Czenczek +Link: https://lore.kernel.org/r/20241015170437.310358-1-hreitz@redhat.com +Signed-off-by: Peter Xu +(cherry picked from commit 37dfcba1a04989830c706f9cbc00450e5d3a7447) +Signed-off-by: zhujun2 +--- + migration/vmstate.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/migration/vmstate.c b/migration/vmstate.c +index b7723a4187..bd08e390c5 100644 +--- a/migration/vmstate.c ++++ b/migration/vmstate.c +@@ -22,7 +22,8 @@ + #include "trace.h" + + static int vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd, +- void *opaque, JSONWriter *vmdesc); ++ void *opaque, JSONWriter *vmdesc, ++ Error **errp); + static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd, + void *opaque); + +@@ -440,12 +441,13 @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd, + json_writer_end_array(vmdesc); + } + +- ret = vmstate_subsection_save(f, vmsd, opaque, vmdesc); ++ ret = vmstate_subsection_save(f, vmsd, opaque, vmdesc, errp); + + if (vmsd->post_save) { + int ps_ret = vmsd->post_save(opaque); +- if (!ret) { ++ if (!ret && ps_ret) { + ret = ps_ret; ++ error_setg(errp, "post-save failed: %s", vmsd->name); + } + } + return ret; +@@ -515,7 +517,8 @@ static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd, + } + + static int vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd, +- void *opaque, JSONWriter *vmdesc) ++ void *opaque, JSONWriter *vmdesc, ++ Error **errp) + { + const VMStateDescription **sub = vmsd->subsections; + bool vmdesc_has_subsections = false; +@@ -543,7 +546,7 @@ static int vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd, + qemu_put_byte(f, len); + qemu_put_buffer(f, (uint8_t *)vmsdsub->name, len); + qemu_put_be32(f, vmsdsub->version_id); +- ret = vmstate_save_state(f, vmsdsub, opaque, vmdesc); ++ ret = vmstate_save_state_with_err(f, vmsdsub, opaque, vmdesc, errp); + if (ret) { + return ret; + } +-- +2.41.0.windows.1 + diff --git a/parallels-fix-ext_off-assertion-failure-due-to-overf.patch b/parallels-fix-ext_off-assertion-failure-due-to-overf.patch new file mode 100644 index 0000000..8f9770c --- /dev/null +++ b/parallels-fix-ext_off-assertion-failure-due-to-overf.patch @@ -0,0 +1,47 @@ +From 44cf15f26215a07876d78d8ee63f0fb10ce2d1d4 Mon Sep 17 00:00:00 2001 +From: qihao_yewu +Date: Wed, 5 Feb 2025 07:07:13 -0500 +Subject: [PATCH] parallels: fix ext_off assertion failure due to overflow + +cheery-pick from 58607752d173438994d28dea7e2c2587726663e6 + +This error was discovered by fuzzing qemu-img. + +When ph.ext_off has a sufficiently large value, the operation +le64_to_cpu(ph.ext_off) << BDRV_SECTOR_BITS in +parallels_read_format_extension() can cause an overflow in int64_t. +This overflow triggers the assert(ext_off > 0) +check in block/parallels-ext.c: parallels_read_format_extension(), +leading to a crash. + +This commit adds a check to prevent overflow when shifting ph.ext_off +by BDRV_SECTOR_BITS, ensuring that the value remains within a valid range. + +Reported-by: Leonid Reviakin +Signed-off-by: Denis Rastyogin +Reviewed-by: Denis V. Lunev +Message-ID: <20241212104212.513947-2-gerben@altlinux.org> +Signed-off-by: Stefan Hajnoczi +Signed-off-by: qihao_yewu +--- + block/parallels.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/block/parallels.c b/block/parallels.c +index 9205a0864f..8f2b58e1c9 100644 +--- a/block/parallels.c ++++ b/block/parallels.c +@@ -1298,6 +1298,10 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags, + error_setg(errp, "Catalog too large"); + return -EFBIG; + } ++ if (le64_to_cpu(ph.ext_off) >= (INT64_MAX >> BDRV_SECTOR_BITS)) { ++ error_setg(errp, "Invalid image: Too big offset"); ++ return -EFBIG; ++ } + + size = bat_entry_off(s->bat_size); + s->header_size = ROUND_UP(size, bdrv_opt_mem_align(bs->file->bs)); +-- +2.41.0.windows.1 + diff --git a/qapi-qom-target-i386-csv-guest-Introduce-secret-head.patch b/qapi-qom-target-i386-csv-guest-Introduce-secret-head.patch new file mode 100644 index 0000000..8cfc34d --- /dev/null +++ b/qapi-qom-target-i386-csv-guest-Introduce-secret-head.patch @@ -0,0 +1,220 @@ +From 10f5fa07068f54b23b01bf875259dc1a259d66b4 Mon Sep 17 00:00:00 2001 +From: hanliyang +Date: Fri, 2 Aug 2024 01:35:25 +0800 +Subject: [PATCH] qapi/qom,target/i386: csv-guest: Introduce + secret-header-file=str and secret-file=str options + +This feature only applied to Hygon CSV. + +User can utilize the hag to generate secret header file and secret file, +and inject these data to guest encrypted secret area automatically. + +Signed-off-by: hanliyang +--- + qapi/qom.json | 9 ++++- + qemu-options.hx | 8 +++- + target/i386/sev.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 115 insertions(+), 2 deletions(-) + +diff --git a/qapi/qom.json b/qapi/qom.json +index 51d9daf55a..a74c7a91f9 100644 +--- a/qapi/qom.json ++++ b/qapi/qom.json +@@ -869,6 +869,11 @@ + # @user-id: the user id of the guest owner, only support on Hygon CPUs + # (since 8.2) + # ++# @secret-header-file: the header file of guest owner's secret, only ++# support on Hygon CPUs (since 8.2) ++# @secret-file: the file guest owner's secret, only support on Hygon ++# CPUs (since 8.2) ++# + # Since: 2.12 + ## + { 'struct': 'SevGuestProperties', +@@ -880,7 +885,9 @@ + '*cbitpos': 'uint32', + 'reduced-phys-bits': 'uint32', + '*kernel-hashes': 'bool', +- '*user-id': 'str' } } ++ '*user-id': 'str', ++ '*secret-header-file': 'str', ++ '*secret-file': 'str' } } + + ## + # @ThreadContextProperties: +diff --git a/qemu-options.hx b/qemu-options.hx +index 51ba9378b9..8516b73206 100644 +--- a/qemu-options.hx ++++ b/qemu-options.hx +@@ -5637,7 +5637,7 @@ SRST + -object secret,id=sec0,keyid=secmaster0,format=base64,\\ + data=$SECRET,iv=$(user_id = g_strdup(value); + } + ++static char * ++sev_guest_get_secret_header_file(Object *obj, Error **errp) ++{ ++ SevGuestState *s = SEV_GUEST(obj); ++ ++ return g_strdup(s->secret_header_file); ++} ++ ++static void ++sev_guest_set_secret_header_file(Object *obj, const char *value, Error **errp) ++{ ++ SevGuestState *s = SEV_GUEST(obj); ++ ++ s->secret_header_file = g_strdup(value); ++} ++ ++static char * ++sev_guest_get_secret_file(Object *obj, Error **errp) ++{ ++ SevGuestState *s = SEV_GUEST(obj); ++ ++ return g_strdup(s->secret_file); ++} ++ ++static void ++sev_guest_set_secret_file(Object *obj, const char *value, Error **errp) ++{ ++ SevGuestState *s = SEV_GUEST(obj); ++ ++ s->secret_file = g_strdup(value); ++} ++ + static char * + sev_guest_get_sev_device(Object *obj, Error **errp) + { +@@ -448,6 +482,16 @@ sev_guest_class_init(ObjectClass *oc, void *data) + sev_guest_set_user_id); + object_class_property_set_description(oc, "user-id", + "user id of the guest owner"); ++ object_class_property_add_str(oc, "secret-header-file", ++ sev_guest_get_secret_header_file, ++ sev_guest_set_secret_header_file); ++ object_class_property_set_description(oc, "secret-header-file", ++ "header file of the guest owner's secret"); ++ object_class_property_add_str(oc, "secret-file", ++ sev_guest_get_secret_file, ++ sev_guest_set_secret_file); ++ object_class_property_set_description(oc, "secret-file", ++ "file of the guest owner's secret"); + } + + static void +@@ -867,6 +911,9 @@ sev_launch_update_vmsa(SevGuestState *sev) + return ret; + } + ++static int ++csv_load_launch_secret(const char *secret_header_file, const char *secret_file); ++ + static void + sev_launch_get_measure(Notifier *notifier, void *unused) + { +@@ -917,6 +964,15 @@ sev_launch_get_measure(Notifier *notifier, void *unused) + /* encode the measurement value and emit the event */ + sev->measurement = g_base64_encode(data, measurement.len); + trace_kvm_sev_launch_measurement(sev->measurement); ++ ++ /* Hygon CSV will auto load guest owner's secret */ ++ if (is_hygon_cpu()) { ++ if (sev->secret_header_file && ++ strlen(sev->secret_header_file) && ++ sev->secret_file && ++ strlen(sev->secret_file)) ++ csv_load_launch_secret(sev->secret_header_file, sev->secret_file); ++ } + } + + static char *sev_get_launch_measurement(void) +@@ -2526,6 +2582,50 @@ int csv_load_incoming_cpu_state(QEMUFile *f) + return ret; + } + ++static int ++csv_load_launch_secret(const char *secret_header_file, const char *secret_file) ++{ ++ gsize secret_header_size, secret_size; ++ gchar *secret_header = NULL, *secret = NULL; ++ uint8_t *data; ++ struct sev_secret_area *area; ++ uint64_t gpa; ++ GError *error = NULL; ++ Error *local_err = NULL; ++ int ret = 0; ++ ++ if (!g_file_get_contents(secret_header_file, ++ &secret_header, ++ &secret_header_size, &error)) { ++ error_report("CSV: Failed to read '%s' (%s)", ++ secret_header_file, error->message); ++ g_error_free(error); ++ return -1; ++ } ++ ++ if (!g_file_get_contents(secret_file, &secret, &secret_size, &error)) { ++ error_report("CSV: Failed to read '%s' (%s)", secret_file, error->message); ++ g_error_free(error); ++ return -1; ++ } ++ ++ if (!pc_system_ovmf_table_find(SEV_SECRET_GUID, &data, NULL)) { ++ error_report("CSV: no secret area found in OVMF, gpa must be" ++ " specified."); ++ return -1; ++ } ++ area = (struct sev_secret_area *)data; ++ gpa = area->base; ++ ++ ret = sev_inject_launch_secret((char *)secret_header, ++ (char *)secret, gpa, &local_err); ++ ++ if (local_err) { ++ error_report_err(local_err); ++ } ++ return ret; ++} ++ + static const QemuUUID sev_hash_table_header_guid = { + .data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93, + 0xd4, 0x11, 0xfd, 0x21) +-- +2.41.0.windows.1 + diff --git a/qemu.spec b/qemu.spec index 1a2682a..c129e8e 100644 --- a/qemu.spec +++ b/qemu.spec @@ -3,7 +3,7 @@ Name: qemu Version: 8.2.0 -Release: 28 +Release: 29 Epoch: 11 Summary: QEMU is a generic and open source machine emulator and virtualizer License: GPLv2 and BSD and MIT and CC-BY-SA-4.0 @@ -573,6 +573,55 @@ Patch0556: Avoid-unaligned-fetch-in-ladr_match.patch Patch0557: cpu-ensure-we-don-t-call-start_exclusive-from-cpu_ex.patch Patch0558: target-i386-Fix-minor-typo-in-NO_NESTED_DATA_BP-feat.patch Patch0559: hw-misc-mos6522-Fix-bad-class-definition-of-the-MOS6.patch +Patch0560: usb-hub-Fix-handling-port-power-control-messages.patch +Patch0561: target-riscv-Fix-vcompress-with-rvv_ta_all_1s.patch +Patch0562: hw-audio-virtio-snd-Always-use-little-endian-audio-f.patch +Patch0563: target-arm-Avoid-shifts-by-1-in-tszimm_shr-and-tszim.patch +Patch0564: hw-timer-exynos4210_mct-fix-possible-int-overflow.patch +Patch0565: target-arm-Don-t-assert-for-128-bit-tile-accesses-wh.patch +Patch0566: target-arm-Fix-A64-scalar-SQSHRN-and-SQRSHRN.patch +Patch0567: linux-user-Print-tid-not-pid-with-strace.patch +Patch0568: target-arm-Don-t-get-MDCR_EL2-in-pmu_counter_enabled.patch +Patch0569: target-arm-fix-exception-syndrome-for-AArch32-bkpt-i.patch +Patch0570: target-arm-Fix-incorrect-aa64_tidcp1-feature-check.patch +Patch0571: crypto-perform-runtime-check-for-hash-hmac-support-i.patch +Patch0572: hw-audio-hda-fix-memory-leak-on-audio-setup.patch +Patch0573: contrib-plugins-add-compat-for-g_memdup2.patch +Patch0574: target-i386-fix-hang-when-using-slow-path-for-ptw_se.patch +Patch0575: migration-Ensure-vmstate_save-sets-errp.patch +Patch0576: target-arm-Drop-user-only-special-case-in-sve_stN_r.patch +Patch0577: hw-intc-Don-t-clear-pending-bits-on-IRQ-lowering.patch +Patch0578: hw-pci-Remove-unused-pci_irq_pulse-method.patch +Patch0579: Change-vmstate_cpuhp_sts-vmstateDescription-version_.patch +Patch0580: crypto-fix-error-check-on-gcry_md_open.patch +Patch0581: target-arm-Fix-nregs-computation-in-do_-ld-st-_zpa.patch +Patch0582: target-arm-Fix-SVE-SME-gross-MTE-suppression-checks.patch +Patch0583: target-arm-Fix-UMOPA-UMOPS-of-16-bit-values.patch +Patch0584: target-arm-Fix-VCMLA-Dd-Dn-Dm-idx.patch +Patch0585: Avoid-taking-address-of-out-of-bounds-array-index.patch +Patch0586: hw-misc-nrf51_rng-Don-t-use-BIT_MASK-when-we-mean-BI.patch +Patch0587: hvf-remove-unused-but-set-variable.patch +Patch0588: target-riscv-Avoid-bad-shift-in-riscv_cpu_do_interru.patch +Patch0589: target-arm-LDAPR-should-honour-SCTLR_ELx.nAA.patch +Patch0590: target-i386-cpu-Fix-notes-for-CPU-models.patch +Patch0591: target-arm-Reinstate-vfp-property-on-AArch32-CPUs.patch +Patch0592: target-arm-take-HSTR-traps-of-cp15-accesses-to-EL2-n.patch +Patch0593: target-arm-Use-float_status-copy-in-sme_fmopa_s.patch +Patch0594: Add-if-condition-to-avoid-assertion-failed-error-in-.patch +Patch0595: virtio-net-Fix-network-stall-at-the-host-side-waitin.patch +Patch0596: target-hexagon-don-t-look-for-static-glib.patch +Patch0597: target-riscv-vector_helper.c-set-vstart-0-in-GEN_VEX.patch +Patch0598: target-riscv-vector_helper.c-optimize-loops-in-ldst-.patch +Patch0599: target-riscv-vector_helper.c-fix-vmvr_v-memcpy-endia.patch +Patch0600: hw-usb-hcd-ehci-Fix-debug-printf-format-string.patch +Patch0601: backends-cryptodev-vhost-user-Fix-local_error-leaks.patch +Patch0602: parallels-fix-ext_off-assertion-failure-due-to-overf.patch +Patch0603: bakcend-VirtCCA-resolve-hugepage-memory-waste-issue-.patch +Patch0604: qapi-qom-target-i386-csv-guest-Introduce-secret-head.patch +Patch0605: target-i386-kvm-Support-to-get-and-enable-extensions.patch +Patch0606: target-i386-csv-Request-to-set-private-memory-of-CSV.patch +Patch0607: target-i386-csv-Support-load-kernel-hashes-for-CSV3-.patch +Patch0608: target-i386-csv-Support-inject-secret-for-CSV3-guest.patch BuildRequires: flex BuildRequires: gcc @@ -1171,6 +1220,57 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* Fri Feb 21 2025 Jiabo Feng - 11:8.2.0-29 +- target/i386: csv: Support inject secret for CSV3 guest only if the extension is enabled +- target/i386: csv: Support load kernel hashes for CSV3 guest only if the extension is enabled +- target/i386: csv: Request to set private memory of CSV3 guest if the extension is enabled +- target/i386: kvm: Support to get and enable extensions for Hygon CoCo guest +- qapi/qom,target/i386: csv-guest: Introduce secret-header-file=str and secret-file=str options +- bakcend: VirtCCA:resolve hugepage memory waste issue in vhost-user scenario +- parallels: fix ext_off assertion failure due to overflow +- backends/cryptodev-vhost-user: Fix local_error leaks +- hw/usb/hcd-ehci: Fix debug printf format string +- target/riscv/vector_helper.c: fix 'vmvr_v' memcpy endianess +- target/riscv/vector_helper.c: optimize loops in ldst helpers +- target/riscv/vector_helper.c: set vstart = 0 in GEN_VEXT_VSLIDEUP_VX() +- target/hexagon: don't look for static glib +- virtio-net: Fix network stall at the host side waiting for kick +- Add if condition to avoid assertion failed error in blockdev_init +- target/arm: Use float_status copy in sme_fmopa_s +- target/arm: take HSTR traps of cp15 accesses to EL2, not EL1 +- target/arm: Reinstate "vfp" property on AArch32 CPUs +- target/i386/cpu: Fix notes for CPU models +- target/arm: LDAPR should honour SCTLR_ELx.nAA +- target/riscv: Avoid bad shift in riscv_cpu_do_interrupt() +- hvf: remove unused but set variable +- hw/misc/nrf51_rng: Don't use BIT_MASK() when we mean BIT() +- Avoid taking address of out-of-bounds array index +- target/arm: Fix VCMLA Dd, Dn, Dm[idx] +- target/arm: Fix UMOPA/UMOPS of 16-bit values +- target/arm: Fix SVE/SME gross MTE suppression checks +- target/arm: Fix nregs computation in do_{ld,st}_zpa +- crypto: fix error check on gcry_md_open +- Change vmstate_cpuhp_sts vmstateDescription version_id +- hw/pci: Remove unused pci_irq_pulse() method +- hw/intc: Don't clear pending bits on IRQ lowering +- target/arm: Drop user-only special case in sve_stN_r +- migration: Ensure vmstate_save() sets errp +- target/i386: fix hang when using slow path for ptw_setl +- contrib/plugins: add compat for g_memdup2 +- hw/audio/hda: fix memory leak on audio setup +- crypto: perform runtime check for hash/hmac support in gcrypt +- target/arm: Fix incorrect aa64_tidcp1 feature check +- target/arm: fix exception syndrome for AArch32 bkpt insn +- target/arm: Don't get MDCR_EL2 in pmu_counter_enabled() before checking ARM_FEATURE_PMU +- linux-user: Print tid not pid with strace +- target/arm: Fix A64 scalar SQSHRN and SQRSHRN +- target/arm: Don't assert for 128-bit tile accesses when SVL is 128 +- hw/timer/exynos4210_mct: fix possible int overflow +- target/arm: Avoid shifts by -1 in tszimm_shr() and tszimm_shl() +- hw/audio/virtio-snd: Always use little endian audio format +- target/riscv: Fix vcompress with rvv_ta_all_1s +- usb-hub: Fix handling port power control messages + * Fri Feb 21 2025 Jiabo Feng - 11:8.2.0-28 - hw/misc/mos6522: Fix bad class definition of the MOS6522 device - target/i386: Fix minor typo in NO_NESTED_DATA_BP feature bit diff --git a/target-arm-Avoid-shifts-by-1-in-tszimm_shr-and-tszim.patch b/target-arm-Avoid-shifts-by-1-in-tszimm_shr-and-tszim.patch new file mode 100644 index 0000000..e001b1d --- /dev/null +++ b/target-arm-Avoid-shifts-by-1-in-tszimm_shr-and-tszim.patch @@ -0,0 +1,66 @@ +From 7810c5462cc56c92f50ecf3878525c15000212f6 Mon Sep 17 00:00:00 2001 +From: gubin +Date: Fri, 22 Nov 2024 18:02:26 +0800 +Subject: [PATCH] target/arm: Avoid shifts by -1 in tszimm_shr() and + tszimm_shl() + +cherry-pick from 76916dfa89e8900639c1055c07a295c06628a0bc + +The function tszimm_esz() returns a shift amount, or possibly -1 in +certain cases that correspond to unallocated encodings in the +instruction set. We catch these later in the trans_ functions +(generally with an "a-esz < 0" check), but before we do the +decodetree-generated code will also call tszimm_shr() or tszimm_sl(), +which will use the tszimm_esz() return value as a shift count without +checking that it is not negative, which is undefined behaviour. + +Avoid the UB by checking the return value in tszimm_shr() and +tszimm_shl(). + +Cc: qemu-stable@nongnu.org +Resolves: Coverity CID 1547617, 1547694 +Signed-off-by: Peter Maydell +Reviewed-by: Richard Henderson +Message-id: 20240722172957.1041231-4-peter.maydell@linaro.org +Signed-off-by: gubin +--- + target/arm/tcg/translate-sve.c | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c +index 296e7d1ce2..dd0c633897 100644 +--- a/target/arm/tcg/translate-sve.c ++++ b/target/arm/tcg/translate-sve.c +@@ -50,13 +50,27 @@ static int tszimm_esz(DisasContext *s, int x) + + static int tszimm_shr(DisasContext *s, int x) + { +- return (16 << tszimm_esz(s, x)) - x; ++ /* ++ * We won't use the tszimm_shr() value if tszimm_esz() returns -1 (the ++ * trans function will check for esz < 0), so we can return any ++ * value we like from here in that case as long as we avoid UB. ++ */ ++ int esz = tszimm_esz(s, x); ++ if (esz < 0) { ++ return esz; ++ } ++ return (16 << esz) - x; + } + + /* See e.g. LSL (immediate, predicated). */ + static int tszimm_shl(DisasContext *s, int x) + { +- return x - (8 << tszimm_esz(s, x)); ++ /* As with tszimm_shr(), value will be unused if esz < 0 */ ++ int esz = tszimm_esz(s, x); ++ if (esz < 0) { ++ return esz; ++ } ++ return x - (8 << esz); + } + + /* The SH bit is in bit 8. Extract the low 8 and shift. */ +-- +2.41.0.windows.1 + diff --git a/target-arm-Don-t-assert-for-128-bit-tile-accesses-wh.patch b/target-arm-Don-t-assert-for-128-bit-tile-accesses-wh.patch new file mode 100644 index 0000000..6f5fab7 --- /dev/null +++ b/target-arm-Don-t-assert-for-128-bit-tile-accesses-wh.patch @@ -0,0 +1,61 @@ +From 9e0b6c4df61aced66c5b3ee9ca93c6ac33868dc0 Mon Sep 17 00:00:00 2001 +From: gubin +Date: Thu, 28 Nov 2024 14:06:44 +0800 +Subject: [PATCH] target/arm: Don't assert for 128-bit tile accesses when SVL + is 128 + +cherry-pick from 56f1c0db928aae0b83fd91c89ddb226b137e2b21 + +For an instruction which accesses a 128-bit element tile when +the SVL is also 128 (for example MOV z0.Q, p0/M, ZA0H.Q[w0,0]), +we will assert in get_tile_rowcol(): + +qemu-system-aarch64: ../../tcg/tcg-op.c:926: tcg_gen_deposit_z_i32: Assertion `len > 0' failed. + +This happens because we calculate + len = ctz32(streaming_vec_reg_size(s)) - esz;$ +but if the SVL and the element size are the same len is 0, and +the deposit operation asserts. + +In this case the ZA storage contains exactly one 128 bit +element ZA tile, and the horizontal or vertical slice is just +that tile. This means that regardless of the index value in +the Ws register, we always access that tile. (In pseudocode terms, +we calculate (index + offset) MOD 1, which is 0.) + +Special case the len == 0 case to avoid hitting the assertion +in tcg_gen_deposit_z_i32(). + +Cc: qemu-stable@nongnu.org +Signed-off-by: Peter Maydell +Reviewed-by: Richard Henderson +Message-id: 20240722172957.1041231-2-peter.maydell@linaro.org +Signed-off-by: gubin +--- + target/arm/tcg/translate-sme.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/target/arm/tcg/translate-sme.c b/target/arm/tcg/translate-sme.c +index 8f0dfc884e..1e89516736 100644 +--- a/target/arm/tcg/translate-sme.c ++++ b/target/arm/tcg/translate-sme.c +@@ -49,7 +49,15 @@ static TCGv_ptr get_tile_rowcol(DisasContext *s, int esz, int rs, + /* Prepare a power-of-two modulo via extraction of @len bits. */ + len = ctz32(streaming_vec_reg_size(s)) - esz; + +- if (vertical) { ++ if (!len) { ++ /* ++ * SVL is 128 and the element size is 128. There is exactly ++ * one 128x128 tile in the ZA storage, and so we calculate ++ * (Rs + imm) MOD 1, which is always 0. We need to special case ++ * this because TCG doesn't allow deposit ops with len 0. ++ */ ++ tcg_gen_movi_i32(tmp, 0); ++ } else if (vertical) { + /* + * Compute the byte offset of the index within the tile: + * (index % (svl / size)) * size +-- +2.41.0.windows.1 + diff --git a/target-arm-Don-t-get-MDCR_EL2-in-pmu_counter_enabled.patch b/target-arm-Don-t-get-MDCR_EL2-in-pmu_counter_enabled.patch new file mode 100644 index 0000000..6187d57 --- /dev/null +++ b/target-arm-Don-t-get-MDCR_EL2-in-pmu_counter_enabled.patch @@ -0,0 +1,68 @@ +From 42a30e10bada5f034b0b2bfe8760482c972a4e61 Mon Sep 17 00:00:00 2001 +From: gubin +Date: Thu, 28 Nov 2024 14:14:21 +0800 +Subject: [PATCH] target/arm: Don't get MDCR_EL2 in pmu_counter_enabled() + before checking ARM_FEATURE_PMU +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cherry-pick from ac1d88e9e7ca0bed83e91e07ce6d0597f10cc77d + +It doesn't make sense to read the value of MDCR_EL2 on a non-A-profile +CPU, and in fact if you try to do it we will assert: + + (assertion=0x5555565a8c70 "!arm_feature(env, ARM_FEATURE_M)", file=0x5555565a6e5c "../../target/arm/helper.c", line=12600, function=0x5555565a9560 <__PRETTY_FUNCTION__.0> "arm_security_space_below_el3") at ./assert/assert.c:101 + +We might call pmu_counter_enabled() on an M-profile CPU (for example +from the migration pre/post hooks in machine.c); this should always +return false because these CPUs don't set ARM_FEATURE_PMU. + +Avoid the assertion by not calling arm_mdcr_el2_eff() before we +have done the early return for "PMU not present". + +This fixes an assertion failure if you try to do a loadvm or +savevm for an M-profile board. + +Cc: qemu-stable@nongnu.org +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2155 +Signed-off-by: Peter Maydell +Reviewed-by: Philippe Mathieu-Daudé +Reviewed-by: Richard Henderson +Message-id: 20240208153346.970021-1-peter.maydell@linaro.org +Signed-off-by: gubin +--- + target/arm/helper.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/target/arm/helper.c b/target/arm/helper.c +index 793aa89cc6..762eb086c5 100644 +--- a/target/arm/helper.c ++++ b/target/arm/helper.c +@@ -1182,13 +1182,21 @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter) + bool enabled, prohibited = false, filtered; + bool secure = arm_is_secure(env); + int el = arm_current_el(env); +- uint64_t mdcr_el2 = arm_mdcr_el2_eff(env); +- uint8_t hpmn = mdcr_el2 & MDCR_HPMN; ++ uint64_t mdcr_el2; ++ uint8_t hpmn; + ++ /* ++ * We might be called for M-profile cores where MDCR_EL2 doesn't ++ * exist and arm_mdcr_el2_eff() will assert, so this early-exit check ++ * must be before we read that value. ++ */ + if (!arm_feature(env, ARM_FEATURE_PMU)) { + return false; + } + ++ mdcr_el2 = arm_mdcr_el2_eff(env); ++ hpmn = mdcr_el2 & MDCR_HPMN; ++ + if (!arm_feature(env, ARM_FEATURE_EL2) || + (counter < hpmn || counter == 31)) { + e = env->cp15.c9_pmcr & PMCRE; +-- +2.41.0.windows.1 + diff --git a/target-arm-Drop-user-only-special-case-in-sve_stN_r.patch b/target-arm-Drop-user-only-special-case-in-sve_stN_r.patch new file mode 100644 index 0000000..6d619d8 --- /dev/null +++ b/target-arm-Drop-user-only-special-case-in-sve_stN_r.patch @@ -0,0 +1,43 @@ +From 1475170931ea2979a150fe4c1d3fc6b649eb3a6e Mon Sep 17 00:00:00 2001 +From: Richard Henderson +Date: Tue, 12 Nov 2024 06:12:32 -0800 +Subject: [PATCH] target/arm: Drop user-only special case in sve_stN_r + +This path is reachable with plugins enabled, and provoked +with run-plugin-catch-syscalls-with-libinline.so. + +Cc: qemu-stable@nongnu.org +Reviewed-by: Peter Maydell +Signed-off-by: Richard Henderson +Message-ID: <20241112141232.321354-1-richard.henderson@linaro.org> +(cherry picked from commit f27550804688da43c6e0d87b2f9e143adbf76271) +Signed-off-by: zhujun2 +--- + target/arm/tcg/sve_helper.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/target/arm/tcg/sve_helper.c b/target/arm/tcg/sve_helper.c +index f006d152cc..ce8134320b 100644 +--- a/target/arm/tcg/sve_helper.c ++++ b/target/arm/tcg/sve_helper.c +@@ -6306,9 +6306,6 @@ void sve_stN_r(CPUARMState *env, uint64_t *vg, target_ulong addr, + + flags = info.page[0].flags | info.page[1].flags; + if (unlikely(flags != 0)) { +-#ifdef CONFIG_USER_ONLY +- g_assert_not_reached(); +-#else + /* + * At least one page includes MMIO. + * Any bus operation can fail with cpu_transaction_failed, +@@ -6339,7 +6336,6 @@ void sve_stN_r(CPUARMState *env, uint64_t *vg, target_ulong addr, + } while (reg_off & 63); + } while (reg_off <= reg_last); + return; +-#endif + } + + mem_off = info.mem_off_first[0]; +-- +2.41.0.windows.1 + diff --git a/target-arm-Fix-A64-scalar-SQSHRN-and-SQRSHRN.patch b/target-arm-Fix-A64-scalar-SQSHRN-and-SQRSHRN.patch new file mode 100644 index 0000000..e8a1081 --- /dev/null +++ b/target-arm-Fix-A64-scalar-SQSHRN-and-SQRSHRN.patch @@ -0,0 +1,53 @@ +From fe9725eed4d9be8e14d2c3865f1d7d5f24cbdd73 Mon Sep 17 00:00:00 2001 +From: gubin +Date: Thu, 28 Nov 2024 14:21:15 +0800 +Subject: [PATCH] target/arm: Fix A64 scalar SQSHRN and SQRSHRN + +cherry-pick from 6fffc8378562c7fea6290c430b4f653f830a4c1a + +In commit 1b7bc9b5c8bf374dd we changed handle_vec_simd_sqshrn() so +that instead of starting with a 0 value and depositing in each new +element from the narrowing operation, it instead started with the raw +result of the narrowing operation of the first element. + +This is fine in the vector case, because the deposit operations for +the second and subsequent elements will always overwrite any higher +bits that might have been in the first element's result value in +tcg_rd. However in the scalar case we only go through this loop +once. The effect is that for a signed narrowing operation, if the +result is negative then we will now return a value where the bits +above the first element are incorrectly 1 (because the narrowfn +returns a sign-extended result, not one that is truncated to the +element size). + +Fix this by using an extract operation to get exactly the correct +bits of the output of the narrowfn for element 1, instead of a +plain move. + +Cc: qemu-stable@nongnu.org +Fixes: 1b7bc9b5c8bf374dd3 ("target/arm: Avoid tcg_const_ptr in handle_vec_simd_sqshrn") +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2089 +Signed-off-by: Peter Maydell +Reviewed-by: Richard Henderson +Message-id: 20240123153416.877308-1-peter.maydell@linaro.org +Signed-off-by: gubin +--- + target/arm/tcg/translate-a64.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c +index 5560a53630..a05182b57f 100644 +--- a/target/arm/tcg/translate-a64.c ++++ b/target/arm/tcg/translate-a64.c +@@ -8221,7 +8221,7 @@ static void handle_vec_simd_sqshrn(DisasContext *s, bool is_scalar, bool is_q, + narrowfn(tcg_rd_narrowed, tcg_env, tcg_rd); + tcg_gen_extu_i32_i64(tcg_rd, tcg_rd_narrowed); + if (i == 0) { +- tcg_gen_mov_i64(tcg_final, tcg_rd); ++ tcg_gen_extract_i64(tcg_final, tcg_rd, 0, esize); + } else { + tcg_gen_deposit_i64(tcg_final, tcg_final, tcg_rd, esize * i, esize); + } +-- +2.41.0.windows.1 + diff --git a/target-arm-Fix-SVE-SME-gross-MTE-suppression-checks.patch b/target-arm-Fix-SVE-SME-gross-MTE-suppression-checks.patch new file mode 100644 index 0000000..dcb3252 --- /dev/null +++ b/target-arm-Fix-SVE-SME-gross-MTE-suppression-checks.patch @@ -0,0 +1,87 @@ +From b69c9f4b7b72c0634f2353135f83d8e59f3308dd Mon Sep 17 00:00:00 2001 +From: gubin +Date: Tue, 17 Dec 2024 14:42:31 +0800 +Subject: [PATCH] target/arm: Fix SVE/SME gross MTE suppression checks + +cherry-pick from 855f94eca80c85a99f459e36684ea2f98f6a3243 + +The TBI and TCMA bits are located within mtedesc, not desc. + +Cc: qemu-stable@nongnu.org +Reviewed-by: Peter Maydell +Signed-off-by: Richard Henderson +Tested-by: Gustavo Romero +Message-id: 20240207025210.8837-7-richard.henderson@linaro.org +Signed-off-by: Peter Maydell +Signed-off-by: gubin +--- + target/arm/tcg/sme_helper.c | 8 ++++---- + target/arm/tcg/sve_helper.c | 12 ++++++------ + 2 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/target/arm/tcg/sme_helper.c b/target/arm/tcg/sme_helper.c +index 1ee2690ceb..904bfdac43 100644 +--- a/target/arm/tcg/sme_helper.c ++++ b/target/arm/tcg/sme_helper.c +@@ -573,8 +573,8 @@ void sme_ld1_mte(CPUARMState *env, void *za, uint64_t *vg, + desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT); + + /* Perform gross MTE suppression early. */ +- if (!tbi_check(desc, bit55) || +- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) { ++ if (!tbi_check(mtedesc, bit55) || ++ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) { + mtedesc = 0; + } + +@@ -750,8 +750,8 @@ void sme_st1_mte(CPUARMState *env, void *za, uint64_t *vg, target_ulong addr, + desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT); + + /* Perform gross MTE suppression early. */ +- if (!tbi_check(desc, bit55) || +- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) { ++ if (!tbi_check(mtedesc, bit55) || ++ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) { + mtedesc = 0; + } + +diff --git a/target/arm/tcg/sve_helper.c b/target/arm/tcg/sve_helper.c +index ce8134320b..9694201550 100644 +--- a/target/arm/tcg/sve_helper.c ++++ b/target/arm/tcg/sve_helper.c +@@ -5800,8 +5800,8 @@ void sve_ldN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr, + desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT); + + /* Perform gross MTE suppression early. */ +- if (!tbi_check(desc, bit55) || +- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) { ++ if (!tbi_check(mtedesc, bit55) || ++ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) { + mtedesc = 0; + } + +@@ -6156,8 +6156,8 @@ void sve_ldnfff1_r_mte(CPUARMState *env, void *vg, target_ulong addr, + desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT); + + /* Perform gross MTE suppression early. */ +- if (!tbi_check(desc, bit55) || +- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) { ++ if (!tbi_check(mtedesc, bit55) || ++ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) { + mtedesc = 0; + } + +@@ -6406,8 +6406,8 @@ void sve_stN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr, + desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT); + + /* Perform gross MTE suppression early. */ +- if (!tbi_check(desc, bit55) || +- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) { ++ if (!tbi_check(mtedesc, bit55) || ++ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) { + mtedesc = 0; + } + +-- +2.41.0.windows.1 + diff --git a/target-arm-Fix-UMOPA-UMOPS-of-16-bit-values.patch b/target-arm-Fix-UMOPA-UMOPS-of-16-bit-values.patch new file mode 100644 index 0000000..be6b147 --- /dev/null +++ b/target-arm-Fix-UMOPA-UMOPS-of-16-bit-values.patch @@ -0,0 +1,63 @@ +From 07dfcad1b3d9ecbf1afe65d3457a6dbcb31f1b94 Mon Sep 17 00:00:00 2001 +From: gubin +Date: Tue, 17 Dec 2024 14:47:59 +0800 +Subject: [PATCH] target/arm: Fix UMOPA/UMOPS of 16-bit values + +cherry-pick from ea3f5a90f036734522e9af3bffd77e69e9f47355 + +The UMOPA/UMOPS instructions are supposed to multiply unsigned 8 or +16 bit elements and accumulate the products into a 64-bit element. +In the Arm ARM pseudocode, this is done with the usual +infinite-precision signed arithmetic. However our implementation +doesn't quite get it right, because in the DEF_IMOP_64() macro we do: + sum += (NTYPE)(n >> 0) * (MTYPE)(m >> 0); + +where NTYPE and MTYPE are uint16_t or int16_t. In the uint16_t case, +the C usual arithmetic conversions mean the values are converted to +"int" type and the multiply is done as a 32-bit multiply. This means +that if the inputs are, for example, 0xffff and 0xffff then the +result is 0xFFFE0001 as an int, which is then promoted to uint64_t +for the accumulation into sum; this promotion incorrectly sign +extends the multiply. + +Avoid the incorrect sign extension by casting to int64_t before +the multiply, so we do the multiply as 64-bit signed arithmetic, +which is a type large enough that the multiply can never +overflow into the sign bit. + +(The equivalent 8-bit operations in DEF_IMOP_32() are fine, because +the 8-bit multiplies can never overflow into the sign bit of a +32-bit integer.) + +Cc: qemu-stable@nongnu.org +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2372 +Signed-off-by: Peter Maydell +Reviewed-by: Richard Henderson +Message-id: 20240722172957.1041231-3-peter.maydell@linaro.org +Signed-off-by: gubin +--- + target/arm/tcg/sme_helper.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/target/arm/tcg/sme_helper.c b/target/arm/tcg/sme_helper.c +index 1ee2690ceb..e94b5335e1 100644 +--- a/target/arm/tcg/sme_helper.c ++++ b/target/arm/tcg/sme_helper.c +@@ -1134,10 +1134,10 @@ static uint64_t NAME(uint64_t n, uint64_t m, uint64_t a, uint8_t p, bool neg) \ + uint64_t sum = 0; \ + /* Apply P to N as a mask, making the inactive elements 0. */ \ + n &= expand_pred_h(p); \ +- sum += (NTYPE)(n >> 0) * (MTYPE)(m >> 0); \ +- sum += (NTYPE)(n >> 16) * (MTYPE)(m >> 16); \ +- sum += (NTYPE)(n >> 32) * (MTYPE)(m >> 32); \ +- sum += (NTYPE)(n >> 48) * (MTYPE)(m >> 48); \ ++ sum += (int64_t)(NTYPE)(n >> 0) * (MTYPE)(m >> 0); \ ++ sum += (int64_t)(NTYPE)(n >> 16) * (MTYPE)(m >> 16); \ ++ sum += (int64_t)(NTYPE)(n >> 32) * (MTYPE)(m >> 32); \ ++ sum += (int64_t)(NTYPE)(n >> 48) * (MTYPE)(m >> 48); \ + return neg ? a - sum : a + sum; \ + } + +-- +2.41.0.windows.1 + diff --git a/target-arm-Fix-VCMLA-Dd-Dn-Dm-idx.patch b/target-arm-Fix-VCMLA-Dd-Dn-Dm-idx.patch new file mode 100644 index 0000000..17111bb --- /dev/null +++ b/target-arm-Fix-VCMLA-Dd-Dn-Dm-idx.patch @@ -0,0 +1,47 @@ +From cdf914a667f9d0f086329174c24f9623b00b8fb2 Mon Sep 17 00:00:00 2001 +From: gubin +Date: Tue, 17 Dec 2024 14:54:18 +0800 +Subject: [PATCH] target/arm: Fix VCMLA Dd, Dn, Dm[idx] + +cherry-pick from 76bccf3cb9d9383da0128bbc6d1300cddbe3ae8f + +The inner loop, bounded by eltspersegment, must not be +larger than the outer loop, bounded by elements. + +Cc: qemu-stable@nongnu.org +Fixes: 18fc2405781 ("target/arm: Implement SVE fp complex multiply add (indexed)") +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2376 +Reviewed-by: Peter Maydell +Signed-off-by: Richard Henderson +Message-id: 20240625183536.1672454-2-richard.henderson@linaro.org +Signed-off-by: Peter Maydell +Signed-off-by: gubin +--- + target/arm/tcg/vec_helper.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/target/arm/tcg/vec_helper.c b/target/arm/tcg/vec_helper.c +index 11e874c05a..83b49ef009 100644 +--- a/target/arm/tcg/vec_helper.c ++++ b/target/arm/tcg/vec_helper.c +@@ -850,7 +850,7 @@ void HELPER(gvec_fcmlah_idx)(void *vd, void *vn, void *vm, void *va, + intptr_t index = extract32(desc, SIMD_DATA_SHIFT + 2, 2); + uint32_t neg_real = flip ^ neg_imag; + intptr_t elements = opr_sz / sizeof(float16); +- intptr_t eltspersegment = 16 / sizeof(float16); ++ intptr_t eltspersegment = MIN(16 / sizeof(float16), elements); + intptr_t i, j; + + /* Shift boolean to the sign bit so we can xor to negate. */ +@@ -912,7 +912,7 @@ void HELPER(gvec_fcmlas_idx)(void *vd, void *vn, void *vm, void *va, + intptr_t index = extract32(desc, SIMD_DATA_SHIFT + 2, 2); + uint32_t neg_real = flip ^ neg_imag; + intptr_t elements = opr_sz / sizeof(float32); +- intptr_t eltspersegment = 16 / sizeof(float32); ++ intptr_t eltspersegment = MIN(16 / sizeof(float32), elements); + intptr_t i, j; + + /* Shift boolean to the sign bit so we can xor to negate. */ +-- +2.41.0.windows.1 + diff --git a/target-arm-Fix-incorrect-aa64_tidcp1-feature-check.patch b/target-arm-Fix-incorrect-aa64_tidcp1-feature-check.patch new file mode 100644 index 0000000..4996a3e --- /dev/null +++ b/target-arm-Fix-incorrect-aa64_tidcp1-feature-check.patch @@ -0,0 +1,39 @@ +From 1ad09007da426e9cd1585babcdd4de25ddfb2f8b Mon Sep 17 00:00:00 2001 +From: gubin +Date: Thu, 28 Nov 2024 14:39:05 +0800 +Subject: [PATCH] target/arm: Fix incorrect aa64_tidcp1 feature check + +cherry-pick from ee0a2e3c9d2991a11c13ffadb15e4d0add43c257 + +A typo in the implementation of isar_feature_aa64_tidcp1() means we +were checking the field in the wrong ID register, so we might have +provided the feature on CPUs that don't have it and not provided +it on CPUs that should have it. Correct this bug. + +Cc: qemu-stable@nongnu.org +Fixes: 9cd0c0dec97be9 "target/arm: Implement FEAT_TIDCP1" +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2120 +Signed-off-by: Peter Maydell +Reviewed-by: Richard Henderson +Message-id: 20240123160333.958841-1-peter.maydell@linaro.org +Signed-off-by: gubin +--- + target/arm/cpu-features.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h +index 954d358268..165a497f7b 100644 +--- a/target/arm/cpu-features.h ++++ b/target/arm/cpu-features.h +@@ -771,7 +771,7 @@ static inline bool isar_feature_aa64_hcx(const ARMISARegisters *id) + + static inline bool isar_feature_aa64_tidcp1(const ARMISARegisters *id) + { +- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR1, TIDCP1) != 0; ++ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, TIDCP1) != 0; + } + + static inline bool isar_feature_aa64_hafs(const ARMISARegisters *id) +-- +2.41.0.windows.1 + diff --git a/target-arm-Fix-nregs-computation-in-do_-ld-st-_zpa.patch b/target-arm-Fix-nregs-computation-in-do_-ld-st-_zpa.patch new file mode 100644 index 0000000..7672694 --- /dev/null +++ b/target-arm-Fix-nregs-computation-in-do_-ld-st-_zpa.patch @@ -0,0 +1,83 @@ +From b6a6427bf45c249e8397bf758055ebb54622e8e2 Mon Sep 17 00:00:00 2001 +From: gubin +Date: Tue, 17 Dec 2024 14:32:17 +0800 +Subject: [PATCH] target/arm: Fix nregs computation in do_{ld,st}_zpa + +cherry-pick from 64c6e7444dff64b42d11b836b9aec9acfbe8ecc2 + +The field is encoded as [0-3], which is convenient for +indexing our array of function pointers, but the true +value is [1-4]. Adjust before calling do_mem_zpa. + +Add an assert, and move the comment re passing ZT to +the helper back next to the relevant code. + +Cc: qemu-stable@nongnu.org +Fixes: 206adacfb8d ("target/arm: Add mte helpers for sve scalar + int loads") +Signed-off-by: Richard Henderson +Tested-by: Gustavo Romero +Message-id: 20240207025210.8837-3-richard.henderson@linaro.org +Reviewed-by: Peter Maydell +Signed-off-by: Peter Maydell +Signed-off-by: gubin +--- + target/arm/tcg/translate-sve.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c +index dd0c633897..1d8e0d29bf 100644 +--- a/target/arm/tcg/translate-sve.c ++++ b/target/arm/tcg/translate-sve.c +@@ -4459,11 +4459,7 @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr, + TCGv_ptr t_pg; + int desc = 0; + +- /* +- * For e.g. LD4, there are not enough arguments to pass all 4 +- * registers as pointers, so encode the regno into the data field. +- * For consistency, do this even for LD1. +- */ ++ assert(mte_n >= 1 && mte_n <= 4); + if (s->mte_active[0]) { + int msz = dtype_msz(dtype); + +@@ -4477,6 +4473,11 @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr, + addr = clean_data_tbi(s, addr); + } + ++ /* ++ * For e.g. LD4, there are not enough arguments to pass all 4 ++ * registers as pointers, so encode the regno into the data field. ++ * For consistency, do this even for LD1. ++ */ + desc = simd_desc(vsz, vsz, zt | desc); + t_pg = tcg_temp_new_ptr(); + +@@ -4614,7 +4615,7 @@ static void do_ld_zpa(DisasContext *s, int zt, int pg, + * accessible via the instruction encoding. + */ + assert(fn != NULL); +- do_mem_zpa(s, zt, pg, addr, dtype, nreg, false, fn); ++ do_mem_zpa(s, zt, pg, addr, dtype, nreg + 1, false, fn); + } + + static bool trans_LD_zprr(DisasContext *s, arg_rprr_load *a) +@@ -5182,14 +5183,13 @@ static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr, + if (nreg == 0) { + /* ST1 */ + fn = fn_single[s->mte_active[0]][be][msz][esz]; +- nreg = 1; + } else { + /* ST2, ST3, ST4 -- msz == esz, enforced by encoding */ + assert(msz == esz); + fn = fn_multiple[s->mte_active[0]][be][nreg - 1][msz]; + } + assert(fn != NULL); +- do_mem_zpa(s, zt, pg, addr, msz_dtype(s, msz), nreg, true, fn); ++ do_mem_zpa(s, zt, pg, addr, msz_dtype(s, msz), nreg + 1, true, fn); + } + + static bool trans_ST_zprr(DisasContext *s, arg_rprr_store *a) +-- +2.41.0.windows.1 + diff --git a/target-arm-LDAPR-should-honour-SCTLR_ELx.nAA.patch b/target-arm-LDAPR-should-honour-SCTLR_ELx.nAA.patch new file mode 100644 index 0000000..01d36f0 --- /dev/null +++ b/target-arm-LDAPR-should-honour-SCTLR_ELx.nAA.patch @@ -0,0 +1,56 @@ +From 626103c76d0d8db8dee3f613b6e3159c8ddd5a57 Mon Sep 17 00:00:00 2001 +From: gubin +Date: Thu, 2 Jan 2025 10:25:00 +0800 +Subject: [PATCH] target/arm: LDAPR should honour SCTLR_ELx.nAA + +cherry-pick from 25489b521b61b874c4c6583956db0012a3674e3a + +In commit c1a1f80518d360b when we added the FEAT_LSE2 relaxations to +the alignment requirements for atomic and ordered loads and stores, +we didn't quite get it right for LDAPR/LDAPRH/LDAPRB with no +immediate offset. These instructions were handled in the old decoder +as part of disas_ldst_atomic(), but unlike all the other insns that +function decoded (LDADD, LDCLR, etc) these insns are "ordered", not +"atomic", so they should be using check_ordered_align() rather than +check_atomic_align(). Commit c1a1f80518d360b used +check_atomic_align() regardless for everything in +disas_ldst_atomic(). We then carried that incorrect check over in +the decodetree conversion, where LDAPR/LDAPRH/LDAPRB are now handled +by trans_LDAPR(). + +The effect is that when FEAT_LSE2 is implemented, these instructions +don't honour the SCTLR_ELx.nAA bit and will generate alignment +faults when they should not. + +(The LDAPR insns with an immediate offset were in disas_ldst_ldapr_stlr() +and then in trans_LDAPR_i() and trans_STLR_i(), and have always used +the correct check_ordered_align().) + +Use check_ordered_align() in trans_LDAPR(). + +Cc: qemu-stable@nongnu.org +Fixes: c1a1f80518d360b ("target/arm: Relax ordered/atomic alignment checks for LSE2") +Signed-off-by: Peter Maydell +Reviewed-by: Richard Henderson +Message-id: 20240709134504.3500007-3-peter.maydell@linaro.org +Signed-off-by: gubin +--- + target/arm/tcg/translate-a64.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c +index a05182b57f..5beac07b60 100644 +--- a/target/arm/tcg/translate-a64.c ++++ b/target/arm/tcg/translate-a64.c +@@ -3306,7 +3306,7 @@ static bool trans_LDAPR(DisasContext *s, arg_LDAPR *a) + if (a->rn == 31) { + gen_check_sp_alignment(s); + } +- mop = check_atomic_align(s, a->rn, a->sz); ++ mop = check_ordered_align(s, a->rn, 0, false, a->sz); + clean_addr = gen_mte_check1(s, cpu_reg_sp(s, a->rn), false, + a->rn != 31, mop); + /* +-- +2.41.0.windows.1 + diff --git a/target-arm-Reinstate-vfp-property-on-AArch32-CPUs.patch b/target-arm-Reinstate-vfp-property-on-AArch32-CPUs.patch new file mode 100644 index 0000000..685dfe4 --- /dev/null +++ b/target-arm-Reinstate-vfp-property-on-AArch32-CPUs.patch @@ -0,0 +1,44 @@ +From 582f5bc85da2d1c6a61e5164dfc272dc96f846d5 Mon Sep 17 00:00:00 2001 +From: gubin +Date: Thu, 2 Jan 2025 10:30:33 +0800 +Subject: [PATCH] target/arm: Reinstate "vfp" property on AArch32 CPUs + +cherry-pick from 185e3fdf8d106cb2f7d234d5e6453939c66db2a9 + +In commit 4315f7c614743 we restructured the logic for creating the +VFP related properties to avoid testing the aa32_simd_r32 feature on +AArch64 CPUs. However in the process we accidentally stopped +exposing the "vfp" QOM property on AArch32 TCG CPUs. + +This mostly hasn't had any ill effects because not many people want +to disable VFP, but it wasn't intentional. Reinstate the property. + +Cc: qemu-stable@nongnu.org +Fixes: 4315f7c614743 ("target/arm: Restructure has_vfp_d32 test") +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2098 +Signed-off-by: Peter Maydell +Reviewed-by: Richard Henderson +Message-id: 20240126193432.2210558-1-peter.maydell@linaro.org +Signed-off-by: gubin +--- + target/arm/cpu.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/target/arm/cpu.c b/target/arm/cpu.c +index 9dd61c10ea..09d391bd34 100644 +--- a/target/arm/cpu.c ++++ b/target/arm/cpu.c +@@ -1635,6 +1635,10 @@ void arm_cpu_post_init(Object *obj) + } + } else if (cpu_isar_feature(aa32_vfp, cpu)) { + cpu->has_vfp = true; ++ if (tcg_enabled() || qtest_enabled()) { ++ qdev_property_add_static(DEVICE(obj), ++ &arm_cpu_has_vfp_property); ++ } + if (cpu_isar_feature(aa32_simd_r32, cpu)) { + cpu->has_vfp_d32 = true; + /* +-- +2.41.0.windows.1 + diff --git a/target-arm-Use-float_status-copy-in-sme_fmopa_s.patch b/target-arm-Use-float_status-copy-in-sme_fmopa_s.patch new file mode 100644 index 0000000..91143bf --- /dev/null +++ b/target-arm-Use-float_status-copy-in-sme_fmopa_s.patch @@ -0,0 +1,47 @@ +From 06da30c93dfd4cff013881582d25c3d04456376b Mon Sep 17 00:00:00 2001 +From: gubin +Date: Thu, 2 Jan 2025 10:40:17 +0800 +Subject: [PATCH] target/arm: Use float_status copy in sme_fmopa_s +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cherry-pick from 31d93fedf41c24b0badb38cd9317590d1ef74e37 + +We made a copy above because the fp exception flags +are not propagated back to the FPST register, but +then failed to use the copy. + +Cc: qemu-stable@nongnu.org +Fixes: 558e956c719 ("target/arm: Implement FMOPA, FMOPS (non-widening)") +Signed-off-by: Daniyal Khan +Signed-off-by: Richard Henderson +Reviewed-by: Philippe Mathieu-Daudé +Reviewed-by: Alex Bennée +Message-id: 20240717060149.204788-2-richard.henderson@linaro.org +[rth: Split from a larger patch] +Signed-off-by: Richard Henderson +Reviewed-by: Philippe Mathieu-Daudé +Reviewed-by: Alex Bennée +Signed-off-by: Peter Maydell +Signed-off-by: gubin +--- + target/arm/tcg/sme_helper.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/target/arm/tcg/sme_helper.c b/target/arm/tcg/sme_helper.c +index 9a9b1a240c..ae4f39ed02 100644 +--- a/target/arm/tcg/sme_helper.c ++++ b/target/arm/tcg/sme_helper.c +@@ -916,7 +916,7 @@ void HELPER(sme_fmopa_s)(void *vza, void *vzn, void *vzm, void *vpn, + if (pb & 1) { + uint32_t *a = vza_row + H1_4(col); + uint32_t *m = vzm + H1_4(col); +- *a = float32_muladd(n, *m, *a, 0, vst); ++ *a = float32_muladd(n, *m, *a, 0, &fpst); + } + col += 4; + pb >>= 4; +-- +2.41.0.windows.1 + diff --git a/target-arm-fix-exception-syndrome-for-AArch32-bkpt-i.patch b/target-arm-fix-exception-syndrome-for-AArch32-bkpt-i.patch new file mode 100644 index 0000000..3380c33 --- /dev/null +++ b/target-arm-fix-exception-syndrome-for-AArch32-bkpt-i.patch @@ -0,0 +1,91 @@ +From 3031ddd4dd45a706def011a9d6afdacd2557d147 Mon Sep 17 00:00:00 2001 +From: gubin +Date: Thu, 28 Nov 2024 14:26:43 +0800 +Subject: [PATCH] target/arm: fix exception syndrome for AArch32 bkpt insn +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cherry-pick from f670be1aad33e801779af580398895b9455747ee + +Debug exceptions that target AArch32 Hyp mode are reported differently +than on AAarch64. Internally, Qemu uses the AArch64 syndromes. Therefore +such exceptions need to be either converted to a prefetch abort +(breakpoints, vector catch) or a data abort (watchpoints). + +Cc: qemu-stable@nongnu.org +Signed-off-by: Jan Klötzke +Reviewed-by: Richard Henderson +Message-id: 20240127202758.3326381-1-jan.kloetzke@kernkonzept.com +Signed-off-by: Peter Maydell +Signed-off-by: gubin +--- + target/arm/helper.c | 18 ++++++++++++++++++ + target/arm/syndrome.h | 8 ++++++++ + 2 files changed, 26 insertions(+) + +diff --git a/target/arm/helper.c b/target/arm/helper.c +index 793aa89cc6..35b8eaf15a 100644 +--- a/target/arm/helper.c ++++ b/target/arm/helper.c +@@ -10848,6 +10848,24 @@ static void arm_cpu_do_interrupt_aarch32(CPUState *cs) + } + + if (env->exception.target_el == 2) { ++ /* Debug exceptions are reported differently on AArch32 */ ++ switch (syn_get_ec(env->exception.syndrome)) { ++ case EC_BREAKPOINT: ++ case EC_BREAKPOINT_SAME_EL: ++ case EC_AA32_BKPT: ++ case EC_VECTORCATCH: ++ env->exception.syndrome = syn_insn_abort(arm_current_el(env) == 2, ++ 0, 0, 0x22); ++ break; ++ case EC_WATCHPOINT: ++ env->exception.syndrome = syn_set_ec(env->exception.syndrome, ++ EC_DATAABORT); ++ break; ++ case EC_WATCHPOINT_SAME_EL: ++ env->exception.syndrome = syn_set_ec(env->exception.syndrome, ++ EC_DATAABORT_SAME_EL); ++ break; ++ } + arm_cpu_do_interrupt_aarch32_hyp(cs); + return; + } +diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h +index 95454b5b3b..eccb759da6 100644 +--- a/target/arm/syndrome.h ++++ b/target/arm/syndrome.h +@@ -25,6 +25,8 @@ + #ifndef TARGET_ARM_SYNDROME_H + #define TARGET_ARM_SYNDROME_H + ++#include "qemu/bitops.h" ++ + /* Valid Syndrome Register EC field values */ + enum arm_exception_class { + EC_UNCATEGORIZED = 0x00, +@@ -80,6 +82,7 @@ typedef enum { + SME_ET_InactiveZA, + } SMEExceptionType; + ++#define ARM_EL_EC_LENGTH 6 + #define ARM_EL_EC_SHIFT 26 + #define ARM_EL_IL_SHIFT 25 + #define ARM_EL_ISV_SHIFT 24 +@@ -91,6 +94,11 @@ static inline uint32_t syn_get_ec(uint32_t syn) + return syn >> ARM_EL_EC_SHIFT; + } + ++static inline uint32_t syn_set_ec(uint32_t syn, uint32_t ec) ++{ ++ return deposit32(syn, ARM_EL_EC_SHIFT, ARM_EL_EC_LENGTH, ec); ++} ++ + /* + * Utility functions for constructing various kinds of syndrome value. + * Note that in general we follow the AArch64 syndrome values; in a +-- +2.41.0.windows.1 + diff --git a/target-arm-take-HSTR-traps-of-cp15-accesses-to-EL2-n.patch b/target-arm-take-HSTR-traps-of-cp15-accesses-to-EL2-n.patch new file mode 100644 index 0000000..aaa839a --- /dev/null +++ b/target-arm-take-HSTR-traps-of-cp15-accesses-to-EL2-n.patch @@ -0,0 +1,42 @@ +From 45e80d1d71f7f4b50b47ec61560a77edd80badc1 Mon Sep 17 00:00:00 2001 +From: gubin +Date: Thu, 2 Jan 2025 10:35:05 +0800 +Subject: [PATCH] target/arm: take HSTR traps of cp15 accesses to EL2, not EL1 + +cherry-pick from fbe5ac5671a9cfcc7f4aee9a5fac7720eea08876 + +The HSTR_EL2 register allows the hypervisor to trap AArch32 EL1 and +EL0 accesses to cp15 registers. We incorrectly implemented this so +they trap to EL1 when we detect the need for a HSTR trap at code +generation time. (The check in access_check_cp_reg() which we do at +runtime to catch traps from EL0 is correctly routing them to EL2.) + +Use the correct target EL when generating the code to take the trap. + +Cc: qemu-stable@nongnu.org +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2226 +Fixes: 049edada5e93df ("target/arm: Make HSTR_EL2 traps take priority over UNDEF-at-EL1") +Signed-off-by: Peter Maydell +Reviewed-by: Richard Henderson +Message-id: 20240325133116.2075362-1-peter.maydell@linaro.org +Signed-off-by: gubin +--- + target/arm/tcg/translate.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c +index b3660173d1..e555e885a1 100644 +--- a/target/arm/tcg/translate.c ++++ b/target/arm/tcg/translate.c +@@ -4584,7 +4584,7 @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64, + tcg_gen_andi_i32(t, t, 1u << maskbit); + tcg_gen_brcondi_i32(TCG_COND_EQ, t, 0, over.label); + +- gen_exception_insn(s, 0, EXCP_UDEF, syndrome); ++ gen_exception_insn_el(s, 0, EXCP_UDEF, syndrome, 2); + /* + * gen_exception_insn() will set is_jmp to DISAS_NORETURN, + * but since we're conditionally branching over it, we want +-- +2.41.0.windows.1 + diff --git a/target-hexagon-don-t-look-for-static-glib.patch b/target-hexagon-don-t-look-for-static-glib.patch new file mode 100644 index 0000000..92fe02e --- /dev/null +++ b/target-hexagon-don-t-look-for-static-glib.patch @@ -0,0 +1,47 @@ +From f698e21192b07335197e8a20032cbb411715775a Mon Sep 17 00:00:00 2001 +From: gubin +Date: Sat, 11 Jan 2025 10:37:12 +0800 +Subject: [PATCH] target/hexagon: don't look for static glib + +cherry-pick from fe68cc0923ebfa0c12e4176f61ec9b363a07a73a + +When cross compiling QEMU configured with --static, I've been getting +configure errors like the following: + + Build-time dependency glib-2.0 found: NO + + ../target/hexagon/meson.build:303:15: ERROR: Dependency lookup for glib-2.0 with method 'pkgconfig' failed: Could not generate libs for glib-2.0: + Package libpcre2-8 was not found in the pkg-config search path. + Perhaps you should add the directory containing `libpcre2-8.pc' + to the PKG_CONFIG_PATH environment variable + Package 'libpcre2-8', required by 'glib-2.0', not found + +This happens because --static sets the prefer_static Meson option, but +my build machine doesn't have a static libpcre2. I don't think it +makes sense to insist that native dependencies are static, just +because I want the non-native QEMU binaries to be static. + +Signed-off-by: Alyssa Ross +Link: https://lore.kernel.org/r/20240805104921.4035256-1-hi@alyssa.is +Signed-off-by: Paolo Bonzini +Signed-off-by: gubin +--- + target/hexagon/meson.build | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/target/hexagon/meson.build b/target/hexagon/meson.build +index da8e608d00..436217f25a 100644 +--- a/target/hexagon/meson.build ++++ b/target/hexagon/meson.build +@@ -188,7 +188,7 @@ if idef_parser_enabled and 'hexagon-linux-user' in target_dirs + arguments: ['@INPUT@', '--defines=@OUTPUT1@', '--output=@OUTPUT0@'] + ) + +- glib_dep = dependency('glib-2.0', native: true) ++ glib_dep = dependency('glib-2.0', native: true, static: false) + + idef_parser = executable( + 'idef-parser', +-- +2.41.0.windows.1 + diff --git a/target-i386-cpu-Fix-notes-for-CPU-models.patch b/target-i386-cpu-Fix-notes-for-CPU-models.patch new file mode 100644 index 0000000..cd5f0d8 --- /dev/null +++ b/target-i386-cpu-Fix-notes-for-CPU-models.patch @@ -0,0 +1,41 @@ +From 96b5acaa5dbff1e5bf8809fd818e6ff813e5a170 Mon Sep 17 00:00:00 2001 +From: qihao_yewu +Date: Tue, 31 Dec 2024 02:04:04 -0500 +Subject: [PATCH] target/i386/cpu: Fix notes for CPU models + +cheery-pick from 93dcc9390e5ad0696ae7e9b7b3a5b08c2d1b6de6 + +Fixes: 644e3c5d812 ("missing vmx features for Skylake-Server and Cascadelake-Server") +Signed-off-by: Han Han +Reviewed-by: Chenyi Qiang +Reviewed-by: Michael Tokarev +Signed-off-by: Michael Tokarev +Signed-off-by: qihao_yewu +--- + target/i386/cpu.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 727beb6a65..1fa08265bc 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -3453,6 +3453,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { + }, + { + .version = 4, ++ .note = "IBRS, EPT switching, no TSX", + .props = (PropValue[]) { + { "vmx-eptp-switching", "on" }, + { /* end of list */ } +@@ -3587,7 +3588,7 @@ static const X86CPUDefinition builtin_x86_defs[] = { + }, + }, + { .version = 4, +- .note = "ARCH_CAPABILITIES, no TSX", ++ .note = "ARCH_CAPABILITIES, EPT switching, no TSX", + .props = (PropValue[]) { + { "vmx-eptp-switching", "on" }, + { /* end of list */ } +-- +2.41.0.windows.1 + diff --git a/target-i386-csv-Request-to-set-private-memory-of-CSV.patch b/target-i386-csv-Request-to-set-private-memory-of-CSV.patch new file mode 100644 index 0000000..b7210f3 --- /dev/null +++ b/target-i386-csv-Request-to-set-private-memory-of-CSV.patch @@ -0,0 +1,149 @@ +From ded4216fbfe740196a3ace80f5cb162b73f676b2 Mon Sep 17 00:00:00 2001 +From: hanliyang +Date: Sat, 28 Sep 2024 17:37:17 +0800 +Subject: [PATCH] target/i386: csv: Request to set private memory of CSV3 guest + if the extension is enabled + +If Qemu negotiates with Linux KVM to enable the +KVM_CAP_HYGON_COCO_EXT_CSV3_SET_PRIV_MEM capability, then Qemu should +explicitly request the issuance of the CSV3_CMD_SET_GUEST_PRIVATE_MEMORY +command. + +Signed-off-by: hanliyang +--- + hw/i386/pc_sysfw.c | 3 +++ + include/sysemu/kvm.h | 9 +++++++++ + linux-headers/linux/kvm.h | 2 ++ + target/i386/csv-sysemu-stub.c | 5 +++++ + target/i386/csv.c | 23 +++++++++++++++++++++++ + target/i386/csv.h | 2 ++ + target/i386/trace-events | 3 ++- + 7 files changed, 46 insertions(+), 1 deletion(-) + +diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c +index 2bbcbb8d35..7c6a910250 100644 +--- a/hw/i386/pc_sysfw.c ++++ b/hw/i386/pc_sysfw.c +@@ -268,6 +268,9 @@ void x86_firmware_configure(void *ptr, int size) + ram_addr_t offset = 0; + MemoryRegion *mr; + ++ if (kvm_csv3_should_set_priv_mem()) ++ csv3_set_guest_private_memory(&error_fatal); ++ + mr = memory_region_from_host(ptr, &offset); + if (!mr) { + error_report("failed to get memory region of flash"); +diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h +index 438b4e9183..176aa53cbe 100644 +--- a/include/sysemu/kvm.h ++++ b/include/sysemu/kvm.h +@@ -154,6 +154,14 @@ extern bool kvm_csv3_allowed; + */ + #define kvm_csv3_enabled() (kvm_csv3_allowed) + ++/** ++ * kvm_csv3_should_set_priv_mem: ++ * Returns: true if we should explicitly request ++ * KVM_CSV3_SET_GUEST_PRIVATE_MEMORY. ++ */ ++#define kvm_csv3_should_set_priv_mem() \ ++ (kvm_hygon_coco_ext_inuse & KVM_CAP_HYGON_COCO_EXT_CSV3_SET_PRIV_MEM) ++ + #else + + #define kvm_enabled() (0) +@@ -171,6 +179,7 @@ extern bool kvm_csv3_allowed; + #define kvm_readonly_mem_enabled() (false) + #define kvm_msi_devid_required() (false) + #define kvm_csv3_enabled() (false) ++#define kvm_csv3_should_set_priv_mem() (false) + + #endif /* CONFIG_KVM_IS_POSSIBLE */ + +diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h +index ab28e9af5e..84cec64b88 100644 +--- a/linux-headers/linux/kvm.h ++++ b/linux-headers/linux/kvm.h +@@ -2133,6 +2133,8 @@ enum csv3_cmd_id { + KVM_CSV3_RECEIVE_ENCRYPT_DATA, + KVM_CSV3_RECEIVE_ENCRYPT_CONTEXT, + ++ KVM_CSV3_SET_GUEST_PRIVATE_MEMORY = 0xc8, ++ + KVM_CSV3_NR_MAX, + }; + +diff --git a/target/i386/csv-sysemu-stub.c b/target/i386/csv-sysemu-stub.c +index db22c299a6..e49755da5c 100644 +--- a/target/i386/csv-sysemu-stub.c ++++ b/target/i386/csv-sysemu-stub.c +@@ -39,3 +39,8 @@ void csv3_shared_region_dma_unmap(uint64_t start, uint64_t end) + { + + } ++ ++int csv3_set_guest_private_memory(Error **errp) ++{ ++ g_assert_not_reached(); ++} +diff --git a/target/i386/csv.c b/target/i386/csv.c +index 4aed225763..d9b50040a3 100644 +--- a/target/i386/csv.c ++++ b/target/i386/csv.c +@@ -698,3 +698,26 @@ int csv3_load_incoming_context(QEMUFile *f) + /* receive csv3 context. */ + return csv3_receive_encrypt_context(s, f); + } ++ ++int csv3_set_guest_private_memory(Error **errp) ++{ ++ int fw_error; ++ int ret = 0; ++ ++ if (!csv3_enabled()) { ++ error_setg(errp, "%s: CSV3 is not enabled", __func__); ++ return -1; ++ } ++ ++ /* if CSV3 is in update state then load the data to secure memory */ ++ if (csv3_check_state(SEV_STATE_LAUNCH_UPDATE)) { ++ trace_kvm_csv3_set_guest_private_memory(); ++ ret = csv3_ioctl(KVM_CSV3_SET_GUEST_PRIVATE_MEMORY, NULL, &fw_error); ++ if (ret) ++ error_setg(errp, "%s: CSV3 fail set private memory, ret=%d" ++ " fw_error=%d '%s'", ++ __func__, ret, fw_error, fw_error_to_str(fw_error)); ++ } ++ ++ return ret; ++} +diff --git a/target/i386/csv.h b/target/i386/csv.h +index c1d4cec3e0..fb669279a8 100644 +--- a/target/i386/csv.h ++++ b/target/i386/csv.h +@@ -130,4 +130,6 @@ int csv3_queue_outgoing_page(uint8_t *ptr, uint32_t sz, uint64_t addr); + int csv3_save_queued_outgoing_pages(QEMUFile *f, uint64_t *bytes_sent); + int csv3_save_outgoing_context(QEMUFile *f, uint64_t *bytes_sent); + ++int csv3_set_guest_private_memory(Error **errp); ++ + #endif +diff --git a/target/i386/trace-events b/target/i386/trace-events +index ad3cfb9612..5d4a709a39 100644 +--- a/target/i386/trace-events ++++ b/target/i386/trace-events +@@ -21,8 +21,9 @@ kvm_sev_send_update_vmsa(uint32_t cpu_id, uint32_t cpu_index, void *dst, int len + kvm_sev_receive_update_vmsa(uint32_t cpu_id, uint32_t cpu_index, void *src, int len, void *hdr, int hdr_len) "cpu_id %d cpu_index %d trans %p len %d hdr %p hdr_len %d" + + # csv.c +-kvm_csv3_launch_encrypt_data(uint64_t gpa, void *addr, uint64_t len) "gpa 0x%" PRIx64 "addr %p len 0x%" PRIx64 ++kvm_csv3_launch_encrypt_data(uint64_t gpa, void *addr, uint64_t len) "gpa 0x%" PRIx64 " addr %p len 0x%" PRIx64 + kvm_csv3_send_encrypt_data(void *dst, int len) "trans %p len %d" + kvm_csv3_send_encrypt_context(void *dst, int len) "trans %p len %d" + kvm_csv3_receive_encrypt_data(void *dst, int len, void *hdr, int hdr_len) "trans %p len %d hdr %p hdr_len %d" + kvm_csv3_receive_encrypt_context(void *dst, int len, void *hdr, int hdr_len) "trans %p len %d hdr %p hdr_len %d" ++kvm_csv3_set_guest_private_memory(void) "" +-- +2.41.0.windows.1 + diff --git a/target-i386-csv-Support-inject-secret-for-CSV3-guest.patch b/target-i386-csv-Support-inject-secret-for-CSV3-guest.patch new file mode 100644 index 0000000..dbb1d97 --- /dev/null +++ b/target-i386-csv-Support-inject-secret-for-CSV3-guest.patch @@ -0,0 +1,43 @@ +From b74c6b8971610ffc9c901a9b22c92b40084a74bf Mon Sep 17 00:00:00 2001 +From: hanliyang +Date: Sun, 29 Sep 2024 15:03:47 +0800 +Subject: [PATCH] target/i386: csv: Support inject secret for CSV3 guest only + if the extension is enabled + +The CSV3 guest can only inject secrets when the +KVM_CAP_HYGON_COCO_EXT_CSV3_INJ_SECRET capability is enabled. + +Additionally, if the guest is a CSV3 guest, the guest_uaddr field of the +KVM ioctl's input should be set to the value of the GPA. + +Signed-off-by: hanliyang +--- + target/i386/sev.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/target/i386/sev.c b/target/i386/sev.c +index 3a9c9ceec7..b4b42fd716 100644 +--- a/target/i386/sev.c ++++ b/target/i386/sev.c +@@ -1416,7 +1416,17 @@ int sev_inject_launch_secret(const char *packet_hdr, const char *secret, + input.trans_uaddr = (uint64_t)(unsigned long)data; + input.trans_len = data_sz; + +- input.guest_uaddr = (uint64_t)(unsigned long)hva; ++ /* For Hygon CSV3 guest, the guest_uaddr should be the gpa */ ++ if (csv3_enabled()) { ++ if (kvm_hygon_coco_ext_inuse & KVM_CAP_HYGON_COCO_EXT_CSV3_INJ_SECRET) { ++ input.guest_uaddr = gpa; ++ } else { ++ error_setg(errp, "CSV3 inject secret unsupported!"); ++ return 1; ++ } ++ } else { ++ input.guest_uaddr = (uint64_t)(unsigned long)hva; ++ } + input.guest_len = data_sz; + + trace_kvm_sev_launch_secret(gpa, input.guest_uaddr, +-- +2.41.0.windows.1 + diff --git a/target-i386-csv-Support-load-kernel-hashes-for-CSV3-.patch b/target-i386-csv-Support-load-kernel-hashes-for-CSV3-.patch new file mode 100644 index 0000000..a0930a6 --- /dev/null +++ b/target-i386-csv-Support-load-kernel-hashes-for-CSV3-.patch @@ -0,0 +1,40 @@ +From ca6d5f032ab4c93d78c90a83beefcfb05bf1ad79 Mon Sep 17 00:00:00 2001 +From: hanliyang +Date: Sat, 28 Sep 2024 17:55:13 +0800 +Subject: [PATCH] target/i386: csv: Support load kernel hashes for CSV3 guest + only if the extension is enabled + +The CSV3 guest can only update kernel hashes when the +KVM_CAP_HYGON_COCO_EXT_CSV3_MULT_LUP_DATA capability is enabled. + +Signed-off-by: hanliyang +--- + target/i386/sev.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/target/i386/sev.c b/target/i386/sev.c +index 721eca2150..3a9c9ceec7 100644 +--- a/target/i386/sev.c ++++ b/target/i386/sev.c +@@ -2748,7 +2748,17 @@ bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp) + /* zero the excess data so the measurement can be reliably calculated */ + memset(padded_ht->padding, 0, sizeof(padded_ht->padding)); + +- if (sev_encrypt_flash((uint8_t *)padded_ht, sizeof(*padded_ht), errp) < 0) { ++ if (csv3_enabled()) { ++ if (kvm_hygon_coco_ext_inuse & KVM_CAP_HYGON_COCO_EXT_CSV3_MULT_LUP_DATA) { ++ if (csv3_load_data(area->base, (uint8_t *)padded_ht, ++ sizeof(*padded_ht), errp) < 0) { ++ ret = false; ++ } ++ } else { ++ error_report("%s: CSV3 load kernel hashes unsupported!", __func__); ++ ret = false; ++ } ++ } else if (sev_encrypt_flash((uint8_t *)padded_ht, sizeof(*padded_ht), errp) < 0) { + ret = false; + } + +-- +2.41.0.windows.1 + diff --git a/target-i386-fix-hang-when-using-slow-path-for-ptw_se.patch b/target-i386-fix-hang-when-using-slow-path-for-ptw_se.patch new file mode 100644 index 0000000..5c50e9d --- /dev/null +++ b/target-i386-fix-hang-when-using-slow-path-for-ptw_se.patch @@ -0,0 +1,59 @@ +From ddb2cb652db80b24ba5ddf0b00dd3ba3f9224eba Mon Sep 17 00:00:00 2001 +From: Pierrick Bouvier +Date: Fri, 25 Oct 2024 10:58:56 -0700 +Subject: [PATCH] target/i386: fix hang when using slow path for ptw_setl + +When instrumenting memory accesses for plugin, we force memory accesses +to use the slow path for mmu [1]. This create a situation where we end +up calling ptw_setl_slow. This was fixed recently in [2] but the issue +still could appear out of plugins use case. + +Since this function gets called during a cpu_exec, start_exclusive then +hangs. This exclusive section was introduced initially for security +reasons [3]. + +I suspect this code path was never triggered, because ptw_setl_slow +would always be called transitively from cpu_exec, resulting in a hang. + +[1] https://gitlab.com/qemu-project/qemu/-/commit/6d03226b42247b68ab2f0b3663e0f624335a4055 +[2] https://gitlab.com/qemu-project/qemu/-/commit/115ade42d50144c15b74368d32dc734ea277d853 +[2] https://gitlab.com/qemu-project/qemu/-/commit/9a96406787afcc9960fbe8791892c78311d6971f in 8.2.x series +[3] https://gitlab.com/qemu-project/qemu/-/issues/279 + +Fixes: https://gitlab.com/qemu-project/qemu/-/issues/2566 +Signed-off-by: Pierrick Bouvier +Reviewed-by: Richard Henderson +Message-ID: <20241025175857.2554252-2-pierrick.bouvier@linaro.org> +Signed-off-by: Richard Henderson +(cherry picked from commit 7ba055b49b74c4d2f4a338c5198485bdff373fb1) +Signed-off-by: zhujun2 +--- + target/i386/tcg/sysemu/excp_helper.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/target/i386/tcg/sysemu/excp_helper.c b/target/i386/tcg/sysemu/excp_helper.c +index 5b86f439ad..294dbc50e2 100644 +--- a/target/i386/tcg/sysemu/excp_helper.c ++++ b/target/i386/tcg/sysemu/excp_helper.c +@@ -107,6 +107,10 @@ static bool ptw_setl_slow(const PTETranslate *in, uint32_t old, uint32_t new) + { + uint32_t cmp; + ++ CPUState *cpu = env_cpu(in->env); ++ /* We are in cpu_exec, and start_exclusive can't be called directly.*/ ++ g_assert(cpu->running); ++ cpu_exec_end(cpu); + /* Does x86 really perform a rmw cycle on mmio for ptw? */ + start_exclusive(); + cmp = cpu_ldl_mmuidx_ra(in->env, in->gaddr, in->ptw_idx, 0); +@@ -114,6 +118,7 @@ static bool ptw_setl_slow(const PTETranslate *in, uint32_t old, uint32_t new) + cpu_stl_mmuidx_ra(in->env, in->gaddr, new, in->ptw_idx, 0); + } + end_exclusive(); ++ cpu_exec_start(cpu); + return cmp == old; + } + +-- +2.41.0.windows.1 + diff --git a/target-i386-kvm-Support-to-get-and-enable-extensions.patch b/target-i386-kvm-Support-to-get-and-enable-extensions.patch new file mode 100644 index 0000000..0686e1d --- /dev/null +++ b/target-i386-kvm-Support-to-get-and-enable-extensions.patch @@ -0,0 +1,105 @@ +From 9eb75830e70638d12efa0ec15a2f8b55e7c905da Mon Sep 17 00:00:00 2001 +From: hanliyang +Date: Sat, 28 Sep 2024 14:46:28 +0800 +Subject: [PATCH] target/i386: kvm: Support to get and enable extensions for + Hygon CoCo guest + +To enable advanced Hygon CoCo features, we should detect these features +during the initialization of VMs in the KVM accelerator. It is +suggested to enable these features if they are detected, allowing the +guest VM to run with additional functionalities. + +Signed-off-by: hanliyang +--- + linux-headers/linux/kvm.h | 7 +++++++ + target/i386/csv.c | 2 ++ + target/i386/csv.h | 2 ++ + target/i386/kvm/csv-stub.c | 2 ++ + target/i386/kvm/kvm.c | 17 +++++++++++++++++ + 5 files changed, 30 insertions(+) + +diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h +index 05e499b45b..ab28e9af5e 100644 +--- a/linux-headers/linux/kvm.h ++++ b/linux-headers/linux/kvm.h +@@ -1204,6 +1204,13 @@ struct kvm_ppc_resize_hpt { + #define KVM_CAP_ARM_TMM 300 + + #define KVM_CAP_SEV_ES_GHCB 500 ++#define KVM_CAP_HYGON_COCO_EXT 501 ++/* support userspace to request firmware to build CSV3 guest's memory space */ ++#define KVM_CAP_HYGON_COCO_EXT_CSV3_SET_PRIV_MEM (1 << 0) ++/* support request to update CSV3 guest's memory region multiple times */ ++#define KVM_CAP_HYGON_COCO_EXT_CSV3_MULT_LUP_DATA (1 << 1) ++/* support request to inject secret to CSV3 guest */ ++#define KVM_CAP_HYGON_COCO_EXT_CSV3_INJ_SECRET (1 << 2) + + #define KVM_CAP_ARM_VIRT_MSI_BYPASS 799 + +diff --git a/target/i386/csv.c b/target/i386/csv.c +index 571beeb61f..4aed225763 100644 +--- a/target/i386/csv.c ++++ b/target/i386/csv.c +@@ -34,6 +34,8 @@ + #include "csv.h" + + bool csv_kvm_cpu_reset_inhibit; ++uint32_t kvm_hygon_coco_ext; ++uint32_t kvm_hygon_coco_ext_inuse; + + struct ConfidentialGuestMemoryEncryptionOps csv3_memory_encryption_ops = { + .save_setup = sev_save_setup, +diff --git a/target/i386/csv.h b/target/i386/csv.h +index 8621f0b6fd..c1d4cec3e0 100644 +--- a/target/i386/csv.h ++++ b/target/i386/csv.h +@@ -58,6 +58,8 @@ bool csv3_enabled(void); + #define CSV_OUTGOING_PAGE_WINDOW_SIZE (4094 * TARGET_PAGE_SIZE) + + extern bool csv_kvm_cpu_reset_inhibit; ++extern uint32_t kvm_hygon_coco_ext; ++extern uint32_t kvm_hygon_coco_ext_inuse; + + typedef struct CsvBatchCmdList CsvBatchCmdList; + typedef void (*CsvDestroyCmdNodeFn) (void *data); +diff --git a/target/i386/kvm/csv-stub.c b/target/i386/kvm/csv-stub.c +index 4d1376f268..8662d33206 100644 +--- a/target/i386/kvm/csv-stub.c ++++ b/target/i386/kvm/csv-stub.c +@@ -15,3 +15,5 @@ + #include "csv.h" + + bool csv_kvm_cpu_reset_inhibit; ++uint32_t kvm_hygon_coco_ext; ++uint32_t kvm_hygon_coco_ext_inuse; +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index 925f4f8040..12e920bbb4 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -2639,6 +2639,23 @@ int kvm_arch_init(MachineState *ms, KVMState *s) + } + } + ++ if (is_hygon_cpu()) { ++ /* check and enable Hygon coco extensions */ ++ kvm_hygon_coco_ext = (uint32_t)kvm_vm_check_extension(s, ++ KVM_CAP_HYGON_COCO_EXT); ++ if (kvm_hygon_coco_ext) { ++ ret = kvm_vm_enable_cap(s, KVM_CAP_HYGON_COCO_EXT, 0, ++ (uint64_t)kvm_hygon_coco_ext); ++ if (ret == -EINVAL) { ++ error_report("kvm: Failed to enable KVM_CAP_HYGON_COCO_EXT cap: %s", ++ strerror(-ret)); ++ kvm_hygon_coco_ext_inuse = 0; ++ } else { ++ kvm_hygon_coco_ext_inuse = (uint32_t)ret; ++ } ++ } ++ } ++ + ret = kvm_get_supported_msrs(s); + if (ret < 0) { + return ret; +-- +2.41.0.windows.1 + diff --git a/target-riscv-Avoid-bad-shift-in-riscv_cpu_do_interru.patch b/target-riscv-Avoid-bad-shift-in-riscv_cpu_do_interru.patch new file mode 100644 index 0000000..45007fb --- /dev/null +++ b/target-riscv-Avoid-bad-shift-in-riscv_cpu_do_interru.patch @@ -0,0 +1,62 @@ +From e52a2122cb1574723c7c8181ba751cc0ff37648e Mon Sep 17 00:00:00 2001 +From: Zhang Jiao +Date: Thu, 12 Dec 2024 09:46:18 +0800 +Subject: [PATCH] target/riscv: Avoid bad shift in riscv_cpu_do_interrupt() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cheery-pick from 5311599cdc48337f2f27b1b51a80d46d75b05ed0 + +In riscv_cpu_do_interrupt() we use the 'cause' value we got out of +cs->exception as a shift value. However this value can be larger +than 31, which means that "1 << cause" is undefined behaviour, +because we do the shift on an 'int' type. + +This causes the undefined behaviour sanitizer to complain +on one of the check-tcg tests: + +$ UBSAN_OPTIONS=print_stacktrace=1:abort_on_error=1:halt_on_error=1 ./build/clang/qemu-system-riscv64 -M virt -semihosting -display none -device loader,file=build/clang/tests/tcg/riscv64-softmmu/issue1060 +../../target/riscv/cpu_helper.c:1805:38: runtime error: shift exponent 63 is too large for 32-bit type 'int' + #0 0x55f2dc026703 in riscv_cpu_do_interrupt /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/clang/../../target/riscv/cpu_helper.c:1805:38 + #1 0x55f2dc3d170e in cpu_handle_exception /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/clang/../../accel/tcg/cpu-exec.c:752:9 + +In this case cause is RISCV_EXCP_SEMIHOST, which is 0x3f. + +Use 1ULL instead to ensure that the shift is in range. + +Signed-off-by: Peter Maydell +Fixes: 1697837ed9 ("target/riscv: Add M-mode virtual interrupt and IRQ filtering support.") +Fixes: 40336d5b1d ("target/riscv: Add HS-mode virtual interrupt and IRQ filtering support.") +Reviewed-by: Daniel Henrique Barboza +Reviewed-by: Richard Henderson +Reviewed-by: Alistair Francis +Message-ID: <20241128103831.3452572-1-peter.maydell@linaro.org> +Signed-off-by: Philippe Mathieu-Daudé +Signed-off-by: Zhang Jiao +--- + target/riscv/cpu_helper.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c +index e7e23b34f4..4d8f1248dd 100644 +--- a/target/riscv/cpu_helper.c ++++ b/target/riscv/cpu_helper.c +@@ -1644,10 +1644,10 @@ void riscv_cpu_do_interrupt(CPUState *cs) + bool async = !!(cs->exception_index & RISCV_EXCP_INT_FLAG); + target_ulong cause = cs->exception_index & RISCV_EXCP_INT_MASK; + uint64_t deleg = async ? env->mideleg : env->medeleg; +- bool s_injected = env->mvip & (1 << cause) & env->mvien && +- !(env->mip & (1 << cause)); +- bool vs_injected = env->hvip & (1 << cause) & env->hvien && +- !(env->mip & (1 << cause)); ++ bool s_injected = env->mvip & (1ULL << cause) & env->mvien && ++ !(env->mip & (1ULL << cause)); ++ bool vs_injected = env->hvip & (1ULL << cause) & env->hvien && ++ !(env->mip & (1ULL << cause)); + target_ulong tval = 0; + target_ulong tinst = 0; + target_ulong htval = 0; +-- +2.41.0.windows.1 + diff --git a/target-riscv-Fix-vcompress-with-rvv_ta_all_1s.patch b/target-riscv-Fix-vcompress-with-rvv_ta_all_1s.patch new file mode 100644 index 0000000..351d8d9 --- /dev/null +++ b/target-riscv-Fix-vcompress-with-rvv_ta_all_1s.patch @@ -0,0 +1,39 @@ +From 0d93daee2da62d0e86d99fd561d2a973c9634d1f Mon Sep 17 00:00:00 2001 +From: qihao_yewu +Date: Mon, 18 Nov 2024 22:32:53 -0500 +Subject: [PATCH] target/riscv: Fix vcompress with rvv_ta_all_1s + +cheery-pick from c128d39edeff337220fc536a3e935bcba01ecb49 + +vcompress packs vl or less fields into vd, so the tail starts after the +last packed field. This could be more clearly expressed in the ISA, +but for now this thread helps to explain it: + +https://github.com/riscv/riscv-v-spec/issues/796 + +Signed-off-by: Anton Blanchard +Reviewed-by: Daniel Henrique Barboza +Reviewed-by: Alistair Francis +Message-ID: <20241030043538.939712-1-antonb@tenstorrent.com> +Signed-off-by: Alistair Francis +Signed-off-by: qihao_yewu +--- + target/riscv/vector_helper.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c +index c1c3a4d1ea..42ffd3a68a 100644 +--- a/target/riscv/vector_helper.c ++++ b/target/riscv/vector_helper.c +@@ -5045,7 +5045,7 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ + } \ + env->vstart = 0; \ + /* set tail elements to 1s */ \ +- vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz); \ ++ vext_set_elems_1s(vd, vta, num * esz, total_elems * esz); \ + } + + /* Compress into vd elements of vs2 where vs1 is enabled */ +-- +2.41.0.windows.1 + diff --git a/target-riscv-vector_helper.c-fix-vmvr_v-memcpy-endia.patch b/target-riscv-vector_helper.c-fix-vmvr_v-memcpy-endia.patch new file mode 100644 index 0000000..1b6c564 --- /dev/null +++ b/target-riscv-vector_helper.c-fix-vmvr_v-memcpy-endia.patch @@ -0,0 +1,49 @@ +From 1c6b234766bae8c2b518cfd882e8907b831d8d03 Mon Sep 17 00:00:00 2001 +From: gubin +Date: Sat, 11 Jan 2025 11:10:29 +0800 +Subject: [PATCH] target/riscv/vector_helper.c: fix 'vmvr_v' memcpy endianess + +cherry-pick from 768e7b329c0be22035da077fe76221dd0a47103b + +vmvr_v isn't handling the case where the host might be big endian and +the bytes to be copied aren't sequential. + +Suggested-by: Richard Henderson +Fixes: f714361ed7 ("target/riscv: rvv-1.0: implement vstart CSR") +Signed-off-by: Daniel Henrique Barboza +Reviewed-by: Alistair Francis +Reviewed-by: LIU Zhiwei +Reviewed-by: Richard Henderson +Message-ID: <20240314175704.478276-4-dbarboza@ventanamicro.com> +Signed-off-by: Alistair Francis +Signed-off-by: gubin +--- + target/riscv/vector_helper.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c +index 42ffd3a68a..351842f66a 100644 +--- a/target/riscv/vector_helper.c ++++ b/target/riscv/vector_helper.c +@@ -5063,9 +5063,17 @@ void HELPER(vmvr_v)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc) + uint32_t startb = env->vstart * sewb; + uint32_t i = startb; + ++ if (HOST_BIG_ENDIAN && i % 8 != 0) { ++ uint32_t j = ROUND_UP(i, 8); ++ memcpy((uint8_t *)vd + H1(j - 1), ++ (uint8_t *)vs2 + H1(j - 1), ++ j - i); ++ i = j; ++ } ++ + memcpy((uint8_t *)vd + H1(i), + (uint8_t *)vs2 + H1(i), +- maxsz - startb); ++ maxsz - i); + + env->vstart = 0; + } +-- +2.41.0.windows.1 + diff --git a/target-riscv-vector_helper.c-optimize-loops-in-ldst-.patch b/target-riscv-vector_helper.c-optimize-loops-in-ldst-.patch new file mode 100644 index 0000000..5e608a2 --- /dev/null +++ b/target-riscv-vector_helper.c-optimize-loops-in-ldst-.patch @@ -0,0 +1,56 @@ +From a820983749a2d3eebcc36b5a3ae34436fd52db45 Mon Sep 17 00:00:00 2001 +From: gubin +Date: Sat, 11 Jan 2025 10:54:33 +0800 +Subject: [PATCH] target/riscv/vector_helper.c: optimize loops in ldst helpers + +cherry-pick from 0a11629c915f61df798919db51a18ffe4649cb65 + +Change the for loops in ldst helpers to do a single increment in the +counter, and assign it env->vstart, to avoid re-reading from vstart +every time. + +Suggested-by: Richard Henderson +Signed-off-by: Daniel Henrique Barboza +Reviewed-by: Alistair Francis +Reviewed-by: Richard Henderson +Message-ID: <20240314175704.478276-11-dbarboza@ventanamicro.com> +Signed-off-by: Alistair Francis +Signed-off-by: gubin +--- + target/riscv/vector_helper.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c +index 42ffd3a68a..b5acf81cc0 100644 +--- a/target/riscv/vector_helper.c ++++ b/target/riscv/vector_helper.c +@@ -196,7 +196,7 @@ vext_ldst_stride(void *vd, void *v0, target_ulong base, + uint32_t esz = 1 << log2_esz; + uint32_t vma = vext_vma(desc); + +- for (i = env->vstart; i < env->vl; i++, env->vstart++) { ++ for (i = env->vstart; i < env->vl; env->vstart = ++i) { + k = 0; + while (k < nf) { + if (!vm && !vext_elem_mask(v0, i)) { +@@ -262,7 +262,7 @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc, + uint32_t esz = 1 << log2_esz; + + /* load bytes from guest memory */ +- for (i = env->vstart; i < evl; i++, env->vstart++) { ++ for (i = env->vstart; i < evl; env->vstart = ++i) { + k = 0; + while (k < nf) { + target_ulong addr = base + ((i * nf + k) << log2_esz); +@@ -376,7 +376,7 @@ vext_ldst_index(void *vd, void *v0, target_ulong base, + uint32_t vma = vext_vma(desc); + + /* load bytes from guest memory */ +- for (i = env->vstart; i < env->vl; i++, env->vstart++) { ++ for (i = env->vstart; i < env->vl; env->vstart = ++i) { + k = 0; + while (k < nf) { + if (!vm && !vext_elem_mask(v0, i)) { +-- +2.41.0.windows.1 + diff --git a/target-riscv-vector_helper.c-set-vstart-0-in-GEN_VEX.patch b/target-riscv-vector_helper.c-set-vstart-0-in-GEN_VEX.patch new file mode 100644 index 0000000..9ba5801 --- /dev/null +++ b/target-riscv-vector_helper.c-set-vstart-0-in-GEN_VEX.patch @@ -0,0 +1,37 @@ +From a7209a19e2d730fed5f52fda44aaa24e8de8a81c Mon Sep 17 00:00:00 2001 +From: gubin +Date: Sat, 11 Jan 2025 10:46:10 +0800 +Subject: [PATCH] target/riscv/vector_helper.c: set vstart = 0 in + GEN_VEXT_VSLIDEUP_VX() + +cherry-pick from d3646e31ce6d1e02e46e6eabdbc2e637c0cbece7 + +The helper isn't setting env->vstart = 0 after its execution, as it is +expected from every vector instruction that completes successfully. + +Signed-off-by: Daniel Henrique Barboza +Reviewed-by: Richard Henderson +Reviewed-by: Alistair Francis +Reviewed-by: LIU Zhiwei +Message-ID: <20240314175704.478276-2-dbarboza@ventanamicro.com> +Signed-off-by: Alistair Francis +Signed-off-by: gubin +--- + target/riscv/vector_helper.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c +index 42ffd3a68a..e69b68ba43 100644 +--- a/target/riscv/vector_helper.c ++++ b/target/riscv/vector_helper.c +@@ -4770,6 +4770,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ + } \ + *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i - offset)); \ + } \ ++ env->vstart = 0; \ + /* set tail elements to 1s */ \ + vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz); \ + } +-- +2.41.0.windows.1 + diff --git a/usb-hub-Fix-handling-port-power-control-messages.patch b/usb-hub-Fix-handling-port-power-control-messages.patch new file mode 100644 index 0000000..0abf598 --- /dev/null +++ b/usb-hub-Fix-handling-port-power-control-messages.patch @@ -0,0 +1,39 @@ +From bdd1d8b5aea219c7ec1fb590430e3c8e99f43700 Mon Sep 17 00:00:00 2001 +From: qihao_yewu +Date: Mon, 18 Nov 2024 21:37:32 -0500 +Subject: [PATCH] usb-hub: Fix handling port power control messages +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cheery-pick from b2cc69997924b651c0c6f4037782e25f2e438715 + +The ClearPortFeature control message fails for PORT_POWER because there +is no break; at the end of the case statement, causing it to fall through +to the failure handler. Add the missing break; to solve the problem. + +Fixes: 1cc403eb21 ("usb-hub: emulate per port power switching") +Signed-off-by: Guenter Roeck +Reviewed-by: Philippe Mathieu-Daudé +Message-ID: <20241112170152.217664-11-linux@roeck-us.net> +Signed-off-by: Philippe Mathieu-Daudé +Signed-off-by: qihao_yewu +--- + hw/usb/dev-hub.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/hw/usb/dev-hub.c b/hw/usb/dev-hub.c +index 5703e0e826..7b3cfa2c1b 100644 +--- a/hw/usb/dev-hub.c ++++ b/hw/usb/dev-hub.c +@@ -479,6 +479,7 @@ static void usb_hub_handle_control(USBDevice *dev, USBPacket *p, + usb_hub_port_clear(port, PORT_STAT_SUSPEND); + port->wPortChange = 0; + } ++ break; + default: + goto fail; + } +-- +2.41.0.windows.1 + diff --git a/virtio-net-Fix-network-stall-at-the-host-side-waitin.patch b/virtio-net-Fix-network-stall-at-the-host-side-waitin.patch new file mode 100644 index 0000000..b374594 --- /dev/null +++ b/virtio-net-Fix-network-stall-at-the-host-side-waitin.patch @@ -0,0 +1,339 @@ +From a481451a811877640a57ccbef2b33b39567f2802 Mon Sep 17 00:00:00 2001 +From: thomas +Date: Fri, 12 Jul 2024 11:10:53 +0800 +Subject: [PATCH] virtio-net: Fix network stall at the host side waiting for + kick + +commit f937309fbdbb48c354220a3e7110c202ae4aa7fa upstream. + +Patch 06b12970174 ("virtio-net: fix network stall under load") +added double-check to test whether the available buffer size +can satisfy the request or not, in case the guest has added +some buffers to the avail ring simultaneously after the first +check. It will be lucky if the available buffer size becomes +okay after the double-check, then the host can send the packet +to the guest. If the buffer size still can't satisfy the request, +even if the guest has added some buffers, viritio-net would +stall at the host side forever. + +The patch enables notification and checks whether the guest has +added some buffers since last check of available buffers when +the available buffers are insufficient. If no buffer is added, +return false, else recheck the available buffers in the loop. +If the available buffers are sufficient, disable notification +and return true. + +Changes: +1. Change the return type of virtqueue_get_avail_bytes() from void + to int, it returns an opaque that represents the shadow_avail_idx + of the virtqueue on success, else -1 on error. +2. Add a new API: virtio_queue_enable_notification_and_check(), + it takes an opaque as input arg which is returned from + virtqueue_get_avail_bytes(). It enables notification firstly, + then checks whether the guest has added some buffers since + last check of available buffers or not by virtio_queue_poll(), + return ture if yes. + +The patch also reverts patch "06b12970174". + +The case below can reproduce the stall. + + Guest 0 + +--------+ + | iperf | + ---------------> | server | + Host | +--------+ + +--------+ | ... + | iperf |---- + | client |---- Guest n + +--------+ | +--------+ + | | iperf | + ---------------> | server | + +--------+ + +Boot many guests from qemu with virtio network: + qemu ... -netdev tap,id=net_x \ + -device virtio-net-pci-non-transitional,\ + iommu_platform=on,mac=xx:xx:xx:xx:xx:xx,netdev=net_x + +Each guest acts as iperf server with commands below: + iperf3 -s -D -i 10 -p 8001 + iperf3 -s -D -i 10 -p 8002 + +The host as iperf client: + iperf3 -c guest_IP -p 8001 -i 30 -w 256k -P 20 -t 40000 + iperf3 -c guest_IP -p 8002 -i 30 -w 256k -P 20 -t 40000 + +After some time, the host loses connection to the guest, +the guest can send packet to the host, but can't receive +packet from the host. + +It's more likely to happen if SWIOTLB is enabled in the guest, +allocating and freeing bounce buffer takes some CPU ticks, +copying from/to bounce buffer takes more CPU ticks, compared +with that there is no bounce buffer in the guest. +Once the rate of producing packets from the host approximates +the rate of receiveing packets in the guest, the guest would +loop in NAPI. + + receive packets --- + | | + v | + free buf virtnet_poll + | | + v | + add buf to avail ring --- + | + | need kick the host? + | NAPI continues + v + receive packets --- + | | + v | + free buf virtnet_poll + | | + v | + add buf to avail ring --- + | + v + ... ... + +On the other hand, the host fetches free buf from avail +ring, if the buf in the avail ring is not enough, the +host notifies the guest the event by writing the avail +idx read from avail ring to the event idx of used ring, +then the host goes to sleep, waiting for the kick signal +from the guest. + +Once the guest finds the host is waiting for kick singal +(in virtqueue_kick_prepare_split()), it kicks the host. + +The host may stall forever at the sequences below: + + Host Guest + ------------ ----------- + fetch buf, send packet receive packet --- + ... ... | + fetch buf, send packet add buf | + ... add buf virtnet_poll + buf not enough avail idx-> add buf | + read avail idx add buf | + add buf --- + receive packet --- + write event idx ... | + wait for kick add buf virtnet_poll + ... | + --- + no more packet, exit NAPI + +In the first loop of NAPI above, indicated in the range of +virtnet_poll above, the host is sending packets while the +guest is receiving packets and adding buffers. + step 1: The buf is not enough, for example, a big packet + needs 5 buf, but the available buf count is 3. + The host read current avail idx. + step 2: The guest adds some buf, then checks whether the + host is waiting for kick signal, not at this time. + The used ring is not empty, the guest continues + the second loop of NAPI. + step 3: The host writes the avail idx read from avail + ring to used ring as event idx via + virtio_queue_set_notification(q->rx_vq, 1). + step 4: At the end of the second loop of NAPI, recheck + whether kick is needed, as the event idx in the + used ring written by the host is beyound the + range of kick condition, the guest will not + send kick signal to the host. + +Fixes: 06b12970174 ("virtio-net: fix network stall under load") +Cc: qemu-stable@nongnu.org +Signed-off-by: Wencheng Yang +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Jason Wang +--- + hw/net/virtio-net.c | 28 ++++++++++------- + hw/virtio/virtio.c | 64 +++++++++++++++++++++++++++++++++++--- + include/hw/virtio/virtio.h | 19 +++++++++-- + 3 files changed, 92 insertions(+), 19 deletions(-) + +diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c +index c9c83fe297..7184c9c526 100644 +--- a/hw/net/virtio-net.c ++++ b/hw/net/virtio-net.c +@@ -1662,24 +1662,28 @@ static bool virtio_net_can_receive(NetClientState *nc) + + static int virtio_net_has_buffers(VirtIONetQueue *q, int bufsize) + { ++ int opaque; ++ unsigned int in_bytes; + VirtIONet *n = q->n; +- if (virtio_queue_empty(q->rx_vq) || +- (n->mergeable_rx_bufs && +- !virtqueue_avail_bytes(q->rx_vq, bufsize, 0))) { +- virtio_queue_set_notification(q->rx_vq, 1); +- +- /* To avoid a race condition where the guest has made some buffers +- * available after the above check but before notification was +- * enabled, check for available buffers again. +- */ +- if (virtio_queue_empty(q->rx_vq) || +- (n->mergeable_rx_bufs && +- !virtqueue_avail_bytes(q->rx_vq, bufsize, 0))) { ++ ++ while (virtio_queue_empty(q->rx_vq) || n->mergeable_rx_bufs) { ++ opaque = virtqueue_get_avail_bytes(q->rx_vq, &in_bytes, NULL, ++ bufsize, 0); ++ /* Buffer is enough, disable notifiaction */ ++ if (bufsize <= in_bytes) { ++ break; ++ } ++ ++ if (virtio_queue_enable_notification_and_check(q->rx_vq, opaque)) { ++ /* Guest has added some buffers, try again */ ++ continue; ++ } else { + return 0; + } + } + + virtio_queue_set_notification(q->rx_vq, 0); ++ + return 1; + } + +diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c +index 8c3b6b87aa..4f5b241fd3 100644 +--- a/hw/virtio/virtio.c ++++ b/hw/virtio/virtio.c +@@ -743,6 +743,60 @@ int virtio_queue_empty(VirtQueue *vq) + } + } + ++static bool virtio_queue_split_poll(VirtQueue *vq, unsigned shadow_idx) ++{ ++ if (unlikely(!vq->vring.avail)) { ++ return false; ++ } ++ ++ return (uint16_t)shadow_idx != vring_avail_idx(vq); ++} ++ ++static bool virtio_queue_packed_poll(VirtQueue *vq, unsigned shadow_idx) ++{ ++ VRingPackedDesc desc; ++ VRingMemoryRegionCaches *caches; ++ ++ if (unlikely(!vq->vring.desc)) { ++ return false; ++ } ++ ++ caches = vring_get_region_caches(vq); ++ if (!caches) { ++ return false; ++ } ++ ++ vring_packed_desc_read(vq->vdev, &desc, &caches->desc, ++ shadow_idx, true); ++ ++ return is_desc_avail(desc.flags, vq->shadow_avail_wrap_counter); ++} ++ ++static bool virtio_queue_poll(VirtQueue *vq, unsigned shadow_idx) ++{ ++ if (virtio_device_disabled(vq->vdev)) { ++ return false; ++ } ++ ++ if (virtio_vdev_has_feature(vq->vdev, VIRTIO_F_RING_PACKED)) { ++ return virtio_queue_packed_poll(vq, shadow_idx); ++ } else { ++ return virtio_queue_split_poll(vq, shadow_idx); ++ } ++} ++ ++bool virtio_queue_enable_notification_and_check(VirtQueue *vq, ++ int opaque) ++{ ++ virtio_queue_set_notification(vq, 1); ++ ++ if (opaque >= 0) { ++ return virtio_queue_poll(vq, (unsigned)opaque); ++ } else { ++ return false; ++ } ++} ++ + static void virtqueue_unmap_sg(VirtQueue *vq, const VirtQueueElement *elem, + unsigned int len) + { +@@ -1322,9 +1376,9 @@ err: + goto done; + } + +-void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes, +- unsigned int *out_bytes, +- unsigned max_in_bytes, unsigned max_out_bytes) ++int virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes, ++ unsigned int *out_bytes, unsigned max_in_bytes, ++ unsigned max_out_bytes) + { + uint16_t desc_size; + VRingMemoryRegionCaches *caches; +@@ -1357,7 +1411,7 @@ void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes, + caches); + } + +- return; ++ return (int)vq->shadow_avail_idx; + err: + if (in_bytes) { + *in_bytes = 0; +@@ -1365,6 +1419,8 @@ err: + if (out_bytes) { + *out_bytes = 0; + } ++ ++ return -1; + } + + int virtqueue_avail_bytes(VirtQueue *vq, unsigned int in_bytes, +diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h +index 60494aed62..78db2bde98 100644 +--- a/include/hw/virtio/virtio.h ++++ b/include/hw/virtio/virtio.h +@@ -273,9 +273,13 @@ void qemu_put_virtqueue_element(VirtIODevice *vdev, QEMUFile *f, + VirtQueueElement *elem); + int virtqueue_avail_bytes(VirtQueue *vq, unsigned int in_bytes, + unsigned int out_bytes); +-void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes, +- unsigned int *out_bytes, +- unsigned max_in_bytes, unsigned max_out_bytes); ++/** ++ * Return <0 on error or an opaque >=0 to pass to ++ * virtio_queue_enable_notification_and_check on success. ++ */ ++int virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes, ++ unsigned int *out_bytes, unsigned max_in_bytes, ++ unsigned max_out_bytes); + + void virtio_notify_irqfd(VirtIODevice *vdev, VirtQueue *vq); + void virtio_notify(VirtIODevice *vdev, VirtQueue *vq); +@@ -309,6 +313,15 @@ int virtio_queue_ready(VirtQueue *vq); + + int virtio_queue_empty(VirtQueue *vq); + ++/** ++ * Enable notification and check whether guest has added some ++ * buffers since last call to virtqueue_get_avail_bytes. ++ * ++ * @opaque: value returned from virtqueue_get_avail_bytes ++ */ ++bool virtio_queue_enable_notification_and_check(VirtQueue *vq, ++ int opaque); ++ + /* Host binding interface. */ + + uint32_t virtio_config_readb(VirtIODevice *vdev, uint32_t addr); +-- +2.41.0.windows.1 + -- Gitee