@@ -33,8 +33,34 @@ static int vfio_pci_dma_buf_pin(struct dma_buf_attachment *attachment)
static int vfio_pci_dma_buf_get_pfn(struct dma_buf_attachment *attachment,
pgoff_t pgoff, u64 *pfn, int *max_order)
{
- /* TODO */
- return -EOPNOTSUPP;
+ struct vfio_pci_dma_buf *priv = attachment->dmabuf->priv;
+ struct vfio_region_dma_range *dma_ranges = priv->dma_ranges;
+ u64 offset = pgoff << PAGE_SHIFT;
+ int i;
+
+ dma_resv_assert_held(priv->dmabuf->resv);
+
+ if (priv->revoked)
+ return -ENODEV;
+
+ if (offset >= priv->dmabuf->size)
+ return -EINVAL;
+
+ for (i = 0; i < priv->nr_ranges; i++) {
+ if (offset < dma_ranges[i].length)
+ break;
+
+ offset -= dma_ranges[i].length;
+ }
+
+ *pfn = PHYS_PFN(pci_resource_start(priv->vdev->pdev, dma_ranges[i].region_index) +
+ dma_ranges[i].offset + offset);
+
+ /* TODO: large page mapping is yet to be supported */
+ if (max_order)
+ *max_order = 0;
+
+ return 0;
}
static void vfio_pci_dma_buf_release(struct dma_buf *dmabuf)
Implement get_pfn() callback for exported MMIO resources. Signed-off-by: Xu Yilun <yilun.xu@linux.intel.com> --- drivers/vfio/pci/dma_buf.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-)