4.9-stable review patch. If anyone has any objections, please let me know.
------------------
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@... 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;