aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/virtio/virtgpu_ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/virtio/virtgpu_ioctl.c')
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_ioctl.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index 5720a0d4ac0a..677ac16c8a6d 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -197,6 +197,9 @@ static int virtio_gpu_getparam_ioctl(struct drm_device *dev, void *data,
197 case VIRTGPU_PARAM_3D_FEATURES: 197 case VIRTGPU_PARAM_3D_FEATURES:
198 value = vgdev->has_virgl_3d == true ? 1 : 0; 198 value = vgdev->has_virgl_3d == true ? 1 : 0;
199 break; 199 break;
200 case VIRTGPU_PARAM_CAPSET_QUERY_FIX:
201 value = 1;
202 break;
200 default: 203 default:
201 return -EINVAL; 204 return -EINVAL;
202 } 205 }
@@ -472,7 +475,7 @@ static int virtio_gpu_get_caps_ioctl(struct drm_device *dev,
472{ 475{
473 struct virtio_gpu_device *vgdev = dev->dev_private; 476 struct virtio_gpu_device *vgdev = dev->dev_private;
474 struct drm_virtgpu_get_caps *args = data; 477 struct drm_virtgpu_get_caps *args = data;
475 int size; 478 unsigned size, host_caps_size;
476 int i; 479 int i;
477 int found_valid = -1; 480 int found_valid = -1;
478 int ret; 481 int ret;
@@ -481,6 +484,10 @@ static int virtio_gpu_get_caps_ioctl(struct drm_device *dev,
481 if (vgdev->num_capsets == 0) 484 if (vgdev->num_capsets == 0)
482 return -ENOSYS; 485 return -ENOSYS;
483 486
487 /* don't allow userspace to pass 0 */
488 if (args->size == 0)
489 return -EINVAL;
490
484 spin_lock(&vgdev->display_info_lock); 491 spin_lock(&vgdev->display_info_lock);
485 for (i = 0; i < vgdev->num_capsets; i++) { 492 for (i = 0; i < vgdev->num_capsets; i++) {
486 if (vgdev->capsets[i].id == args->cap_set_id) { 493 if (vgdev->capsets[i].id == args->cap_set_id) {
@@ -496,11 +503,9 @@ static int virtio_gpu_get_caps_ioctl(struct drm_device *dev,
496 return -EINVAL; 503 return -EINVAL;
497 } 504 }
498 505
499 size = vgdev->capsets[found_valid].max_size; 506 host_caps_size = vgdev->capsets[found_valid].max_size;
500 if (args->size > size) { 507 /* only copy to user the minimum of the host caps size or the guest caps size */
501 spin_unlock(&vgdev->display_info_lock); 508 size = min(args->size, host_caps_size);
502 return -EINVAL;
503 }
504 509
505 list_for_each_entry(cache_ent, &vgdev->cap_cache, head) { 510 list_for_each_entry(cache_ent, &vgdev->cap_cache, head) {
506 if (cache_ent->id == args->cap_set_id && 511 if (cache_ent->id == args->cap_set_id &&