xhci HCIVERSION register read emulation incorrectly handled

Bug #1693050 reported by Robert Mustacchi
16
This bug affects 2 people
Affects Status Importance Assigned to Milestone
QEMU
Expired
Undecided
Unassigned

Bug Description

We had an illumos user trying to run illumos in QEMU 2.9.0 with the qemu-xhci device enabled. Note, that while this was discovered against QEMU 2.9.0, from my current read of the HEAD, it is still present. The illumos bug at https://www.illumos.org/issues/8173 has additional information on how the user invoked qemu. While investigating the problem we found that the illumos driver was reading a version of 0x0000 when reading the HCIVERSION register from qemu.

In the illumos driver we're performing a 16-bit read of the version register at offset 0x2. From looking around at other OSes, while Linux performs a 4 byte read at offset 0x0 and masks out the version, others that care about the version are doing a two byte read, though not all actually act on the version and some just discard the information.

The user who hit this was able to enable tracing (note the tracing file is attached to the illumos bug linked previously) and we hit the unimplemented register read with offset 0x2 at http://git.qemu.org/?p=qemu.git;a=blob;f=hw/usb/hcd-xhci.c;hb=HEAD#l2960. The xhci register specifies today that its allowed for users to do 1-4 byte reads; however, that it implements only four byte reads in its implementation (http://git.qemu.org/?p=qemu.git;a=blob;f=hw/usb/hcd-xhci.c;hb=HEAD#l3333). Hence why when we read the HCIVERSION register at offset 0x2, it isn't handled in xhci_cap_read() which then returns zeros.

From digging into this, I think that we're coming into memory_region_dispatch_read() and then memory_region_dispatch_read1(). However, I don't see anything in either the general memory region logic or in the xhci_cap_read() function that would deal with adjusting the offset that we're reading at and then masking it off again. While the access_with_adjusted_size() attempts to deal with this, it never adjusts the hardware address that's passed in to be a multiple of the implementation defined offset that I can see. I suspect that the FIXME at line 582 (http://git.qemu.org/?p=qemu.git;a=blob;f=memory.c;hb=HEAD#l582) and the implementation in the xhci code is the crux of the problem.

For the time being we're working around this in the illumos driver, but I wanted to point this out such that it might be helpful for other systems which are assuming that they can do the two byte read like on hardware.

Revision history for this message
Paul Menzel (paulmenzel) wrote :

According to [1], this is still an issue today.

[1]: https://review.coreboot.org/c/coreboot/+/39838/

Revision history for this message
Philippe Mathieu-Daudé (philmd) wrote :

Odd, this should be fixed by commit 6ee021d41 and 36960b4d66..98f52cdbb5c.

Revision history for this message
Paul Menzel (paulmenzel) wrote :

According to Duncan, it’s not, and the paragraph from the original issue still applies.

> The xhci register specifies today that its allowed for users to do 1-4 byte reads; however, that
> it implements only four byte reads in its implementation
> (https://git.qemu.org/?p=qemu.git;a=blob;f=hw/usb/hcd-xhci.c;hb=HEAD#l3333). Hence why when we
> read the HCIVERSION register at offset 0x2, it isn't handled in xhci_cap_read() which then
> returns zeros.

Revision history for this message
Thomas Huth (th-huth) wrote : Moved bug report

This is an automated cleanup. This bug report has been moved to QEMU's
new bug tracker on gitlab.com and thus gets marked as 'expired' now.
Please continue with the discussion here:

 https://gitlab.com/qemu-project/qemu/-/issues/143

Changed in qemu:
status: New → Expired
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.