1 /* 2 * Copyright (C) 2015 Red Hat, Inc. 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sublicense, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial 15 * portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26 #include <linux/suspend.h> 27 #include <linux/virtio.h> 28 #include <linux/virtio_config.h> 29 #include <linux/virtio_ring.h> 30 31 #include <drm/drm_file.h> 32 #include <drm/drm_managed.h> 33 #include <drm/drm_print.h> 34 35 #include "virtgpu_drv.h" 36 37 static void virtio_gpu_config_changed_work_func(struct work_struct *work) 38 { 39 struct virtio_gpu_device *vgdev = 40 container_of(work, struct virtio_gpu_device, 41 config_changed_work); 42 u32 events_read, events_clear = 0; 43 44 /* read the config space */ 45 virtio_cread_le(vgdev->vdev, struct virtio_gpu_config, 46 events_read, &events_read); 47 if (events_read & VIRTIO_GPU_EVENT_DISPLAY) { 48 if (vgdev->num_scanouts) { 49 if (vgdev->has_edid) 50 virtio_gpu_cmd_get_edids(vgdev); 51 virtio_gpu_cmd_get_display_info(vgdev); 52 virtio_gpu_notify(vgdev); 53 wait_event_timeout(vgdev->resp_wq, 54 !vgdev->display_info_pending, 55 5 * HZ); 56 drm_kms_helper_hotplug_event(vgdev->ddev); 57 } 58 events_clear |= VIRTIO_GPU_EVENT_DISPLAY; 59 } 60 virtio_cwrite_le(vgdev->vdev, struct virtio_gpu_config, 61 events_clear, &events_clear); 62 } 63 64 static void virtio_gpu_init_vq(struct virtio_gpu_queue *vgvq, 65 void (*work_func)(struct work_struct *work)) 66 { 67 spin_lock_init(&vgvq->qlock); 68 init_waitqueue_head(&vgvq->ack_queue); 69 INIT_WORK(&vgvq->dequeue_work, work_func); 70 } 71 72 static void virtio_gpu_get_capsets(struct virtio_gpu_device *vgdev, 73 int num_capsets) 74 { 75 int i, ret; 76 bool invalid_capset_id = false; 77 struct drm_device *drm = vgdev->ddev; 78 79 vgdev->capsets = drmm_kcalloc(drm, num_capsets, 80 sizeof(struct virtio_gpu_drv_capset), 81 GFP_KERNEL); 82 if (!vgdev->capsets) { 83 DRM_ERROR("failed to allocate cap sets\n"); 84 return; 85 } 86 for (i = 0; i < num_capsets; i++) { 87 virtio_gpu_cmd_get_capset_info(vgdev, i); 88 virtio_gpu_notify(vgdev); 89 ret = wait_event_timeout(vgdev->resp_wq, 90 vgdev->capsets[i].id > 0, 5 * HZ); 91 /* 92 * Capability ids are defined in the virtio-gpu spec and are 93 * between 1 to 63, inclusive. 94 */ 95 if (!vgdev->capsets[i].id || 96 vgdev->capsets[i].id > MAX_CAPSET_ID) 97 invalid_capset_id = true; 98 99 if (ret == 0) 100 DRM_ERROR("timed out waiting for cap set %d\n", i); 101 else if (invalid_capset_id) 102 DRM_ERROR("invalid capset id %u", vgdev->capsets[i].id); 103 104 if (ret == 0 || invalid_capset_id) { 105 spin_lock(&vgdev->display_info_lock); 106 drmm_kfree(drm, vgdev->capsets); 107 vgdev->capsets = NULL; 108 spin_unlock(&vgdev->display_info_lock); 109 return; 110 } 111 112 vgdev->capset_id_mask |= 1 << vgdev->capsets[i].id; 113 DRM_INFO("cap set %d: id %d, max-version %d, max-size %d\n", 114 i, vgdev->capsets[i].id, 115 vgdev->capsets[i].max_version, 116 vgdev->capsets[i].max_size); 117 } 118 119 vgdev->num_capsets = num_capsets; 120 } 121 122 int virtio_gpu_find_vqs(struct virtio_gpu_device *vgdev) 123 { 124 struct virtqueue_info vqs_info[] = { 125 { "control", virtio_gpu_ctrl_ack }, 126 { "cursor", virtio_gpu_cursor_ack }, 127 }; 128 struct virtqueue *vqs[2]; 129 int ret; 130 131 ret = virtio_find_vqs(vgdev->vdev, 2, vqs, vqs_info, NULL); 132 if (ret) 133 return ret; 134 135 vgdev->ctrlq.vq = vqs[0]; 136 vgdev->cursorq.vq = vqs[1]; 137 138 return 0; 139 } 140 141 static int virtio_gpu_pm_notifier(struct notifier_block *nb, unsigned long mode, 142 void *data) 143 { 144 struct virtio_gpu_device *vgdev = container_of(nb, 145 struct virtio_gpu_device, 146 pm_nb); 147 148 switch (mode) { 149 case PM_HIBERNATION_PREPARE: 150 if (vgdev->has_virgl_3d) { 151 DRM_ERROR("S4 not allowed when VIRGL is enabled\n"); 152 return notifier_from_errno(-EPERM); 153 } 154 155 vgdev->hibernated = true; 156 break; 157 158 case PM_POST_HIBERNATION: 159 vgdev->hibernated = false; 160 break; 161 } 162 163 return NOTIFY_DONE; 164 } 165 166 int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev) 167 { 168 struct virtio_gpu_device *vgdev; 169 u32 num_scanouts, num_capsets, blob_alignment; 170 int ret = 0; 171 172 if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) 173 return -ENODEV; 174 175 vgdev = drmm_kzalloc(dev, sizeof(struct virtio_gpu_device), GFP_KERNEL); 176 if (!vgdev) 177 return -ENOMEM; 178 179 vgdev->ddev = dev; 180 dev->dev_private = vgdev; 181 vgdev->vdev = vdev; 182 183 spin_lock_init(&vgdev->display_info_lock); 184 spin_lock_init(&vgdev->resource_export_lock); 185 spin_lock_init(&vgdev->host_visible_lock); 186 ida_init(&vgdev->ctx_id_ida); 187 ida_init(&vgdev->resource_ida); 188 init_waitqueue_head(&vgdev->resp_wq); 189 virtio_gpu_init_vq(&vgdev->ctrlq, virtio_gpu_dequeue_ctrl_func); 190 virtio_gpu_init_vq(&vgdev->cursorq, virtio_gpu_dequeue_cursor_func); 191 192 vgdev->fence_drv.context = dma_fence_context_alloc(1); 193 spin_lock_init(&vgdev->fence_drv.lock); 194 INIT_LIST_HEAD(&vgdev->fence_drv.fences); 195 INIT_LIST_HEAD(&vgdev->cap_cache); 196 INIT_WORK(&vgdev->config_changed_work, 197 virtio_gpu_config_changed_work_func); 198 199 INIT_WORK(&vgdev->obj_free_work, 200 virtio_gpu_array_put_free_work); 201 INIT_LIST_HEAD(&vgdev->obj_free_list); 202 spin_lock_init(&vgdev->obj_free_lock); 203 INIT_LIST_HEAD(&vgdev->obj_restore_list); 204 mutex_init(&vgdev->obj_restore_lock); 205 206 #ifdef __LITTLE_ENDIAN 207 if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_VIRGL)) 208 vgdev->has_virgl_3d = true; 209 #endif 210 if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_EDID)) 211 vgdev->has_edid = true; 212 213 if (virtio_has_feature(vgdev->vdev, VIRTIO_RING_F_INDIRECT_DESC)) 214 vgdev->has_indirect = true; 215 216 if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_RESOURCE_UUID)) 217 vgdev->has_resource_assign_uuid = true; 218 219 if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_RESOURCE_BLOB)) 220 vgdev->has_resource_blob = true; 221 222 if (virtio_get_shm_region(vgdev->vdev, &vgdev->host_visible_region, 223 VIRTIO_GPU_SHM_ID_HOST_VISIBLE)) { 224 if (!devm_request_mem_region(&vgdev->vdev->dev, 225 vgdev->host_visible_region.addr, 226 vgdev->host_visible_region.len, 227 dev_name(&vgdev->vdev->dev))) { 228 DRM_ERROR("Could not reserve host visible region\n"); 229 ret = -EBUSY; 230 goto err_vqs; 231 } 232 233 DRM_INFO("Host memory window: 0x%lx +0x%lx\n", 234 (unsigned long)vgdev->host_visible_region.addr, 235 (unsigned long)vgdev->host_visible_region.len); 236 vgdev->has_host_visible = true; 237 drm_mm_init(&vgdev->host_visible_mm, 238 (unsigned long)vgdev->host_visible_region.addr, 239 (unsigned long)vgdev->host_visible_region.len); 240 } 241 242 if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_CONTEXT_INIT)) 243 vgdev->has_context_init = true; 244 245 if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_BLOB_ALIGNMENT)) { 246 vgdev->has_blob_alignment = true; 247 virtio_cread_le(vgdev->vdev, struct virtio_gpu_config, 248 blob_alignment, &blob_alignment); 249 vgdev->blob_alignment = blob_alignment; 250 } 251 252 DRM_INFO("features: %cvirgl %cedid %cresource_blob %chost_visible", 253 vgdev->has_virgl_3d ? '+' : '-', 254 vgdev->has_edid ? '+' : '-', 255 vgdev->has_resource_blob ? '+' : '-', 256 vgdev->has_host_visible ? '+' : '-'); 257 258 DRM_INFO("features: %ccontext_init %cblob_alignment\n", 259 vgdev->has_context_init ? '+' : '-', 260 vgdev->has_blob_alignment ? '+' : '-'); 261 262 ret = virtio_gpu_find_vqs(vgdev); 263 if (ret) { 264 DRM_ERROR("failed to find virt queues\n"); 265 goto err_vqs; 266 } 267 ret = virtio_gpu_alloc_vbufs(vgdev); 268 if (ret) { 269 DRM_ERROR("failed to alloc vbufs\n"); 270 goto err_vbufs; 271 } 272 273 /* get display info */ 274 virtio_cread_le(vgdev->vdev, struct virtio_gpu_config, 275 num_scanouts, &num_scanouts); 276 vgdev->num_scanouts = min_t(uint32_t, num_scanouts, 277 VIRTIO_GPU_MAX_SCANOUTS); 278 279 if (!IS_ENABLED(CONFIG_DRM_VIRTIO_GPU_KMS) || !vgdev->num_scanouts) { 280 DRM_INFO("KMS disabled\n"); 281 vgdev->num_scanouts = 0; 282 vgdev->has_edid = false; 283 dev->driver_features &= ~(DRIVER_MODESET | DRIVER_ATOMIC); 284 } else { 285 DRM_INFO("number of scanouts: %d\n", num_scanouts); 286 } 287 288 virtio_cread_le(vgdev->vdev, struct virtio_gpu_config, 289 num_capsets, &num_capsets); 290 DRM_INFO("number of cap sets: %d\n", num_capsets); 291 292 ret = virtio_gpu_modeset_init(vgdev); 293 if (ret) { 294 DRM_ERROR("modeset init failed\n"); 295 goto err_scanouts; 296 } 297 298 virtio_device_ready(vgdev->vdev); 299 300 if (num_capsets) 301 virtio_gpu_get_capsets(vgdev, num_capsets); 302 if (vgdev->num_scanouts) { 303 if (vgdev->has_edid) 304 virtio_gpu_cmd_get_edids(vgdev); 305 virtio_gpu_cmd_get_display_info(vgdev); 306 virtio_gpu_notify(vgdev); 307 if (!wait_event_timeout(vgdev->resp_wq, 308 !vgdev->display_info_pending, 309 5 * HZ)) { 310 DRM_ERROR("timed out waiting for display info\n"); 311 ret = -ETIMEDOUT; 312 goto err_reset_device; 313 } 314 } 315 316 vgdev->pm_nb.notifier_call = virtio_gpu_pm_notifier; 317 ret = register_pm_notifier(&vgdev->pm_nb); 318 if (ret) 319 goto err_reset_device; 320 321 return 0; 322 323 err_reset_device: 324 virtio_reset_device(vgdev->vdev); 325 virtio_gpu_modeset_fini(vgdev); 326 err_scanouts: 327 virtio_gpu_free_vbufs(vgdev); 328 err_vbufs: 329 vgdev->vdev->config->del_vqs(vgdev->vdev); 330 err_vqs: 331 dev->dev_private = NULL; 332 return ret; 333 } 334 335 static void virtio_gpu_cleanup_cap_cache(struct virtio_gpu_device *vgdev) 336 { 337 struct virtio_gpu_drv_cap_cache *cache_ent, *tmp; 338 339 list_for_each_entry_safe(cache_ent, tmp, &vgdev->cap_cache, head) { 340 kfree(cache_ent->caps_cache); 341 kfree(cache_ent); 342 } 343 } 344 345 void virtio_gpu_deinit(struct drm_device *dev) 346 { 347 struct virtio_gpu_device *vgdev = dev->dev_private; 348 349 unregister_pm_notifier(&vgdev->pm_nb); 350 flush_work(&vgdev->obj_free_work); 351 flush_work(&vgdev->ctrlq.dequeue_work); 352 flush_work(&vgdev->cursorq.dequeue_work); 353 flush_work(&vgdev->config_changed_work); 354 virtio_reset_device(vgdev->vdev); 355 vgdev->vdev->config->del_vqs(vgdev->vdev); 356 mutex_destroy(&vgdev->obj_restore_lock); 357 } 358 359 void virtio_gpu_release(struct drm_device *dev) 360 { 361 struct virtio_gpu_device *vgdev = dev->dev_private; 362 363 if (!vgdev) 364 return; 365 366 virtio_gpu_modeset_fini(vgdev); 367 virtio_gpu_free_vbufs(vgdev); 368 virtio_gpu_cleanup_cap_cache(vgdev); 369 370 if (vgdev->has_host_visible) 371 drm_mm_takedown(&vgdev->host_visible_mm); 372 } 373 374 int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file) 375 { 376 struct virtio_gpu_device *vgdev = dev->dev_private; 377 struct virtio_gpu_fpriv *vfpriv; 378 int handle; 379 380 /* can't create contexts without 3d renderer */ 381 if (!vgdev->has_virgl_3d) 382 return 0; 383 384 /* allocate a virt GPU context for this opener */ 385 vfpriv = kzalloc_obj(*vfpriv); 386 if (!vfpriv) 387 return -ENOMEM; 388 389 mutex_init(&vfpriv->context_lock); 390 391 handle = ida_alloc(&vgdev->ctx_id_ida, GFP_KERNEL); 392 if (handle < 0) { 393 kfree(vfpriv); 394 return handle; 395 } 396 397 vfpriv->ctx_id = handle + 1; 398 file->driver_priv = vfpriv; 399 return 0; 400 } 401 402 void virtio_gpu_driver_postclose(struct drm_device *dev, struct drm_file *file) 403 { 404 struct virtio_gpu_device *vgdev = dev->dev_private; 405 struct virtio_gpu_fpriv *vfpriv = file->driver_priv; 406 407 if (!vgdev->has_virgl_3d) 408 return; 409 410 if (vfpriv->context_created) { 411 virtio_gpu_cmd_context_destroy(vgdev, vfpriv->ctx_id); 412 virtio_gpu_notify(vgdev); 413 } 414 415 ida_free(&vgdev->ctx_id_ida, vfpriv->ctx_id - 1); 416 mutex_destroy(&vfpriv->context_lock); 417 kfree(vfpriv); 418 file->driver_priv = NULL; 419 } 420