* [pve-devel] [PATCH qemu] fix #2874: SATA: avoid unsolicited write to sector 0 during reset
@ 2023-08-24 13:51 Fiona Ebner
2023-09-25 9:16 ` Fiona Ebner
2023-09-26 9:33 ` [pve-devel] applied: " Thomas Lamprecht
0 siblings, 2 replies; 3+ messages in thread
From: Fiona Ebner @ 2023-08-24 13:51 UTC (permalink / raw)
To: pve-devel
If there is a pending DMA operation during ide_bus_reset(), the fact
that the IDEstate is already reset before the operation is canceled
can be problematic. In particular, ide_dma_cb() might be called and
then use the reset IDEstate which contains the signature after the
reset. When used to construct the IO operation this leads to
ide_get_sector() returning 0 and nsector being 1. This is particularly
bad, because a write command will thus destroy the first sector which
often contains a partition table or similar.
Upstream discussion:
https://lists.nongnu.org/archive/html/qemu-devel/2023-08/msg04239.html
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
...cel-async-DMA-operation-before-reset.patch | 100 ++++++++++++++++++
debian/patches/series | 1 +
2 files changed, 101 insertions(+)
create mode 100644 debian/patches/extra/0012-hw-ide-reset-cancel-async-DMA-operation-before-reset.patch
diff --git a/debian/patches/extra/0012-hw-ide-reset-cancel-async-DMA-operation-before-reset.patch b/debian/patches/extra/0012-hw-ide-reset-cancel-async-DMA-operation-before-reset.patch
new file mode 100644
index 0000000..d11ae00
--- /dev/null
+++ b/debian/patches/extra/0012-hw-ide-reset-cancel-async-DMA-operation-before-reset.patch
@@ -0,0 +1,100 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Fiona Ebner <f.ebner@proxmox.com>
+Date: Thu, 24 Aug 2023 11:22:21 +0200
+Subject: [PATCH] hw/ide: reset: cancel async DMA operation before reseting
+ state
+
+If there is a pending DMA operation during ide_bus_reset(), the fact
+that the IDEstate is already reset before the operation is canceled
+can be problematic. In particular, ide_dma_cb() might be called and
+then use the reset IDEstate which contains the signature after the
+reset. When used to construct the IO operation this leads to
+ide_get_sector() returning 0 and nsector being 1. This is particularly
+bad, because a write command will thus destroy the first sector which
+often contains a partition table or similar.
+
+Traces showing the unsolicited write happening with IDEstate
+0x5595af6949d0 being used after reset:
+
+> ahci_port_write ahci(0x5595af6923f0)[0]: port write [reg:PxSCTL] @ 0x2c: 0x00000300
+> ahci_reset_port ahci(0x5595af6923f0)[0]: reset port
+> ide_reset IDEstate 0x5595af6949d0
+> ide_reset IDEstate 0x5595af694da8
+> ide_bus_reset_aio aio_cancel
+> dma_aio_cancel dbs=0x7f64600089a0
+> dma_blk_cb dbs=0x7f64600089a0 ret=0
+> dma_complete dbs=0x7f64600089a0 ret=0 cb=0x5595acd40b30
+> ahci_populate_sglist ahci(0x5595af6923f0)[0]
+> ahci_dma_prepare_buf ahci(0x5595af6923f0)[0]: prepare buf limit=512 prepared=512
+> ide_dma_cb IDEState 0x5595af6949d0; sector_num=0 n=1 cmd=DMA WRITE
+> dma_blk_io dbs=0x7f6420802010 bs=0x5595ae2c6c30 offset=0 to_dev=1
+> dma_blk_cb dbs=0x7f6420802010 ret=0
+
+> (gdb) p *qiov
+> $11 = {iov = 0x7f647c76d840, niov = 1, {{nalloc = 1, local_iov = {iov_base = 0x0,
+> iov_len = 512}}, {__pad = "\001\000\000\000\000\000\000\000\000\000\000",
+> size = 512}}}
+> (gdb) bt
+> #0 blk_aio_pwritev (blk=0x5595ae2c6c30, offset=0, qiov=0x7f6420802070, flags=0,
+> cb=0x5595ace6f0b0 <dma_blk_cb>, opaque=0x7f6420802010)
+> at ../block/block-backend.c:1682
+> #1 0x00005595ace6f185 in dma_blk_cb (opaque=0x7f6420802010, ret=<optimized out>)
+> at ../softmmu/dma-helpers.c:179
+> #2 0x00005595ace6f778 in dma_blk_io (ctx=0x5595ae0609f0,
+> sg=sg@entry=0x5595af694d00, offset=offset@entry=0, align=align@entry=512,
+> io_func=io_func@entry=0x5595ace6ee30 <dma_blk_write_io_func>,
+> io_func_opaque=io_func_opaque@entry=0x5595ae2c6c30,
+> cb=0x5595acd40b30 <ide_dma_cb>, opaque=0x5595af6949d0,
+> dir=DMA_DIRECTION_TO_DEVICE) at ../softmmu/dma-helpers.c:244
+> #3 0x00005595ace6f90a in dma_blk_write (blk=0x5595ae2c6c30,
+> sg=sg@entry=0x5595af694d00, offset=offset@entry=0, align=align@entry=512,
+> cb=cb@entry=0x5595acd40b30 <ide_dma_cb>, opaque=opaque@entry=0x5595af6949d0)
+> at ../softmmu/dma-helpers.c:280
+> #4 0x00005595acd40e18 in ide_dma_cb (opaque=0x5595af6949d0, ret=<optimized out>)
+> at ../hw/ide/core.c:953
+> #5 0x00005595ace6f319 in dma_complete (ret=0, dbs=0x7f64600089a0)
+> at ../softmmu/dma-helpers.c:107
+> #6 dma_blk_cb (opaque=0x7f64600089a0, ret=0) at ../softmmu/dma-helpers.c:127
+> #7 0x00005595ad12227d in blk_aio_complete (acb=0x7f6460005b10)
+> at ../block/block-backend.c:1527
+> #8 blk_aio_complete (acb=0x7f6460005b10) at ../block/block-backend.c:1524
+> #9 blk_aio_write_entry (opaque=0x7f6460005b10) at ../block/block-backend.c:1594
+> #10 0x00005595ad258cfb in coroutine_trampoline (i0=<optimized out>,
+> i1=<optimized out>) at ../util/coroutine-ucontext.c:177
+
+Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
+---
+ hw/ide/core.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/hw/ide/core.c b/hw/ide/core.c
+index 08e1f0c3d7..148fccdef2 100644
+--- a/hw/ide/core.c
++++ b/hw/ide/core.c
+@@ -2513,19 +2513,19 @@ static void ide_dummy_transfer_stop(IDEState *s)
+
+ void ide_bus_reset(IDEBus *bus)
+ {
+- bus->unit = 0;
+- bus->cmd = 0;
+- ide_reset(&bus->ifs[0]);
+- ide_reset(&bus->ifs[1]);
+- ide_clear_hob(bus);
+-
+- /* pending async DMA */
++ /* pending async DMA - needs the IDEState before it is reset */
+ if (bus->dma->aiocb) {
+ trace_ide_bus_reset_aio();
+ blk_aio_cancel(bus->dma->aiocb);
+ bus->dma->aiocb = NULL;
+ }
+
++ bus->unit = 0;
++ bus->cmd = 0;
++ ide_reset(&bus->ifs[0]);
++ ide_reset(&bus->ifs[1]);
++ ide_clear_hob(bus);
++
+ /* reset dma provider too */
+ if (bus->dma->ops->reset) {
+ bus->dma->ops->reset(bus->dma);
diff --git a/debian/patches/series b/debian/patches/series
index 74578f6..996fa1f 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -9,6 +9,7 @@ extra/0008-raven-disable-reentrancy-detection-for-iomem.patch
extra/0009-apic-disable-reentrancy-detection-for-apic-msi.patch
extra/0010-migration-block-dirty-bitmap-fix-loading-bitmap-when.patch
extra/0011-vhost-fix-the-fd-leak.patch
+extra/0012-hw-ide-reset-cancel-async-DMA-operation-before-reset.patch
bitmap-mirror/0001-drive-mirror-add-support-for-sync-bitmap-mode-never.patch
bitmap-mirror/0002-drive-mirror-add-support-for-conditional-and-always-.patch
bitmap-mirror/0003-mirror-add-check-for-bitmap-mode-without-bitmap.patch
--
2.39.2
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [pve-devel] [PATCH qemu] fix #2874: SATA: avoid unsolicited write to sector 0 during reset
2023-08-24 13:51 [pve-devel] [PATCH qemu] fix #2874: SATA: avoid unsolicited write to sector 0 during reset Fiona Ebner
@ 2023-09-25 9:16 ` Fiona Ebner
2023-09-26 9:33 ` [pve-devel] applied: " Thomas Lamprecht
1 sibling, 0 replies; 3+ messages in thread
From: Fiona Ebner @ 2023-09-25 9:16 UTC (permalink / raw)
To: pve-devel
Am 24.08.23 um 15:51 schrieb Fiona Ebner:
> If there is a pending DMA operation during ide_bus_reset(), the fact
> that the IDEstate is already reset before the operation is canceled
> can be problematic. In particular, ide_dma_cb() might be called and
> then use the reset IDEstate which contains the signature after the
> reset. When used to construct the IO operation this leads to
> ide_get_sector() returning 0 and nsector being 1. This is particularly
> bad, because a write command will thus destroy the first sector which
> often contains a partition table or similar.
>
> Upstream discussion:
> https://lists.nongnu.org/archive/html/qemu-devel/2023-08/msg04239.html
>
> Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Ping
^ permalink raw reply [flat|nested] 3+ messages in thread
* [pve-devel] applied: [PATCH qemu] fix #2874: SATA: avoid unsolicited write to sector 0 during reset
2023-08-24 13:51 [pve-devel] [PATCH qemu] fix #2874: SATA: avoid unsolicited write to sector 0 during reset Fiona Ebner
2023-09-25 9:16 ` Fiona Ebner
@ 2023-09-26 9:33 ` Thomas Lamprecht
1 sibling, 0 replies; 3+ messages in thread
From: Thomas Lamprecht @ 2023-09-26 9:33 UTC (permalink / raw)
To: Proxmox VE development discussion, Fiona Ebner
Am 24/08/2023 um 15:51 schrieb Fiona Ebner:
> If there is a pending DMA operation during ide_bus_reset(), the fact
> that the IDEstate is already reset before the operation is canceled
> can be problematic. In particular, ide_dma_cb() might be called and
> then use the reset IDEstate which contains the signature after the
> reset. When used to construct the IO operation this leads to
> ide_get_sector() returning 0 and nsector being 1. This is particularly
> bad, because a write command will thus destroy the first sector which
> often contains a partition table or similar.
>
> Upstream discussion:
> https://lists.nongnu.org/archive/html/qemu-devel/2023-08/msg04239.html
>
> Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
> ---
> ...cel-async-DMA-operation-before-reset.patch | 100 ++++++++++++++++++
> debian/patches/series | 1 +
> 2 files changed, 101 insertions(+)
> create mode 100644 debian/patches/extra/0012-hw-ide-reset-cancel-async-DMA-operation-before-reset.patch
>
>
applied, thanks!
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2023-09-26 9:34 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-24 13:51 [pve-devel] [PATCH qemu] fix #2874: SATA: avoid unsolicited write to sector 0 during reset Fiona Ebner
2023-09-25 9:16 ` Fiona Ebner
2023-09-26 9:33 ` [pve-devel] applied: " Thomas Lamprecht
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal