free_assigned_device just frees device from qemu, it should also deassign the device from guest when guest exits or hot remove assigned device. Acked-by: Mark McLoughlin <markmc@xxxxxxxxxx> Signed-off-by: Weidong Han <weidong.han@xxxxxxxxx> --- qemu/hw/device-assignment.c | 28 ++++++++++++++++++++++++++-- qemu/hw/device-assignment.h | 1 + 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/qemu/hw/device-assignment.c b/qemu/hw/device-assignment.c index 5341ef2..fc89c6f 100644 --- a/qemu/hw/device-assignment.c +++ b/qemu/hw/device-assignment.c @@ -549,6 +549,28 @@ static int assign_irq(AssignedDevInfo *adev) return r; } +static void deassign_device(AssignedDevInfo *adev) +{ + struct kvm_assigned_pci_dev assigned_dev_data; + AssignedDevice *dev = adev->assigned_dev; + int r; + + memset(&assigned_dev_data, 0, sizeof(assigned_dev_data)); + assigned_dev_data.assigned_dev_id = + calc_assigned_dev_id(dev->h_busnr, dev->h_devfn); + + r = kvm_deassign_pci_device(kvm_context, &assigned_dev_data); + if (r < 0) + fprintf(stderr, "Failed to deassign device \"%s\" : %s\n", + adev->name, strerror(-r)); +} + +void remove_assigned_device(AssignedDevInfo *adev) +{ + deassign_device(adev); + free_assigned_device(adev); +} + /* The pci config space got updated. Check if irq numbers have changed * for our devices */ @@ -563,7 +585,7 @@ void assigned_dev_update_irqs() r = assign_irq(adev); if (r < 0) - free_assigned_device(adev); + remove_assigned_device(adev); adev = next; } @@ -615,10 +637,12 @@ struct PCIDevice *init_assigned_device(AssignedDevInfo *adev, PCIBus *bus) /* assign device to guest */ r = assign_device(adev); if (r < 0) - goto out; + goto assigned_out; return &dev->dev; +assigned_out: + deassign_device(adev); out: free_assigned_device(adev); return NULL; diff --git a/qemu/hw/device-assignment.h b/qemu/hw/device-assignment.h index 6a9b9fa..84f3f32 100644 --- a/qemu/hw/device-assignment.h +++ b/qemu/hw/device-assignment.h @@ -97,6 +97,7 @@ struct AssignedDevInfo { 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); ram_addr_t assigned_dev_load_option_roms(ram_addr_t rom_base_offset); void assigned_dev_update_irqs(void); -- 1.6.0.4
Attachment:
0007-kvm-qemu-deassign-device-from-guest.patch
Description: 0007-kvm-qemu-deassign-device-from-guest.patch