From: Guenter Roeck <linux@roeck-us.net>
To: Gerd Hoffmann <kraxel@redhat.com>
Cc: Alan Stern <stern@rowland.harvard.edu>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
linux-usb@vger.kernel.org, qemu-devel@nongnu.org
Subject: Re: Problems (timeouts) when testing usb-ohci with qemu
Date: Wed, 24 Apr 2024 08:23:36 -0700 [thread overview]
Message-ID: <b815670f-fea4-4ab5-bf67-671c8395bfa6@roeck-us.net> (raw)
In-Reply-To: <edfmff7qm46edap6nz2ppvfhcw4jp6ahjltrv76jsiq5rhz5hw@v2lcbclpdsjt>
On 4/24/24 04:16, Gerd Hoffmann wrote:
>> qemu hack:
>>
>> hw/usb/hcd-ohci.c | 11 +++++++++++
>> hw/usb/hcd-ohci.h | 1 +
>> 2 files changed, 12 insertions(+)
>>
>> diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
>> index fc8fc91a1d..99e52ad13a 100644
>> --- a/hw/usb/hcd-ohci.c
>> +++ b/hw/usb/hcd-ohci.c
>> @@ -267,6 +267,10 @@ static inline void ohci_intr_update(OHCIState *ohci)
>> (ohci->intr_status & ohci->intr))
>> level = 1;
>>
>> + if (level && ohci->level)
>> + qemu_set_irq(ohci->irq, 0);
>> +
>> + ohci->level = level;
>> qemu_set_irq(ohci->irq, level);
>> }
>>
>> diff --git a/hw/usb/hcd-ohci.h b/hw/usb/hcd-ohci.h
>> index e1827227ac..6f82e72bd9 100644
>> --- a/hw/usb/hcd-ohci.h
>> +++ b/hw/usb/hcd-ohci.h
>> @@ -52,6 +52,7 @@ struct OHCIState {
>> uint32_t ctl, status;
>> uint32_t intr_status;
>> uint32_t intr;
>> + int level;
>>
>> /* memory pointer partition */
>> uint32_t hcca;
>
> Phew. Disclaimer: Havn't looked at the ohci emulation code for years.
>
> It should not be needed to store the interrupt level that way. It is
> possible to calculate what the interrupt level should be, based on the
> interrupt status register and the interrupt mask register, and the code
> above seems to do exactly that (the "ohci->intr_status & ohci->intr"
> bit).
>
You are correct. For the purpose of this kludge a simpler
+ qemu_set_irq(ohci->irq, 0);
qemu_set_irq(ohci->irq, level);
would have been sufficient. My original code added tracing,
where this generated a lot of noise. I didn't completely simplify
the kludge. Sorry for that and for any confusion it may have caused.
> ohci_intr_update() must be called if one of these two registers changes,
> i.e. if the guest changes the mask, if the guest acks an IRQ by clearing
> an status bit, if the device raises an IRQ by setting an status bit.
> Might be the ohci emulation has a bug here.
>
> Another possible trouble spot is that the timing behavior is different
> on virtual vs. physical hardware. Specifically with the emulated
> hardware some actions appear to complete instantly (when the vmexit to
> handle the mmio register write returns it's finished already), which
> will never complete that quickly on physical hardware. So drivers can
> have race conditions which only trigger on virtual hardware. The error
> pattern you are describing sounds like this could be the case here.
>
I think the underlying problem is that both the qemu emulation and
the Linux kernel driver expect that the interrupt is level triggered.
It looks like some entity in between handles the interrupts as edge
triggered. This makes the kludge necessary: All it does is to generate
an artificial interrupt edge.
This can be worked around in the Linux interrupt handler by checking
if another interrupt arrived while the original interrupt was handled.
This will ensure that all interrupts are handled and cleared when the
handler exits, and that a later arriving interrupt will generate the
necessary edge and thus another interrupt. That doesn't fix the
edge<->level triggered interrupt confusion (if that is indeed the root
cause of the problem), but it does address its consequences.
If anyone has an idea how to find out where the interrupt confusion
happens, please let me know, and I'll be happy to do some more testing.
I am quite curious myself, and it would make sense to solve the problem
at its root.
Thanks,
Guenter
next prev parent reply other threads:[~2024-04-24 15:24 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-23 17:04 Problems (timeouts) when testing usb-ohci with qemu Guenter Roeck
2024-04-23 17:30 ` Alan Stern
2024-04-23 21:10 ` Guenter Roeck
2024-04-24 2:11 ` Alan Stern
2024-04-24 15:11 ` Guenter Roeck
2024-04-24 11:16 ` Gerd Hoffmann
2024-04-24 15:23 ` Guenter Roeck [this message]
2024-04-24 17:05 ` Guenter Roeck
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=b815670f-fea4-4ab5-bf67-671c8395bfa6@roeck-us.net \
--to=linux@roeck-us.net \
--cc=gregkh@linuxfoundation.org \
--cc=kraxel@redhat.com \
--cc=linux-usb@vger.kernel.org \
--cc=qemu-devel@nongnu.org \
--cc=stern@rowland.harvard.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).