From patchwork Fri Feb 13 09:49:49 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Han, Weidong" X-Patchwork-Id: 6980 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n1D9nvaC002886 for ; Fri, 13 Feb 2009 09:49:57 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755620AbZBMJtz (ORCPT ); Fri, 13 Feb 2009 04:49:55 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1755434AbZBMJty (ORCPT ); Fri, 13 Feb 2009 04:49:54 -0500 Received: from mga01.intel.com ([192.55.52.88]:17609 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755191AbZBMJtx (ORCPT ); Fri, 13 Feb 2009 04:49:53 -0500 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP; 13 Feb 2009 01:43:54 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.38,201,1233561600"; d="scan'208,223";a="665333649" Received: from unknown (HELO azsmsx601.amr.corp.intel.com) ([10.2.121.193]) by fmsmga001.fm.intel.com with ESMTP; 13 Feb 2009 01:53:46 -0800 Received: from pdsmsx602.ccr.corp.intel.com (172.16.12.184) by azsmsx601.amr.corp.intel.com (10.2.121.193) with Microsoft SMTP Server (TLS) id 8.1.311.2; Fri, 13 Feb 2009 02:49:51 -0700 Received: from pdsmsx503.ccr.corp.intel.com ([172.16.12.95]) by pdsmsx602.ccr.corp.intel.com ([172.16.12.184]) with mapi; Fri, 13 Feb 2009 17:49:50 +0800 From: "Han, Weidong" To: "'Avi Kivity'" CC: "'kvm@vger.kernel.org'" , "'Mark McLoughlin'" Date: Fri, 13 Feb 2009 17:49:49 +0800 Subject: [PATCH 7/7] [V3] kvm: qemu: fix hot remove assigned device with iommu Thread-Topic: [PATCH 7/7] [V3] kvm: qemu: fix hot remove assigned device with iommu Thread-Index: AcmNwGkW649ilAj4QR+fKqDp9tkwSw== Message-ID: <715D42877B251141A38726ABF5CABF2C01959AFEBC@pdsmsx503.ccr.corp.intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: yes X-MS-TNEF-Correlator: acceptlanguage: en-US MIME-Version: 1.0 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org when hot remove the assigned device with iommu, it should deassign it from guest and free it from qemu. assign_dev_update_irqs may not be invoked when hot add a device, so need to assign irq after device assignment in init_assigned_device. Acked-by: Mark McLoughlin Signed-off-by: Weidong Han --- qemu/hw/device-assignment.c | 20 ++++++++++++++++++++ qemu/hw/device-assignment.h | 1 + qemu/hw/device-hotplug.c | 17 +++++++++++++++++ 3 files changed, 38 insertions(+), 0 deletions(-) diff --git a/qemu/hw/device-assignment.c b/qemu/hw/device-assignment.c index fc89c6f..d6acc67 100644 --- a/qemu/hw/device-assignment.c +++ b/qemu/hw/device-assignment.c @@ -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: diff --git a/qemu/hw/device-assignment.h b/qemu/hw/device-assignment.h index 84f3f32..da775d7 100644 --- a/qemu/hw/device-assignment.h +++ b/qemu/hw/device-assignment.h @@ -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); diff --git a/qemu/hw/device-hotplug.c b/qemu/hw/device-hotplug.c index 671acb2..03987ab 100644 --- a/qemu/hw/device-hotplug.c +++ b/qemu/hw/device-hotplug.c @@ -63,6 +63,14 @@ static PCIDevice *qemu_system_hot_assign_device(const char *opts, int bus_nr) return ret; } +static void qemu_system_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 */ static int add_init_drive(const char *opts) @@ -240,12 +248,21 @@ void device_hot_remove_success(int pcibus, int slot) { PCIDevice *d = pci_find_device(pcibus, slot); 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_system_hot_deassign_device(adev); + return; + } +#endif /* USE_KVM_DEVICE_ASSIGNMENT */ + class_code = d->config_read(d, PCI_CLASS_DEVICE+1, 1); pci_unregister_device(d);