From patchwork Mon Jun 27 18:19:54 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 922012 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.4) with ESMTP id p5RILTDZ021783 for ; Mon, 27 Jun 2011 18:21:29 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753362Ab1F0SUt (ORCPT ); Mon, 27 Jun 2011 14:20:49 -0400 Received: from fmmailgate01.web.de ([217.72.192.221]:52414 "EHLO fmmailgate01.web.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753257Ab1F0SUm (ORCPT ); Mon, 27 Jun 2011 14:20:42 -0400 Received: from smtp03.web.de ( [172.20.0.65]) by fmmailgate01.web.de (Postfix) with ESMTP id 80EA41921D35F; Mon, 27 Jun 2011 20:20:41 +0200 (CEST) Received: from [2.204.233.154] (helo=localhost.localdomain) by smtp03.web.de with asmtp (TLSv1:AES256-SHA:256) (WEB.DE 4.110 #2) id 1QbGQK-0007wf-00; Mon, 27 Jun 2011 20:20:41 +0200 From: Jan Kiszka To: Avi Kivity , Marcelo Tosatti Cc: kvm@vger.kernel.org, "Michael S. Tsirkin" , Alex Williamson Subject: [PATCH 11/13] pci-assign: Track MSI/MSI-X capability position, clean up related code Date: Mon, 27 Jun 2011 20:19:54 +0200 Message-Id: X-Mailer: git-send-email 1.7.1 In-Reply-To: References: In-Reply-To: References: X-Sender: jan.kiszka@web.de X-Provags-ID: V01U2FsdGVkX1+0/1a/Um/es6a6h/q6C4sTN9JGtlZK6Kjq6u0m bMqrVNkVCh6byCLWnx0EiVdIDghd5xDHKLVx38j7P3d7qN5fdy YIHSEotUE= Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Mon, 27 Jun 2011 18:21:56 +0000 (UTC) From: Jan Kiszka Store the MSI and MSI-X capability position in the same fields the QEMU core uses as well. Although we still open-code MSI support, this does not cause conflicts. Instead, it allow us to drop config space searches from assigned_device_pci_cap_write_config. Moreover, we no longer need to pass the cap position around and can clean up assigned_dev_update_msi/msix a bit as well. Signed-off-by: Jan Kiszka --- hw/device-assignment.c | 37 ++++++++++++++++++++----------------- 1 files changed, 20 insertions(+), 17 deletions(-) diff --git a/hw/device-assignment.c b/hw/device-assignment.c index 43a048f..6a2ca8c 100644 --- a/hw/device-assignment.c +++ b/hw/device-assignment.c @@ -1069,11 +1069,12 @@ void assigned_dev_update_irqs(void) } } -static void assigned_dev_update_msi(PCIDevice *pci_dev, unsigned int ctrl_pos) +static void assigned_dev_update_msi(PCIDevice *pci_dev) { struct kvm_assigned_irq assigned_irq_data; AssignedDevice *assigned_dev = DO_UPCAST(AssignedDevice, dev, pci_dev); - uint8_t ctrl_byte = pci_dev->config[ctrl_pos]; + uint8_t ctrl_byte = pci_get_byte(pci_dev->config + pci_dev->msi_cap + + PCI_MSI_FLAGS); int r; memset(&assigned_irq_data, 0, sizeof assigned_irq_data); @@ -1096,13 +1097,13 @@ static void assigned_dev_update_msi(PCIDevice *pci_dev, unsigned int ctrl_pos) } if (ctrl_byte & PCI_MSI_FLAGS_ENABLE) { - int pos = ctrl_pos - PCI_MSI_FLAGS; + uint8_t *pos = pci_dev->config + pci_dev->msi_cap; + assigned_dev->entry = qemu_mallocz(sizeof(*(assigned_dev->entry))); assigned_dev->entry->u.msi.address_lo = - pci_get_long(pci_dev->config + pos + PCI_MSI_ADDRESS_LO); + pci_get_long(pos + PCI_MSI_ADDRESS_LO); assigned_dev->entry->u.msi.address_hi = 0; - assigned_dev->entry->u.msi.data = - pci_get_word(pci_dev->config + pos + PCI_MSI_DATA_32); + assigned_dev->entry->u.msi.data = pci_get_word(pos + PCI_MSI_DATA_32); assigned_dev->entry->type = KVM_IRQ_ROUTING_MSI; r = kvm_get_irq_route_gsi(); if (r < 0) { @@ -1221,11 +1222,12 @@ static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev) return r; } -static void assigned_dev_update_msix(PCIDevice *pci_dev, unsigned int ctrl_pos) +static void assigned_dev_update_msix(PCIDevice *pci_dev) { struct kvm_assigned_irq assigned_irq_data; AssignedDevice *assigned_dev = DO_UPCAST(AssignedDevice, dev, pci_dev); - uint16_t *ctrl_word = (uint16_t *)(pci_dev->config + ctrl_pos); + uint16_t ctrl_word = pci_get_word(pci_dev->config + pci_dev->msix_cap + + PCI_MSIX_FLAGS); int r; memset(&assigned_irq_data, 0, sizeof assigned_irq_data); @@ -1235,7 +1237,7 @@ static void assigned_dev_update_msix(PCIDevice *pci_dev, unsigned int ctrl_pos) * try to catch this by only deassigning irqs if the guest is using * MSIX or intends to start. */ if ((assigned_dev->irq_requested_type & KVM_DEV_IRQ_GUEST_MSIX) || - (*ctrl_word & PCI_MSIX_FLAGS_ENABLE)) { + (ctrl_word & PCI_MSIX_FLAGS_ENABLE)) { assigned_irq_data.flags = assigned_dev->irq_requested_type; free_dev_irq_entries(assigned_dev); @@ -1247,7 +1249,7 @@ static void assigned_dev_update_msix(PCIDevice *pci_dev, unsigned int ctrl_pos) assigned_dev->irq_requested_type = 0; } - if (*ctrl_word & PCI_MSIX_FLAGS_ENABLE) { + if (ctrl_word & PCI_MSIX_FLAGS_ENABLE) { assigned_irq_data.flags = KVM_DEV_IRQ_HOST_MSIX | KVM_DEV_IRQ_GUEST_MSIX; @@ -1311,21 +1313,20 @@ static void assigned_device_pci_cap_write_config(PCIDevice *pci_dev, uint32_t val, int len) { uint8_t cap_id = pci_dev->config_map[address]; - uint8_t cap; pci_default_write_config(pci_dev, address, val, len); switch (cap_id) { case PCI_CAP_ID_MSI: - cap = pci_find_capability(pci_dev, cap_id); - if (ranges_overlap(address - cap, len, PCI_MSI_FLAGS, 1)) { - assigned_dev_update_msi(pci_dev, cap + PCI_MSI_FLAGS); + if (range_covers_byte(address, len, + pci_dev->msi_cap + PCI_MSI_FLAGS)) { + assigned_dev_update_msi(pci_dev); } break; case PCI_CAP_ID_MSIX: - cap = pci_find_capability(pci_dev, cap_id); - if (ranges_overlap(address - cap, len, PCI_MSIX_FLAGS + 1, 1)) { - assigned_dev_update_msix(pci_dev, cap + PCI_MSIX_FLAGS); + if (range_covers_byte(address, len, + pci_dev->msix_cap + PCI_MSIX_FLAGS + 1)) { + assigned_dev_update_msix(pci_dev); } break; @@ -1356,6 +1357,7 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev) if ((ret = pci_add_capability(pci_dev, PCI_CAP_ID_MSI, pos, 10)) < 0) { return ret; } + pci_dev->msi_cap = pos; pci_set_word(pci_dev->config + pos + PCI_MSI_FLAGS, pci_get_word(pci_dev->config + pos + PCI_MSI_FLAGS) & @@ -1378,6 +1380,7 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev) if ((ret = pci_add_capability(pci_dev, PCI_CAP_ID_MSIX, pos, 12)) < 0) { return ret; } + pci_dev->msix_cap = pos; pci_set_word(pci_dev->config + pos + PCI_MSIX_FLAGS, pci_get_word(pci_dev->config + pos + PCI_MSIX_FLAGS) &