From abc3bbc4adb1c9a81b174607122f322d39dd46f0 Mon Sep 17 00:00:00 2001 From: Jiabo Feng Date: Mon, 22 Apr 2024 10:37:40 +0800 Subject: [PATCH] QEMU update to version 6.2.0-88 - hw/virtio/virtio-crypto: Protect from DMA re-entrancy bugs(CVE-2024-3446) - hw/char/virtio-serial-bus: Protect from DMA re-entrancy bugs(CVE-2024-3446) - hw/display/virtio-gpu: Protect from DMA re-entrancy bugs(CVE-2024-3446) - hw/virtio: Introduce virtio_bh_new_guarded() helper - hw: replace most qemu_bh_new calls with qemu_bh_new_guarded - checkpatch: add qemu_bh_new/aio_bh_new checks - async: avoid use-after-free on re-entrancy guard - async: Add an optional reentrancy guard to the BH API - hw/sd/sdhci: Do not update TRNMOD when Command Inhibit (DAT) is set(CVE-2024-3447) - rtl8139: Remove unused variable - tulip: Remove unused variable - virtio-mem: Fix the bitmap index of the section offset - virtio-mem: Fix the iterator variable in a vmem->rdl_list loop - system/memory: use ldn_he_p/stn_he_p - block: Fix crash when loading snapshot on inactive node - smmu: Clear SMMUPciBus pointer cache when system reset - block/mirror: Fix NULL s->job in active writes - amd_iommu: Fix APIC address check - virtio-crypto: fix NULL pointer dereference in virtio_crypto_free_reques - libqos/virtio.c: Correct 'flags' reading in qvirtqueue_kick cherry-pick from 66e411885a23c96ff73742d06b793fec3ceaebb7 - ivshmem-test.c: enable test_ivshmem_server for ppc64 arch - ivshmem.c: change endianness to LITTLE_ENDIAN - hw/ppc/mac.h: Remove MAX_CPUS macro - configure: remove dead variables - virtio-gpu: do not byteswap padding - hw/intc: clean-up error reporting for failed ITS cmd - qemu-iotests: Discard stderr when probing devices - linux-user: un-parent OBJECT(cpu) when closing thread - hw/net/rocker: Avoid undefined shifts with more than 31 ports - contrib/vhost-user-blk: Clean up deallocation of VuVirtqElement - scsi-disk: fix overflow when block size is not a multiple of BDRV_SECTOR_SIZE Signed-off-by: Jiabo Feng --- amd_iommu-Fix-APIC-address-check.patch | 57 +++ ...ional-reentrancy-guard-to-the-BH-API.patch | 214 +++++++++ ...-use-after-free-on-re-entrancy-guard.patch | 52 +++ ...when-loading-snapshot-on-inactive-no.patch | 49 ++ ...rror-Fix-NULL-s-job-in-active-writes.patch | 66 +++ ...ch-add-qemu_bh_new-aio_bh_new-checks.patch | 37 ++ configure-remove-dead-variables.patch | 46 ++ ...er-blk-Clean-up-deallocation-of-VuVi.patch | 68 +++ ...erial-bus-Protect-from-DMA-re-entran.patch | 42 ++ ...o-gpu-Protect-from-DMA-re-entrancy-b.patch | 143 ++++++ ...p-error-reporting-for-failed-ITS-cmd.patch | 94 ++++ ...oid-undefined-shifts-with-more-than-.patch | 55 +++ hw-ppc-mac.h-Remove-MAX_CPUS-macro.patch | 79 ++++ ...qemu_bh_new-calls-with-qemu_bh_new_g.patch | 427 ++++++++++++++++++ ...ot-update-TRNMOD-when-Command-Inhibi.patch | 135 ++++++ ...troduce-virtio_bh_new_guarded-helper.patch | 67 +++ ...-crypto-Protect-from-DMA-re-entrancy.patch | 43 ++ ...nable-test_ivshmem_server-for-ppc64-.patch | 69 +++ ...c-change-endianness-to-LITTLE_ENDIAN.patch | 56 +++ ...Correct-flags-reading-in-qvirtqueue_.patch | 40 ++ ...arent-OBJECT-cpu-when-closing-thread.patch | 66 +++ ...-Discard-stderr-when-probing-devices.patch | 68 +++ qemu.spec | 66 ++- rtl8139-Remove-unused-variable.patch | 44 ++ ...erflow-when-block-size-is-not-a-mult.patch | 59 +++ ...ciBus-pointer-cache-when-system-rese.patch | 41 ++ system-memory-use-ldn_he_p-stn_he_p.patch | 78 ++++ tulip-Remove-unused-variable.patch | 48 ++ ...x-NULL-pointer-dereference-in-virtio.patch | 56 +++ virtio-gpu-do-not-byteswap-padding.patch | 41 ++ ...he-bitmap-index-of-the-section-offse.patch | 47 ++ ...he-iterator-variable-in-a-vmem-rdl_l.patch | 39 ++ 32 files changed, 2491 insertions(+), 1 deletion(-) create mode 100644 amd_iommu-Fix-APIC-address-check.patch create mode 100644 async-Add-an-optional-reentrancy-guard-to-the-BH-API.patch create mode 100644 async-avoid-use-after-free-on-re-entrancy-guard.patch create mode 100644 block-Fix-crash-when-loading-snapshot-on-inactive-no.patch create mode 100644 block-mirror-Fix-NULL-s-job-in-active-writes.patch create mode 100644 checkpatch-add-qemu_bh_new-aio_bh_new-checks.patch create mode 100644 configure-remove-dead-variables.patch create mode 100644 contrib-vhost-user-blk-Clean-up-deallocation-of-VuVi.patch create mode 100644 hw-char-virtio-serial-bus-Protect-from-DMA-re-entran.patch create mode 100644 hw-display-virtio-gpu-Protect-from-DMA-re-entrancy-b.patch create mode 100644 hw-intc-clean-up-error-reporting-for-failed-ITS-cmd.patch create mode 100644 hw-net-rocker-Avoid-undefined-shifts-with-more-than-.patch create mode 100644 hw-ppc-mac.h-Remove-MAX_CPUS-macro.patch create mode 100644 hw-replace-most-qemu_bh_new-calls-with-qemu_bh_new_g.patch create mode 100644 hw-sd-sdhci-Do-not-update-TRNMOD-when-Command-Inhibi.patch create mode 100644 hw-virtio-Introduce-virtio_bh_new_guarded-helper.patch create mode 100644 hw-virtio-virtio-crypto-Protect-from-DMA-re-entrancy.patch create mode 100644 ivshmem-test.c-enable-test_ivshmem_server-for-ppc64-.patch create mode 100644 ivshmem.c-change-endianness-to-LITTLE_ENDIAN.patch create mode 100644 libqos-virtio.c-Correct-flags-reading-in-qvirtqueue_.patch create mode 100644 linux-user-un-parent-OBJECT-cpu-when-closing-thread.patch create mode 100644 qemu-iotests-Discard-stderr-when-probing-devices.patch create mode 100644 rtl8139-Remove-unused-variable.patch create mode 100644 scsi-disk-fix-overflow-when-block-size-is-not-a-mult.patch create mode 100644 smmu-Clear-SMMUPciBus-pointer-cache-when-system-rese.patch create mode 100644 system-memory-use-ldn_he_p-stn_he_p.patch create mode 100644 tulip-Remove-unused-variable.patch create mode 100644 virtio-crypto-fix-NULL-pointer-dereference-in-virtio.patch create mode 100644 virtio-gpu-do-not-byteswap-padding.patch create mode 100644 virtio-mem-Fix-the-bitmap-index-of-the-section-offse.patch create mode 100644 virtio-mem-Fix-the-iterator-variable-in-a-vmem-rdl_l.patch diff --git a/amd_iommu-Fix-APIC-address-check.patch b/amd_iommu-Fix-APIC-address-check.patch new file mode 100644 index 00000000..3c3012e5 --- /dev/null +++ b/amd_iommu-Fix-APIC-address-check.patch @@ -0,0 +1,57 @@ +From ea8049e63b663cab607d1f900ce593547485b33b Mon Sep 17 00:00:00 2001 +From: zhujun2 +Date: Wed, 10 Apr 2024 20:02:38 -0700 +Subject: [PATCH] amd_iommu: Fix APIC address check + +An MSI from I/O APIC may not exactly equal to APIC_DEFAULT_ADDRESS. In +fact, Windows 17763.3650 configures I/O APIC to set the dest_mode bit. +Cover the range assigned to APIC. + +Fixes: 577c470f43 ("x86_iommu/amd: Prepare for interrupt remap support") +Signed-off-by: Akihiko Odaki +Message-Id: <20230921114612.40671-1-akihiko.odaki@daynix.com> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 0114c4513095598cdf1cd8d7dacdfff757628121) +Signed-off-by: zhujun2 +--- + hw/i386/amd_iommu.c | 9 ++------- + hw/i386/amd_iommu.h | 2 -- + 2 files changed, 2 insertions(+), 9 deletions(-) + +diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c +index 4d13d8e697..dfb9a2d8e6 100644 +--- a/hw/i386/amd_iommu.c ++++ b/hw/i386/amd_iommu.c +@@ -1245,13 +1245,8 @@ static int amdvi_int_remap_msi(AMDVIState *iommu, + return -AMDVI_IR_ERR; + } + +- if (origin->address & AMDVI_MSI_ADDR_HI_MASK) { +- trace_amdvi_err("MSI address high 32 bits non-zero when " +- "Interrupt Remapping enabled."); +- return -AMDVI_IR_ERR; +- } +- +- if ((origin->address & AMDVI_MSI_ADDR_LO_MASK) != APIC_DEFAULT_ADDRESS) { ++ if (origin->address < AMDVI_INT_ADDR_FIRST || ++ origin->address + sizeof(origin->data) > AMDVI_INT_ADDR_LAST + 1) { + trace_amdvi_err("MSI is not from IOAPIC."); + return -AMDVI_IR_ERR; + } +diff --git a/hw/i386/amd_iommu.h b/hw/i386/amd_iommu.h +index 79d38a3e41..210a37dfb1 100644 +--- a/hw/i386/amd_iommu.h ++++ b/hw/i386/amd_iommu.h +@@ -210,8 +210,6 @@ + #define AMDVI_INT_ADDR_FIRST 0xfee00000 + #define AMDVI_INT_ADDR_LAST 0xfeefffff + #define AMDVI_INT_ADDR_SIZE (AMDVI_INT_ADDR_LAST - AMDVI_INT_ADDR_FIRST + 1) +-#define AMDVI_MSI_ADDR_HI_MASK (0xffffffff00000000ULL) +-#define AMDVI_MSI_ADDR_LO_MASK (0x00000000ffffffffULL) + + /* SB IOAPIC is always on this device in AMD systems */ + #define AMDVI_IOAPIC_SB_DEVID PCI_BUILD_BDF(0, PCI_DEVFN(0x14, 0)) +-- +2.27.0 + diff --git a/async-Add-an-optional-reentrancy-guard-to-the-BH-API.patch b/async-Add-an-optional-reentrancy-guard-to-the-BH-API.patch new file mode 100644 index 00000000..dad79037 --- /dev/null +++ b/async-Add-an-optional-reentrancy-guard-to-the-BH-API.patch @@ -0,0 +1,214 @@ +From 2a9e9bb0201c513a085d51cb1d7b2cc83cad1d3b Mon Sep 17 00:00:00 2001 +From: Alexander Bulekov +Date: Thu, 27 Apr 2023 17:10:07 -0400 +Subject: [PATCH] async: Add an optional reentrancy guard to the BH API + +Devices can pass their MemoryReentrancyGuard (from their DeviceState), +when creating new BHes. Then, the async API will toggle the guard +before/after calling the BH call-back. This prevents bh->mmio reentrancy +issues. + +Signed-off-by: Alexander Bulekov +Reviewed-by: Darren Kenny +Message-Id: <20230427211013.2994127-3-alxndr@bu.edu> +[thuth: Fix "line over 90 characters" checkpatch.pl error] +Signed-off-by: Thomas Huth +Signed-off-by: liuxiangdong +--- + docs/devel/multiple-iothreads.txt | 7 +++++++ + include/block/aio.h | 18 ++++++++++++++++-- + include/qemu/main-loop.h | 7 +++++-- + tests/unit/ptimer-test-stubs.c | 3 ++- + util/async.c | 18 +++++++++++++++++- + util/main-loop.c | 6 ++++-- + util/trace-events | 1 + + 7 files changed, 52 insertions(+), 8 deletions(-) + +diff --git a/docs/devel/multiple-iothreads.txt b/docs/devel/multiple-iothreads.txt +index aeb997bed5..a11576bc74 100644 +--- a/docs/devel/multiple-iothreads.txt ++++ b/docs/devel/multiple-iothreads.txt +@@ -61,6 +61,7 @@ There are several old APIs that use the main loop AioContext: + * LEGACY qemu_aio_set_event_notifier() - monitor an event notifier + * LEGACY timer_new_ms() - create a timer + * LEGACY qemu_bh_new() - create a BH ++ * LEGACY qemu_bh_new_guarded() - create a BH with a device re-entrancy guard + * LEGACY qemu_aio_wait() - run an event loop iteration + + Since they implicitly work on the main loop they cannot be used in code that +@@ -72,8 +73,14 @@ Instead, use the AioContext functions directly (see include/block/aio.h): + * aio_set_event_notifier() - monitor an event notifier + * aio_timer_new() - create a timer + * aio_bh_new() - create a BH ++ * aio_bh_new_guarded() - create a BH with a device re-entrancy guard + * aio_poll() - run an event loop iteration + ++The qemu_bh_new_guarded/aio_bh_new_guarded APIs accept a "MemReentrancyGuard" ++argument, which is used to check for and prevent re-entrancy problems. For ++BHs associated with devices, the reentrancy-guard is contained in the ++corresponding DeviceState and named "mem_reentrancy_guard". ++ + The AioContext can be obtained from the IOThread using + iothread_get_aio_context() or for the main loop using qemu_get_aio_context(). + Code that takes an AioContext argument works both in IOThreads or the main +diff --git a/include/block/aio.h b/include/block/aio.h +index 47fbe9d81f..c7da152985 100644 +--- a/include/block/aio.h ++++ b/include/block/aio.h +@@ -22,6 +22,8 @@ + #include "qemu/event_notifier.h" + #include "qemu/thread.h" + #include "qemu/timer.h" ++#include "hw/qdev-core.h" ++ + + typedef struct BlockAIOCB BlockAIOCB; + typedef void BlockCompletionFunc(void *opaque, int ret); +@@ -321,9 +323,11 @@ void aio_bh_schedule_oneshot_full(AioContext *ctx, QEMUBHFunc *cb, void *opaque, + * is opaque and must be allocated prior to its use. + * + * @name: A human-readable identifier for debugging purposes. ++ * @reentrancy_guard: A guard set when entering a cb to prevent ++ * device-reentrancy issues + */ + QEMUBH *aio_bh_new_full(AioContext *ctx, QEMUBHFunc *cb, void *opaque, +- const char *name); ++ const char *name, MemReentrancyGuard *reentrancy_guard); + + /** + * aio_bh_new: Allocate a new bottom half structure +@@ -332,7 +336,17 @@ QEMUBH *aio_bh_new_full(AioContext *ctx, QEMUBHFunc *cb, void *opaque, + * string. + */ + #define aio_bh_new(ctx, cb, opaque) \ +- aio_bh_new_full((ctx), (cb), (opaque), (stringify(cb))) ++ aio_bh_new_full((ctx), (cb), (opaque), (stringify(cb)), NULL) ++ ++/** ++ * aio_bh_new_guarded: Allocate a new bottom half structure with a ++ * reentrancy_guard ++ * ++ * A convenience wrapper for aio_bh_new_full() that uses the cb as the name ++ * string. ++ */ ++#define aio_bh_new_guarded(ctx, cb, opaque, guard) \ ++ aio_bh_new_full((ctx), (cb), (opaque), (stringify(cb)), guard) + + /** + * aio_notify: Force processing of pending events. +diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h +index 8dbc6fcb89..85dd5ada9e 100644 +--- a/include/qemu/main-loop.h ++++ b/include/qemu/main-loop.h +@@ -294,9 +294,12 @@ void qemu_cond_timedwait_iothread(QemuCond *cond, int ms); + + void qemu_fd_register(int fd); + ++#define qemu_bh_new_guarded(cb, opaque, guard) \ ++ qemu_bh_new_full((cb), (opaque), (stringify(cb)), guard) + #define qemu_bh_new(cb, opaque) \ +- qemu_bh_new_full((cb), (opaque), (stringify(cb))) +-QEMUBH *qemu_bh_new_full(QEMUBHFunc *cb, void *opaque, const char *name); ++ qemu_bh_new_full((cb), (opaque), (stringify(cb)), NULL) ++QEMUBH *qemu_bh_new_full(QEMUBHFunc *cb, void *opaque, const char *name, ++ MemReentrancyGuard *reentrancy_guard); + void qemu_bh_schedule_idle(QEMUBH *bh); + + enum { +diff --git a/tests/unit/ptimer-test-stubs.c b/tests/unit/ptimer-test-stubs.c +index 2a3ef58799..a7a2d08e7e 100644 +--- a/tests/unit/ptimer-test-stubs.c ++++ b/tests/unit/ptimer-test-stubs.c +@@ -108,7 +108,8 @@ int64_t qemu_clock_deadline_ns_all(QEMUClockType type, int attr_mask) + return deadline; + } + +-QEMUBH *qemu_bh_new_full(QEMUBHFunc *cb, void *opaque, const char *name) ++QEMUBH *qemu_bh_new_full(QEMUBHFunc *cb, void *opaque, const char *name, ++ MemReentrancyGuard *reentrancy_guard) + { + QEMUBH *bh = g_new(QEMUBH, 1); + +diff --git a/util/async.c b/util/async.c +index 6f6717a34b..3eb6b50163 100644 +--- a/util/async.c ++++ b/util/async.c +@@ -62,6 +62,7 @@ struct QEMUBH { + void *opaque; + QSLIST_ENTRY(QEMUBH) next; + unsigned flags; ++ MemReentrancyGuard *reentrancy_guard; + }; + + /* Called concurrently from any thread */ +@@ -123,7 +124,7 @@ void aio_bh_schedule_oneshot_full(AioContext *ctx, QEMUBHFunc *cb, + } + + QEMUBH *aio_bh_new_full(AioContext *ctx, QEMUBHFunc *cb, void *opaque, +- const char *name) ++ const char *name, MemReentrancyGuard *reentrancy_guard) + { + QEMUBH *bh; + bh = g_new(QEMUBH, 1); +@@ -132,13 +133,28 @@ QEMUBH *aio_bh_new_full(AioContext *ctx, QEMUBHFunc *cb, void *opaque, + .cb = cb, + .opaque = opaque, + .name = name, ++ .reentrancy_guard = reentrancy_guard, + }; + return bh; + } + + void aio_bh_call(QEMUBH *bh) + { ++ bool last_engaged_in_io = false; ++ ++ if (bh->reentrancy_guard) { ++ last_engaged_in_io = bh->reentrancy_guard->engaged_in_io; ++ if (bh->reentrancy_guard->engaged_in_io) { ++ trace_reentrant_aio(bh->ctx, bh->name); ++ } ++ bh->reentrancy_guard->engaged_in_io = true; ++ } ++ + bh->cb(bh->opaque); ++ ++ if (bh->reentrancy_guard) { ++ bh->reentrancy_guard->engaged_in_io = last_engaged_in_io; ++ } + } + + /* Multiple occurrences of aio_bh_poll cannot be called concurrently. */ +diff --git a/util/main-loop.c b/util/main-loop.c +index 06b18b195c..1eacf04691 100644 +--- a/util/main-loop.c ++++ b/util/main-loop.c +@@ -544,9 +544,11 @@ void main_loop_wait(int nonblocking) + + /* Functions to operate on the main QEMU AioContext. */ + +-QEMUBH *qemu_bh_new_full(QEMUBHFunc *cb, void *opaque, const char *name) ++QEMUBH *qemu_bh_new_full(QEMUBHFunc *cb, void *opaque, const char *name, ++ MemReentrancyGuard *reentrancy_guard) + { +- return aio_bh_new_full(qemu_aio_context, cb, opaque, name); ++ return aio_bh_new_full(qemu_aio_context, cb, opaque, name, ++ reentrancy_guard); + } + + /* +diff --git a/util/trace-events b/util/trace-events +index c8f53d7d9f..dc3b1eb3bf 100644 +--- a/util/trace-events ++++ b/util/trace-events +@@ -11,6 +11,7 @@ poll_remove(void *ctx, void *node, int fd) "ctx %p node %p fd %d" + # async.c + aio_co_schedule(void *ctx, void *co) "ctx %p co %p" + aio_co_schedule_bh_cb(void *ctx, void *co) "ctx %p co %p" ++reentrant_aio(void *ctx, const char *name) "ctx %p name %s" + + # thread-pool.c + thread_pool_submit(void *pool, void *req, void *opaque) "pool %p req %p opaque %p" +-- +2.27.0 + diff --git a/async-avoid-use-after-free-on-re-entrancy-guard.patch b/async-avoid-use-after-free-on-re-entrancy-guard.patch new file mode 100644 index 00000000..49598bae --- /dev/null +++ b/async-avoid-use-after-free-on-re-entrancy-guard.patch @@ -0,0 +1,52 @@ +From b2b00599451de0c9fe4dcdf7c47fb1d585ab7d23 Mon Sep 17 00:00:00 2001 +From: Alexander Bulekov +Date: Mon, 1 May 2023 10:19:56 -0400 +Subject: [PATCH] async: avoid use-after-free on re-entrancy guard + +A BH callback can free the BH, causing a use-after-free in aio_bh_call. +Fix that by keeping a local copy of the re-entrancy guard pointer. + +Buglink: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=58513 +Fixes: 9c86c97f12 ("async: Add an optional reentrancy guard to the BH API") +Signed-off-by: Alexander Bulekov +Message-Id: <20230501141956.3444868-1-alxndr@bu.edu> +Reviewed-by: Thomas Huth +Signed-off-by: Thomas Huth +--- + util/async.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +diff --git a/util/async.c b/util/async.c +index 3eb6b50163..760ad73404 100644 +--- a/util/async.c ++++ b/util/async.c +@@ -142,18 +142,20 @@ void aio_bh_call(QEMUBH *bh) + { + bool last_engaged_in_io = false; + +- if (bh->reentrancy_guard) { +- last_engaged_in_io = bh->reentrancy_guard->engaged_in_io; +- if (bh->reentrancy_guard->engaged_in_io) { ++ /* Make a copy of the guard-pointer as cb may free the bh */ ++ MemReentrancyGuard *reentrancy_guard = bh->reentrancy_guard; ++ if (reentrancy_guard) { ++ last_engaged_in_io = reentrancy_guard->engaged_in_io; ++ if (reentrancy_guard->engaged_in_io) { + trace_reentrant_aio(bh->ctx, bh->name); + } +- bh->reentrancy_guard->engaged_in_io = true; ++ reentrancy_guard->engaged_in_io = true; + } + + bh->cb(bh->opaque); + +- if (bh->reentrancy_guard) { +- bh->reentrancy_guard->engaged_in_io = last_engaged_in_io; ++ if (reentrancy_guard) { ++ reentrancy_guard->engaged_in_io = last_engaged_in_io; + } + } + +-- +2.27.0 + diff --git a/block-Fix-crash-when-loading-snapshot-on-inactive-no.patch b/block-Fix-crash-when-loading-snapshot-on-inactive-no.patch new file mode 100644 index 00000000..518beecc --- /dev/null +++ b/block-Fix-crash-when-loading-snapshot-on-inactive-no.patch @@ -0,0 +1,49 @@ +From aad76e8af00e2d507de9a2e562bdbc43a3bc2bc8 Mon Sep 17 00:00:00 2001 +From: zhujun2 +Date: Mon, 8 Apr 2024 00:42:25 -0700 +Subject: [PATCH] block: Fix crash when loading snapshot on inactive node + +bdrv_is_read_only() only checks if the node is configured to be +read-only eventually, but even if it returns false, writing to the node +may not be permitted at the moment (because it's inactive). + +bdrv_is_writable() checks that the node can be written to right now, and +this is what the snapshot operations really need. + +Change bdrv_can_snapshot() to use bdrv_is_writable() to fix crashes like +the following: + +$ ./qemu-system-x86_64 -hda /tmp/test.qcow2 -loadvm foo -incoming defer +qemu-system-x86_64: ../block/io.c:1990: int bdrv_co_write_req_prepare(BdrvChild *, int64_t, int64_t, BdrvTrackedRequest *, int): Assertion `!(bs->open_flags & BDRV_O_INACTIVE)' failed. + +The resulting error message after this patch isn't perfect yet, but at +least it doesn't crash any more: + +$ ./qemu-system-x86_64 -hda /tmp/test.qcow2 -loadvm foo -incoming defer +qemu-system-x86_64: Device 'ide0-hd0' is writable but does not support snapshots + +Signed-off-by: Kevin Wolf +Message-ID: <20231201142520.32255-2-kwolf@redhat.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit d3007d348adaaf04ee8b099a475282034a662414) +Signed-off-by: zhujun2 +--- + block/snapshot.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/block/snapshot.c b/block/snapshot.c +index ccacda8bd5..f5703aa28b 100644 +--- a/block/snapshot.c ++++ b/block/snapshot.c +@@ -200,7 +200,7 @@ static BlockDriverState *bdrv_snapshot_fallback(BlockDriverState *bs) + int bdrv_can_snapshot(BlockDriverState *bs) + { + BlockDriver *drv = bs->drv; +- if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) { ++ if (!drv || !bdrv_is_inserted(bs) || !bdrv_is_writable(bs)) { + return 0; + } + +-- +2.27.0 + diff --git a/block-mirror-Fix-NULL-s-job-in-active-writes.patch b/block-mirror-Fix-NULL-s-job-in-active-writes.patch new file mode 100644 index 00000000..f5762251 --- /dev/null +++ b/block-mirror-Fix-NULL-s-job-in-active-writes.patch @@ -0,0 +1,66 @@ +From ed1ffd883ab3bfbcd3a11d63a7aba6a3a3f53372 Mon Sep 17 00:00:00 2001 +From: zhujun2 +Date: Thu, 11 Apr 2024 01:04:58 -0700 +Subject: [PATCH] block/mirror: Fix NULL s->job in active writes + +There is a small gap in mirror_start_job() before putting the mirror +filter node into the block graph (bdrv_append() call) and the actual job +being created. Before the job is created, MirrorBDSOpaque.job is NULL. + +It is possible that requests come in when bdrv_drained_end() is called, +and those requests would see MirrorBDSOpaque.job == NULL. Have our +filter node handle that case gracefully. + +Signed-off-by: Hanna Reitz +Message-Id: <20221109165452.67927-4-hreitz@redhat.com> +Reviewed-by: Kevin Wolf +Signed-off-by: Kevin Wolf +(cherry picked from commit da93d5c84e56e6b4e84aa8e98b6b984c9b6bb528) +Signed-off-by: zhujun2 +--- + block/mirror.c | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +diff --git a/block/mirror.c b/block/mirror.c +index d1863565c4..de020bdb3e 100644 +--- a/block/mirror.c ++++ b/block/mirror.c +@@ -1420,11 +1420,13 @@ static int coroutine_fn bdrv_mirror_top_do_write(BlockDriverState *bs, + MirrorOp *op = NULL; + MirrorBDSOpaque *s = bs->opaque; + int ret = 0; +- bool copy_to_target; ++ bool copy_to_target = false; + +- copy_to_target = s->job->ret >= 0 && +- !job_is_cancelled(&s->job->common.job) && +- s->job->copy_mode == MIRROR_COPY_MODE_WRITE_BLOCKING; ++ if (s->job) { ++ copy_to_target = s->job->ret >= 0 && ++ !job_is_cancelled(&s->job->common.job) && ++ s->job->copy_mode == MIRROR_COPY_MODE_WRITE_BLOCKING; ++ } + + if (copy_to_target) { + op = active_write_prepare(s->job, offset, bytes); +@@ -1469,11 +1471,13 @@ static int coroutine_fn bdrv_mirror_top_pwritev(BlockDriverState *bs, + QEMUIOVector bounce_qiov; + void *bounce_buf; + int ret = 0; +- bool copy_to_target; ++ bool copy_to_target = false; + +- copy_to_target = s->job->ret >= 0 && +- !job_is_cancelled(&s->job->common.job) && +- s->job->copy_mode == MIRROR_COPY_MODE_WRITE_BLOCKING; ++ if (s->job) { ++ copy_to_target = s->job->ret >= 0 && ++ !job_is_cancelled(&s->job->common.job) && ++ s->job->copy_mode == MIRROR_COPY_MODE_WRITE_BLOCKING; ++ } + + if (copy_to_target) { + /* The guest might concurrently modify the data to write; but +-- +2.27.0 + diff --git a/checkpatch-add-qemu_bh_new-aio_bh_new-checks.patch b/checkpatch-add-qemu_bh_new-aio_bh_new-checks.patch new file mode 100644 index 00000000..23550518 --- /dev/null +++ b/checkpatch-add-qemu_bh_new-aio_bh_new-checks.patch @@ -0,0 +1,37 @@ +From f537178e29501b93349362bc46a0463550ff2206 Mon Sep 17 00:00:00 2001 +From: Alexander Bulekov +Date: Thu, 27 Apr 2023 17:10:08 -0400 +Subject: [PATCH] checkpatch: add qemu_bh_new/aio_bh_new checks + +Advise authors to use the _guarded versions of the APIs, instead. + +Signed-off-by: Alexander Bulekov +Reviewed-by: Darren Kenny +Message-Id: <20230427211013.2994127-4-alxndr@bu.edu> +Signed-off-by: Thomas Huth +--- + scripts/checkpatch.pl | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl +index cb8eff233e..b2428e80cc 100755 +--- a/scripts/checkpatch.pl ++++ b/scripts/checkpatch.pl +@@ -2858,6 +2858,14 @@ sub process { + if ($line =~ /\bsignal\s*\(/ && !($line =~ /SIG_(?:IGN|DFL)/)) { + ERROR("use sigaction to establish signal handlers; signal is not portable\n" . $herecurr); + } ++# recommend qemu_bh_new_guarded instead of qemu_bh_new ++ if ($realfile =~ /.*\/hw\/.*/ && $line =~ /\bqemu_bh_new\s*\(/) { ++ ERROR("use qemu_bh_new_guarded() instead of qemu_bh_new() to avoid reentrancy problems\n" . $herecurr); ++ } ++# recommend aio_bh_new_guarded instead of aio_bh_new ++ if ($realfile =~ /.*\/hw\/.*/ && $line =~ /\baio_bh_new\s*\(/) { ++ ERROR("use aio_bh_new_guarded() instead of aio_bh_new() to avoid reentrancy problems\n" . $herecurr); ++ } + # check for module_init(), use category-specific init macros explicitly please + if ($line =~ /^module_init\s*\(/) { + ERROR("please use block_init(), type_init() etc. instead of module_init()\n" . $herecurr); +-- +2.27.0 + diff --git a/configure-remove-dead-variables.patch b/configure-remove-dead-variables.patch new file mode 100644 index 00000000..e941f441 --- /dev/null +++ b/configure-remove-dead-variables.patch @@ -0,0 +1,46 @@ +From 259d232f7273fca7e703fc03a449516e1ab3aa7f Mon Sep 17 00:00:00 2001 +From: Luo Yifan +Date: Thu, 28 Mar 2024 11:00:36 +0800 +Subject: [PATCH] configure: remove dead variables + +cherry picked from commit cbe08c35cfa8f96125512a8aa3e1bf251b1410a5 + +Signed-off-by: Paolo Bonzini +Signed-off-by: Luo Yifan +--- + configure | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/configure b/configure +index 8c9abd0e6e..991fe67886 100755 +--- a/configure ++++ b/configure +@@ -630,7 +630,6 @@ fi + case $targetos in + MINGW32*) + mingw32="yes" +- supported_os="yes" + plugins="no" + pie="no" + ;; +@@ -672,7 +671,6 @@ SunOS) + QEMU_CFLAGS="-D__EXTENSIONS__ $QEMU_CFLAGS" + ;; + Haiku) +- haiku="yes" + pie="no" + QEMU_CFLAGS="-DB_USE_POSITIVE_POSIX_ERRORS -D_BSD_SOURCE -fPIC $QEMU_CFLAGS" + ;; +@@ -3388,9 +3386,6 @@ fi + if test "$solaris" = "yes" ; then + echo "CONFIG_SOLARIS=y" >> $config_host_mak + fi +-if test "$haiku" = "yes" ; then +- echo "CONFIG_HAIKU=y" >> $config_host_mak +-fi + if test "$static" = "yes" ; then + echo "CONFIG_STATIC=y" >> $config_host_mak + fi +-- +2.27.0 + diff --git a/contrib-vhost-user-blk-Clean-up-deallocation-of-VuVi.patch b/contrib-vhost-user-blk-Clean-up-deallocation-of-VuVi.patch new file mode 100644 index 00000000..c3766297 --- /dev/null +++ b/contrib-vhost-user-blk-Clean-up-deallocation-of-VuVi.patch @@ -0,0 +1,68 @@ +From 37e47eef108920f6afad0c575bc658520bf5f3e2 Mon Sep 17 00:00:00 2001 +From: tangbinzy +Date: Mon, 25 Mar 2024 08:43:30 +0000 +Subject: [PATCH] contrib/vhost-user-blk: Clean up deallocation of VuVirtqElement + mainline inclusion + commit a32086de4919b9affb2ab2d0112d400eaf89f607 + category: bugfix + +--------------------------------------------------------------- + +We allocate VuVirtqElement with g_malloc() in +virtqueue_alloc_element(), but free it with free() in +vhost-user-blk.c. Harmless, but use g_free() anyway. + +One of the calls is guarded by a "not null" condition. Useless, +because it cannot be null (it's dereferenced right before), and even +it it could be, free() and g_free() do the right thing. Drop the +conditional. + +Fixes: Coverity CID 1490290 +Signed-off-by: Markus Armbruster +Reviewed-by: Raphael Norwitz +Acked-by: Michael S. Tsirkin +Message-Id: <20220630085219.1305519-1-armbru@redhat.com> +Signed-off-by: Laurent Vivier + +Signed-off-by: tangbinzy +--- + contrib/vhost-user-blk/vhost-user-blk.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +diff --git a/contrib/vhost-user-blk/vhost-user-blk.c b/contrib/vhost-user-blk/vhost-user-blk.c +index d14b2896bf..91c4462659 100644 +--- a/contrib/vhost-user-blk/vhost-user-blk.c ++++ b/contrib/vhost-user-blk/vhost-user-blk.c +@@ -106,10 +106,7 @@ static void vub_req_complete(VubReq *req) + req->size + 1); + vu_queue_notify(vu_dev, req->vq); + +- if (req->elem) { +- free(req->elem); +- } +- ++ g_free(req->elem); + g_free(req); + } + +@@ -243,7 +240,7 @@ static int vub_virtio_process_req(VubDev *vdev_blk, + /* refer to hw/block/virtio_blk.c */ + if (elem->out_num < 1 || elem->in_num < 1) { + fprintf(stderr, "virtio-blk request missing headers\n"); +- free(elem); ++ g_free(elem); + return -1; + } + +@@ -325,7 +322,7 @@ static int vub_virtio_process_req(VubDev *vdev_blk, + return 0; + + err: +- free(elem); ++ g_free(elem); + g_free(req); + return -1; + } +-- +2.27.0 + diff --git a/hw-char-virtio-serial-bus-Protect-from-DMA-re-entran.patch b/hw-char-virtio-serial-bus-Protect-from-DMA-re-entran.patch new file mode 100644 index 00000000..151825ee --- /dev/null +++ b/hw-char-virtio-serial-bus-Protect-from-DMA-re-entran.patch @@ -0,0 +1,42 @@ +From 4d1cd3fcaa2939da851e39e419c433adcd672145 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= +Date: Thu, 4 Apr 2024 20:56:35 +0200 +Subject: [PATCH] hw/char/virtio-serial-bus: Protect from DMA re-entrancy + bugs(CVE-2024-3446) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Replace qemu_bh_new_guarded() by virtio_bh_new_guarded() +so the bus and device use the same guard. Otherwise the +DMA-reentrancy protection can be bypassed. + +Fixes: CVE-2024-3446 +Cc: qemu-stable@nongnu.org +Suggested-by: Alexander Bulekov +Reviewed-by: Gerd Hoffmann +Acked-by: Michael S. Tsirkin +Signed-off-by: Philippe Mathieu-Daudé +Reviewed-by: Michael S. Tsirkin +Message-Id: <20240409105537.18308-4-philmd@linaro.org> +--- + hw/char/virtio-serial-bus.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c +index 14716b66cc..e7f3e1eb87 100644 +--- a/hw/char/virtio-serial-bus.c ++++ b/hw/char/virtio-serial-bus.c +@@ -990,8 +990,7 @@ static void virtser_port_device_realize(DeviceState *dev, Error **errp) + return; + } + +- port->bh = qemu_bh_new_guarded(flush_queued_data_bh, port, +- &dev->mem_reentrancy_guard); ++ port->bh = virtio_bh_new_guarded(dev, flush_queued_data_bh, port); + port->elem = NULL; + } + +-- +2.27.0 + diff --git a/hw-display-virtio-gpu-Protect-from-DMA-re-entrancy-b.patch b/hw-display-virtio-gpu-Protect-from-DMA-re-entrancy-b.patch new file mode 100644 index 00000000..219ea010 --- /dev/null +++ b/hw-display-virtio-gpu-Protect-from-DMA-re-entrancy-b.patch @@ -0,0 +1,143 @@ +From c2f82029db6fe278c45e421ba6fece412f084516 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= +Date: Thu, 4 Apr 2024 20:56:27 +0200 +Subject: [PATCH] hw/display/virtio-gpu: Protect from DMA re-entrancy + bugs(CVE-2024-3446) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Replace qemu_bh_new_guarded() by virtio_bh_new_guarded() +so the bus and device use the same guard. Otherwise the +DMA-reentrancy protection can be bypassed: + + $ cat << EOF | qemu-system-i386 -display none -nodefaults \ + -machine q35,accel=qtest \ + -m 512M \ + -device virtio-gpu \ + -qtest stdio + outl 0xcf8 0x80000820 + outl 0xcfc 0xe0004000 + outl 0xcf8 0x80000804 + outw 0xcfc 0x06 + write 0xe0004030 0x4 0x024000e0 + write 0xe0004028 0x1 0xff + write 0xe0004020 0x4 0x00009300 + write 0xe000401c 0x1 0x01 + write 0x101 0x1 0x04 + write 0x103 0x1 0x1c + write 0x9301c8 0x1 0x18 + write 0x105 0x1 0x1c + write 0x107 0x1 0x1c + write 0x109 0x1 0x1c + write 0x10b 0x1 0x00 + write 0x10d 0x1 0x00 + write 0x10f 0x1 0x00 + write 0x111 0x1 0x00 + write 0x113 0x1 0x00 + write 0x115 0x1 0x00 + write 0x117 0x1 0x00 + write 0x119 0x1 0x00 + write 0x11b 0x1 0x00 + write 0x11d 0x1 0x00 + write 0x11f 0x1 0x00 + write 0x121 0x1 0x00 + write 0x123 0x1 0x00 + write 0x125 0x1 0x00 + write 0x127 0x1 0x00 + write 0x129 0x1 0x00 + write 0x12b 0x1 0x00 + write 0x12d 0x1 0x00 + write 0x12f 0x1 0x00 + write 0x131 0x1 0x00 + write 0x133 0x1 0x00 + write 0x135 0x1 0x00 + write 0x137 0x1 0x00 + write 0x139 0x1 0x00 + write 0xe0007003 0x1 0x00 + EOF + ... + ================================================================= + ==276099==ERROR: AddressSanitizer: heap-use-after-free on address 0x60d000011178 + at pc 0x562cc3b736c7 bp 0x7ffed49dee60 sp 0x7ffed49dee58 + READ of size 8 at 0x60d000011178 thread T0 + #0 0x562cc3b736c6 in virtio_gpu_ctrl_response hw/display/virtio-gpu.c:180:42 + #1 0x562cc3b7c40b in virtio_gpu_ctrl_response_nodata hw/display/virtio-gpu.c:192:5 + #2 0x562cc3b7c40b in virtio_gpu_simple_process_cmd hw/display/virtio-gpu.c:1015:13 + #3 0x562cc3b82873 in virtio_gpu_process_cmdq hw/display/virtio-gpu.c:1050:9 + #4 0x562cc4a85514 in aio_bh_call util/async.c:169:5 + #5 0x562cc4a85c52 in aio_bh_poll util/async.c:216:13 + #6 0x562cc4a1a79b in aio_dispatch util/aio-posix.c:423:5 + #7 0x562cc4a8a2da in aio_ctx_dispatch util/async.c:358:5 + #8 0x7f36840547a8 in g_main_context_dispatch (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x547a8) + #9 0x562cc4a8b753 in glib_pollfds_poll util/main-loop.c:290:9 + #10 0x562cc4a8b753 in os_host_main_loop_wait util/main-loop.c:313:5 + #11 0x562cc4a8b753 in main_loop_wait util/main-loop.c:592:11 + #12 0x562cc3938186 in qemu_main_loop system/runstate.c:782:9 + #13 0x562cc43b7af5 in qemu_default_main system/main.c:37:14 + #14 0x7f3683a6c189 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16 + #15 0x7f3683a6c244 in __libc_start_main csu/../csu/libc-start.c:381:3 + #16 0x562cc2a58ac0 in _start (qemu-system-i386+0x231bac0) + + 0x60d000011178 is located 56 bytes inside of 136-byte region [0x60d000011140,0x60d0000111c8) + freed by thread T0 here: + #0 0x562cc2adb662 in __interceptor_free (qemu-system-i386+0x239e662) + #1 0x562cc3b86b21 in virtio_gpu_reset hw/display/virtio-gpu.c:1524:9 + #2 0x562cc416e20e in virtio_reset hw/virtio/virtio.c:2145:9 + #3 0x562cc37c5644 in virtio_pci_reset hw/virtio/virtio-pci.c:2249:5 + #4 0x562cc4233758 in memory_region_write_accessor system/memory.c:497:5 + #5 0x562cc4232eea in access_with_adjusted_size system/memory.c:573:18 + + previously allocated by thread T0 here: + #0 0x562cc2adb90e in malloc (qemu-system-i386+0x239e90e) + #1 0x7f368405a678 in g_malloc (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5a678) + #2 0x562cc4163ffc in virtqueue_split_pop hw/virtio/virtio.c:1612:12 + #3 0x562cc4163ffc in virtqueue_pop hw/virtio/virtio.c:1783:16 + #4 0x562cc3b91a95 in virtio_gpu_handle_ctrl hw/display/virtio-gpu.c:1112:15 + #5 0x562cc4a85514 in aio_bh_call util/async.c:169:5 + #6 0x562cc4a85c52 in aio_bh_poll util/async.c:216:13 + #7 0x562cc4a1a79b in aio_dispatch util/aio-posix.c:423:5 + + SUMMARY: AddressSanitizer: heap-use-after-free hw/display/virtio-gpu.c:180:42 in virtio_gpu_ctrl_response + +With this change, the same reproducer triggers: + + qemu-system-i386: warning: Blocked re-entrant IO on MemoryRegion: virtio-pci-common-virtio-gpu at addr: 0x6 + +Fixes: CVE-2024-3446 +Cc: qemu-stable@nongnu.org +Reported-by: Alexander Bulekov +Reported-by: Yongkang Jia +Reported-by: Xiao Lei +Reported-by: Yiming Tao +Buglink: https://bugs.launchpad.net/qemu/+bug/1888606 +Reviewed-by: Gerd Hoffmann +Acked-by: Michael S. Tsirkin +Signed-off-by: Philippe Mathieu-Daudé +Reviewed-by: Michael S. Tsirkin +Message-Id: <20240409105537.18308-3-philmd@linaro.org> +Signed-off-by: liuxiangdong +--- + hw/display/virtio-gpu.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c +index 897042c3dc..0e5f5045b5 100644 +--- a/hw/display/virtio-gpu.c ++++ b/hw/display/virtio-gpu.c +@@ -1335,10 +1335,8 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error **errp) + + g->ctrl_vq = virtio_get_queue(vdev, 0); + g->cursor_vq = virtio_get_queue(vdev, 1); +- g->ctrl_bh = qemu_bh_new_guarded(virtio_gpu_ctrl_bh, g, +- &qdev->mem_reentrancy_guard); +- g->cursor_bh = qemu_bh_new_guarded(virtio_gpu_cursor_bh, g, +- &qdev->mem_reentrancy_guard); ++ g->ctrl_bh = virtio_bh_new_guarded(qdev, virtio_gpu_ctrl_bh, g); ++ g->cursor_bh = virtio_bh_new_guarded(qdev, virtio_gpu_cursor_bh, g); + QTAILQ_INIT(&g->reslist); + QTAILQ_INIT(&g->cmdq); + QTAILQ_INIT(&g->fenceq); +-- +2.27.0 + diff --git a/hw-intc-clean-up-error-reporting-for-failed-ITS-cmd.patch b/hw-intc-clean-up-error-reporting-for-failed-ITS-cmd.patch new file mode 100644 index 00000000..21ecbfa6 --- /dev/null +++ b/hw-intc-clean-up-error-reporting-for-failed-ITS-cmd.patch @@ -0,0 +1,94 @@ +From 227f7f8b076ac11ff5959ddebc16569665b68e21 Mon Sep 17 00:00:00 2001 +From: Luo Yifan +Date: Thu, 28 Mar 2024 10:17:35 +0800 +Subject: [PATCH] hw/intc: clean-up error reporting for failed ITS cmd +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cherry picked from commit 229c57b1986484ea2cd1eb744e3492af7eee063e + +While trying to debug a GIC ITS failure I saw some guest errors that +had poor formatting as well as leaving me confused as to what failed. +As most of the checks aren't possible without a valid dte split that +check apart and then check the other conditions in steps. This avoids +us relying on undefined data. + +I still get a failure with the current kvm-unit-tests but at least I +know (partially) why now: + + Exception return from AArch64 EL1 to AArch64 EL1 PC 0x40080588 + PASS: gicv3: its-trigger: inv/invall: dev2/eventid=20 now triggers an LPI + ITS: MAPD devid=2 size = 0x8 itt=0x40430000 valid=0 + INT dev_id=2 event_id=20 + process_its_cmd: invalid command attributes: invalid dte: 0 for 2 (MEM_TX: 0) + PASS: gicv3: its-trigger: mapd valid=false: no LPI after device unmap + SUMMARY: 6 tests, 1 unexpected failures + +Signed-off-by: Alex Bennée +Reviewed-by: Peter Maydell +Message-id: 20211112170454.3158925-1-alex.bennee@linaro.org +Cc: Shashi Mallela +Cc: Peter Maydell +Signed-off-by: Peter Maydell +Signed-off-by: Luo Yifan +--- + hw/intc/arm_gicv3_its.c | 39 +++++++++++++++++++++++++++------------ + 1 file changed, 27 insertions(+), 12 deletions(-) + +diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c +index c929a9cb5c..b99e63d58f 100644 +--- a/hw/intc/arm_gicv3_its.c ++++ b/hw/intc/arm_gicv3_its.c +@@ -274,21 +274,36 @@ static bool process_its_cmd(GICv3ITSState *s, uint64_t value, uint32_t offset, + if (res != MEMTX_OK) { + return result; + } ++ } else { ++ qemu_log_mask(LOG_GUEST_ERROR, ++ "%s: invalid command attributes: " ++ "invalid dte: %"PRIx64" for %d (MEM_TX: %d)\n", ++ __func__, dte, devid, res); ++ return result; + } + +- if ((devid > s->dt.maxids.max_devids) || !dte_valid || !ite_valid || +- !cte_valid || (eventid > max_eventid)) { ++ ++ /* ++ * In this implementation, in case of guest errors we ignore the ++ * command and move onto the next command in the queue. ++ */ ++ if (devid > s->dt.maxids.max_devids) { + qemu_log_mask(LOG_GUEST_ERROR, +- "%s: invalid command attributes " +- "devid %d or eventid %d or invalid dte %d or" +- "invalid cte %d or invalid ite %d\n", +- __func__, devid, eventid, dte_valid, cte_valid, +- ite_valid); +- /* +- * in this implementation, in case of error +- * we ignore this command and move onto the next +- * command in the queue +- */ ++ "%s: invalid command attributes: devid %d>%d", ++ __func__, devid, s->dt.maxids.max_devids); ++ ++ } else if (!dte_valid || !ite_valid || !cte_valid) { ++ qemu_log_mask(LOG_GUEST_ERROR, ++ "%s: invalid command attributes: " ++ "dte: %s, ite: %s, cte: %s\n", ++ __func__, ++ dte_valid ? "valid" : "invalid", ++ ite_valid ? "valid" : "invalid", ++ cte_valid ? "valid" : "invalid"); ++ } else if (eventid > max_eventid) { ++ qemu_log_mask(LOG_GUEST_ERROR, ++ "%s: invalid command attributes: eventid %d > %d\n", ++ __func__, eventid, max_eventid); + } else { + /* + * Current implementation only supports rdbase == procnum +-- +2.27.0 + diff --git a/hw-net-rocker-Avoid-undefined-shifts-with-more-than-.patch b/hw-net-rocker-Avoid-undefined-shifts-with-more-than-.patch new file mode 100644 index 00000000..a82e37f6 --- /dev/null +++ b/hw-net-rocker-Avoid-undefined-shifts-with-more-than-.patch @@ -0,0 +1,55 @@ +From 4b01fe41d731409b8bf2b569a38aa5959ed473c4 Mon Sep 17 00:00:00 2001 +From: tangbinzy +Date: Mon, 25 Mar 2024 08:58:38 +0000 +Subject: [PATCH] hw/net/rocker: Avoid undefined shifts with more than 31 ports + mainline inclusion + commit 7cf745dd9c25f0740dc1009598b58dd8dd989876 + category: bugfix + +--------------------------------------------------------------- + +In rocker_port_phys_link_status() and rocker_port_phys_enable_read() +we construct a 64-bit value with one bit per front-panel port. +However we accidentally do the shift as 32-bit arithmetic, which +means that if there are more than 31 front-panel ports this is +undefined behaviour. + +Fix the problem by ensuring we use 64-bit arithmetic for the whole +calculation. (We won't ever shift off the 64-bit value because +ROCKER_FP_PORTS_MAX is 62.) + +Resolves: Coverity CID 1487121, 1487160 +Reviewed-by: Richard Henderson +Signed-off-by: Peter Maydell +Signed-off-by: Jason Wang + +Signed-off-by: tangbinzy +--- + hw/net/rocker/rocker.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c +index 31f2340fb9..d8f3f16fe8 100644 +--- a/hw/net/rocker/rocker.c ++++ b/hw/net/rocker/rocker.c +@@ -1010,7 +1010,7 @@ static uint64_t rocker_port_phys_link_status(Rocker *r) + FpPort *port = r->fp_port[i]; + + if (fp_port_get_link_up(port)) { +- status |= 1 << (i + 1); ++ status |= 1ULL << (i + 1); + } + } + return status; +@@ -1025,7 +1025,7 @@ static uint64_t rocker_port_phys_enable_read(Rocker *r) + FpPort *port = r->fp_port[i]; + + if (fp_port_enabled(port)) { +- ret |= 1 << (i + 1); ++ ret |= 1ULL << (i + 1); + } + } + return ret; +-- +2.27.0 + diff --git a/hw-ppc-mac.h-Remove-MAX_CPUS-macro.patch b/hw-ppc-mac.h-Remove-MAX_CPUS-macro.patch new file mode 100644 index 00000000..292aa1de --- /dev/null +++ b/hw-ppc-mac.h-Remove-MAX_CPUS-macro.patch @@ -0,0 +1,79 @@ +From a2c1183a858ff592e0efb1886bbe6941b4ce018b Mon Sep 17 00:00:00 2001 +From: Luo Yifan +Date: Thu, 28 Mar 2024 13:54:29 +0800 +Subject: [PATCH] hw/ppc/mac.h: Remove MAX_CPUS macro +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cherry picked from commit 83234b8289e64fc359a5bf02d886a333d65b8f8c + +The mac.h header defines a MAX_CPUS macro. This is confusingly named, +because it suggests it's a generic setting, but in fact it's used +by only the g3beige and mac99 machines. It's also using a single +macro for two values which aren't inherently the same -- if one +of these two machines was updated to support SMP configurations +then it would want a different max_cpus value to the other. + +Since the macro is used in only two places, just expand it out +and get rid of it. If hypothetical future work to support SMP +in these boards needs a compile-time-known limit on the number +of CPUs, we can give it a suitable name at that point. + +Signed-off-by: Peter Maydell +Reviewed-by: Philippe Mathieu-Daudé +Reviewed-by: Cédric Le Goater +Message-Id: <20211105184216.120972-1-peter.maydell@linaro.org> +Signed-off-by: Cédric Le Goater +Signed-off-by: Luo Yifan +--- + hw/ppc/mac.h | 3 --- + hw/ppc/mac_newworld.c | 3 ++- + hw/ppc/mac_oldworld.c | 3 ++- + 3 files changed, 4 insertions(+), 5 deletions(-) + +diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h +index 22c8408078..a1fa8f8e41 100644 +--- a/hw/ppc/mac.h ++++ b/hw/ppc/mac.h +@@ -36,9 +36,6 @@ + #include "hw/pci-host/uninorth.h" + #include "qom/object.h" + +-/* SMP is not enabled, for now */ +-#define MAX_CPUS 1 +- + #define NVRAM_SIZE 0x2000 + #define PROM_FILENAME "openbios-ppc" + +diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c +index 7bb7ac3997..4bddb529c2 100644 +--- a/hw/ppc/mac_newworld.c ++++ b/hw/ppc/mac_newworld.c +@@ -581,7 +581,8 @@ static void core99_machine_class_init(ObjectClass *oc, void *data) + mc->desc = "Mac99 based PowerMAC"; + mc->init = ppc_core99_init; + mc->block_default_type = IF_IDE; +- mc->max_cpus = MAX_CPUS; ++ /* SMP is not supported currently */ ++ mc->max_cpus = 1; + mc->default_boot_order = "cd"; + mc->default_display = "std"; + mc->kvm_type = core99_kvm_type; +diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c +index de2be960e6..7016979a7c 100644 +--- a/hw/ppc/mac_oldworld.c ++++ b/hw/ppc/mac_oldworld.c +@@ -423,7 +423,8 @@ static void heathrow_class_init(ObjectClass *oc, void *data) + mc->desc = "Heathrow based PowerMAC"; + mc->init = ppc_heathrow_init; + mc->block_default_type = IF_IDE; +- mc->max_cpus = MAX_CPUS; ++ /* SMP is not supported currently */ ++ mc->max_cpus = 1; + #ifndef TARGET_PPC64 + mc->is_default = true; + #endif +-- +2.27.0 + diff --git a/hw-replace-most-qemu_bh_new-calls-with-qemu_bh_new_g.patch b/hw-replace-most-qemu_bh_new-calls-with-qemu_bh_new_g.patch new file mode 100644 index 00000000..d5f9e115 --- /dev/null +++ b/hw-replace-most-qemu_bh_new-calls-with-qemu_bh_new_g.patch @@ -0,0 +1,427 @@ +From 458b3f30a4e5d7b6361e6040061c9e30b4d75d1d Mon Sep 17 00:00:00 2001 +From: Alexander Bulekov +Date: Thu, 27 Apr 2023 17:10:09 -0400 +Subject: [PATCH] hw: replace most qemu_bh_new calls with qemu_bh_new_guarded + +This protects devices from bh->mmio reentrancy issues. + +Thanks: Thomas Huth for diagnosing OS X test failure. +Signed-off-by: Alexander Bulekov +Reviewed-by: Darren Kenny +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Michael S. Tsirkin +Reviewed-by: Paul Durrant +Reviewed-by: Thomas Huth +Message-Id: <20230427211013.2994127-5-alxndr@bu.edu> +Signed-off-by: Thomas Huth +Signed-off-by: liuxiangdong +--- + hw/9pfs/xen-9p-backend.c | 5 ++++- + hw/block/dataplane/virtio-blk.c | 3 ++- + hw/block/dataplane/xen-block.c | 5 +++-- + hw/char/virtio-serial-bus.c | 3 ++- + hw/display/qxl.c | 9 ++++++--- + hw/display/virtio-gpu.c | 6 ++++-- + hw/ide/ahci.c | 3 ++- + hw/ide/ahci_internal.h | 1 + + hw/ide/core.c | 4 +++- + hw/misc/imx_rngc.c | 6 ++++-- + hw/misc/macio/mac_dbdma.c | 2 +- + hw/net/virtio-net.c | 3 ++- + hw/scsi/mptsas.c | 3 ++- + hw/scsi/scsi-bus.c | 3 ++- + hw/scsi/vmw_pvscsi.c | 3 ++- + hw/usb/dev-uas.c | 3 ++- + hw/usb/hcd-dwc2.c | 3 ++- + hw/usb/hcd-ehci.c | 3 ++- + hw/usb/hcd-uhci.c | 2 +- + hw/usb/host-libusb.c | 6 ++++-- + hw/usb/redirect.c | 6 ++++-- + hw/usb/xen-usb.c | 3 ++- + hw/virtio/virtio-balloon.c | 5 +++-- + hw/virtio/virtio-crypto.c | 3 ++- + 24 files changed, 62 insertions(+), 31 deletions(-) + +diff --git a/hw/9pfs/xen-9p-backend.c b/hw/9pfs/xen-9p-backend.c +index 65c4979c3c..09f7c13588 100644 +--- a/hw/9pfs/xen-9p-backend.c ++++ b/hw/9pfs/xen-9p-backend.c +@@ -60,6 +60,7 @@ typedef struct Xen9pfsDev { + + int num_rings; + Xen9pfsRing *rings; ++ MemReentrancyGuard mem_reentrancy_guard; + } Xen9pfsDev; + + static void xen_9pfs_disconnect(struct XenLegacyDevice *xendev); +@@ -441,7 +442,9 @@ static int xen_9pfs_connect(struct XenLegacyDevice *xendev) + xen_9pdev->rings[i].ring.out = xen_9pdev->rings[i].data + + XEN_FLEX_RING_SIZE(ring_order); + +- xen_9pdev->rings[i].bh = qemu_bh_new(xen_9pfs_bh, &xen_9pdev->rings[i]); ++ xen_9pdev->rings[i].bh = qemu_bh_new_guarded(xen_9pfs_bh, ++ &xen_9pdev->rings[i], ++ &xen_9pdev->mem_reentrancy_guard); + xen_9pdev->rings[i].out_cons = 0; + xen_9pdev->rings[i].out_size = 0; + xen_9pdev->rings[i].inprogress = false; +diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c +index ee5a5352dc..5f0de7da1e 100644 +--- a/hw/block/dataplane/virtio-blk.c ++++ b/hw/block/dataplane/virtio-blk.c +@@ -127,7 +127,8 @@ bool virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf, + } else { + s->ctx = qemu_get_aio_context(); + } +- s->bh = aio_bh_new(s->ctx, notify_guest_bh, s); ++ s->bh = aio_bh_new_guarded(s->ctx, notify_guest_bh, s, ++ &DEVICE(vdev)->mem_reentrancy_guard); + s->batch_notify_vqs = bitmap_new(conf->num_queues); + + *dataplane = s; +diff --git a/hw/block/dataplane/xen-block.c b/hw/block/dataplane/xen-block.c +index 860787580a..07855feea6 100644 +--- a/hw/block/dataplane/xen-block.c ++++ b/hw/block/dataplane/xen-block.c +@@ -631,8 +631,9 @@ XenBlockDataPlane *xen_block_dataplane_create(XenDevice *xendev, + } else { + dataplane->ctx = qemu_get_aio_context(); + } +- dataplane->bh = aio_bh_new(dataplane->ctx, xen_block_dataplane_bh, +- dataplane); ++ dataplane->bh = aio_bh_new_guarded(dataplane->ctx, xen_block_dataplane_bh, ++ dataplane, ++ &DEVICE(xendev)->mem_reentrancy_guard); + + return dataplane; + } +diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c +index edb7a44ee9..14716b66cc 100644 +--- a/hw/char/virtio-serial-bus.c ++++ b/hw/char/virtio-serial-bus.c +@@ -990,7 +990,8 @@ static void virtser_port_device_realize(DeviceState *dev, Error **errp) + return; + } + +- port->bh = qemu_bh_new(flush_queued_data_bh, port); ++ port->bh = qemu_bh_new_guarded(flush_queued_data_bh, port, ++ &dev->mem_reentrancy_guard); + port->elem = NULL; + } + +diff --git a/hw/display/qxl.c b/hw/display/qxl.c +index bcd9e8716a..0f663b9912 100644 +--- a/hw/display/qxl.c ++++ b/hw/display/qxl.c +@@ -2206,11 +2206,14 @@ static void qxl_realize_common(PCIQXLDevice *qxl, Error **errp) + + qemu_add_vm_change_state_handler(qxl_vm_change_state_handler, qxl); + +- qxl->update_irq = qemu_bh_new(qxl_update_irq_bh, qxl); ++ qxl->update_irq = qemu_bh_new_guarded(qxl_update_irq_bh, qxl, ++ &DEVICE(qxl)->mem_reentrancy_guard); + qxl_reset_state(qxl); + +- qxl->update_area_bh = qemu_bh_new(qxl_render_update_area_bh, qxl); +- qxl->ssd.cursor_bh = qemu_bh_new(qemu_spice_cursor_refresh_bh, &qxl->ssd); ++ qxl->update_area_bh = qemu_bh_new_guarded(qxl_render_update_area_bh, qxl, ++ &DEVICE(qxl)->mem_reentrancy_guard); ++ qxl->ssd.cursor_bh = qemu_bh_new_guarded(qemu_spice_cursor_refresh_bh, &qxl->ssd, ++ &DEVICE(qxl)->mem_reentrancy_guard); + } + + static void qxl_realize_primary(PCIDevice *dev, Error **errp) +diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c +index 9ccc0575e3..897042c3dc 100644 +--- a/hw/display/virtio-gpu.c ++++ b/hw/display/virtio-gpu.c +@@ -1335,8 +1335,10 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error **errp) + + g->ctrl_vq = virtio_get_queue(vdev, 0); + g->cursor_vq = virtio_get_queue(vdev, 1); +- g->ctrl_bh = qemu_bh_new(virtio_gpu_ctrl_bh, g); +- g->cursor_bh = qemu_bh_new(virtio_gpu_cursor_bh, g); ++ g->ctrl_bh = qemu_bh_new_guarded(virtio_gpu_ctrl_bh, g, ++ &qdev->mem_reentrancy_guard); ++ g->cursor_bh = qemu_bh_new_guarded(virtio_gpu_cursor_bh, g, ++ &qdev->mem_reentrancy_guard); + QTAILQ_INIT(&g->reslist); + QTAILQ_INIT(&g->cmdq); + QTAILQ_INIT(&g->fenceq); +diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c +index 1e482738de..36d050aafc 100644 +--- a/hw/ide/ahci.c ++++ b/hw/ide/ahci.c +@@ -1510,7 +1510,8 @@ static void ahci_cmd_done(const IDEDMA *dma) + ahci_write_fis_d2h(ad); + + if (ad->port_regs.cmd_issue && !ad->check_bh) { +- ad->check_bh = qemu_bh_new(ahci_check_cmd_bh, ad); ++ ad->check_bh = qemu_bh_new_guarded(ahci_check_cmd_bh, ad, ++ &ad->mem_reentrancy_guard); + qemu_bh_schedule(ad->check_bh); + } + } +diff --git a/hw/ide/ahci_internal.h b/hw/ide/ahci_internal.h +index 109de9e2d1..a7768dd69e 100644 +--- a/hw/ide/ahci_internal.h ++++ b/hw/ide/ahci_internal.h +@@ -321,6 +321,7 @@ struct AHCIDevice { + bool init_d2h_sent; + AHCICmdHdr *cur_cmd; + NCQTransferState ncq_tfs[AHCI_MAX_CMDS]; ++ MemReentrancyGuard mem_reentrancy_guard; + }; + + struct AHCIPCIState { +diff --git a/hw/ide/core.c b/hw/ide/core.c +index 0d925c5ca5..14283a84a5 100644 +--- a/hw/ide/core.c ++++ b/hw/ide/core.c +@@ -510,6 +510,7 @@ BlockAIOCB *ide_issue_trim( + BlockCompletionFunc *cb, void *cb_opaque, void *opaque) + { + IDEState *s = opaque; ++ IDEDevice *dev = s->unit ? s->bus->slave : s->bus->master; + TrimAIOCB *iocb; + + /* Paired with a decrement in ide_trim_bh_cb() */ +@@ -517,7 +518,8 @@ BlockAIOCB *ide_issue_trim( + + iocb = blk_aio_get(&trim_aiocb_info, s->blk, cb, cb_opaque); + iocb->s = s; +- iocb->bh = qemu_bh_new(ide_trim_bh_cb, iocb); ++ iocb->bh = qemu_bh_new_guarded(ide_trim_bh_cb, iocb, ++ &DEVICE(dev)->mem_reentrancy_guard); + iocb->ret = 0; + iocb->qiov = qiov; + iocb->i = -1; +diff --git a/hw/misc/imx_rngc.c b/hw/misc/imx_rngc.c +index 632c03779c..082c6980ad 100644 +--- a/hw/misc/imx_rngc.c ++++ b/hw/misc/imx_rngc.c +@@ -228,8 +228,10 @@ static void imx_rngc_realize(DeviceState *dev, Error **errp) + sysbus_init_mmio(sbd, &s->iomem); + + sysbus_init_irq(sbd, &s->irq); +- s->self_test_bh = qemu_bh_new(imx_rngc_self_test, s); +- s->seed_bh = qemu_bh_new(imx_rngc_seed, s); ++ s->self_test_bh = qemu_bh_new_guarded(imx_rngc_self_test, s, ++ &dev->mem_reentrancy_guard); ++ s->seed_bh = qemu_bh_new_guarded(imx_rngc_seed, s, ++ &dev->mem_reentrancy_guard); + } + + static void imx_rngc_reset(DeviceState *dev) +diff --git a/hw/misc/macio/mac_dbdma.c b/hw/misc/macio/mac_dbdma.c +index efcc02609f..cc7e02203d 100644 +--- a/hw/misc/macio/mac_dbdma.c ++++ b/hw/misc/macio/mac_dbdma.c +@@ -914,7 +914,7 @@ static void mac_dbdma_realize(DeviceState *dev, Error **errp) + { + DBDMAState *s = MAC_DBDMA(dev); + +- s->bh = qemu_bh_new(DBDMA_run_bh, s); ++ s->bh = qemu_bh_new_guarded(DBDMA_run_bh, s, &dev->mem_reentrancy_guard); + } + + static void mac_dbdma_class_init(ObjectClass *oc, void *data) +diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c +index cdf1313053..f3fb9393b3 100644 +--- a/hw/net/virtio-net.c ++++ b/hw/net/virtio-net.c +@@ -2812,7 +2812,8 @@ static void virtio_net_add_queue(VirtIONet *n, int index) + n->vqs[index].tx_vq = + virtio_add_queue(vdev, n->net_conf.tx_queue_size, + virtio_net_handle_tx_bh); +- n->vqs[index].tx_bh = qemu_bh_new(virtio_net_tx_bh, &n->vqs[index]); ++ n->vqs[index].tx_bh = qemu_bh_new_guarded(virtio_net_tx_bh, &n->vqs[index], ++ &DEVICE(vdev)->mem_reentrancy_guard); + } + + n->vqs[index].tx_waiting = 0; +diff --git a/hw/scsi/mptsas.c b/hw/scsi/mptsas.c +index 5181b0c0b0..8487138cb6 100644 +--- a/hw/scsi/mptsas.c ++++ b/hw/scsi/mptsas.c +@@ -1321,7 +1321,8 @@ static void mptsas_scsi_realize(PCIDevice *dev, Error **errp) + } + s->max_devices = MPTSAS_NUM_PORTS; + +- s->request_bh = qemu_bh_new(mptsas_fetch_requests, s); ++ s->request_bh = qemu_bh_new_guarded(mptsas_fetch_requests, s, ++ &DEVICE(dev)->mem_reentrancy_guard); + + scsi_bus_init(&s->bus, sizeof(s->bus), &dev->qdev, &mptsas_scsi_info); + } +diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c +index 2b613ad2b3..89c4693cc2 100644 +--- a/hw/scsi/scsi-bus.c ++++ b/hw/scsi/scsi-bus.c +@@ -199,7 +199,8 @@ static void scsi_dma_restart_cb(void *opaque, bool running, RunState state) + AioContext *ctx = blk_get_aio_context(s->conf.blk); + /* The reference is dropped in scsi_dma_restart_bh.*/ + object_ref(OBJECT(s)); +- s->bh = aio_bh_new(ctx, scsi_dma_restart_bh, s); ++ s->bh = aio_bh_new_guarded(ctx, scsi_dma_restart_bh, s, ++ &DEVICE(s)->mem_reentrancy_guard); + qemu_bh_schedule(s->bh); + } + } +diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c +index 4d9969f3b1..d5c6293a21 100644 +--- a/hw/scsi/vmw_pvscsi.c ++++ b/hw/scsi/vmw_pvscsi.c +@@ -1184,7 +1184,8 @@ pvscsi_realizefn(PCIDevice *pci_dev, Error **errp) + pcie_endpoint_cap_init(pci_dev, PVSCSI_EXP_EP_OFFSET); + } + +- s->completion_worker = qemu_bh_new(pvscsi_process_completion_queue, s); ++ s->completion_worker = qemu_bh_new_guarded(pvscsi_process_completion_queue, s, ++ &DEVICE(pci_dev)->mem_reentrancy_guard); + + scsi_bus_init(&s->bus, sizeof(s->bus), DEVICE(pci_dev), &pvscsi_scsi_info); + /* override default SCSI bus hotplug-handler, with pvscsi's one */ +diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c +index c9f295e7e4..67bcfac626 100644 +--- a/hw/usb/dev-uas.c ++++ b/hw/usb/dev-uas.c +@@ -936,7 +936,8 @@ static void usb_uas_realize(USBDevice *dev, Error **errp) + + QTAILQ_INIT(&uas->results); + QTAILQ_INIT(&uas->requests); +- uas->status_bh = qemu_bh_new(usb_uas_send_status_bh, uas); ++ uas->status_bh = qemu_bh_new_guarded(usb_uas_send_status_bh, uas, ++ &d->mem_reentrancy_guard); + + dev->flags |= (1 << USB_DEV_FLAG_IS_SCSI_STORAGE); + scsi_bus_init(&uas->bus, sizeof(uas->bus), DEVICE(dev), &usb_uas_scsi_info); +diff --git a/hw/usb/hcd-dwc2.c b/hw/usb/hcd-dwc2.c +index 8755e9cbb0..a0c4e782b2 100644 +--- a/hw/usb/hcd-dwc2.c ++++ b/hw/usb/hcd-dwc2.c +@@ -1364,7 +1364,8 @@ static void dwc2_realize(DeviceState *dev, Error **errp) + s->fi = USB_FRMINTVL - 1; + s->eof_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, dwc2_frame_boundary, s); + s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, dwc2_work_timer, s); +- s->async_bh = qemu_bh_new(dwc2_work_bh, s); ++ s->async_bh = qemu_bh_new_guarded(dwc2_work_bh, s, ++ &dev->mem_reentrancy_guard); + + sysbus_init_irq(sbd, &s->irq); + } +diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c +index f9aa567f5d..3fbb06e248 100644 +--- a/hw/usb/hcd-ehci.c ++++ b/hw/usb/hcd-ehci.c +@@ -2535,7 +2535,8 @@ void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp) + } + + s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ehci_work_timer, s); +- s->async_bh = qemu_bh_new(ehci_work_bh, s); ++ s->async_bh = qemu_bh_new_guarded(ehci_work_bh, s, ++ &dev->mem_reentrancy_guard); + s->device = dev; + + s->vmstate = qemu_add_vm_change_state_handler(usb_ehci_vm_state_change, s); +diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c +index 693c68f445..00a8de2fba 100644 +--- a/hw/usb/hcd-uhci.c ++++ b/hw/usb/hcd-uhci.c +@@ -1236,7 +1236,7 @@ void usb_uhci_common_realize(PCIDevice *dev, Error **errp) + USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); + } + } +- s->bh = qemu_bh_new(uhci_bh, s); ++ s->bh = qemu_bh_new_guarded(uhci_bh, s, &DEVICE(dev)->mem_reentrancy_guard); + s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, uhci_frame_timer, s); + s->num_ports_vmstate = NB_PORTS; + s->frame_time = NANOSECONDS_PER_SECOND / uhci_frame_timer_freq; +diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c +index 3394b04f50..13e83a3050 100644 +--- a/hw/usb/host-libusb.c ++++ b/hw/usb/host-libusb.c +@@ -1178,7 +1178,8 @@ static void usb_host_nodev_bh(void *opaque) + static void usb_host_nodev(USBHostDevice *s) + { + if (!s->bh_nodev) { +- s->bh_nodev = qemu_bh_new(usb_host_nodev_bh, s); ++ s->bh_nodev = qemu_bh_new_guarded(usb_host_nodev_bh, s, ++ &DEVICE(s)->mem_reentrancy_guard); + } + qemu_bh_schedule(s->bh_nodev); + } +@@ -1776,7 +1777,8 @@ static int usb_host_post_load(void *opaque, int version_id) + USBHostDevice *dev = opaque; + + if (!dev->bh_postld) { +- dev->bh_postld = qemu_bh_new(usb_host_post_load_bh, dev); ++ dev->bh_postld = qemu_bh_new_guarded(usb_host_post_load_bh, dev, ++ &DEVICE(dev)->mem_reentrancy_guard); + } + qemu_bh_schedule(dev->bh_postld); + dev->bh_postld_pending = true; +diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c +index 5f0ef9cb3b..59cd3cd7c4 100644 +--- a/hw/usb/redirect.c ++++ b/hw/usb/redirect.c +@@ -1437,8 +1437,10 @@ static void usbredir_realize(USBDevice *udev, Error **errp) + } + } + +- dev->chardev_close_bh = qemu_bh_new(usbredir_chardev_close_bh, dev); +- dev->device_reject_bh = qemu_bh_new(usbredir_device_reject_bh, dev); ++ dev->chardev_close_bh = qemu_bh_new_guarded(usbredir_chardev_close_bh, dev, ++ &DEVICE(dev)->mem_reentrancy_guard); ++ dev->device_reject_bh = qemu_bh_new_guarded(usbredir_device_reject_bh, dev, ++ &DEVICE(dev)->mem_reentrancy_guard); + dev->attach_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, usbredir_do_attach, dev); + + packet_id_queue_init(&dev->cancelled, dev, "cancelled"); +diff --git a/hw/usb/xen-usb.c b/hw/usb/xen-usb.c +index 0f7369e7ed..dec91294ad 100644 +--- a/hw/usb/xen-usb.c ++++ b/hw/usb/xen-usb.c +@@ -1021,7 +1021,8 @@ static void usbback_alloc(struct XenLegacyDevice *xendev) + + QTAILQ_INIT(&usbif->req_free_q); + QSIMPLEQ_INIT(&usbif->hotplug_q); +- usbif->bh = qemu_bh_new(usbback_bh, usbif); ++ usbif->bh = qemu_bh_new_guarded(usbback_bh, usbif, ++ &DEVICE(xendev)->mem_reentrancy_guard); + } + + static int usbback_free(struct XenLegacyDevice *xendev) +diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c +index 9a4f491b54..f503572e27 100644 +--- a/hw/virtio/virtio-balloon.c ++++ b/hw/virtio/virtio-balloon.c +@@ -917,8 +917,9 @@ static void virtio_balloon_device_realize(DeviceState *dev, Error **errp) + precopy_add_notifier(&s->free_page_hint_notify); + + object_ref(OBJECT(s->iothread)); +- s->free_page_bh = aio_bh_new(iothread_get_aio_context(s->iothread), +- virtio_ballloon_get_free_page_hints, s); ++ s->free_page_bh = aio_bh_new_guarded(iothread_get_aio_context(s->iothread), ++ virtio_ballloon_get_free_page_hints, s, ++ &dev->mem_reentrancy_guard); + } + + if (virtio_has_feature(s->host_features, VIRTIO_BALLOON_F_REPORTING)) { +diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c +index 8c2047f4e0..bcca4fb72a 100644 +--- a/hw/virtio/virtio-crypto.c ++++ b/hw/virtio/virtio-crypto.c +@@ -829,7 +829,8 @@ static void virtio_crypto_device_realize(DeviceState *dev, Error **errp) + vcrypto->vqs[i].dataq = + virtio_add_queue(vdev, 1024, virtio_crypto_handle_dataq_bh); + vcrypto->vqs[i].dataq_bh = +- qemu_bh_new(virtio_crypto_dataq_bh, &vcrypto->vqs[i]); ++ qemu_bh_new_guarded(virtio_crypto_dataq_bh, &vcrypto->vqs[i], ++ &dev->mem_reentrancy_guard); + vcrypto->vqs[i].vcrypto = vcrypto; + } + +-- +2.27.0 + diff --git a/hw-sd-sdhci-Do-not-update-TRNMOD-when-Command-Inhibi.patch b/hw-sd-sdhci-Do-not-update-TRNMOD-when-Command-Inhibi.patch new file mode 100644 index 00000000..f30b3108 --- /dev/null +++ b/hw-sd-sdhci-Do-not-update-TRNMOD-when-Command-Inhibi.patch @@ -0,0 +1,135 @@ +From da4d478b1ae6082b6ca333ece1985e014f58fd5b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= +Date: Tue, 9 Apr 2024 16:19:27 +0200 +Subject: [PATCH] hw/sd/sdhci: Do not update TRNMOD when Command Inhibit (DAT) + is set(CVE-2024-3447) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Per "SD Host Controller Standard Specification Version 3.00": + + * 2.2.5 Transfer Mode Register (Offset 00Ch) + + Writes to this register shall be ignored when the Command + Inhibit (DAT) in the Present State register is 1. + +Do not update the TRNMOD register when Command Inhibit (DAT) +bit is set to avoid the present-status register going out of +sync, leading to malicious guest using DMA mode and overflowing +the FIFO buffer: + + $ cat << EOF | qemu-system-i386 \ + -display none -nographic -nodefaults \ + -machine accel=qtest -m 512M \ + -device sdhci-pci,sd-spec-version=3 \ + -device sd-card,drive=mydrive \ + -drive if=none,index=0,file=null-co://,format=raw,id=mydrive \ + -qtest stdio + outl 0xcf8 0x80001013 + outl 0xcfc 0x91 + outl 0xcf8 0x80001001 + outl 0xcfc 0x06000000 + write 0x9100002c 0x1 0x05 + write 0x91000058 0x1 0x16 + write 0x91000005 0x1 0x04 + write 0x91000028 0x1 0x08 + write 0x16 0x1 0x21 + write 0x19 0x1 0x20 + write 0x9100000c 0x1 0x01 + write 0x9100000e 0x1 0x20 + write 0x9100000f 0x1 0x00 + write 0x9100000c 0x1 0x00 + write 0x91000020 0x1 0x00 + EOF + +Stack trace (part): +================================================================= +==89993==ERROR: AddressSanitizer: heap-buffer-overflow on address +0x615000029900 at pc 0x55d5f885700d bp 0x7ffc1e1e9470 sp 0x7ffc1e1e9468 +WRITE of size 1 at 0x615000029900 thread T0 + #0 0x55d5f885700c in sdhci_write_dataport hw/sd/sdhci.c:564:39 + #1 0x55d5f8849150 in sdhci_write hw/sd/sdhci.c:1223:13 + #2 0x55d5fa01db63 in memory_region_write_accessor system/memory.c:497:5 + #3 0x55d5fa01d245 in access_with_adjusted_size system/memory.c:573:18 + #4 0x55d5fa01b1a9 in memory_region_dispatch_write system/memory.c:1521:16 + #5 0x55d5fa09f5c9 in flatview_write_continue system/physmem.c:2711:23 + #6 0x55d5fa08f78b in flatview_write system/physmem.c:2753:12 + #7 0x55d5fa08f258 in address_space_write system/physmem.c:2860:18 + ... +0x615000029900 is located 0 bytes to the right of 512-byte region +[0x615000029700,0x615000029900) allocated by thread T0 here: + #0 0x55d5f7237b27 in __interceptor_calloc + #1 0x7f9e36dd4c50 in g_malloc0 + #2 0x55d5f88672f7 in sdhci_pci_realize hw/sd/sdhci-pci.c:36:5 + #3 0x55d5f844b582 in pci_qdev_realize hw/pci/pci.c:2092:9 + #4 0x55d5fa2ee74b in device_set_realized hw/core/qdev.c:510:13 + #5 0x55d5fa325bfb in property_set_bool qom/object.c:2358:5 + #6 0x55d5fa31ea45 in object_property_set qom/object.c:1472:5 + #7 0x55d5fa332509 in object_property_set_qobject om/qom-qobject.c:28:10 + #8 0x55d5fa31f6ed in object_property_set_bool qom/object.c:1541:15 + #9 0x55d5fa2e2948 in qdev_realize hw/core/qdev.c:292:12 + #10 0x55d5f8eed3f1 in qdev_device_add_from_qdict system/qdev-monitor.c:719:10 + #11 0x55d5f8eef7ff in qdev_device_add system/qdev-monitor.c:738:11 + #12 0x55d5f8f211f0 in device_init_func system/vl.c:1200:11 + #13 0x55d5fad0877d in qemu_opts_foreach util/qemu-option.c:1135:14 + #14 0x55d5f8f0df9c in qemu_create_cli_devices system/vl.c:2638:5 + #15 0x55d5f8f0db24 in qmp_x_exit_preconfig system/vl.c:2706:5 + #16 0x55d5f8f14dc0 in qemu_init system/vl.c:3737:9 + ... +SUMMARY: AddressSanitizer: heap-buffer-overflow hw/sd/sdhci.c:564:39 +in sdhci_write_dataport + +Add assertions to ensure the fifo_buffer[] is not overflowed by +malicious accesses to the Buffer Data Port register. + +Fixes: CVE-2024-3447 +Cc: qemu-stable@nongnu.org +Fixes: d7dfca0807 ("hw/sdhci: introduce standard SD host controller") +Buglink: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=58813 +Reported-by: Alexander Bulekov +Reported-by: Chuhong Yuan +Signed-off-by: Peter Maydell +Message-Id: +Signed-off-by: Philippe Mathieu-Daudé +Message-Id: <20240409145524.27913-1-philmd@linaro.org> +--- + hw/sd/sdhci.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c +index e0bbc90344..211daa4bb0 100644 +--- a/hw/sd/sdhci.c ++++ b/hw/sd/sdhci.c +@@ -471,6 +471,7 @@ static uint32_t sdhci_read_dataport(SDHCIState *s, unsigned size) + } + + for (i = 0; i < size; i++) { ++ assert(s->data_count < s->buf_maxsz); + value |= s->fifo_buffer[s->data_count] << i * 8; + s->data_count++; + /* check if we've read all valid data (blksize bytes) from buffer */ +@@ -559,6 +560,7 @@ static void sdhci_write_dataport(SDHCIState *s, uint32_t value, unsigned size) + } + + for (i = 0; i < size; i++) { ++ assert(s->data_count < s->buf_maxsz); + s->fifo_buffer[s->data_count] = value & 0xFF; + s->data_count++; + value >>= 8; +@@ -1184,6 +1186,12 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size) + if (!(s->capareg & R_SDHC_CAPAB_SDMA_MASK)) { + value &= ~SDHC_TRNS_DMA; + } ++ ++ /* TRNMOD writes are inhibited while Command Inhibit (DAT) is true */ ++ if (s->prnsts & SDHC_DATA_INHIBIT) { ++ mask |= 0xffff; ++ } ++ + MASKED_WRITE(s->trnmod, mask, value & SDHC_TRNMOD_MASK); + MASKED_WRITE(s->cmdreg, mask >> 16, value >> 16); + +-- +2.27.0 + diff --git a/hw-virtio-Introduce-virtio_bh_new_guarded-helper.patch b/hw-virtio-Introduce-virtio_bh_new_guarded-helper.patch new file mode 100644 index 00000000..8898a360 --- /dev/null +++ b/hw-virtio-Introduce-virtio_bh_new_guarded-helper.patch @@ -0,0 +1,67 @@ +From 53203b7c0c933bd0ce07c58bdd7113e2fba62fa3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= +Date: Thu, 4 Apr 2024 20:56:11 +0200 +Subject: [PATCH] hw/virtio: Introduce virtio_bh_new_guarded() helper +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Introduce virtio_bh_new_guarded(), similar to qemu_bh_new_guarded() +but using the transport memory guard, instead of the device one +(there can only be one virtio device per virtio bus). + +Inspired-by: Gerd Hoffmann +Reviewed-by: Gerd Hoffmann +Acked-by: Michael S. Tsirkin +Signed-off-by: Philippe Mathieu-Daudé +Reviewed-by: Michael S. Tsirkin +Message-Id: <20240409105537.18308-2-philmd@linaro.org> +Signed-off-by: liuxiangdong +--- + hw/virtio/virtio.c | 10 ++++++++++ + include/hw/virtio/virtio.h | 7 +++++++ + 2 files changed, 17 insertions(+) + +diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c +index e3f392fc59..80156bfbd5 100644 +--- a/hw/virtio/virtio.c ++++ b/hw/virtio/virtio.c +@@ -3960,3 +3960,13 @@ static void virtio_register_types(void) + } + + type_init(virtio_register_types) ++ ++QEMUBH *virtio_bh_new_guarded_full(DeviceState *dev, ++ QEMUBHFunc *cb, void *opaque, ++ const char *name) ++{ ++ DeviceState *transport = qdev_get_parent_bus(dev)->parent; ++ ++ return qemu_bh_new_full(cb, opaque, name, ++ &transport->mem_reentrancy_guard); ++} +diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h +index 43509b33ff..4cc278f12c 100644 +--- a/include/hw/virtio/virtio.h ++++ b/include/hw/virtio/virtio.h +@@ -23,5 +23,6 @@ + #include "standard-headers/linux/virtio_ring.h" + #include "qom/object.h" ++#include "block/aio.h" + + /* A guest should never accept this. It implies negotiation is broken. */ + #define VIRTIO_F_BAD_FEATURE 30 +@@ -399,4 +400,10 @@ static inline bool virtio_device_disabled(VirtIODevice *vdev) + bool virtio_legacy_allowed(VirtIODevice *vdev); + bool virtio_legacy_check_disabled(VirtIODevice *vdev); + ++QEMUBH *virtio_bh_new_guarded_full(DeviceState *dev, ++ QEMUBHFunc *cb, void *opaque, ++ const char *name); ++#define virtio_bh_new_guarded(dev, cb, opaque) \ ++ virtio_bh_new_guarded_full((dev), (cb), (opaque), (stringify(cb))) ++ + #endif +-- +2.27.0 + diff --git a/hw-virtio-virtio-crypto-Protect-from-DMA-re-entrancy.patch b/hw-virtio-virtio-crypto-Protect-from-DMA-re-entrancy.patch new file mode 100644 index 00000000..8ad27f24 --- /dev/null +++ b/hw-virtio-virtio-crypto-Protect-from-DMA-re-entrancy.patch @@ -0,0 +1,43 @@ +From 13eea576219af3919ac31f7e63818b46c4fcbab6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= +Date: Thu, 4 Apr 2024 20:56:41 +0200 +Subject: [PATCH] hw/virtio/virtio-crypto: Protect from DMA re-entrancy + bugs(CVE-2024-3446) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Replace qemu_bh_new_guarded() by virtio_bh_new_guarded() +so the bus and device use the same guard. Otherwise the +DMA-reentrancy protection can be bypassed. + +Fixes: CVE-2024-3446 +Cc: qemu-stable@nongnu.org +Suggested-by: Alexander Bulekov +Reviewed-by: Gerd Hoffmann +Acked-by: Michael S. Tsirkin +Signed-off-by: Philippe Mathieu-Daudé +Reviewed-by: Michael S. Tsirkin +Message-Id: <20240409105537.18308-5-philmd@linaro.org> +--- + hw/virtio/virtio-crypto.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c +index bcca4fb72a..07566f0d46 100644 +--- a/hw/virtio/virtio-crypto.c ++++ b/hw/virtio/virtio-crypto.c +@@ -829,8 +829,8 @@ static void virtio_crypto_device_realize(DeviceState *dev, Error **errp) + vcrypto->vqs[i].dataq = + virtio_add_queue(vdev, 1024, virtio_crypto_handle_dataq_bh); + vcrypto->vqs[i].dataq_bh = +- qemu_bh_new_guarded(virtio_crypto_dataq_bh, &vcrypto->vqs[i], +- &dev->mem_reentrancy_guard); ++ virtio_bh_new_guarded(dev, virtio_crypto_dataq_bh, ++ &vcrypto->vqs[i]); + vcrypto->vqs[i].vcrypto = vcrypto; + } + +-- +2.27.0 + diff --git a/ivshmem-test.c-enable-test_ivshmem_server-for-ppc64-.patch b/ivshmem-test.c-enable-test_ivshmem_server-for-ppc64-.patch new file mode 100644 index 00000000..2753460f --- /dev/null +++ b/ivshmem-test.c-enable-test_ivshmem_server-for-ppc64-.patch @@ -0,0 +1,69 @@ +From d193565aa9b9b293337a82f347fa1c877814d871 Mon Sep 17 00:00:00 2001 +From: Luo Yifan +Date: Thu, 28 Mar 2024 14:00:37 +0800 +Subject: [PATCH] ivshmem-test.c: enable test_ivshmem_server for ppc64 arch +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cherry picked from commit d04aeb6862a18540b7f72617b05be19846e1b047 + +This test, if enabled by hand, was failing when the ivhsmem device was +being declared as DEVICE_NATIVE_ENDIAN with the following error: + +/ppc64/ivshmem/pair: OK +/ppc64/ivshmem/server: +** +ERROR:/home/danielhb/qemu/tests/qtest/ivshmem-test.c:367:test_ivshmem_server: +assertion failed (ret != 0): (0 != 0) +Aborted + +After the endianness change done in the previous patch, we can verify in +both a a Power 9 little-endian host and in a Power 8 big-endian host +that this test is now passing: + +$ QTEST_QEMU_BINARY=./ppc64-softmmu/qemu-system-ppc64 ./tests/qtest/ivshmem-test -m slow +/ppc64/ivshmem/single: OK +/ppc64/ivshmem/hotplug: OK +/ppc64/ivshmem/memdev: OK +/ppc64/ivshmem/pair: OK +/ppc64/ivshmem/server: OK + +Let's keep it that way by officially enabling it for ppc64. + +Acked-by: Thomas Huth +Signed-off-by: Daniel Henrique Barboza +Reviewed-by: Philippe Mathieu-Daudé +Message-Id: <20211124092948.335389-3-danielhb413@gmail.com> +Signed-off-by: Cédric Le Goater +Signed-off-by: Luo Yifan +--- + tests/qtest/ivshmem-test.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/tests/qtest/ivshmem-test.c b/tests/qtest/ivshmem-test.c +index dfa69424ed..fe94dd3b96 100644 +--- a/tests/qtest/ivshmem-test.c ++++ b/tests/qtest/ivshmem-test.c +@@ -463,7 +463,6 @@ static gchar *mktempshm(int size, int *fd) + int main(int argc, char **argv) + { + int ret, fd; +- const char *arch = qtest_get_arch(); + gchar dir[] = "/tmp/ivshmem-test.XXXXXX"; + + g_test_init(&argc, &argv, NULL); +@@ -488,9 +487,7 @@ int main(int argc, char **argv) + qtest_add_func("/ivshmem/memdev", test_ivshmem_memdev); + if (g_test_slow()) { + qtest_add_func("/ivshmem/pair", test_ivshmem_pair); +- if (strcmp(arch, "ppc64") != 0) { +- qtest_add_func("/ivshmem/server", test_ivshmem_server); +- } ++ qtest_add_func("/ivshmem/server", test_ivshmem_server); + } + + out: +-- +2.27.0 + diff --git a/ivshmem.c-change-endianness-to-LITTLE_ENDIAN.patch b/ivshmem.c-change-endianness-to-LITTLE_ENDIAN.patch new file mode 100644 index 00000000..80cc63a9 --- /dev/null +++ b/ivshmem.c-change-endianness-to-LITTLE_ENDIAN.patch @@ -0,0 +1,56 @@ +From b2120f0a316470369451103d9d1b50b2d13cd68b Mon Sep 17 00:00:00 2001 +From: Luo Yifan +Date: Thu, 28 Mar 2024 13:58:20 +0800 +Subject: [PATCH] ivshmem.c: change endianness to LITTLE_ENDIAN +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cherry picked from commit ef80a708b57ddc8f605d9982bfaa0536e720ed9f + +The ivshmem device, as with most PCI devices, uses little endian byte +order. However, the endianness of its mmio_ops is marked as +DEVICE_NATIVE_ENDIAN. This presents not only the usual problems with big +endian hosts but also with PowerPC little endian hosts as well, since +the Power architecture in QEMU uses big endian hardware (XIVE controller, +PCI Host Bridges, etc) even if the host is in little endian byte order. + +As it is today, the IVPosition of the device will be byte swapped when +running in Power BE and LE. This can be seen by changing the existing +qtest 'ivshmem-test' to run in ppc64 hosts and printing the IVPOSITION +regs in test_ivshmem_server() right after the VM ids assert. For x86_64 +the VM id values read are '0' and '1', for ppc64 (tested in a Power8 +RHEL 7.9 BE server) and ppc64le (tested in a Power9 RHEL 8.6 LE server) +the ids will be '0' and '0x1000000'. + +Change this device to LITTLE_ENDIAN fixes the issue for Power hosts of +both endianness, and every other big-endian architecture that might use +this device, without impacting x86 users. + +Fixes: cb06608e17f8 ("ivshmem: convert to memory API") +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/168 +Signed-off-by: Daniel Henrique Barboza +Reviewed-by: Philippe Mathieu-Daudé +Message-Id: <20211124092948.335389-2-danielhb413@gmail.com> +Signed-off-by: Cédric Le Goater +Signed-off-by: Luo Yifan +--- + hw/misc/ivshmem.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c +index 05f06ed6cf..4093c59079 100644 +--- a/hw/misc/ivshmem.c ++++ b/hw/misc/ivshmem.c +@@ -243,7 +243,7 @@ static uint64_t ivshmem_io_read(void *opaque, hwaddr addr, + static const MemoryRegionOps ivshmem_mmio_ops = { + .read = ivshmem_io_read, + .write = ivshmem_io_write, +- .endianness = DEVICE_NATIVE_ENDIAN, ++ .endianness = DEVICE_LITTLE_ENDIAN, + .impl = { + .min_access_size = 4, + .max_access_size = 4, +-- +2.27.0 + diff --git a/libqos-virtio.c-Correct-flags-reading-in-qvirtqueue_.patch b/libqos-virtio.c-Correct-flags-reading-in-qvirtqueue_.patch new file mode 100644 index 00000000..f0d1b080 --- /dev/null +++ b/libqos-virtio.c-Correct-flags-reading-in-qvirtqueue_.patch @@ -0,0 +1,40 @@ +From c4acd87e379d6b6c3a9b8e381c91af255d96aeaa Mon Sep 17 00:00:00 2001 +From: guping +Date: Sat, 30 Mar 2024 14:59:51 +0000 +Subject: [PATCH] libqos/virtio.c: Correct 'flags' reading in qvirtqueue_kick + cherry-pick from 66e411885a23c96ff73742d06b793fec3ceaebb7 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In qvirtqueue_kick(), the 'flags' were previously being incorrectly read from +vq->avail instead of the correct vq->used location. This update ensures 'flags' +are read from the correct location as per the virtio standard. + +Signed-off-by: default avatarZheyu Ma +Reviewed-by: default avatarPhilippe Mathieu-Daudé +Reviewed-by: Stefan Hajnoczi's avatarStefan Hajnoczi +Message-ID: <20240320090442.267525-1-zheyuma97@gmail.com> +Signed-off-by: Thomas Huth's avatarThomas Huth + +Signed-off-by: guping +--- + tests/qtest/libqos/virtio.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/qtest/libqos/virtio.c b/tests/qtest/libqos/virtio.c +index 6fe7bf9555..08e5bcdca1 100644 +--- a/tests/qtest/libqos/virtio.c ++++ b/tests/qtest/libqos/virtio.c +@@ -377,7 +377,7 @@ void qvirtqueue_kick(QTestState *qts, QVirtioDevice *d, QVirtQueue *vq, + qvirtio_writew(d, qts, vq->avail + 2, idx + 1); + + /* Must read after idx is updated */ +- flags = qvirtio_readw(d, qts, vq->avail); ++ flags = qvirtio_readw(d, qts, vq->used); + avail_event = qvirtio_readw(d, qts, vq->used + 4 + + sizeof(struct vring_used_elem) * vq->size); + +-- +2.27.0 + diff --git a/linux-user-un-parent-OBJECT-cpu-when-closing-thread.patch b/linux-user-un-parent-OBJECT-cpu-when-closing-thread.patch new file mode 100644 index 00000000..b70504aa --- /dev/null +++ b/linux-user-un-parent-OBJECT-cpu-when-closing-thread.patch @@ -0,0 +1,66 @@ +From 41f426180f0d5d5a1720166a77a0d741fd072680 Mon Sep 17 00:00:00 2001 +From: tangbinzy +Date: Mon, 25 Mar 2024 09:32:04 +0000 +Subject: [PATCH] linux-user: un-parent OBJECT(cpu) when closing thread + mainline inclusion + commit 52f0c1607671293afcdb2acc2f83e9bccbfa74bb + category: bugfix + +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +--------------------------------------------------------------- + +While forcing the CPU to unrealize by hand does trigger the clean-up +code we never fully free resources because refcount never reaches +zero. This is because QOM automatically added objects without an +explicit parent to /unattached/, incrementing the refcount. + +Instead of manually triggering unrealization just unparent the object +and let the device machinery deal with that for us. + +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/866 +Signed-off-by: Alex Bennée +Reviewed-by: Laurent Vivier +Message-Id: <20220811151413.3350684-2-alex.bennee@linaro.org> + +Signed-off-by: tangbinzy +--- + linux-user/syscall.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/linux-user/syscall.c b/linux-user/syscall.c +index 92df0f9d8c..a5fe399277 100644 +--- a/linux-user/syscall.c ++++ b/linux-user/syscall.c +@@ -8345,7 +8345,13 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, + if (CPU_NEXT(first_cpu)) { + TaskState *ts = cpu->opaque; + +- object_property_set_bool(OBJECT(cpu), "realized", false, NULL); ++ if (ts->child_tidptr) { ++ put_user_u32(0, ts->child_tidptr); ++ do_sys_futex(g2h(cpu, ts->child_tidptr), ++ FUTEX_WAKE, INT_MAX, NULL, NULL, 0); ++ } ++ ++ object_unparent(OBJECT(cpu)); + object_unref(OBJECT(cpu)); + /* + * At this point the CPU should be unrealized and removed +@@ -8355,11 +8361,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, + + pthread_mutex_unlock(&clone_lock); + +- if (ts->child_tidptr) { +- put_user_u32(0, ts->child_tidptr); +- do_sys_futex(g2h(cpu, ts->child_tidptr), +- FUTEX_WAKE, INT_MAX, NULL, NULL, 0); +- } + thread_cpu = NULL; + g_free(ts); + rcu_unregister_thread(); +-- +2.27.0 + diff --git a/qemu-iotests-Discard-stderr-when-probing-devices.patch b/qemu-iotests-Discard-stderr-when-probing-devices.patch new file mode 100644 index 00000000..683e630f --- /dev/null +++ b/qemu-iotests-Discard-stderr-when-probing-devices.patch @@ -0,0 +1,68 @@ +From ae868555000f3f9a37df2faf2551825381a86b45 Mon Sep 17 00:00:00 2001 +From: tangbinzy +Date: Mon, 25 Mar 2024 10:07:25 +0000 +Subject: [PATCH] qemu-iotests: Discard stderr when probing devices + mainline inclusion + commit e13fe274bfbc4c5b338854a3519a64b84c2d5517 + category: bugfix + +--------------------------------------------------------------- + +qemu-iotests fails in the following setup: + + ./configure --enable-modules --enable-smartcard \ + --target-list=x86_64-softmmu,s390x-softmmu + make + cd build + QEMU_PROG=`pwd`/s390x-softmmu/qemu-system-s390x \ + ../tests/check-block.sh qcow2 + ... + --- /home/crobinso/src/qemu/tests/qemu-iotests/127.out + +++ /home/crobinso/src/qemu/build/tests/qemu-iotests/scratch/127.out.bad +// @@ -1,4 +1,18 @@ + QA output created by 127 + +Failed to open module: /home/crobinso/src/qemu/build/hw-usb-smartcard.so: undefined symbol: ccid_card_ccid_attach + ... + --- /home/crobinso/src/qemu/tests/qemu-iotests/267.out + +++ /home/crobinso/src/qemu/build/tests/qemu-iotests/scratch/267.out.bad +// @@ -1,4 +1,11 @@ + QA output created by 267 + +Failed to open module: /home/crobinso/src/qemu/build/hw-usb-smartcard.so: undefined symbol: ccid_card_ccid_attach + +The stderr spew is its own known issue, but seems like iotests should +be discarding stderr in this case. + +Signed-off-by: Cole Robinson +Reviewed-by: Thomas Huth +Signed-off-by: Kevin Wolf + +Signed-off-by: tangbinzy +--- + tests/qemu-iotests/common.rc | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc +index d8582454de..4c468675d3 100644 +--- a/tests/qemu-iotests/common.rc ++++ b/tests/qemu-iotests/common.rc +@@ -973,7 +973,7 @@ _require_large_file() + # + _require_devices() + { +- available=$($QEMU -M none -device help | \ ++ available=$($QEMU -M none -device help 2> /dev/null | \ + grep ^name | sed -e 's/^name "//' -e 's/".*$//') + for device + do +@@ -985,7 +985,7 @@ _require_devices() + + _require_one_device_of() + { +- available=$($QEMU -M none -device help | \ ++ available=$($QEMU -M none -device help 2> /dev/null | \ + grep ^name | sed -e 's/^name "//' -e 's/".*$//') + for device + do +-- +2.27.0 + diff --git a/qemu.spec b/qemu.spec index 13fd8847..93b7ef4f 100644 --- a/qemu.spec +++ b/qemu.spec @@ -1,6 +1,6 @@ Name: qemu Version: 6.2.0 -Release: 87 +Release: 88 Epoch: 10 Summary: QEMU is a generic and open source machine emulator and virtualizer License: GPLv2 and BSD and MIT and CC-BY-SA-4.0 @@ -727,6 +727,37 @@ Patch0715: i386-cpu-Clear-FEAT_XSAVE_XSS_LO-HI-leafs-when-CPUID.patch Patch0716: i386-cpu-Mask-with-XCR0-XSS-mask-for-FEAT_XSAVE_XCR0.patch Patch0717: i386-cpuid-Decrease-cpuid_i-when-skipping-CPUID-leaf.patch Patch0718: i386-cpuid-Move-leaf-7-to-correct-group.patch +Patch0719: scsi-disk-fix-overflow-when-block-size-is-not-a-mult.patch +Patch0720: contrib-vhost-user-blk-Clean-up-deallocation-of-VuVi.patch +Patch0721: hw-net-rocker-Avoid-undefined-shifts-with-more-than-.patch +Patch0722: linux-user-un-parent-OBJECT-cpu-when-closing-thread.patch +Patch0723: qemu-iotests-Discard-stderr-when-probing-devices.patch +Patch0724: hw-intc-clean-up-error-reporting-for-failed-ITS-cmd.patch +Patch0725: virtio-gpu-do-not-byteswap-padding.patch +Patch0726: configure-remove-dead-variables.patch +Patch0727: hw-ppc-mac.h-Remove-MAX_CPUS-macro.patch +Patch0728: ivshmem.c-change-endianness-to-LITTLE_ENDIAN.patch +Patch0729: ivshmem-test.c-enable-test_ivshmem_server-for-ppc64-.patch +Patch0730: libqos-virtio.c-Correct-flags-reading-in-qvirtqueue_.patch +Patch0731: virtio-crypto-fix-NULL-pointer-dereference-in-virtio.patch +Patch0732: amd_iommu-Fix-APIC-address-check.patch +Patch0733: block-mirror-Fix-NULL-s-job-in-active-writes.patch +Patch0734: smmu-Clear-SMMUPciBus-pointer-cache-when-system-rese.patch +Patch0735: block-Fix-crash-when-loading-snapshot-on-inactive-no.patch +Patch0736: system-memory-use-ldn_he_p-stn_he_p.patch +Patch0737: virtio-mem-Fix-the-iterator-variable-in-a-vmem-rdl_l.patch +Patch0738: virtio-mem-Fix-the-bitmap-index-of-the-section-offse.patch +Patch0739: tulip-Remove-unused-variable.patch +Patch0740: rtl8139-Remove-unused-variable.patch +Patch0741: hw-sd-sdhci-Do-not-update-TRNMOD-when-Command-Inhibi.patch +Patch0742: async-Add-an-optional-reentrancy-guard-to-the-BH-API.patch +Patch0743: async-avoid-use-after-free-on-re-entrancy-guard.patch +Patch0744: checkpatch-add-qemu_bh_new-aio_bh_new-checks.patch +Patch0745: hw-replace-most-qemu_bh_new-calls-with-qemu_bh_new_g.patch +Patch0746: hw-virtio-Introduce-virtio_bh_new_guarded-helper.patch +Patch0747: hw-display-virtio-gpu-Protect-from-DMA-re-entrancy-b.patch +Patch0748: hw-char-virtio-serial-bus-Protect-from-DMA-re-entran.patch +Patch0749: hw-virtio-virtio-crypto-Protect-from-DMA-re-entrancy.patch BuildRequires: flex BuildRequires: gcc @@ -1286,6 +1317,39 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* Mon Apr 22 2024 - 10:6.2.0-88 +- hw/virtio/virtio-crypto: Protect from DMA re-entrancy bugs(CVE-2024-3446) +- hw/char/virtio-serial-bus: Protect from DMA re-entrancy bugs(CVE-2024-3446) +- hw/display/virtio-gpu: Protect from DMA re-entrancy bugs(CVE-2024-3446) +- hw/virtio: Introduce virtio_bh_new_guarded() helper +- hw: replace most qemu_bh_new calls with qemu_bh_new_guarded +- checkpatch: add qemu_bh_new/aio_bh_new checks +- async: avoid use-after-free on re-entrancy guard +- async: Add an optional reentrancy guard to the BH API +- hw/sd/sdhci: Do not update TRNMOD when Command Inhibit (DAT) is set(CVE-2024-3447) +- rtl8139: Remove unused variable +- tulip: Remove unused variable +- virtio-mem: Fix the bitmap index of the section offset +- virtio-mem: Fix the iterator variable in a vmem->rdl_list loop +- system/memory: use ldn_he_p/stn_he_p +- block: Fix crash when loading snapshot on inactive node +- smmu: Clear SMMUPciBus pointer cache when system reset +- block/mirror: Fix NULL s->job in active writes +- amd_iommu: Fix APIC address check +- virtio-crypto: fix NULL pointer dereference in virtio_crypto_free_reques +- libqos/virtio.c: Correct 'flags' reading in qvirtqueue_kick +- ivshmem-test.c: enable test_ivshmem_server for ppc64 arch +- ivshmem.c: change endianness to LITTLE_ENDIAN +- hw/ppc/mac.h: Remove MAX_CPUS macro +- configure: remove dead variables +- virtio-gpu: do not byteswap padding +- hw/intc: clean-up error reporting for failed ITS cmd +- qemu-iotests: Discard stderr when probing devices +- linux-user: un-parent OBJECT(cpu) when closing thread +- hw/net/rocker: Avoid undefined shifts with more than 31 ports +- contrib/vhost-user-blk: Clean up deallocation of VuVirtqElement +- scsi-disk: fix overflow when block size is not a multiple of BDRV_SECTOR_SIZE + * Sat Mar 23 2024 - 10:6.2.0-87 - i386/cpuid: Move leaf 7 to correct group - i386/cpuid: Decrease cpuid_i when skipping CPUID leaf 1F diff --git a/rtl8139-Remove-unused-variable.patch b/rtl8139-Remove-unused-variable.patch new file mode 100644 index 00000000..f3c89776 --- /dev/null +++ b/rtl8139-Remove-unused-variable.patch @@ -0,0 +1,44 @@ +From 9058e3d3fcb3fcb397d72caca54a4d6a8cacbd50 Mon Sep 17 00:00:00 2001 +From: zhujun2 +Date: Thu, 11 Apr 2024 00:58:48 -0700 +Subject: [PATCH] rtl8139: Remove unused variable + +Variable send_count used in rtl8139_cplus_transmit_one function is only +incremented but never read. This causes 'Unused but set variable' warning +on Clang 15.0.1 compiler. + +Removing the variable to prevent the warning. + +Signed-off-by: Miroslav Rezanina +Reviewed-by: Thomas Huth +Message-Id: <15a32dd06c492216cbf27cd3ddcbe1e9afb8d8f5.1668009030.git.mrezanin@redhat.com> +Signed-off-by: Thomas Huth +(cherry picked from commit 7d7238c72b983cff5064734349d2d45be9c6282c) +Signed-off-by: zhujun2 +--- + hw/net/rtl8139.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c +index 43d65d7252..8af396cf06 100644 +--- a/hw/net/rtl8139.c ++++ b/hw/net/rtl8139.c +@@ -2156,7 +2156,6 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) + ip_data_len, saved_size - ETH_HLEN, large_send_mss); + + int tcp_send_offset = 0; +- int send_count = 0; + + /* maximum IP header length is 60 bytes */ + uint8_t saved_ip_header[60]; +@@ -2261,7 +2260,6 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) + /* add transferred count to TCP sequence number */ + stl_be_p(&p_tcp_hdr->th_seq, + chunk_size + ldl_be_p(&p_tcp_hdr->th_seq)); +- ++send_count; + } + + /* Stop sending this frame */ +-- +2.27.0 + diff --git a/scsi-disk-fix-overflow-when-block-size-is-not-a-mult.patch b/scsi-disk-fix-overflow-when-block-size-is-not-a-mult.patch new file mode 100644 index 00000000..e4e4594e --- /dev/null +++ b/scsi-disk-fix-overflow-when-block-size-is-not-a-mult.patch @@ -0,0 +1,59 @@ +From 53b627a98b78ac06e7cba29c3614464469e7c11f Mon Sep 17 00:00:00 2001 +From: tangbinzy +Date: Mon, 25 Mar 2024 08:14:12 +0000 +Subject: [PATCH] scsi-disk: fix overflow when block size is not a multiple of BDRV_SECTOR_SIZE + mainline inclusion + commit 54a53a006ed9c1fe027fd89045d6de1e9128d7f4 + category: bugfix + +--------------------------------------------------------------- + +In scsi_disk_emulate_write_same() the number of host sectors to transfer is +calculated as (s->qdev.blocksize / BDRV_SECTOR_SIZE) which is then used to +copy data in block size chunks to the iov buffer. + +Since the loop copying the data to the iov buffer uses a fixed increment of +s->qdev.blocksize then using a block size that isn't a multiple of +BDRV_SECTOR_SIZE introduces a rounding error in the iov buffer size calculation +such that the iov buffer copy overflows the space allocated. + +Update the iov buffer copy for() loop so that it will use the smallest of either +the current block size or the remaining transfer count to prevent the overflow. + +Signed-off-by: Mark Cave-Ayland +Message-Id: <20220730122656.253448-2-mark.cave-ayland@ilande.co.uk> +Signed-off-by: Paolo Bonzini + +Signed-off-by: tangbinzy +--- + hw/scsi/scsi-disk.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c +index a66d2b0a98..edd2f895e7 100644 +--- a/hw/scsi/scsi-disk.c ++++ b/hw/scsi/scsi-disk.c +@@ -1800,7 +1800,7 @@ static void scsi_disk_emulate_write_same(SCSIDiskReq *r, uint8_t *inbuf) + uint32_t nb_sectors = scsi_data_cdb_xfer(r->req.cmd.buf); + WriteSameCBData *data; + uint8_t *buf; +- int i; ++ int i, l; + + /* Fail if PBDATA=1 or LBDATA=1 or ANCHOR=1. */ + if (nb_sectors == 0 || (req->cmd.buf[1] & 0x16)) { +@@ -1842,8 +1842,9 @@ static void scsi_disk_emulate_write_same(SCSIDiskReq *r, uint8_t *inbuf) + data->iov.iov_len); + qemu_iovec_init_external(&data->qiov, &data->iov, 1); + +- for (i = 0; i < data->iov.iov_len; i += s->qdev.blocksize) { +- memcpy(&buf[i], inbuf, s->qdev.blocksize); ++ for (i = 0; i < data->iov.iov_len; i += l) { ++ l = MIN(s->qdev.blocksize, data->iov.iov_len - i); ++ memcpy(&buf[i], inbuf, l); + } + + scsi_req_ref(&r->req); +-- +2.27.0 + diff --git a/smmu-Clear-SMMUPciBus-pointer-cache-when-system-rese.patch b/smmu-Clear-SMMUPciBus-pointer-cache-when-system-rese.patch new file mode 100644 index 00000000..d07ac4f9 --- /dev/null +++ b/smmu-Clear-SMMUPciBus-pointer-cache-when-system-rese.patch @@ -0,0 +1,41 @@ +From c7b0d41391267e278a3d7e9297041b29888a461e Mon Sep 17 00:00:00 2001 +From: zhujun2 +Date: Mon, 8 Apr 2024 00:12:40 -0700 +Subject: [PATCH] smmu: Clear SMMUPciBus pointer cache when system reset + +s->smmu_pcibus_by_bus_num is a SMMUPciBus pointer cache indexed +by bus number, bus number may not always be a fixed value, +i.e., guest reboot to different kernel which set bus number with +different algorithm. + +This could lead to smmu_iommu_mr() providing the wrong iommu MR. + +Suggested-by: Eric Auger +Signed-off-by: Zhenzhong Duan +Message-Id: <20240125073706.339369-3-zhenzhong.duan@intel.com> +Reviewed-by: Eric Auger +Tested-by: Eric Auger +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 8a6b3f4dc95a064e88adaca86374108da0ecb38d) +Signed-off-by: zhujun2 +--- + hw/arm/smmu-common.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c +index e09b9c13b7..d8fc81c102 100644 +--- a/hw/arm/smmu-common.c ++++ b/hw/arm/smmu-common.c +@@ -530,6 +530,8 @@ static void smmu_base_reset(DeviceState *dev) + { + SMMUState *s = ARM_SMMU(dev); + ++ memset(s->smmu_pcibus_by_bus_num, 0, sizeof(s->smmu_pcibus_by_bus_num)); ++ + g_hash_table_remove_all(s->configs); + g_hash_table_remove_all(s->iotlb); + } +-- +2.27.0 + diff --git a/system-memory-use-ldn_he_p-stn_he_p.patch b/system-memory-use-ldn_he_p-stn_he_p.patch new file mode 100644 index 00000000..dee36f98 --- /dev/null +++ b/system-memory-use-ldn_he_p-stn_he_p.patch @@ -0,0 +1,78 @@ +From 8a0a03a259eec5879a514363e3a80fea5039510f Mon Sep 17 00:00:00 2001 +From: zhujun2 +Date: Mon, 8 Apr 2024 01:09:55 -0700 +Subject: [PATCH] system/memory: use ldn_he_p/stn_he_p +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Using direct pointer dereferencing can allow for unaligned accesses, +which was seen during execution with sanitizers enabled. + +Cc: qemu-stable@nongnu.org +Reviewed-by: Chris Rauer +Reviewed-by: Peter Foley +Signed-off-by: Patrick Venture +Reviewed-by: Philippe Mathieu-Daudé o +Reviewed-by: David Hildenbrand +Message-ID: <20231116163633.276671-1-venture@google.com> +Signed-off-by: Philippe Mathieu-Daudé o +(cherry picked from commit 2b8fe81b3c2e76d241510a9a85496d544e42f5ec) +Signed-off-by: zhujun2 +--- + softmmu/memory.c | 32 ++------------------------------ + 1 file changed, 2 insertions(+), 30 deletions(-) + +diff --git a/softmmu/memory.c b/softmmu/memory.c +index 102f0a4248..0bf37f11aa 100644 +--- a/softmmu/memory.c ++++ b/softmmu/memory.c +@@ -1325,22 +1325,7 @@ static uint64_t memory_region_ram_device_read(void *opaque, + hwaddr addr, unsigned size) + { + MemoryRegion *mr = opaque; +- uint64_t data = (uint64_t)~0; +- +- switch (size) { +- case 1: +- data = *(uint8_t *)(mr->ram_block->host + addr); +- break; +- case 2: +- data = *(uint16_t *)(mr->ram_block->host + addr); +- break; +- case 4: +- data = *(uint32_t *)(mr->ram_block->host + addr); +- break; +- case 8: +- data = *(uint64_t *)(mr->ram_block->host + addr); +- break; +- } ++ uint64_t data = ldn_he_p(mr->ram_block->host + addr, size); + + trace_memory_region_ram_device_read(get_cpu_index(), mr, addr, data, size); + +@@ -1354,20 +1339,7 @@ static void memory_region_ram_device_write(void *opaque, hwaddr addr, + + trace_memory_region_ram_device_write(get_cpu_index(), mr, addr, data, size); + +- switch (size) { +- case 1: +- *(uint8_t *)(mr->ram_block->host + addr) = (uint8_t)data; +- break; +- case 2: +- *(uint16_t *)(mr->ram_block->host + addr) = (uint16_t)data; +- break; +- case 4: +- *(uint32_t *)(mr->ram_block->host + addr) = (uint32_t)data; +- break; +- case 8: +- *(uint64_t *)(mr->ram_block->host + addr) = data; +- break; +- } ++ stn_he_p(mr->ram_block->host + addr, size, data); + } + + static const MemoryRegionOps ram_device_mem_ops = { +-- +2.27.0 + diff --git a/tulip-Remove-unused-variable.patch b/tulip-Remove-unused-variable.patch new file mode 100644 index 00000000..b203113d --- /dev/null +++ b/tulip-Remove-unused-variable.patch @@ -0,0 +1,48 @@ +From 743ade13f9b675b4a5aa8631235d681fd66ee854 Mon Sep 17 00:00:00 2001 +From: zhujun2 +Date: Thu, 11 Apr 2024 00:53:25 -0700 +Subject: [PATCH] tulip: Remove unused variable + +Variable n used in tulip_idblock_crc function is only incremented but never read. +This causes 'Unused but set variable' warning on Clang 15.0.1 compiler. + +Removing the variable to prevent the warning. + +Signed-off-by: Miroslav Rezanina +Reviewed-by: Thomas Huth +Message-Id: <02e1560d115c208df32236df8916fed98429fda1.1668009030.git.mrezanin@redhat.com> +Signed-off-by: Thomas Huth +(cherry picked from commit 6083dcad80743718620a3f8a72fb76ea8b7c28ca) +Signed-off-by: zhujun2 +--- + hw/net/tulip.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/hw/net/tulip.c b/hw/net/tulip.c +index d319f9fb80..956093abd7 100644 +--- a/hw/net/tulip.c ++++ b/hw/net/tulip.c +@@ -870,11 +870,10 @@ static const MemoryRegionOps tulip_ops = { + + static void tulip_idblock_crc(TULIPState *s, uint16_t *srom) + { +- int word, n; ++ int word; + int bit; + unsigned char bitval, crc; + const int len = 9; +- n = 0; + crc = -1; + + for (word = 0; word < len; word++) { +@@ -887,7 +886,6 @@ static void tulip_idblock_crc(TULIPState *s, uint16_t *srom) + srom[len - 1] = (srom[len - 1] & 0xff00) | (unsigned short)crc; + break; + } +- n++; + bitval = ((srom[word] >> bit) & 1) ^ ((crc >> 7) & 1); + crc = crc << 1; + if (bitval == 1) { +-- +2.27.0 + diff --git a/virtio-crypto-fix-NULL-pointer-dereference-in-virtio.patch b/virtio-crypto-fix-NULL-pointer-dereference-in-virtio.patch new file mode 100644 index 00000000..c8cf82e7 --- /dev/null +++ b/virtio-crypto-fix-NULL-pointer-dereference-in-virtio.patch @@ -0,0 +1,56 @@ +From 7e0e009f5e5b39fc59aaa082cc092cb6438e5842 Mon Sep 17 00:00:00 2001 +From: zhujun2 +Date: Wed, 10 Apr 2024 23:03:47 -0700 +Subject: [PATCH] virtio-crypto: fix NULL pointer dereference in + virtio_crypto_free_reques + +Ensure op_info is not NULL in case of QCRYPTODEV_BACKEND_ALG_SYM algtype. + +Fixes: 0e660a6f90a ("crypto: Introduce RSA algorithm") +Signed-off-by: Mauro Matteo Cascella +Reported-by: Yiming Tao +Message-Id: <20230509075317.1132301-1-mcascell@redhat.com> +Reviewed-by: Gonglei +Reviewed-by: zhenwei pi +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +(cherry picked from commit 3e69908907f8d3dd20d5753b0777a6e3824ba824) +Signed-off-by: zhujun2 +--- + hw/virtio/virtio-crypto.c | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c +index 61b421aab3..8c2047f4e0 100644 +--- a/hw/virtio/virtio-crypto.c ++++ b/hw/virtio/virtio-crypto.c +@@ -349,15 +349,17 @@ static void virtio_crypto_free_request(VirtIOCryptoReq *req) + size_t max_len; + CryptoDevBackendSymOpInfo *op_info = req->u.sym_op_info; + +- max_len = op_info->iv_len + +- op_info->aad_len + +- op_info->src_len + +- op_info->dst_len + +- op_info->digest_result_len; +- +- /* Zeroize and free request data structure */ +- memset(op_info, 0, sizeof(*op_info) + max_len); +- g_free(op_info); ++ if (op_info) { ++ max_len = op_info->iv_len + ++ op_info->aad_len + ++ op_info->src_len + ++ op_info->dst_len + ++ op_info->digest_result_len; ++ ++ /* Zeroize and free request data structure */ ++ memset(op_info, 0, sizeof(*op_info) + max_len); ++ g_free(op_info); ++ } + } + g_free(req); + } +-- +2.27.0 + diff --git a/virtio-gpu-do-not-byteswap-padding.patch b/virtio-gpu-do-not-byteswap-padding.patch new file mode 100644 index 00000000..fe758c20 --- /dev/null +++ b/virtio-gpu-do-not-byteswap-padding.patch @@ -0,0 +1,41 @@ +From 365d14a81001ac41fd4aa2134b11a23d4a4a0656 Mon Sep 17 00:00:00 2001 +From: Luo Yifan +Date: Thu, 28 Mar 2024 10:38:37 +0800 +Subject: [PATCH] virtio-gpu: do not byteswap padding +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cherry picked from commit a4663f1a5506626175fc64c86e52135587c36872 + +In Linux 5.16, the padding of struct virtio_gpu_ctrl_hdr has become a +single-byte field followed by a uint8_t[3] array of padding bytes, +and virtio_gpu_ctrl_hdr_bswap does not compile anymore. + +Signed-off-by: Paolo Bonzini +Acked-by: Cornelia Huck +Reviewed-by: Alex Bennée +Reviewed-by: Michael S. Tsirkin +Reviewed-by: Philippe Mathieu-Daudé +Message-Id: <20211111110604.207376-2-pbonzini@redhat.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Luo Yifan +--- + include/hw/virtio/virtio-gpu-bswap.h | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/include/hw/virtio/virtio-gpu-bswap.h b/include/hw/virtio/virtio-gpu-bswap.h +index e2bee8f595..5faac0d8d5 100644 +--- a/include/hw/virtio/virtio-gpu-bswap.h ++++ b/include/hw/virtio/virtio-gpu-bswap.h +@@ -24,7 +24,6 @@ virtio_gpu_ctrl_hdr_bswap(struct virtio_gpu_ctrl_hdr *hdr) + le32_to_cpus(&hdr->flags); + le64_to_cpus(&hdr->fence_id); + le32_to_cpus(&hdr->ctx_id); +- le32_to_cpus(&hdr->padding); + } + + static inline void +-- +2.27.0 + diff --git a/virtio-mem-Fix-the-bitmap-index-of-the-section-offse.patch b/virtio-mem-Fix-the-bitmap-index-of-the-section-offse.patch new file mode 100644 index 00000000..7cda05e2 --- /dev/null +++ b/virtio-mem-Fix-the-bitmap-index-of-the-section-offse.patch @@ -0,0 +1,47 @@ +From a1afd7b993903510f946a979ff31ccf21b34006c Mon Sep 17 00:00:00 2001 +From: zhujun2 +Date: Thu, 11 Apr 2024 00:39:56 -0700 +Subject: [PATCH] virtio-mem: Fix the bitmap index of the section offset + +vmem->bitmap indexes the memory region of the virtio-mem backend at a +granularity of block_size. To calculate the index of target section offset, +the block_size should be divided instead of the bitmap_size. + +Fixes: 2044969f0b ("virtio-mem: Implement RamDiscardManager interface") +Signed-off-by: Chenyi Qiang +Message-Id: <20221216062231.11181-1-chenyi.qiang@intel.com> +Reviewed-by: David Hildenbrand +Reviewed-by: Michael S. Tsirkin +Cc: qemu-stable@nongnu.org +Signed-off-by: David Hildenbrand +(cherry picked from commit b11cf32e07a2f7ff0d171b89497381a04c9d07e0) +Signed-off-by: zhujun2 +--- + hw/virtio/virtio-mem.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c +index becac0d93b..4dac2c051b 100644 +--- a/hw/virtio/virtio-mem.c ++++ b/hw/virtio/virtio-mem.c +@@ -205,7 +205,7 @@ static int virtio_mem_for_each_plugged_section(const VirtIOMEM *vmem, + uint64_t offset, size; + int ret = 0; + +- first_bit = s->offset_within_region / vmem->bitmap_size; ++ first_bit = s->offset_within_region / vmem->block_size; + first_bit = find_next_bit(vmem->bitmap, vmem->bitmap_size, first_bit); + while (first_bit < vmem->bitmap_size) { + MemoryRegionSection tmp = *s; +@@ -237,7 +237,7 @@ static int virtio_mem_for_each_unplugged_section(const VirtIOMEM *vmem, + uint64_t offset, size; + int ret = 0; + +- first_bit = s->offset_within_region / vmem->bitmap_size; ++ first_bit = s->offset_within_region / vmem->block_size; + first_bit = find_next_zero_bit(vmem->bitmap, vmem->bitmap_size, first_bit); + while (first_bit < vmem->bitmap_size) { + MemoryRegionSection tmp = *s; +-- +2.27.0 + diff --git a/virtio-mem-Fix-the-iterator-variable-in-a-vmem-rdl_l.patch b/virtio-mem-Fix-the-iterator-variable-in-a-vmem-rdl_l.patch new file mode 100644 index 00000000..c4bb1065 --- /dev/null +++ b/virtio-mem-Fix-the-iterator-variable-in-a-vmem-rdl_l.patch @@ -0,0 +1,39 @@ +From 9fb38321dbddc7e0e8c18c2cde47bc0261bd8058 Mon Sep 17 00:00:00 2001 +From: zhujun2 +Date: Thu, 11 Apr 2024 00:31:44 -0700 +Subject: [PATCH] virtio-mem: Fix the iterator variable in a vmem->rdl_list + loop +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It should be the variable rdl2 to revert the already-notified listeners. + +Fixes: 2044969f0b ("virtio-mem: Implement RamDiscardManager interface") +Signed-off-by: Chenyi Qiang +Message-Id: <20221228090312.17276-1-chenyi.qiang@intel.com> +Cc: qemu-stable@nongnu.org +Reviewed-by: Philippe Mathieu-Daudé +Signed-off-by: David Hildenbrand +(cherry picked from commit 29f1b328e3b767cba2661920a8470738469b9e36) +Signed-off-by: zhujun2 +--- + hw/virtio/virtio-mem.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c +index becac0d93b..ddf7e2ec12 100644 +--- a/hw/virtio/virtio-mem.c ++++ b/hw/virtio/virtio-mem.c +@@ -311,7 +311,7 @@ static int virtio_mem_notify_plug(VirtIOMEM *vmem, uint64_t offset, + if (ret) { + /* Notify all already-notified listeners. */ + QLIST_FOREACH(rdl2, &vmem->rdl_list, next) { +- MemoryRegionSection tmp = *rdl->section; ++ MemoryRegionSection tmp = *rdl2->section; + + if (rdl2 == rdl) { + break; +-- +2.27.0 + -- Gitee