Re: [PATCH 09/10] vfio-pci: create an iommu mapping for msi address

2016-01-26 Thread kbuild test robot
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, );
 > 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, 
_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 & 0x);
   335  pci_write_msi_msg(irq, );
   336  

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: Binary data
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Re: [PATCH 09/10] vfio-pci: create an iommu mapping for msi address

2016-01-26 Thread Eric Auger
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
> 
>318dma_addr_t msi_iova;
>319struct vfio_group *group = vdev->vfio_group;
>320struct msi_msg msg;
>321int ret;
>322
>323get_cached_msi_msg(irq, );
>  > 324msi_addr = (phys_addr_t)(msg.address_hi) << 32 |
>325(phys_addr_t)(msg.address_lo);
>326
>327ret = vfio_group_alloc_map_reserved_iova(group, 
> msi_addr,
>328 IOMMU_WRITE, 
> _iova);
>329if (ret)
>330goto out;
>331
>332/* Re-program the msi-address with the iova */
>  > 333msg.address_hi = (u32)(msi_iova >> 32);
>334msg.address_lo = (u32)(msi_iova & 0x);
>335pci_write_msi_msg(irq, );
>336
> 
> ---
> 0-DAY kernel test infrastructureOpen Source Technology Center
> https://lists.01.org/pipermail/kbuild-all   Intel Corporation
> 

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 09/10] vfio-pci: create an iommu mapping for msi address

2016-01-26 Thread Eric Auger
Some platforms require the MSI address programmed in the PCI
device to be an IOVA and not a host physical address.
This is typically the case for ARM and PowerPC, as opposed
to x86. This patch allocates an IOVA page and maps it onto
the physical page which contains the target MSI write transaction
address. In case an IOMMU binding already exists between those 2,
simply reprogram the device.

The binding is destroyed by the VFIO IOMMU backend.

Signed-off-by: Bharat Bhushan 
Signed-off-by: Eric Auger 

---
---
 drivers/vfio/pci/vfio_pci_intrs.c | 73 ---
 1 file changed, 68 insertions(+), 5 deletions(-)

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, );
+   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, _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 & 0x);
+   pci_write_msi_msg(irq, );
+
+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, );
+   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(>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,
-- 
1.9.1

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu