@@ -571,6 +571,21 @@ void remove_assigned_device(AssignedDevInfo *adev)
free_assigned_device(adev);
}
+AssignedDevInfo *get_assigned_device(int pcibus, int slot)
+{
+ AssignedDevice *assigned_dev = NULL;
+ AssignedDevInfo *adev = NULL;
+
+ LIST_FOREACH(adev, &adev_head, next) {
+ assigned_dev = adev->assigned_dev;
+ if (pci_bus_num(assigned_dev->dev.bus) == pcibus &&
+ PCI_SLOT(assigned_dev->dev.devfn) == slot)
+ return adev;
+ }
+
+ return NULL;
+}
+
/* The pci config space got updated. Check if irq numbers have changed
* for our devices
*/
@@ -639,6 +654,11 @@ struct PCIDevice *init_assigned_device(AssignedDevInfo *adev, PCIBus *bus)
if (r < 0)
goto assigned_out;
+ /* assign irq for the device */
+ r = assign_irq(adev);
+ if (r < 0)
+ goto assigned_out;
+
return &dev->dev;
assigned_out:
@@ -98,6 +98,7 @@ PCIDevice *init_assigned_device(AssignedDevInfo *adev, PCIBus *bus);
AssignedDevInfo *add_assigned_device(const char *arg);
void add_assigned_devices(PCIBus *bus, const char **devices, int n_devices);
void remove_assigned_device(AssignedDevInfo *adev);
+AssignedDevInfo *get_assigned_device(int pcibus, int slot);
ram_addr_t assigned_dev_load_option_roms(ram_addr_t rom_base_offset);
void assigned_dev_update_irqs(void);
@@ -155,6 +155,14 @@ static PCIDevice *qemu_pci_hot_assign_device(PCIBus *pci_bus, const char *opts)
return ret;
}
+static void qemu_pci_hot_deassign_device(AssignedDevInfo *adev)
+{
+ remove_assigned_device(adev);
+
+ term_printf("Unregister host PCI device %02x:%02x.%1x "
+ "(\"%s\") from guest\n",
+ adev->bus, adev->dev, adev->func, adev->name);
+}
#endif /* USE_KVM_DEVICE_ASSIGNMENT */
void pci_device_hot_add(const char *pci_addr, const char *type, const char *opts)
@@ -231,12 +239,21 @@ void pci_device_hot_remove_success(int pcibus, int slot)
{
PCIDevice *d = pci_find_device(pcibus, slot, 0);
int class_code;
+ AssignedDevInfo *adev;
if (!d) {
term_printf("invalid slot %d\n", slot);
return;
}
+#ifdef USE_KVM_DEVICE_ASSIGNMENT
+ adev = get_assigned_device(pcibus, slot);
+ if (adev) {
+ qemu_pci_hot_deassign_device(adev);
+ return;
+ }
+#endif /* USE_KVM_DEVICE_ASSIGNMENT */
+
class_code = d->config_read(d, PCI_CLASS_DEVICE+1, 1);
switch(class_code) {