qemu/hw/usb
David Hubbard 53aaa88105 hw/usb/hcd-ohci: Fix ohci_service_td: accept zero-length TDs where CBP=BE+1
This changes the way the ohci emulation handles a Transfer Descriptor
with "Buffer End" set to "Current Buffer Pointer" - 1, specifically
in the case of a zero-length packet.

The OHCI spec 4.3.1.2 Table 4-2 specifies td.cbp to be zero for a
zero-length packet.  Peter Maydell tracked down commit 1328fe0c32
(hw: usb: hcd-ohci: check len and frame_number variables) where qemu
started checking this according to the spec.

What this patch does is loosen the qemu ohci implementation to allow a
zero-length packet if td.be (Buffer End) is set to td.cbp - 1, and with a
non-zero td.cbp value.

The spec is unclear whether this is valid or not -- it is not the
clearly documented way to send a zero length TD (which is CBP=BE=0),
but it isn't specifically forbidden. Actual hw seems to be ok with it.

Does any OS rely on this behavior? There have been no reports to
qemu-devel of this problem.

This is attempting to have qemu behave like actual hardware,
but this is just a minor change.

With a tiny OS[1] that boots and executes a test, the issue can be seen:

* OS that sends USB requests to a USB mass storage device
  but sends td.cbp = td.be + 1
* qemu 4.2
* qemu HEAD (4e66a0854)
* Actual OHCI controller (hardware)

Command line:
qemu-system-x86_64 -m 20 \
 -device pci-ohci,id=ohci \
 -drive if=none,format=raw,id=d,file=testmbr.raw \
 -device usb-storage,bus=ohci.0,drive=d \
 --trace "usb_*" --trace "ohci_*" -D qemu.log

Results are:

 qemu 4.2   | qemu HEAD  | actual HW
 -----------+------------+-----------
 works fine | ohci_die() | works fine

Tip: if the flags "-serial pty -serial stdio" are added to the command line
the test will output USB requests like this:

Testing qemu HEAD:

> Free mem 2M ohci port2 conn FS
> setup { 80 6 0 1 0 0 8 0 }
> ED info=80000 { mps=8 en=0 d=0 } tail=c20920
>   td0 c20880 nxt=c20960 f2000000 setup cbp=c20900 be=c20907
>   td1 c20960 nxt=c20980 f3140000    in cbp=c20908 be=c2090f
>   td2 c20980 nxt=c20920 f3080000   out cbp=c20910 be=c2090f ohci20 host err
> usb stopped

And in qemu.log:

usb_ohci_iso_td_bad_cc_overrun ISO_TD start_offset=0x00c20910 > next_offset=0x00c2090f

Testing qemu 4.2:

> Free mem 2M ohci port2 conn FS
> setup { 80 6 0 1 0 0 8 0 }
> ED info=80000 { mps=8 en=0 d=0 } tail=620920
>   td0 620880 nxt=620960 f2000000 setup cbp=620900 be=620907       cbp=0 be=620907
>   td1 620960 nxt=620980 f3140000    in cbp=620908 be=62090f       cbp=0 be=62090f
>   td2 620980 nxt=620920 f3080000   out cbp=620910 be=62090f       cbp=0 be=62090f
>    rx { 12 1 0 2 0 0 0 8 }
> setup { 0 5 1 0 0 0 0 0 } tx {}
> ED info=80000 { mps=8 en=0 d=0 } tail=620880
>   td0 620920 nxt=620960 f2000000 setup cbp=620900 be=620907       cbp=0 be=620907
>   td1 620960 nxt=620880 f3100000    in cbp=620908 be=620907       cbp=0 be=620907
> setup { 80 6 0 1 0 0 12 0 }
> ED info=80001 { mps=8 en=0 d=1 } tail=620960
>   td0 620880 nxt=6209c0 f2000000 setup cbp=620920 be=620927       cbp=0 be=620927
>   td1 6209c0 nxt=6209e0 f3140000    in cbp=620928 be=620939       cbp=0 be=620939
>   td2 6209e0 nxt=620960 f3080000   out cbp=62093a be=620939       cbp=0 be=620939
>    rx { 12 1 0 2 0 0 0 8 f4 46 1 0 0 0 1 2 3 1 }
> setup { 80 6 0 2 0 0 0 1 }
> ED info=80001 { mps=8 en=0 d=1 } tail=620880
>   td0 620960 nxt=6209a0 f2000000 setup cbp=620a20 be=620a27       cbp=0 be=620a27
>   td1 6209a0 nxt=6209c0 f3140004    in cbp=620a28 be=620b27       cbp=620a48 be=620b27
>   td2 6209c0 nxt=620880 f3080000   out cbp=620b28 be=620b27       cbp=0 be=620b27
>    rx { 9 2 20 0 1 1 4 c0 0 9 4 0 0 2 8 6 50 0 7 5 81 2 40 0 0 7 5 2 2 40 0 0 }
> setup { 0 9 1 0 0 0 0 0 } tx {}
> ED info=80001 { mps=8 en=0 d=1 } tail=620900
>   td0 620880 nxt=620940 f2000000 setup cbp=620a00 be=620a07       cbp=0 be=620a07
>   td1 620940 nxt=620900 f3100000    in cbp=620a08 be=620a07       cbp=0 be=620a07

