hw/usb/hcd-xhci: rejected DCBAA read writes contexts to guest address zero

Host environment

  • Operating system: macOS 14.8.9
  • OS/kernel version: Darwin 23.6.0
  • Architecture: arm64
  • QEMU flavor: qemu-system-x86_64
  • QEMU version: 11.1.50 (commit a19f59a7)
  • QEMU command line: generated by the attached reproducer using pc, accel=qtest, qemu-xhci, and usb-kbd

Emulated/Virtualized environment

  • Operating system: none (qtest)
  • OS/kernel version: not applicable
  • Architecture: x86_64 PC

Description of problem

Disclosure: An LLM agent helped me investigate this bug and prepare the reproducer.

When an Address Device command reads its output-context pointer through an inaccessible DCBAA address, qemu-xhci reports Command Completion Code Success and writes the slot and endpoint-zero contexts to guest physical addresses 0 and 32. Host System Error and Host Controller Error both remain clear.

Steps to reproduce

  1. Run the attached qemu-xhci-ignored-dcbaa-dma.py:

    python3 qemu-xhci-ignored-dcbaa-dma.py --qemu /path/to/qemu-system-x86_64
  2. Observe:

    mapped DCBAA: completion=1, USBSTS=0x00000008, invalid reads=0
    unmapped DCBAA: completion=1, USBSTS=0x00000008, invalid reads=2, low RAM changed=True
    low RAM[0:64]: 00000008000005000000000001000010aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0100000020004000016001000000000000000000aaaaaaaaaaaaaaaaaaaaaaaa
    BUG REPRODUCED: rejected DCBAA fetch completed and wrote low RAM

Completion code 1 is Success. The reproducer fills guest addresses 0 through 63 with 0xaa before submitting the failing command. The failure was reproduced with QEMU 11.0.2 and current master at commit a19f59a7.

Additional information

xhci_address_slot() discards the MemTxResult from ldq_le_dma() and immediately uses the output value as the output-context address. It later writes the slot and endpoint-zero contexts through that address and returns success.

The xHCI 1.2b specification, section 4.10.2.6 requires a catastrophic error during a host-system access to set USBSTS.HSE and clear USBCMD.R/S; it lists PCI Master Abort and Target Abort as examples.

qemu-xhci-ignored-dcbaa-dma.py