| From foo@baz Sun May 27 17:33:38 CEST 2018 |
| From: Dave Airlie <airlied@redhat.com> |
| Date: Wed, 21 Feb 2018 11:50:03 +1000 |
| Subject: virtio-gpu: fix ioctl and expose the fixed status to userspace. |
| |
| From: Dave Airlie <airlied@redhat.com> |
| |
| [ Upstream commit 9a191b114906457c4b2494c474f58ae4142d4e67 ] |
| |
| This exposes to mesa that it can use the fixed ioctl for querying |
| later cap sets, cap set 1 is forever frozen in time. |
| |
| Signed-off-by: Dave Airlie <airlied@redhat.com> |
| Link: http://patchwork.freedesktop.org/patch/msgid/20180221015003.22884-1-airlied@gmail.com |
| Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> |
| Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/gpu/drm/virtio/virtgpu_ioctl.c | 17 +++++++++++------ |
| include/uapi/drm/virtgpu_drm.h | 1 + |
| 2 files changed, 12 insertions(+), 6 deletions(-) |
| |
| --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c |
| +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c |
| @@ -194,6 +194,9 @@ static int virtio_gpu_getparam_ioctl(str |
| case VIRTGPU_PARAM_3D_FEATURES: |
| value = vgdev->has_virgl_3d == true ? 1 : 0; |
| break; |
| + case VIRTGPU_PARAM_CAPSET_QUERY_FIX: |
| + value = 1; |
| + break; |
| default: |
| return -EINVAL; |
| } |
| @@ -469,7 +472,7 @@ static int virtio_gpu_get_caps_ioctl(str |
| { |
| struct virtio_gpu_device *vgdev = dev->dev_private; |
| struct drm_virtgpu_get_caps *args = data; |
| - int size; |
| + unsigned size, host_caps_size; |
| int i; |
| int found_valid = -1; |
| int ret; |
| @@ -478,6 +481,10 @@ static int virtio_gpu_get_caps_ioctl(str |
| if (vgdev->num_capsets == 0) |
| return -ENOSYS; |
| |
| + /* don't allow userspace to pass 0 */ |
| + if (args->size == 0) |
| + return -EINVAL; |
| + |
| spin_lock(&vgdev->display_info_lock); |
| for (i = 0; i < vgdev->num_capsets; i++) { |
| if (vgdev->capsets[i].id == args->cap_set_id) { |
| @@ -493,11 +500,9 @@ static int virtio_gpu_get_caps_ioctl(str |
| return -EINVAL; |
| } |
| |
| - size = vgdev->capsets[found_valid].max_size; |
| - if (args->size > size) { |
| - spin_unlock(&vgdev->display_info_lock); |
| - return -EINVAL; |
| - } |
| + host_caps_size = vgdev->capsets[found_valid].max_size; |
| + /* only copy to user the minimum of the host caps size or the guest caps size */ |
| + size = min(args->size, host_caps_size); |
| |
| list_for_each_entry(cache_ent, &vgdev->cap_cache, head) { |
| if (cache_ent->id == args->cap_set_id && |
| --- a/include/uapi/drm/virtgpu_drm.h |
| +++ b/include/uapi/drm/virtgpu_drm.h |
| @@ -63,6 +63,7 @@ struct drm_virtgpu_execbuffer { |
| }; |
| |
| #define VIRTGPU_PARAM_3D_FEATURES 1 /* do we have 3D features in the hw */ |
| +#define VIRTGPU_PARAM_CAPSET_QUERY_FIX 2 /* do we have the capset fix */ |
| |
| struct drm_virtgpu_getparam { |
| __u64 param; |