The xHCI PCI wrapper owns an embedded xhci-core child via
object_initialize_child(), while the child's strong host link points back to the
PCI wrapper. On hot-unplug, usb_xhci_pci_exit() does not unrealize the embedded
child or clear the host link, so the strong back-reference keeps the PCI
device's QOM refcount from reaching zero.

As a result, the xHCI PCI device is unrealized and unparented, but it is never
finalized. This leaks the controller object and prevents finalization-side
cleanup from running, including DEVICE_DELETED emission from device_finalize().

This is independently an upstream QEMU object-lifetime bug. It can also have
latent higher-level effects for CPR orchestration: CPR relies on the new or
re-executed QEMU being launched with a command line that matches the current
source VM topology. If management relies on hot-unplug completion/finalization
signals to update that topology, the missing finalization/DEVICE_DELETED event
can leave a stale -device qemu-xhci or -device nec-usb-xhci entry in the CPR
restart command, causing a previously unplugged controller to be recreated after
cpr-reboot, cpr-transfer, or cpr-exec.

Xiangfeng Cai (2):
  hw/usb/hcd-xhci-pci: break host link cycle so device_finalize() runs
    on unplug
  tests/qtest: add xhci-pci unplug finalize regression test

 hw/usb/hcd-xhci-pci.c           | 12 ++++++
 tests/qtest/usb-hcd-xhci-test.c | 67 +++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+)

-- 
2.55.0.rc1

Reply via email to