drm/vmwgfx: Fix prime import/export
[linux.git] / drivers / gpu / drm / vmwgfx / vmwgfx_blit.c
index c52c7bf1485b1fa95b1e9ca3f1e05135167a8c5c..717d624e9a052298d5d5070551e909cc65ee0cc5 100644 (file)
@@ -456,8 +456,10 @@ int vmw_bo_cpu_blit(struct ttm_buffer_object *dst,
                .no_wait_gpu = false
        };
        u32 j, initial_line = dst_offset / dst_stride;
-       struct vmw_bo_blit_line_data d;
+       struct vmw_bo_blit_line_data d = {0};
        int ret = 0;
+       struct page **dst_pages = NULL;
+       struct page **src_pages = NULL;
 
        /* Buffer objects need to be either pinned or reserved: */
        if (!(dst->pin_count))
@@ -477,12 +479,35 @@ int vmw_bo_cpu_blit(struct ttm_buffer_object *dst,
                        return ret;
        }
 
+       if (!src->ttm->pages && src->ttm->sg) {
+               src_pages = kvmalloc_array(src->ttm->num_pages,
+                                          sizeof(struct page *), GFP_KERNEL);
+               if (!src_pages)
+                       return -ENOMEM;
+               ret = drm_prime_sg_to_page_array(src->ttm->sg, src_pages,
+                                                src->ttm->num_pages);
+               if (ret)
+                       goto out;
+       }
+       if (!dst->ttm->pages && dst->ttm->sg) {
+               dst_pages = kvmalloc_array(dst->ttm->num_pages,
+                                          sizeof(struct page *), GFP_KERNEL);
+               if (!dst_pages) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+               ret = drm_prime_sg_to_page_array(dst->ttm->sg, dst_pages,
+                                                dst->ttm->num_pages);
+               if (ret)
+                       goto out;
+       }
+
        d.mapped_dst = 0;
        d.mapped_src = 0;
        d.dst_addr = NULL;
        d.src_addr = NULL;
-       d.dst_pages = dst->ttm->pages;
-       d.src_pages = src->ttm->pages;
+       d.dst_pages = dst->ttm->pages ? dst->ttm->pages : dst_pages;
+       d.src_pages = src->ttm->pages ? src->ttm->pages : src_pages;
        d.dst_num_pages = PFN_UP(dst->resource->size);
        d.src_num_pages = PFN_UP(src->resource->size);
        d.dst_prot = ttm_io_prot(dst, dst->resource, PAGE_KERNEL);
@@ -504,6 +529,10 @@ out:
                kunmap_atomic(d.src_addr);
        if (d.dst_addr)
                kunmap_atomic(d.dst_addr);
+       if (src_pages)
+               kvfree(src_pages);
+       if (dst_pages)
+               kvfree(dst_pages);
 
        return ret;
 }
This page took 0.026949 seconds and 4 git commands to generate.