static struct drm_gem_object *vgem_gem_create(struct drm_device *dev, struct drm_file *file, unsigned int *handle, unsigned long size) { struct drm_vgem_gem_object *obj; int ret; obj = __vgem_gem_create(dev, size); if (IS_ERR(obj)) return ERR_CAST(obj); ret = drm_gem_handle_create(file, &obj->base, handle); drm_gem_object_put_unlocked(&obj->base); if (ret) goto err; return &obj->base; err: __vgem_gem_destroy(obj); return ERR_PTR(ret); }
static struct drm_gem_object *vgem_prime_import_sg_table(struct drm_device *dev, struct dma_buf_attachment *attach, struct sg_table *sg) { struct drm_vgem_gem_object *obj; int npages; obj = __vgem_gem_create(dev, attach->dmabuf->size); if (IS_ERR(obj)) return ERR_CAST(obj); npages = PAGE_ALIGN(attach->dmabuf->size) / PAGE_SIZE; obj->table = sg; obj->pages = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL); if (!obj->pages) { __vgem_gem_destroy(obj); return ERR_PTR(-ENOMEM); } obj->pages_pin_count++; /* perma-pinned */ drm_prime_sg_to_page_addr_arrays(obj->table, obj->pages, NULL, npages); return &obj->base; }