All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/2] hw/usb/hcd-ehci: Fix Coverity CID 1685236 and check DMA errors
@ 2026-08-17  2:36 Jamin Lin
  2026-08-17  2:36 ` [PATCH v2 1/2] hw/usb/hcd-ehci: Handle get_dwords() failures in async writeback Jamin Lin
  2026-08-17  2:36 ` [PATCH v2 2/2] hw/usb/hcd-ehci: Check for DMA errors in get_dwords()/put_dwords() Jamin Lin
  0 siblings, 2 replies; 5+ messages in thread
From: Jamin Lin @ 2026-08-17  2:36 UTC (permalink / raw)
  To: clg@redhat.com, pbonzini@redhat.com, peter.maydell@linaro.org,
	philmd@mailo.com, open list:All patches CC here
  Cc: Jamin Lin, Troy Lee

v1:
 1. Fix Fix Coverity CID 1685236
 
v2:
 1. Drops the dead NULL test and checks the actual accesses instead, and makes put_dwords() return void
    since no caller can act on a failed writeback.

Jamin Lin (2):
  hw/usb/hcd-ehci: Handle get_dwords() failures in async writeback
  hw/usb/hcd-ehci: Check for DMA errors in get_dwords()/put_dwords()

 hw/usb/hcd-ehci.c | 48 +++++++++++++++++++++--------------------------
 1 file changed, 21 insertions(+), 27 deletions(-)

-- 
2.53.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2 1/2] hw/usb/hcd-ehci: Handle get_dwords() failures in async writeback
  2026-08-17  2:36 [PATCH v2 0/2] hw/usb/hcd-ehci: Fix Coverity CID 1685236 and check DMA errors Jamin Lin
@ 2026-08-17  2:36 ` Jamin Lin
  2026-08-17  2:36 ` [PATCH v2 2/2] hw/usb/hcd-ehci: Check for DMA errors in get_dwords()/put_dwords() Jamin Lin
  1 sibling, 0 replies; 5+ messages in thread
From: Jamin Lin @ 2026-08-17  2:36 UTC (permalink / raw)
  To: clg@redhat.com, pbonzini@redhat.com, peter.maydell@linaro.org,
	philmd@mailo.com, open list:All patches CC here
  Cc: Jamin Lin, Troy Lee, Philippe Mathieu-Daudé

Coverity reports that ehci_writeback_async_complete_packet() ignores
the return value of get_dwords() when reading the QH and qTD.

Handle read failures in the same way as QH and qTD verification
failures by freeing the packet and returning early.

Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
Resolves: Coverity CID 1685236
Fixes: 2b3de6ada5d ("ehci: writeback_async_complete_packet: verify qh and qtd")
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
 hw/usb/hcd-ehci.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 451a918e9f..d43951975a 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -533,11 +533,11 @@ static void ehci_writeback_async_complete_packet(EHCIPacket *p)
     /* Verify the qh + qtd, like we do when going through fetchqh & fetchqtd */
     memset(&qh, 0, sizeof(qh));
     memset(&qtd, 0, sizeof(qtd));
