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