1 // SPDX-License-Identifier: GPL-2.0
2 #include "virtgpu_drv.h"
4 static void virtio_gpu_vram_free(struct drm_gem_object *obj)
6 struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj);
7 struct virtio_gpu_device *vgdev = obj->dev->dev_private;
8 struct virtio_gpu_object_vram *vram = to_virtio_gpu_vram(bo);
12 spin_lock(&vgdev->host_visible_lock);
13 unmap = drm_mm_node_allocated(&vram->vram_node);
14 spin_unlock(&vgdev->host_visible_lock);
17 virtio_gpu_cmd_unmap(vgdev, bo);
19 virtio_gpu_cmd_unref_resource(vgdev, bo);
20 virtio_gpu_notify(vgdev);
25 static const struct vm_operations_struct virtio_gpu_vram_vm_ops = {
26 .open = drm_gem_vm_open,
27 .close = drm_gem_vm_close,
30 static int virtio_gpu_vram_mmap(struct drm_gem_object *obj,
31 struct vm_area_struct *vma)
34 struct virtio_gpu_device *vgdev = obj->dev->dev_private;
35 struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj);
36 struct virtio_gpu_object_vram *vram = to_virtio_gpu_vram(bo);
37 unsigned long vm_size = vma->vm_end - vma->vm_start;
39 if (!(bo->blob_flags & VIRTGPU_BLOB_FLAG_USE_MAPPABLE))
42 wait_event(vgdev->resp_wq, vram->map_state != STATE_INITIALIZING);
43 if (vram->map_state != STATE_OK)
46 vma->vm_pgoff -= drm_vma_node_start(&obj->vma_node);
47 vma->vm_flags |= VM_MIXEDMAP | VM_DONTEXPAND;
48 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
49 vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
50 vma->vm_ops = &virtio_gpu_vram_vm_ops;
52 if (vram->map_info == VIRTIO_GPU_MAP_CACHE_WC)
53 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
54 else if (vram->map_info == VIRTIO_GPU_MAP_CACHE_UNCACHED)
55 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
57 /* Partial mappings of GEM buffers don't happen much in practice. */
58 if (vm_size != vram->vram_node.size)
61 ret = io_remap_pfn_range(vma, vma->vm_start,
62 vram->vram_node.start >> PAGE_SHIFT,
63 vm_size, vma->vm_page_prot);
67 static const struct drm_gem_object_funcs virtio_gpu_vram_funcs = {
68 .open = virtio_gpu_gem_object_open,
69 .close = virtio_gpu_gem_object_close,
70 .free = virtio_gpu_vram_free,
71 .mmap = virtio_gpu_vram_mmap,
72 .export = virtgpu_gem_prime_export,
75 bool virtio_gpu_is_vram(struct virtio_gpu_object *bo)
77 return bo->base.base.funcs == &virtio_gpu_vram_funcs;
80 static int virtio_gpu_vram_map(struct virtio_gpu_object *bo)
84 struct virtio_gpu_object_array *objs;
85 struct virtio_gpu_device *vgdev = bo->base.base.dev->dev_private;
86 struct virtio_gpu_object_vram *vram = to_virtio_gpu_vram(bo);
88 if (!vgdev->has_host_visible)
91 spin_lock(&vgdev->host_visible_lock);
92 ret = drm_mm_insert_node(&vgdev->host_visible_mm, &vram->vram_node,
94 spin_unlock(&vgdev->host_visible_lock);
99 objs = virtio_gpu_array_alloc(1);
102 goto err_remove_node;
105 virtio_gpu_array_add_obj(objs, &bo->base.base);
106 /*TODO: Add an error checking helper function in drm_mm.h */
107 offset = vram->vram_node.start - vgdev->host_visible_region.addr;
109 ret = virtio_gpu_cmd_map(vgdev, objs, offset);
111 virtio_gpu_array_put_free(objs);
112 goto err_remove_node;
118 spin_lock(&vgdev->host_visible_lock);
119 drm_mm_remove_node(&vram->vram_node);
120 spin_unlock(&vgdev->host_visible_lock);
124 int virtio_gpu_vram_create(struct virtio_gpu_device *vgdev,
125 struct virtio_gpu_object_params *params,
126 struct virtio_gpu_object **bo_ptr)
128 struct drm_gem_object *obj;
129 struct virtio_gpu_object_vram *vram;
132 vram = kzalloc(sizeof(*vram), GFP_KERNEL);
136 obj = &vram->base.base.base;
137 obj->funcs = &virtio_gpu_vram_funcs;
139 params->size = PAGE_ALIGN(params->size);
140 drm_gem_private_object_init(vgdev->ddev, obj, params->size);
142 /* Create fake offset */
143 ret = drm_gem_create_mmap_offset(obj);
149 ret = virtio_gpu_resource_id_get(vgdev, &vram->base.hw_res_handle);
155 virtio_gpu_cmd_resource_create_blob(vgdev, &vram->base, params, NULL,
157 if (params->blob_flags & VIRTGPU_BLOB_FLAG_USE_MAPPABLE) {
158 ret = virtio_gpu_vram_map(&vram->base);
160 virtio_gpu_vram_free(obj);
165 *bo_ptr = &vram->base;