-    get_dwords(q->ehci, NLPTR_GET(q->qhaddr),
-               (uint32_t *) &qh, ehci_qh_dwords(q->ehci));
-    get_dwords(q->ehci, NLPTR_GET(q->qtdaddr),
-               (uint32_t *) &qtd, ehci_qtd_dwords(q->ehci));
-    if (!ehci_verify_qh(q, &qh) || !ehci_verify_qtd(p, &qtd)) {
+    if (get_dwords(q->ehci, NLPTR_GET(q->qhaddr),
+                   (uint32_t *) &qh, ehci_qh_dwords(q->ehci)) < 0 ||
+        get_dwords(q->ehci, NLPTR_GET(q->qtdaddr),
+                   (uint32_t *) &qtd, ehci_qtd_dwords(q->ehci)) < 0 ||
+        !ehci_verify_qh(q, &qh) || !ehci_verify_qtd(p, &qtd)) {
         p->async = EHCI_ASYNC_INITIALIZED;
         ehci_free_packet(p);
         return;
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 2/2] hw/usb/hcd-ehci: Check for DMA errors in get_dwords()/put_dwords()
  2026-08-17  2:36 [PATCH v2 0/2] hw/usb/hcd-ehci: Fix Coverity CID 1685236 and check DMA errors Jamin Lin
  2026-08-17  2:36 ` [PATCH v2 1/2] hw/usb/hcd-ehci: Handle get_dwords() failures in async writeback Jamin Lin
@ 2026-08-17  2:36 ` Jamin Lin
  2026-08-17  4:17   ` Philippe Mathieu-Daudé
  1 sibling, 1 reply; 5+ messages in thread
From: Jamin Lin @ 2026-08-17  2:36 UTC (permalink / raw)
  To: clg@redhat.com, pbonzini@redhat.com, peter.maydell@linaro.org,
	philmd@mailo.com, open list:All patches CC here
  Cc: Jamin Lin, Troy Lee

get_dwords() and put_dwords() return -1 when ehci->as is NULL, but that
can no longer happen. The sysbus variants set it in instance_init
(ehci_sysbus_init()), the PCI variant sets it in realize
(usb_ehci_pci_realize()), and usb_ehci_pci_write_config() only switches
between the bus master address space and address_space_memory.

Meanwhile the results of dma_memory_read() and dma_memory_write() are
ignored, so a failed guest memory access is silently treated as success.

Drop the dead NULL test and check the MemTxResult of each access
instead, so that the existing -1 error path reports real DMA errors:
raise USBSTS_HSE, clear USBCMD_RUNSTOP and stop processing the
descriptor, as the NULL path used to do. All 11 get_dwords() callers
already check the return value.

put_dwords() now returns void: none of its four callers (ehci_flush_qh(),
ehci_state_fetchitd() and twice in ehci_state_writeback()) looks at the
status.

Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
 hw/usb/hcd-ehci.c | 38 ++++++++++++++++----------------------
 1 file changed, 16 insertions(+), 22 deletions(-)

diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index d43951975a..daab5783bc 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -421,16 +421,14 @@ static inline int get_dwords(EHCIState *ehci, uint64_t addr,
 {
     int i;
 
-    if (!ehci->as) {
-        ehci_raise_irq(ehci, USBSTS_HSE);
-        ehci->usbcmd &= ~USBCMD_RUNSTOP;
-        trace_usb_ehci_dma_error();
-        return -1;
-    }
-
     for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
-        dma_memory_read(ehci->as, addr, buf, sizeof(*buf),
-                        MEMTXATTRS_UNSPECIFIED);
+        if (dma_memory_read(ehci->as, addr, buf, sizeof(*buf),
+                            MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
+            ehci_raise_irq(ehci, USBSTS_HSE);
+            ehci->usbcmd &= ~USBCMD_RUNSTOP;
+            trace_usb_ehci_dma_error();
+            return -1;
+        }
         *buf = le32_to_cpu(*buf);
     }
 
@@ -438,25 +436,21 @@ static inline int get_dwords(EHCIState *ehci, uint64_t addr,
 }
 
 /* Put an array of dwords in to main memory */
-static inline int put_dwords(EHCIState *ehci, uint64_t addr,
-                             uint32_t *buf, int num)
+static inline void put_dwords(EHCIState *ehci, uint64_t addr,
+                              uint32_t *buf, int num)
 {
     int i;
 
-    if (!ehci->as) {
-        ehci_raise_irq(ehci, USBSTS_HSE);
-        ehci->usbcmd &= ~USBCMD_RUNSTOP;
-        trace_usb_ehci_dma_error();
-        return -1;
-    }
-
     for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
         uint32_t tmp = cpu_to_le32(*buf);
-        dma_memory_write(ehci->as, addr, &tmp, sizeof(tmp),
-                         MEMTXATTRS_UNSPECIFIED);
+        if (dma_memory_write(ehci->as, addr, &tmp, sizeof(tmp),
+                             MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
+            ehci_raise_irq(ehci, USBSTS_HSE);
+            ehci->usbcmd &= ~USBCMD_RUNSTOP;
+            trace_usb_ehci_dma_error();
+            return;
+        }
     }
-
-    return num;
 }
 
 static int ehci_get_pid(EHCIqtd *qtd)
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 2/2] hw/usb/hcd-ehci: Check for DMA errors in get_dwords()/put_dwords()
  2026-08-17  2:36 ` [PATCH v2 2/2] hw/usb/hcd-ehci: Check for DMA errors in get_dwords()/put_dwords() Jamin Lin
@ 2026-08-17  4:17   ` Philippe Mathieu-Daudé
  2026-08-17  5:13     ` Jamin Lin
  0 siblings, 1 reply; 5+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-17  4:17 UTC (permalink / raw)
  To: Jamin Lin, clg@redhat.com, pbonzini@redhat.com,
	peter.maydell@linaro.org, philmd@mailo.com,
	open list:All patches CC here
  Cc: Troy Lee

On 17/8/26 04:36, Jamin Lin wrote:
> get_dwords() and put_dwords() return -1 when ehci->as is NULL, but that
> can no longer happen. The sysbus variants set it in instance_init
> (ehci_sysbus_init()), the PCI variant sets it in realize
> (usb_ehci_pci_realize()), and usb_ehci_pci_write_config() only switches
> between the bus master address space and address_space_memory.
> 
> Meanwhile the results of dma_memory_read() and dma_memory_write() are
> ignored, so a failed guest memory access is silently treated as success.
> 
> Drop the dead NULL test and check the MemTxResult of each access
> instead, so that the existing -1 error path reports real DMA errors:
> raise USBSTS_HSE, clear USBCMD_RUNSTOP and stop processing the
> descriptor, as the NULL path used to do. All 11 get_dwords() callers
> already check the return value.
> 
> put_dwords() now returns void: none of its four callers (ehci_flush_qh(),
> ehci_state_fetchitd() and twice in ehci_state_writeback()) looks at the
> status.
> 

Suggested-by: Peter Maydell <peter.maydell@linaro.org>

> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> ---
>   hw/usb/hcd-ehci.c | 38 ++++++++++++++++----------------------
>   1 file changed, 16 insertions(+), 22 deletions(-)
> 
> diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
> index d43951975a..daab5783bc 100644
> --- a/hw/usb/hcd-ehci.c
> +++ b/hw/usb/hcd-ehci.c
> @@ -421,16 +421,14 @@ static inline int get_dwords(EHCIState *ehci, uint64_t addr,
>   {
>       int i;
>   
> -    if (!ehci->as) {
> -        ehci_raise_irq(ehci, USBSTS_HSE);
> -        ehci->usbcmd &= ~USBCMD_RUNSTOP;
> -        trace_usb_ehci_dma_error();
> -        return -1;
> -    }
> -
>       for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
> -        dma_memory_read(ehci->as, addr, buf, sizeof(*buf),
> -                        MEMTXATTRS_UNSPECIFIED);
> +        if (dma_memory_read(ehci->as, addr, buf, sizeof(*buf),
> +                            MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
> +            ehci_raise_irq(ehci, USBSTS_HSE);
> +            ehci->usbcmd &= ~USBCMD_RUNSTOP;
> +            trace_usb_ehci_dma_error();
> +            return -1;
> +        }
>           *buf = le32_to_cpu(*buf);
>       }

Maybe reorder before previous patch?

Note, for EHCI get_dwords() is only used as returning a boolean,
which would match with your conversion of put_dwords to void. While
the change involves some code churn, the result would be clearer
IMHO. Anyway can be done later.

Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>



^ permalink raw reply	[flat|nested] 5+ messages in thread

* RE: [PATCH v2 2/2] hw/usb/hcd-ehci: Check for DMA errors in get_dwords()/put_dwords()
  2026-08-17  4:17   ` Philippe Mathieu-Daudé
@ 2026-08-17  5:13     ` Jamin Lin
  0 siblings, 0 replies; 5+ messages in thread
From: Jamin Lin @ 2026-08-17  5:13 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, clg@redhat.com, pbonzini@redhat.com,
	peter.maydell@linaro.org, philmd@mailo.com,
	open list:All patches CC here
  Cc: Troy Lee

Hi Philippe

> Subject: Re: [PATCH v2 2/2] hw/usb/hcd-ehci: Check for DMA errors in
> get_dwords()/put_dwords()
> 
> On 17/8/26 04:36, Jamin Lin wrote:
> > get_dwords() and put_dwords() return -1 when ehci->as is NULL, but
> > that can no longer happen. The sysbus variants set it in instance_init
> > (ehci_sysbus_init()), the PCI variant sets it in realize
> > (usb_ehci_pci_realize()), and usb_ehci_pci_write_config() only
> > switches between the bus master address space and
> address_space_memory.
> >
> > Meanwhile the results of dma_memory_read() and dma_memory_write()
> are
> > ignored, so a failed guest memory access is silently treated as success.
> >
> > Drop the dead NULL test and check the MemTxResult of each access
> > instead, so that the existing -1 error path reports real DMA errors:
> > raise USBSTS_HSE, clear USBCMD_RUNSTOP and stop processing the
> > descriptor, as the NULL path used to do. All 11 get_dwords() callers
> > already check the return value.
> >
> > put_dwords() now returns void: none of its four callers
> > (ehci_flush_qh(),
> > ehci_state_fetchitd() and twice in ehci_state_writeback()) looks at
> > the status.
> >
> 
> Suggested-by: Peter Maydell <peter.maydell@linaro.org>
> 
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> > ---
> >   hw/usb/hcd-ehci.c | 38 ++++++++++++++++----------------------
> >   1 file changed, 16 insertions(+), 22 deletions(-)
> >
> > diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c index
> > d43951975a..daab5783bc 100644
> > --- a/hw/usb/hcd-ehci.c
> > +++ b/hw/usb/hcd-ehci.c
> > @@ -421,16 +421,14 @@ static inline int get_dwords(EHCIState *ehci,
> uint64_t addr,
> >   {
> >       int i;
> >
> > -    if (!ehci->as) {
> > -        ehci_raise_irq(ehci, USBSTS_HSE);
> > -        ehci->usbcmd &= ~USBCMD_RUNSTOP;
> > -        trace_usb_ehci_dma_error();
> > -        return -1;
> > -    }
> > -
> >       for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
> > -        dma_memory_read(ehci->as, addr, buf, sizeof(*buf),
> > -                        MEMTXATTRS_UNSPECIFIED);
> > +        if (dma_memory_read(ehci->as, addr, buf, sizeof(*buf),
> > +                            MEMTXATTRS_UNSPECIFIED) !=
> MEMTX_OK) {
> > +            ehci_raise_irq(ehci, USBSTS_HSE);
> > +            ehci->usbcmd &= ~USBCMD_RUNSTOP;
> > +            trace_usb_ehci_dma_error();
> > +            return -1;
> > +        }
> >           *buf = le32_to_cpu(*buf);
> >       }
> 
> Maybe reorder before previous patch?
> 
Will resend v3.

> Note, for EHCI get_dwords() is only used as returning a boolean, which would
> match with your conversion of put_dwords to void. While the change involves
> some code churn, the result would be clearer IMHO. Anyway can be done later.
> 
Will add new patch in v3 and change get_dwords return type to a boolean.
Thanks,
Jamin

> Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-08-17  5:14 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-17  2:36 [PATCH v2 0/2] hw/usb/hcd-ehci: Fix Coverity CID 1685236 and check DMA errors Jamin Lin
2026-08-17  2:36 ` [PATCH v2 1/2] hw/usb/hcd-ehci: Handle get_dwords() failures in async writeback Jamin Lin
2026-08-17  2:36 ` [PATCH v2 2/2] hw/usb/hcd-ehci: Check for DMA errors in get_dwords()/put_dwords() Jamin Lin
2026-08-17  4:17   ` Philippe Mathieu-Daudé
2026-08-17  5:13     ` Jamin Lin

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.