hc
2024-05-10 cde9070d9970eef1f7ec2360586c802a16230ad8
kernel/drivers/gpu/drm/virtio/virtgpu_gem.c
....@@ -23,57 +23,36 @@
2323 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2424 */
2525
26
-#include <drm/drmP.h>
26
+#include <drm/drm_file.h>
27
+#include <drm/drm_fourcc.h>
28
+
2729 #include "virtgpu_drv.h"
2830
29
-void virtio_gpu_gem_free_object(struct drm_gem_object *gem_obj)
30
-{
31
- struct virtio_gpu_object *obj = gem_to_virtio_gpu_obj(gem_obj);
32
-
33
- if (obj)
34
- virtio_gpu_object_unref(&obj);
35
-}
36
-
37
-struct virtio_gpu_object*
38
-virtio_gpu_alloc_object(struct drm_device *dev,
39
- struct virtio_gpu_object_params *params,
40
- struct virtio_gpu_fence *fence)
31
+static int virtio_gpu_gem_create(struct drm_file *file,
32
+ struct drm_device *dev,
33
+ struct virtio_gpu_object_params *params,
34
+ struct drm_gem_object **obj_p,
35
+ uint32_t *handle_p)
4136 {
4237 struct virtio_gpu_device *vgdev = dev->dev_private;
4338 struct virtio_gpu_object *obj;
4439 int ret;
45
-
46
- ret = virtio_gpu_object_create(vgdev, params, &obj, fence);
47
- if (ret)
48
- return ERR_PTR(ret);
49
-
50
- return obj;
51
-}
52
-
53
-int virtio_gpu_gem_create(struct drm_file *file,
54
- struct drm_device *dev,
55
- struct virtio_gpu_object_params *params,
56
- struct drm_gem_object **obj_p,
57
- uint32_t *handle_p)
58
-{
59
- struct virtio_gpu_object *obj;
60
- int ret;
6140 u32 handle;
6241
63
- obj = virtio_gpu_alloc_object(dev, params, NULL);
64
- if (IS_ERR(obj))
65
- return PTR_ERR(obj);
42
+ ret = virtio_gpu_object_create(vgdev, params, &obj, NULL);
43
+ if (ret < 0)
44
+ return ret;
6645
67
- ret = drm_gem_handle_create(file, &obj->gem_base, &handle);
46
+ ret = drm_gem_handle_create(file, &obj->base.base, &handle);
6847 if (ret) {
69
- drm_gem_object_release(&obj->gem_base);
48
+ drm_gem_object_release(&obj->base.base);
7049 return ret;
7150 }
7251
73
- *obj_p = &obj->gem_base;
52
+ *obj_p = &obj->base.base;
7453
7554 /* drop reference from allocate - handle holds it now */
76
- drm_gem_object_put_unlocked(&obj->gem_base);
55
+ drm_gem_object_put(&obj->base.base);
7756
7857 *handle_p = handle;
7958 return 0;
....@@ -88,7 +67,10 @@
8867 int ret;
8968 uint32_t pitch;
9069
91
- pitch = args->width * ((args->bpp + 1) / 8);
70
+ if (args->bpp != 32)
71
+ return -EINVAL;
72
+
73
+ pitch = args->width * 4;
9274 args->size = pitch * args->height;
9375 args->size = ALIGN(args->size, PAGE_SIZE);
9476
....@@ -114,15 +96,13 @@
11496 uint32_t handle, uint64_t *offset_p)
11597 {
11698 struct drm_gem_object *gobj;
117
- struct virtio_gpu_object *obj;
11899
119100 BUG_ON(!offset_p);
120101 gobj = drm_gem_object_lookup(file_priv, handle);
121102 if (gobj == NULL)
122103 return -ENOENT;
123
- obj = gem_to_virtio_gpu_obj(gobj);
124
- *offset_p = virtio_gpu_object_mmap_offset(obj);
125
- drm_gem_object_put_unlocked(gobj);
104
+ *offset_p = drm_vma_node_offset_addr(&gobj->vma_node);
105
+ drm_gem_object_put(gobj);
126106 return 0;
127107 }
128108
....@@ -131,19 +111,25 @@
131111 {
132112 struct virtio_gpu_device *vgdev = obj->dev->dev_private;
133113 struct virtio_gpu_fpriv *vfpriv = file->driver_priv;
134
- struct virtio_gpu_object *qobj = gem_to_virtio_gpu_obj(obj);
135
- int r;
114
+ struct virtio_gpu_object_array *objs;
136115
137116 if (!vgdev->has_virgl_3d)
138
- return 0;
117
+ goto out_notify;
139118
140
- r = virtio_gpu_object_reserve(qobj, false);
141
- if (r)
142
- return r;
119
+ /* the context might still be missing when the first ioctl is
120
+ * DRM_IOCTL_MODE_CREATE_DUMB or DRM_IOCTL_PRIME_FD_TO_HANDLE
121
+ */
122
+ virtio_gpu_create_context(obj->dev, file);
123
+
124
+ objs = virtio_gpu_array_alloc(1);
125
+ if (!objs)
126
+ return -ENOMEM;
127
+ virtio_gpu_array_add_obj(objs, obj);
143128
144129 virtio_gpu_cmd_context_attach_resource(vgdev, vfpriv->ctx_id,
145
- qobj->hw_res_handle);
146
- virtio_gpu_object_unreserve(qobj);
130
+ objs);
131
+out_notify:
132
+ virtio_gpu_notify(vgdev);
147133 return 0;
148134 }
149135
....@@ -152,17 +138,136 @@
152138 {
153139 struct virtio_gpu_device *vgdev = obj->dev->dev_private;
154140 struct virtio_gpu_fpriv *vfpriv = file->driver_priv;
155
- struct virtio_gpu_object *qobj = gem_to_virtio_gpu_obj(obj);
156
- int r;
141
+ struct virtio_gpu_object_array *objs;
157142
158143 if (!vgdev->has_virgl_3d)
159144 return;
160145
161
- r = virtio_gpu_object_reserve(qobj, false);
162
- if (r)
146
+ objs = virtio_gpu_array_alloc(1);
147
+ if (!objs)
163148 return;
149
+ virtio_gpu_array_add_obj(objs, obj);
164150
165151 virtio_gpu_cmd_context_detach_resource(vgdev, vfpriv->ctx_id,
166
- qobj->hw_res_handle);
167
- virtio_gpu_object_unreserve(qobj);
152
+ objs);
153
+ virtio_gpu_notify(vgdev);
154
+}
155
+
156
+struct virtio_gpu_object_array *virtio_gpu_array_alloc(u32 nents)
157
+{
158
+ struct virtio_gpu_object_array *objs;
159
+
160
+ objs = kmalloc(struct_size(objs, objs, nents), GFP_KERNEL);
161
+ if (!objs)
162
+ return NULL;
163
+
164
+ objs->nents = 0;
165
+ objs->total = nents;
166
+ return objs;
167
+}
168
+
169
+static void virtio_gpu_array_free(struct virtio_gpu_object_array *objs)
170
+{
171
+ kfree(objs);
172
+}
173
+
174
+struct virtio_gpu_object_array*
175
+virtio_gpu_array_from_handles(struct drm_file *drm_file, u32 *handles, u32 nents)
176
+{
177
+ struct virtio_gpu_object_array *objs;
178
+ u32 i;
179
+
180
+ objs = virtio_gpu_array_alloc(nents);
181
+ if (!objs)
182
+ return NULL;
183
+
184
+ for (i = 0; i < nents; i++) {
185
+ objs->objs[i] = drm_gem_object_lookup(drm_file, handles[i]);
186
+ if (!objs->objs[i]) {
187
+ objs->nents = i;
188
+ virtio_gpu_array_put_free(objs);
189
+ return NULL;
190
+ }
191
+ }
192
+ objs->nents = i;
193
+ return objs;
194
+}
195
+
196
+void virtio_gpu_array_add_obj(struct virtio_gpu_object_array *objs,
197
+ struct drm_gem_object *obj)
198
+{
199
+ if (WARN_ON_ONCE(objs->nents == objs->total))
200
+ return;
201
+
202
+ drm_gem_object_get(obj);
203
+ objs->objs[objs->nents] = obj;
204
+ objs->nents++;
205
+}
206
+
207
+int virtio_gpu_array_lock_resv(struct virtio_gpu_object_array *objs)
208
+{
209
+ int ret;
210
+
211
+ if (objs->nents == 1) {
212
+ ret = dma_resv_lock_interruptible(objs->objs[0]->resv, NULL);
213
+ } else {
214
+ ret = drm_gem_lock_reservations(objs->objs, objs->nents,
215
+ &objs->ticket);
216
+ }
217
+ return ret;
218
+}
219
+
220
+void virtio_gpu_array_unlock_resv(struct virtio_gpu_object_array *objs)
221
+{
222
+ if (objs->nents == 1) {
223
+ dma_resv_unlock(objs->objs[0]->resv);
224
+ } else {
225
+ drm_gem_unlock_reservations(objs->objs, objs->nents,
226
+ &objs->ticket);
227
+ }
228
+}
229
+
230
+void virtio_gpu_array_add_fence(struct virtio_gpu_object_array *objs,
231
+ struct dma_fence *fence)
232
+{
233
+ int i;
234
+
235
+ for (i = 0; i < objs->nents; i++)
236
+ dma_resv_add_excl_fence(objs->objs[i]->resv, fence);
237
+}
238
+
239
+void virtio_gpu_array_put_free(struct virtio_gpu_object_array *objs)
240
+{
241
+ u32 i;
242
+
243
+ for (i = 0; i < objs->nents; i++)
244
+ drm_gem_object_put(objs->objs[i]);
245
+ virtio_gpu_array_free(objs);
246
+}
247
+
248
+void virtio_gpu_array_put_free_delayed(struct virtio_gpu_device *vgdev,
249
+ struct virtio_gpu_object_array *objs)
250
+{
251
+ spin_lock(&vgdev->obj_free_lock);
252
+ list_add_tail(&objs->next, &vgdev->obj_free_list);
253
+ spin_unlock(&vgdev->obj_free_lock);
254
+ schedule_work(&vgdev->obj_free_work);
255
+}
256
+
257
+void virtio_gpu_array_put_free_work(struct work_struct *work)
258
+{
259
+ struct virtio_gpu_device *vgdev =
260
+ container_of(work, struct virtio_gpu_device, obj_free_work);
261
+ struct virtio_gpu_object_array *objs;
262
+
263
+ spin_lock(&vgdev->obj_free_lock);
264
+ while (!list_empty(&vgdev->obj_free_list)) {
265
+ objs = list_first_entry(&vgdev->obj_free_list,
266
+ struct virtio_gpu_object_array, next);
267
+ list_del(&objs->next);
268
+ spin_unlock(&vgdev->obj_free_lock);
269
+ virtio_gpu_array_put_free(objs);
270
+ spin_lock(&vgdev->obj_free_lock);
271
+ }
272
+ spin_unlock(&vgdev->obj_free_lock);
168273 }