Message ID | 1453813968-2024-10-git-send-email-eric.auger@linaro.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi Eric, [auto build test WARNING on v4.5-rc1] [also build test WARNING on next-20160125] [cannot apply to iommu/next] [if your patch is applied to the wrong git tree, please drop us a note to help improving the system] url: https://github.com/0day-ci/linux/commits/Eric-Auger/KVM-PCIe-MSI-passthrough-on-ARM-ARM64/20160126-211921 config: i386-allmodconfig (attached as .config) reproduce: # save the attached .config to linux build tree make ARCH=i386 All warnings (new ones prefixed by >>): drivers/vfio/pci/vfio_pci_intrs.c: In function 'vfio_set_mapped_msi_addr': >> drivers/vfio/pci/vfio_pci_intrs.c:324:43: warning: left shift count >= width of type [-Wshift-count-overflow] msi_addr = (phys_addr_t)(msg.address_hi) << 32 | ^ >> drivers/vfio/pci/vfio_pci_intrs.c:333:34: warning: right shift count >= width of type [-Wshift-count-overflow] msg.address_hi = (u32)(msi_iova >> 32); ^ vim +324 drivers/vfio/pci/vfio_pci_intrs.c 318 dma_addr_t msi_iova; 319 struct vfio_group *group = vdev->vfio_group; 320 struct msi_msg msg; 321 int ret; 322 323 get_cached_msi_msg(irq, &msg); > 324 msi_addr = (phys_addr_t)(msg.address_hi) << 32 | 325 (phys_addr_t)(msg.address_lo); 326 327 ret = vfio_group_alloc_map_reserved_iova(group, msi_addr, 328 IOMMU_WRITE, &msi_iova); 329 if (ret) 330 goto out; 331 332 /* Re-program the msi-address with the iova */ > 333 msg.address_hi = (u32)(msi_iova >> 32); 334 msg.address_lo = (u32)(msi_iova & 0xffffffff); 335 pci_write_msi_msg(irq, &msg); 336 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
Hi, On 01/26/2016 03:43 PM, kbuild test robot wrote: > Hi Eric, > > [auto build test WARNING on v4.5-rc1] > [also build test WARNING on next-20160125] > [cannot apply to iommu/next] > [if your patch is applied to the wrong git tree, please drop us a note to help improving the system] > > url: https://github.com/0day-ci/linux/commits/Eric-Auger/KVM-PCIe-MSI-passthrough-on-ARM-ARM64/20160126-211921 > config: i386-allmodconfig (attached as .config) > reproduce: > # save the attached .config to linux build tree > make ARCH=i386 > > All warnings (new ones prefixed by >>): > > drivers/vfio/pci/vfio_pci_intrs.c: In function 'vfio_set_mapped_msi_addr': >>> drivers/vfio/pci/vfio_pci_intrs.c:324:43: warning: left shift count >= width of type [-Wshift-count-overflow] > msi_addr = (phys_addr_t)(msg.address_hi) << 32 | > ^ >>> drivers/vfio/pci/vfio_pci_intrs.c:333:34: warning: right shift count >= width of type [-Wshift-count-overflow] > msg.address_hi = (u32)(msi_iova >> 32); I definitively need to revisit that code. I Better understand Alex' comment now :-( Thanks Eric > ^ > > vim +324 drivers/vfio/pci/vfio_pci_intrs.c > > 318 dma_addr_t msi_iova; > 319 struct vfio_group *group = vdev->vfio_group; > 320 struct msi_msg msg; > 321 int ret; > 322 > 323 get_cached_msi_msg(irq, &msg); > > 324 msi_addr = (phys_addr_t)(msg.address_hi) << 32 | > 325 (phys_addr_t)(msg.address_lo); > 326 > 327 ret = vfio_group_alloc_map_reserved_iova(group, msi_addr, > 328 IOMMU_WRITE, &msi_iova); > 329 if (ret) > 330 goto out; > 331 > 332 /* Re-program the msi-address with the iova */ > > 333 msg.address_hi = (u32)(msi_iova >> 32); > 334 msg.address_lo = (u32)(msi_iova & 0xffffffff); > 335 pci_write_msi_msg(irq, &msg); > 336 > > --- > 0-DAY kernel test infrastructure Open Source Technology Center > https://lists.01.org/pipermail/kbuild-all Intel Corporation >
diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c index 3b3ba15..bac24c9 100644 --- a/drivers/vfio/pci/vfio_pci_intrs.c +++ b/drivers/vfio/pci/vfio_pci_intrs.c @@ -305,6 +305,57 @@ static int vfio_msi_enable(struct vfio_pci_device *vdev, int nvec, bool msix) return 0; } +/** + * vfio_set_mapped_msi_addr: overwrites the msi physical address with an iova + * + * @pdev: vfio pci device handle + * @irq: irq linux number + * returns 0 upon success, < 0 on failure + */ +static int vfio_set_mapped_msi_addr(struct vfio_pci_device *vdev, int irq) +{ + phys_addr_t msi_addr; + dma_addr_t msi_iova; + struct vfio_group *group = vdev->vfio_group; + struct msi_msg msg; + int ret; + + get_cached_msi_msg(irq, &msg); + msi_addr = (phys_addr_t)(msg.address_hi) << 32 | + (phys_addr_t)(msg.address_lo); + + ret = vfio_group_alloc_map_reserved_iova(group, msi_addr, + IOMMU_WRITE, &msi_iova); + if (ret) + goto out; + + /* Re-program the msi-address with the iova */ + msg.address_hi = (u32)(msi_iova >> 32); + msg.address_lo = (u32)(msi_iova & 0xffffffff); + pci_write_msi_msg(irq, &msg); + +out: + return ret; +} + +/** + * vfio_unset_mapped_msi_addr: decrement the ref counter of the msi iova page + * associated to the linux irq (in case it is null unmaps and frees resources) + * + * @pdev: vfio pci device handle + * @irq: irq linux number + */ +static void vfio_unset_mapped_msi_addr(struct vfio_pci_device *vdev, int irq) +{ + dma_addr_t msi_iova; + struct vfio_group *group = vdev->vfio_group; + struct msi_msg msg; + + get_cached_msi_msg(irq, &msg); + msi_iova = (u64)(msg.address_hi) << 32 | (u64)(msg.address_lo); + vfio_group_unmap_free_reserved_iova(group, msi_iova); +} + static int vfio_msi_set_vector_signal(struct vfio_pci_device *vdev, int vector, int fd, bool msix) { @@ -318,6 +369,7 @@ static int vfio_msi_set_vector_signal(struct vfio_pci_device *vdev, return -EINVAL; if (vdev->ctx[vector].trigger) { + vfio_unset_mapped_msi_addr(vdev, irq); free_irq(irq, vdev->ctx[vector].trigger); irq_bypass_unregister_producer(&vdev->ctx[vector].producer); kfree(vdev->ctx[vector].name); @@ -355,11 +407,8 @@ static int vfio_msi_set_vector_signal(struct vfio_pci_device *vdev, ret = request_irq(irq, vfio_msihandler, 0, vdev->ctx[vector].name, trigger); - if (ret) { - kfree(vdev->ctx[vector].name); - eventfd_ctx_put(trigger); - return ret; - } + if (ret) + goto error_free; vdev->ctx[vector].producer.token = trigger; vdev->ctx[vector].producer.irq = irq; @@ -369,9 +418,23 @@ static int vfio_msi_set_vector_signal(struct vfio_pci_device *vdev, "irq bypass producer (token %p) registration fails: %d\n", vdev->ctx[vector].producer.token, ret); + if (vfio_group_require_msi_mapping(vdev->vfio_group)) { + ret = vfio_set_mapped_msi_addr(vdev, irq); + if (ret) + goto error_free_irq; + } + vdev->ctx[vector].trigger = trigger; return 0; + +error_free_irq: + free_irq(irq, vdev->ctx[vector].trigger); +error_free: + kfree(vdev->ctx[vector].name); + eventfd_ctx_put(trigger); + return ret; + } static int vfio_msi_set_block(struct vfio_pci_device *vdev, unsigned start,