On 9/11/2026 8:21 AM, Konstantin Shkolnyy wrote:
@@ -1303,11 +1380,22 @@ static void s390_pcihost_unplug(HotplugHandler
*hotplug_dev, DeviceState *dev,
pbdev = S390_PCI_DEVICE(dev);
pbdev->fid = 0;
QTAILQ_REMOVE(&s->zpci_devs, pbdev, link);
- g_hash_table_remove(s->zpci_table, &pbdev->idx);
+ /*
+ * If this QEMU is running a migrated guest, and was configured with
+ * more zpci devices than the source QEMU, extra zpci devices could be
+ * excluded from zpci_table and invisible to the guest and have
+ * pbdev->idx values duplicating those of active devices. If the
+ * pbdev being unplugged is such, the zpci_table entry for pbdev->idx
+ * can find a different pbdev which we must not remove.
+ */
+ if (g_hash_table_lookup(s->zpci_table, &pbdev->idx) == pbdev) {
+ g_hash_table_remove(s->zpci_table, &pbdev->idx);
+ }
If we are migrating, won't we re-create the exact same state and devices
on the target host? Is it possible that the target QEMU can have more
devices than source?
if (pbdev->dma_limit) {
s390_pci_end_dma_count(s, pbdev->dma_limit);
}
g_hash_table_destroy(pbdev->iotlb);
+ s390_clear_zpci_migration_blocker(pbdev);
qdev_unrealize(dev);
}