QEMU-Devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1] hw/usb/hcd-ehci: Handle get_dwords() failures in async writeback
@ 2026-08-13  7:23 Jamin Lin
  2026-08-13  9:43 ` Philippe Mathieu-Daudé
  2026-08-14  9:06 ` Peter Maydell
  0 siblings, 2 replies; 6+ messages in thread
From: Jamin Lin @ 2026-08-13  7:23 UTC (permalink / raw)
  To: clg@redhat.com, Philippe Mathieu-Daudé, Paolo Bonzini,
	open list:All patches CC here
  Cc: Jamin Lin, Troy Lee

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>
---
 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.43.0


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

* Re: [PATCH v1] hw/usb/hcd-ehci: Handle get_dwords() failures in async writeback
  2026-08-13  7:23 [PATCH v1] hw/usb/hcd-ehci: Handle get_dwords() failures in async writeback Jamin Lin
@ 2026-08-13  9:43 ` Philippe Mathieu-Daudé
  2026-08-14  0:47   ` Jamin Lin
  2026-08-14  9:06 ` Peter Maydell
  1 sibling, 1 reply; 6+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-13  9:43 UTC (permalink / raw)
  To: Jamin Lin, clg@redhat.com, Philippe Mathieu-Daudé,
	Paolo Bonzini, open list:All patches CC here
  Cc: Troy Lee

On 13/8/26 09:23, Jamin Lin wrote:
> 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>
> ---
>   hw/usb/hcd-ehci.c | 10 +++++-----
>   1 file changed, 5 insertions(+), 5 deletions(-)

Fixes: 2b3de6ada5d ("ehci: writeback_async_complete_packet: verify qh 
and qtd")
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>



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

* RE: [PATCH v1] hw/usb/hcd-ehci: Handle get_dwords() failures in async writeback
  2026-08-13  9:43 ` Philippe Mathieu-Daudé
@ 2026-08-14  0:47   ` Jamin Lin
  0 siblings, 0 replies; 6+ messages in thread
From: Jamin Lin @ 2026-08-14  0:47 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, clg@redhat.com,
	Philippe Mathieu-Daudé, Paolo Bonzini,
	open list:All patches CC here, clg@kaod.org
  Cc: Troy Lee

+ Cédric Le Goater <clg@kaod.org>

> -----Original Message-----
> From: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
> Sent: Thursday, August 13, 2026 5:43 PM
> To: Jamin Lin <jamin_lin@aspeedtech.com>; clg@redhat.com; Philippe
> Mathieu-Daudé <philmd@mailo.com>; Paolo Bonzini <pbonzini@redhat.com>;
> open list:All patches CC here <qemu-devel@nongnu.org>
> Cc: Troy Lee <troy_lee@aspeedtech.com>
> Subject: Re: [PATCH v1] hw/usb/hcd-ehci: Handle get_dwords() failures in async
> writeback
> 
> On 13/8/26 09:23, Jamin Lin wrote:
> > 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>
> > ---
> >   hw/usb/hcd-ehci.c | 10 +++++-----
> >   1 file changed, 5 insertions(+), 5 deletions(-)
> 
> Fixes: 2b3de6ada5d ("ehci: writeback_async_complete_packet: verify qh and
> qtd")
> Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>

Thanks for adding the Fixes tag.
I’ve also added the Resolves tag.

Resolves: Coverity CID 1685236

Jamin

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

* Re: [PATCH v1] hw/usb/hcd-ehci: Handle get_dwords() failures in async writeback
  2026-08-13  7:23 [PATCH v1] hw/usb/hcd-ehci: Handle get_dwords() failures in async writeback Jamin Lin
  2026-08-13  9:43 ` Philippe Mathieu-Daudé
