lkml.org 
[lkml]   [2018]   [Sep]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    Date
    SubjectRe: [virtio-dev] [PATCH 2/2] drm/virtio: add iommu support.
    For the series,

    Reviewed-by: Dave Airlie <airlied@redhat.com>
    On Wed, 29 Aug 2018 at 22:20, Gerd Hoffmann <kraxel@redhat.com> wrote:
    >
    > Use the dma mapping api and properly add iommu mappings for
    > objects, unless virtio is in iommu quirk mode.
    >
    > Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
    > ---
    > drivers/gpu/drm/virtio/virtgpu_drv.h | 1 +
    > drivers/gpu/drm/virtio/virtgpu_vq.c | 46 +++++++++++++++++++++++++++++-------
    > 2 files changed, 38 insertions(+), 9 deletions(-)
    >
    > diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
    > index cbbff01077..ec9a38f995 100644
    > --- a/drivers/gpu/drm/virtio/virtgpu_drv.h
    > +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
    > @@ -57,6 +57,7 @@ struct virtio_gpu_object {
    > uint32_t hw_res_handle;
    >
    > struct sg_table *pages;
    > + uint32_t mapped;
    > void *vmap;
    > bool dumb;
    > struct ttm_place placement_code;
    > diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
    > index af24e91267..bf631d32d4 100644
    > --- a/drivers/gpu/drm/virtio/virtgpu_vq.c
    > +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
    > @@ -424,7 +424,8 @@ void virtio_gpu_cmd_unref_resource(struct virtio_gpu_device *vgdev,
    > }
    >
    > static void virtio_gpu_cmd_resource_inval_backing(struct virtio_gpu_device *vgdev,
    > - uint32_t resource_id)
    > + uint32_t resource_id,
    > + struct virtio_gpu_fence **fence)
    > {
    > struct virtio_gpu_resource_detach_backing *cmd_p;
    > struct virtio_gpu_vbuffer *vbuf;
    > @@ -435,7 +436,7 @@ static void virtio_gpu_cmd_resource_inval_backing(struct virtio_gpu_device *vgde
    > cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING);
    > cmd_p->resource_id = cpu_to_le32(resource_id);
    >
    > - virtio_gpu_queue_ctrl_buffer(vgdev, vbuf);
    > + virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, &cmd_p->hdr, fence);
    > }
    >
    > void virtio_gpu_cmd_set_scanout(struct virtio_gpu_device *vgdev,
    > @@ -848,9 +849,10 @@ int virtio_gpu_object_attach(struct virtio_gpu_device *vgdev,
    > uint32_t resource_id,
    > struct virtio_gpu_fence **fence)
    > {
    > + bool use_dma_api = !virtio_has_iommu_quirk(vgdev->vdev);
    > struct virtio_gpu_mem_entry *ents;
    > struct scatterlist *sg;
    > - int si;
    > + int si, nents;
    >
    > if (!obj->pages) {
    > int ret;
    > @@ -860,23 +862,33 @@ int virtio_gpu_object_attach(struct virtio_gpu_device *vgdev,
    > return ret;
    > }
    >
    > + if (use_dma_api) {
    > + obj->mapped = dma_map_sg(vgdev->vdev->dev.parent,
    > + obj->pages->sgl, obj->pages->nents,
    > + DMA_TO_DEVICE);
    > + nents = obj->mapped;
    > + } else {
    > + nents = obj->pages->nents;
    > + }
    > +
    > /* gets freed when the ring has consumed it */
    > - ents = kmalloc_array(obj->pages->nents,
    > - sizeof(struct virtio_gpu_mem_entry),
    > + ents = kmalloc_array(nents, sizeof(struct virtio_gpu_mem_entry),
    > GFP_KERNEL);
    > if (!ents) {
    > DRM_ERROR("failed to allocate ent list\n");
    > return -ENOMEM;
    > }
    >
    > - for_each_sg(obj->pages->sgl, sg, obj->pages->nents, si) {
    > - ents[si].addr = cpu_to_le64(sg_phys(sg));
    > + for_each_sg(obj->pages->sgl, sg, nents, si) {
    > + ents[si].addr = cpu_to_le64(use_dma_api
    > + ? sg_dma_address(sg)
    > + : sg_phys(sg));
    > ents[si].length = cpu_to_le32(sg->length);
    > ents[si].padding = 0;
    > }
    >
    > virtio_gpu_cmd_resource_attach_backing(vgdev, resource_id,
    > - ents, obj->pages->nents,
    > + ents, nents,
    > fence);
    > obj->hw_res_handle = resource_id;
    > return 0;
    > @@ -885,7 +897,23 @@ int virtio_gpu_object_attach(struct virtio_gpu_device *vgdev,
    > void virtio_gpu_object_detach(struct virtio_gpu_device *vgdev,
    > struct virtio_gpu_object *obj)
    > {
    > - virtio_gpu_cmd_resource_inval_backing(vgdev, obj->hw_res_handle);
    > + bool use_dma_api = !virtio_has_iommu_quirk(vgdev->vdev);
    > + struct virtio_gpu_fence *fence;
    > +
    > + if (use_dma_api && obj->mapped) {
    > + /* detach backing and wait for the host process it ... */
    > + virtio_gpu_cmd_resource_inval_backing(vgdev, obj->hw_res_handle, &fence);
    > + dma_fence_wait(&fence->f, true);
    > + dma_fence_put(&fence->f);
    > +
    > + /* ... then tear down iommu mappings */
    > + dma_unmap_sg(vgdev->vdev->dev.parent,
    > + obj->pages->sgl, obj->mapped,
    > + DMA_TO_DEVICE);
    > + obj->mapped = 0;
    > + } else {
    > + virtio_gpu_cmd_resource_inval_backing(vgdev, obj->hw_res_handle, NULL);
    > + }
    > }
    >
    > void virtio_gpu_cursor_ping(struct virtio_gpu_device *vgdev,
    > --
    > 2.9.3
    >
    >
    > ---------------------------------------------------------------------
    > To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
    > For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org
    >

    \
     
     \ /
      Last update: 2018-09-04 01:51    [W:4.918 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site