[1] The OS disk image has been emailed to philmd@linaro.org, mjt@tls.msk.ru,
and kraxel@redhat.com:

* testCbpOffBy1.img.xz
* sha256: f87baddcb86de845de12f002c698670a426affb40946025cc32694f9daa3abed

Signed-off-by: David Hubbard <dmamfmgm@gmail.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2024-06-21 16:20:45 +01:00
..
bus-stub.c hw/usb: move stubs out of stubs/ 2024-04-18 11:17:27 +02:00
bus.c hw/usb/bus.c: PCAP adding 0xA in Windows version 2024-03-01 08:27:33 +01:00
canokey.c hw/usb/canokey: change license to GPLv2+ 2023-07-25 17:24:12 +01:00
canokey.h hw/usb/canokey: change license to GPLv2+ 2023-07-25 17:24:12 +01:00
ccid-card-emulated.c hw/usb: spelling fixes 2023-08-31 19:47:43 +02:00
ccid-card-passthru.c hw/usb: Constify VMState 2023-12-30 07:38:06 +11:00
ccid.h
chipidea.c
combined-packet.c usb: limit combined packets to 1 MiB (CVE-2021-3527) 2021-05-05 15:06:01 +02:00
core.c
desc-msos.c hw/usb: Fix typo in comments and print 2021-09-01 06:37:13 +02:00
desc.c hw/usb: Silence compiler warnings in USB code when compiling with -Wshadow 2023-10-06 13:27:48 +02:00
desc.h usb: allow max 8192 bytes for desc 2022-01-13 10:22:37 +01:00
dev-audio.c usb-audio: Fix invalid values in AudioControl descriptors 2024-04-01 19:47:40 +03:00
dev-hid.c hw/usb: Constify VMState 2023-12-30 07:38:06 +11:00
dev-hub.c hw/usb: Constify VMState 2023-12-30 07:38:06 +11:00
dev-mtp.c hw/usb/dev-mtp: Correctly report free space 2024-06-19 12:42:03 +02:00
dev-network.c hw/usb/dev-network: Remove unused struct 'rndis_config_parameter' 2024-05-09 00:07:21 +02:00
dev-serial.c
dev-smartcard-reader.c hw/usb: Constify VMState 2023-12-30 07:38:06 +11:00
dev-storage-bot.c Don't include headers already included by qemu/osdep.h 2023-02-08 07:28:05 +01:00
dev-storage-classic.c usb-storage: Fix BlockConf defaults 2024-04-16 11:50:52 +01:00
dev-storage.c hw/usb: Constify VMState 2023-12-30 07:38:06 +11:00
dev-uas.c hw/usb: Constify VMState 2023-12-30 07:38:06 +11:00
dev-wacom.c hw/usb: fix tab indentation 2022-11-08 11:13:48 +01:00
hcd-dwc2.c hw/usb/hcd-dwc2: Handle invalid address access in read and write functions 2024-06-21 14:01:59 +01:00
hcd-dwc2.h Clean up header guards that don't match their file name 2022-05-11 16:49:06 +02:00
hcd-dwc3.c hw/usb: Constify VMState 2023-12-30 07:38:06 +11:00
hcd-ehci-pci.c hw/usb/ehci: Rename NB_PORTS -> EHCI_PORTS 2024-02-20 20:34:21 +03:00
hcd-ehci-sysbus.c hw/usb/ehci: Rename NB_PORTS -> EHCI_PORTS 2024-02-20 20:34:21 +03:00
hcd-ehci.c hw/usb/ehci: Rename NB_PORTS -> EHCI_PORTS 2024-02-20 20:34:21 +03:00
hcd-ehci.h hw/usb/ehci: Rename NB_PORTS -> EHCI_PORTS 2024-02-20 20:34:21 +03:00
hcd-musb.c hw/usb: fix tab indentation 2022-11-08 11:13:48 +01:00
hcd-ohci-pci.c hw/usb: Constify VMState 2023-12-30 07:38:06 +11:00
hcd-ohci-sysbus.c hw/usb: extract sysbus-ohci to a separate file 2024-02-27 09:37:25 +01:00
hcd-ohci.c hw/usb/hcd-ohci: Fix ohci_service_td: accept zero-length TDs where CBP=BE+1 2024-06-21 16:20:45 +01:00
hcd-ohci.h hw/usb/ohci: Use OHCIState type definition 2023-02-27 22:29:02 +01:00
hcd-uhci.c hw/usb/uhci: Rename NB_PORTS -> UHCI_PORTS 2024-02-20 20:34:21 +03:00
hcd-uhci.h hw/usb/uhci: Rename NB_PORTS -> UHCI_PORTS 2024-02-20 20:34:21 +03:00
hcd-xhci-nec.c hw/usb/hcd-xhci: Remove XHCI_FLAG_SS_FIRST flag 2024-06-19 12:40:48 +02:00
hcd-xhci-pci.c hw/usb/hcd-xhci: Remove XHCI_FLAG_SS_FIRST flag 2024-06-19 12:40:48 +02:00
hcd-xhci-pci.h include/hw/pci: Split pci_device.h off pci.h 2023-01-08 01:54:22 -05:00
hcd-xhci-sysbus.c hw/usb: Constify VMState 2023-12-30 07:38:06 +11:00
hcd-xhci-sysbus.h
hcd-xhci.c hw/usb/hcd-xhci: Remove XHCI_FLAG_SS_FIRST flag 2024-06-19 12:40:48 +02:00
hcd-xhci.h hw/usb/hcd-xhci: Remove XHCI_FLAG_SS_FIRST flag 2024-06-19 12:40:48 +02:00
host-libusb.c hw/usb: Constify VMState 2023-12-30 07:38:06 +11:00
imx-usb-phy.c hw/usb: Constify VMState 2023-12-30 07:38:06 +11:00
Kconfig usb: add config options for the hub and hid devices 2024-06-04 11:53:43 +02:00
libhw.c dma: Let dma_memory_map() take MemTxAttrs argument 2021-12-30 17:16:32 +01:00
meson.build usb: add config options for the hub and hid devices 2024-06-04 11:53:43 +02:00
pcap.c
quirks-ftdi-ids.h hw/usb: Fix typo in comments and print 2021-09-01 06:37:13 +02:00
quirks-pl2303-ids.h hw/usb: fix tab indentation 2022-11-08 11:13:48 +01:00
quirks.c
quirks.h hw/usb: spelling fixes 2023-08-31 19:47:43 +02:00
redirect.c migration 1st pull for 9.0 2024-01-05 13:35:25 +00:00
trace-events hw/usb/hcd-ohci: Fix ohci_service_td: accept zero-length TDs where CBP=BE+1 2024-06-21 16:20:45 +01:00
trace.h
tusb6010.c
u2f-emulated.c hw/usb: Fix typo in comments and print 2021-09-01 06:37:13 +02:00
u2f-passthru.c hw/usb: Constify VMState 2023-12-30 07:38:06 +11:00
u2f.c hw/usb: Constify VMState 2023-12-30 07:38:06 +11:00
u2f.h hw/usb/u2f: Declare QOM macros using OBJECT_DECLARE_TYPE() 2023-02-27 22:29:02 +01:00
vt82c686-uhci-pci.c hw/usb/vt82c686-uhci-pci: Use ISA instead of PCI interrupts 2023-11-28 14:26:37 +01:00
xen-usb.c hw/xen: Make XenDevOps structures const 2024-06-04 11:53:43 +02:00
xlnx-usb-subsystem.c
xlnx-versal-usb2-ctrl-regs.c hw, target: Add ResetType argument to hold and exit phase methods 2024-04-25 10:21:06 +01:00