hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/drivers/gpu/drm/virtio/virtgpu_kms.c
....@@ -25,7 +25,10 @@
2525
2626 #include <linux/virtio.h>
2727 #include <linux/virtio_config.h>
28
-#include <drm/drmP.h>
28
+#include <linux/virtio_ring.h>
29
+
30
+#include <drm/drm_file.h>
31
+
2932 #include "virtgpu_drv.h"
3033
3134 static void virtio_gpu_config_changed_work_func(struct work_struct *work)
....@@ -36,36 +39,18 @@
3639 u32 events_read, events_clear = 0;
3740
3841 /* read the config space */
39
- virtio_cread(vgdev->vdev, struct virtio_gpu_config,
40
- events_read, &events_read);
42
+ virtio_cread_le(vgdev->vdev, struct virtio_gpu_config,
43
+ events_read, &events_read);
4144 if (events_read & VIRTIO_GPU_EVENT_DISPLAY) {
4245 if (vgdev->has_edid)
4346 virtio_gpu_cmd_get_edids(vgdev);
4447 virtio_gpu_cmd_get_display_info(vgdev);
48
+ virtio_gpu_notify(vgdev);
4549 drm_helper_hpd_irq_event(vgdev->ddev);
4650 events_clear |= VIRTIO_GPU_EVENT_DISPLAY;
4751 }
48
- virtio_cwrite(vgdev->vdev, struct virtio_gpu_config,
49
- events_clear, &events_clear);
50
-}
51
-
52
-static int virtio_gpu_context_create(struct virtio_gpu_device *vgdev,
53
- uint32_t nlen, const char *name)
54
-{
55
- int handle = ida_alloc(&vgdev->ctx_id_ida, GFP_KERNEL);
56
-
57
- if (handle < 0)
58
- return handle;
59
- handle += 1;
60
- virtio_gpu_cmd_context_create(vgdev, handle, nlen, name);
61
- return handle;
62
-}
63
-
64
-static void virtio_gpu_context_destroy(struct virtio_gpu_device *vgdev,
65
- uint32_t ctx_id)
66
-{
67
- virtio_gpu_cmd_context_destroy(vgdev, ctx_id);
68
- ida_free(&vgdev->ctx_id_ida, ctx_id - 1);
52
+ virtio_cwrite_le(vgdev->vdev, struct virtio_gpu_config,
53
+ events_clear, &events_clear);
6954 }
7055
7156 static void virtio_gpu_init_vq(struct virtio_gpu_queue *vgvq,
....@@ -90,6 +75,7 @@
9075 }
9176 for (i = 0; i < num_capsets; i++) {
9277 virtio_gpu_cmd_get_capset_info(vgdev, i);
78
+ virtio_gpu_notify(vgdev);
9379 ret = wait_event_timeout(vgdev->resp_wq,
9480 vgdev->capsets[i].id > 0, 5 * HZ);
9581 if (ret == 0) {
....@@ -119,7 +105,7 @@
119105 /* this will expand later */
120106 struct virtqueue *vqs[2];
121107 u32 num_scanouts, num_capsets;
122
- int ret;
108
+ int ret = 0;
123109
124110 if (!virtio_has_feature(dev_to_virtio(dev->dev), VIRTIO_F_VERSION_1))
125111 return -ENODEV;
....@@ -134,6 +120,7 @@
134120 vgdev->dev = dev->dev;
135121
136122 spin_lock_init(&vgdev->display_info_lock);
123
+ spin_lock_init(&vgdev->resource_export_lock);
137124 ida_init(&vgdev->ctx_id_ida);
138125 ida_init(&vgdev->resource_ida);
139126 init_waitqueue_head(&vgdev->resp_wq);
....@@ -147,18 +134,28 @@
147134 INIT_WORK(&vgdev->config_changed_work,
148135 virtio_gpu_config_changed_work_func);
149136
137
+ INIT_WORK(&vgdev->obj_free_work,
138
+ virtio_gpu_array_put_free_work);
139
+ INIT_LIST_HEAD(&vgdev->obj_free_list);
140
+ spin_lock_init(&vgdev->obj_free_lock);
141
+
150142 #ifdef __LITTLE_ENDIAN
151143 if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_VIRGL))
152144 vgdev->has_virgl_3d = true;
153
- DRM_INFO("virgl 3d acceleration %s\n",
154
- vgdev->has_virgl_3d ? "enabled" : "not supported by host");
155
-#else
156
- DRM_INFO("virgl 3d acceleration not supported by guest\n");
157145 #endif
158146 if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_EDID)) {
159147 vgdev->has_edid = true;
160
- DRM_INFO("EDID support available.\n");
161148 }
149
+ if (virtio_has_feature(vgdev->vdev, VIRTIO_RING_F_INDIRECT_DESC)) {
150
+ vgdev->has_indirect = true;
151
+ }
152
+ if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_RESOURCE_UUID)) {
153
+ vgdev->has_resource_assign_uuid = true;
154
+ }
155
+
156
+ DRM_INFO("features: %cvirgl %cedid\n",
157
+ vgdev->has_virgl_3d ? '+' : '-',
158
+ vgdev->has_edid ? '+' : '-');
162159
163160 ret = virtio_find_vqs(vgdev->vdev, 2, vqs, callbacks, names, NULL);
164161 if (ret) {
....@@ -173,15 +170,9 @@
173170 goto err_vbufs;
174171 }
175172
176
- ret = virtio_gpu_ttm_init(vgdev);
177
- if (ret) {
178
- DRM_ERROR("failed to init ttm %d\n", ret);
179
- goto err_ttm;
180
- }
181
-
182173 /* get display info */
183
- virtio_cread(vgdev->vdev, struct virtio_gpu_config,
184
- num_scanouts, &num_scanouts);
174
+ virtio_cread_le(vgdev->vdev, struct virtio_gpu_config,
175
+ num_scanouts, &num_scanouts);
185176 vgdev->num_scanouts = min_t(uint32_t, num_scanouts,
186177 VIRTIO_GPU_MAX_SCANOUTS);
187178 if (!vgdev->num_scanouts) {
....@@ -191,27 +182,29 @@
191182 }
192183 DRM_INFO("number of scanouts: %d\n", num_scanouts);
193184
194
- virtio_cread(vgdev->vdev, struct virtio_gpu_config,
195
- num_capsets, &num_capsets);
185
+ virtio_cread_le(vgdev->vdev, struct virtio_gpu_config,
186
+ num_capsets, &num_capsets);
196187 DRM_INFO("number of cap sets: %d\n", num_capsets);
197188
198
- virtio_gpu_modeset_init(vgdev);
189
+ ret = virtio_gpu_modeset_init(vgdev);
190
+ if (ret) {
191
+ DRM_ERROR("modeset init failed\n");
192
+ goto err_scanouts;
193
+ }
199194
200195 virtio_device_ready(vgdev->vdev);
201
- vgdev->vqs_ready = true;
202196
203197 if (num_capsets)
204198 virtio_gpu_get_capsets(vgdev, num_capsets);
205199 if (vgdev->has_edid)
206200 virtio_gpu_cmd_get_edids(vgdev);
207201 virtio_gpu_cmd_get_display_info(vgdev);
202
+ virtio_gpu_notify(vgdev);
208203 wait_event_timeout(vgdev->resp_wq, !vgdev->display_info_pending,
209204 5 * HZ);
210205 return 0;
211206
212207 err_scanouts:
213
- virtio_gpu_ttm_fini(vgdev);
214
-err_ttm:
215208 virtio_gpu_free_vbufs(vgdev);
216209 err_vbufs:
217210 vgdev->vdev->config->del_vqs(vgdev->vdev);
....@@ -235,15 +228,19 @@
235228 {
236229 struct virtio_gpu_device *vgdev = dev->dev_private;
237230
238
- vgdev->vqs_ready = false;
231
+ flush_work(&vgdev->obj_free_work);
239232 flush_work(&vgdev->ctrlq.dequeue_work);
240233 flush_work(&vgdev->cursorq.dequeue_work);
241234 flush_work(&vgdev->config_changed_work);
242235 vgdev->vdev->config->reset(vgdev->vdev);
243236 vgdev->vdev->config->del_vqs(vgdev->vdev);
237
+}
238
+
239
+void virtio_gpu_release(struct drm_device *dev)
240
+{
241
+ struct virtio_gpu_device *vgdev = dev->dev_private;
244242
245243 virtio_gpu_modeset_fini(vgdev);
246
- virtio_gpu_ttm_fini(vgdev);
247244 virtio_gpu_free_vbufs(vgdev);
248245 virtio_gpu_cleanup_cap_cache(vgdev);
249246 kfree(vgdev->capsets);
....@@ -254,8 +251,7 @@
254251 {
255252 struct virtio_gpu_device *vgdev = dev->dev_private;
256253 struct virtio_gpu_fpriv *vfpriv;
257
- int id;
258
- char dbgname[TASK_COMM_LEN];
254
+ int handle;
259255
260256 /* can't create contexts without 3d renderer */
261257 if (!vgdev->has_virgl_3d)
....@@ -266,14 +262,15 @@
266262 if (!vfpriv)
267263 return -ENOMEM;
268264
269
- get_task_comm(dbgname, current);
270
- id = virtio_gpu_context_create(vgdev, strlen(dbgname), dbgname);
271
- if (id < 0) {
265
+ mutex_init(&vfpriv->context_lock);
266
+
267
+ handle = ida_alloc(&vgdev->ctx_id_ida, GFP_KERNEL);
268
+ if (handle < 0) {
272269 kfree(vfpriv);
273
- return id;
270
+ return handle;
274271 }
275272
276
- vfpriv->ctx_id = id;
273
+ vfpriv->ctx_id = handle + 1;
277274 file->driver_priv = vfpriv;
278275 return 0;
279276 }
....@@ -281,14 +278,18 @@
281278 void virtio_gpu_driver_postclose(struct drm_device *dev, struct drm_file *file)
282279 {
283280 struct virtio_gpu_device *vgdev = dev->dev_private;
284
- struct virtio_gpu_fpriv *vfpriv;
281
+ struct virtio_gpu_fpriv *vfpriv = file->driver_priv;
285282
286283 if (!vgdev->has_virgl_3d)
287284 return;
288285
289
- vfpriv = file->driver_priv;
286
+ if (vfpriv->context_created) {
287
+ virtio_gpu_cmd_context_destroy(vgdev, vfpriv->ctx_id);
288
+ virtio_gpu_notify(vgdev);
289
+ }
290290
291
- virtio_gpu_context_destroy(vgdev, vfpriv->ctx_id);
291
+ ida_free(&vgdev->ctx_id_ida, vfpriv->ctx_id - 1);
292
+ mutex_destroy(&vfpriv->context_lock);
292293 kfree(vfpriv);
293294 file->driver_priv = NULL;
294295 }