@ 2026-08-14  9:06 ` Peter Maydell
  2026-08-17  2:43   ` Jamin Lin
  2026-08-17  4:08   ` Philippe Mathieu-Daudé
  1 sibling, 2 replies; 6+ messages in thread
From: Peter Maydell @ 2026-08-14  9:06 UTC (permalink / raw)
  To: Jamin Lin
  Cc: clg@redhat.com, Philippe Mathieu-Daudé, Paolo Bonzini,
	open list:All patches CC here, Troy Lee

On Thu, 13 Aug 2026 at 08:24, Jamin Lin <jamin_lin@aspeedtech.com> wrote:
>
> 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>
> ---
>  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;

Looking at the coverity report, my question is whether echi->as
can ever actually be NULL. This is the address space we use to
do DMA, so it feels like every EHCI device must set that up
somehow. ehci_sysbus_init() does. So does usb_ehci_pci_realize().
usb_ehci_pci_write_config() can change it, but never to NULL.

If echi->as is always non-NULL then we could change get_dwords()
and put_dwords() to return "void".

Alternatively, maybe get_dwords() and put_dwords() should be
checking the return value from dma_memory_write() and
dma_memory_read() so that they fail if the DMA fails...

-- PMM


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

* RE: [PATCH v1] hw/usb/hcd-ehci: Handle get_dwords() failures in async writeback
  2026-08-14  9:06 ` Peter Maydell
@ 2026-08-17  2:43   ` Jamin Lin
  2026-08-17  4:08   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 6+ messages in thread
From: Jamin Lin @ 2026-08-17  2:43 UTC (permalink / raw)
  To: Peter Maydell
  Cc: clg@redhat.com, Philippe Mathieu-Daudé, Paolo Bonzini,
	open list:All patches CC here, Troy Lee

Hi Peter,

> > 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;
> 
> Looking at the coverity report, my question is whether echi->as can ever
> actually be NULL. This is the address space we use to do DMA, so it feels like
> every EHCI device must set that up somehow. ehci_sysbus_init() does. So does
> usb_ehci_pci_realize().
> usb_ehci_pci_write_config() can change it, but never to NULL.
> 
> If echi->as is always non-NULL then we could change get_dwords() and
> put_dwords() to return "void".
> 
> Alternatively, maybe get_dwords() and put_dwords() should be checking the
> return value from dma_memory_write() and
> dma_memory_read() so that they fail if the DMA fails...
> 

Thanks for the review and the suggestion.

I have sent a v2 that drops the dead NULL check, checks the MemTxResult
of dma_memory_read()/dma_memory_write() instead, and makes put_dwords()
return void since no caller can act on a failed writeback.

https://patchwork.kernel.org/project/qemu-devel/list/?series=1146899 

Thanks,
Jamin

> -- PMM

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

* Re: [PATCH v1] hw/usb/hcd-ehci: Handle get_dwords() failures in async writeback
  2026-08-14  9:06 ` Peter Maydell
  2026-08-17  2:43   ` Jamin Lin
@ 2026-08-17  4:08   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 6+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-17  4:08 UTC (permalink / raw)
  To: Peter Maydell, Jamin Lin
  Cc: clg@redhat.com, Philippe Mathieu-Daudé, Paolo Bonzini,
	open list:All patches CC here, Troy Lee, Richard Henderson

On 14/8/26 11:06, Peter Maydell wrote:
> On Thu, 13 Aug 2026 at 08:24, Jamin Lin <jamin_lin@aspeedtech.com> wrote:
>>
>> 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>
>> ---
>>   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;
> 
> Looking at the coverity report, my question is whether echi->as
> can ever actually be NULL. This is the address space we use to
> do DMA, so it feels like every EHCI device must set that up
> somehow. ehci_sysbus_init() does. So does usb_ehci_pci_realize().
> usb_ehci_pci_write_config() can change it, but never to NULL.
> 
> If echi->as is always non-NULL then we could change get_dwords()
> and put_dwords() to return "void".
> 
> Alternatively, maybe get_dwords() and put_dwords() should be
> checking the return value from dma_memory_write() and
> dma_memory_read() so that they fail if the DMA fails...

Oh good point, I missed that. We really should qualify
dma_memory_write() & co with G_GNUC_WARN_UNUSED_RESULT, that'd
help us preventing such mistakes.



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

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

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-13  7:23 [PATCH v1] hw/usb/hcd-ehci: Handle get_dwords() failures in async writeback Jamin Lin
2026-08-13  9:43 ` Philippe Mathieu-Daudé
2026-08-14  0:47   ` Jamin Lin
2026-08-14  9:06 ` Peter Maydell
2026-08-17  2:43   ` Jamin Lin
2026-08-17  4:08   ` Philippe Mathieu-Daudé

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox