drm/virtio: Add option to disable KMS support
Add a build option to disable modesetting support. This is useful in cases where the guest only needs to use the GPU in a headless mode, or (such as in the CrOS usage) window surfaces are proxied to a host compositor. As the modesetting ioctls are a big surface area for potential security bugs to be found (it's happened in the past, we should assume it will again in the future), it makes sense to have a build option to disable those ioctls in cases where they serve no legitimate purpose. v2: Use more if (IS_ENABLED(...)) v3: Also permit the host to advertise no scanouts v4: Spiff out commit msg v5: Make num_scanouts==0 and DRM_VIRTIO_GPU_KMS=n behave the same v6: Drop conditionally building virtgpu_display.c and early-out of it's init/fini fxns instead Signed-off-by: Rob Clark <robdclark@chromium.org> Reviewed-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Reviewed-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> Link: https://patchwork.freedesktop.org/patch/msgid/20230302233506.3146290-1-robdclark@gmail.com
This commit is contained in:
parent
e3ecbd2177
commit
72122c69d7
4 changed files with 35 additions and 9 deletions
|
@ -11,3 +11,14 @@ config DRM_VIRTIO_GPU
|
||||||
QEMU based VMMs (like KVM or Xen).
|
QEMU based VMMs (like KVM or Xen).
|
||||||
|
|
||||||
If unsure say M.
|
If unsure say M.
|
||||||
|
|
||||||
|
config DRM_VIRTIO_GPU_KMS
|
||||||
|
bool "Virtio GPU driver modesetting support"
|
||||||
|
depends on DRM_VIRTIO_GPU
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Enable modesetting support for virtio GPU driver. This can be
|
||||||
|
disabled in cases where only "headless" usage of the GPU is
|
||||||
|
required.
|
||||||
|
|
||||||
|
If unsure, say Y.
|
||||||
|
|
|
@ -336,6 +336,9 @@ int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev)
|
||||||
{
|
{
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
|
||||||
|
if (!vgdev->num_scanouts)
|
||||||
|
return 0;
|
||||||
|
|
||||||
ret = drmm_mode_config_init(vgdev->ddev);
|
ret = drmm_mode_config_init(vgdev->ddev);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -362,6 +365,9 @@ void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (!vgdev->num_scanouts)
|
||||||
|
return;
|
||||||
|
|
||||||
for (i = 0 ; i < vgdev->num_scanouts; ++i)
|
for (i = 0 ; i < vgdev->num_scanouts; ++i)
|
||||||
kfree(vgdev->outputs[i].edid);
|
kfree(vgdev->outputs[i].edid);
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,6 +172,10 @@ MODULE_AUTHOR("Alon Levy");
|
||||||
DEFINE_DRM_GEM_FOPS(virtio_gpu_driver_fops);
|
DEFINE_DRM_GEM_FOPS(virtio_gpu_driver_fops);
|
||||||
|
|
||||||
static const struct drm_driver driver = {
|
static const struct drm_driver driver = {
|
||||||
|
/*
|
||||||
|
* If KMS is disabled DRIVER_MODESET and DRIVER_ATOMIC are masked
|
||||||
|
* out via drm_device::driver_features:
|
||||||
|
*/
|
||||||
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_RENDER | DRIVER_ATOMIC,
|
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_RENDER | DRIVER_ATOMIC,
|
||||||
.open = virtio_gpu_driver_open,
|
.open = virtio_gpu_driver_open,
|
||||||
.postclose = virtio_gpu_driver_postclose,
|
.postclose = virtio_gpu_driver_postclose,
|
||||||
|
|
|
@ -223,12 +223,15 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev)
|
||||||
num_scanouts, &num_scanouts);
|
num_scanouts, &num_scanouts);
|
||||||
vgdev->num_scanouts = min_t(uint32_t, num_scanouts,
|
vgdev->num_scanouts = min_t(uint32_t, num_scanouts,
|
||||||
VIRTIO_GPU_MAX_SCANOUTS);
|
VIRTIO_GPU_MAX_SCANOUTS);
|
||||||
if (!vgdev->num_scanouts) {
|
|
||||||
DRM_ERROR("num_scanouts is zero\n");
|
if (IS_ENABLED(CONFIG_DRM_VIRTIO_GPU_KMS) || !vgdev->num_scanouts) {
|
||||||
ret = -EINVAL;
|
DRM_INFO("KMS disabled\n");
|
||||||
goto err_scanouts;
|
vgdev->num_scanouts = 0;
|
||||||
|
vgdev->has_edid = false;
|
||||||
|
dev->driver_features &= ~(DRIVER_MODESET | DRIVER_ATOMIC);
|
||||||
|
} else {
|
||||||
|
DRM_INFO("number of scanouts: %d\n", num_scanouts);
|
||||||
}
|
}
|
||||||
DRM_INFO("number of scanouts: %d\n", num_scanouts);
|
|
||||||
|
|
||||||
virtio_cread_le(vgdev->vdev, struct virtio_gpu_config,
|
virtio_cread_le(vgdev->vdev, struct virtio_gpu_config,
|
||||||
num_capsets, &num_capsets);
|
num_capsets, &num_capsets);
|
||||||
|
@ -246,10 +249,12 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev)
|
||||||
virtio_gpu_get_capsets(vgdev, num_capsets);
|
virtio_gpu_get_capsets(vgdev, num_capsets);
|
||||||
if (vgdev->has_edid)
|
if (vgdev->has_edid)
|
||||||
virtio_gpu_cmd_get_edids(vgdev);
|
virtio_gpu_cmd_get_edids(vgdev);
|
||||||
virtio_gpu_cmd_get_display_info(vgdev);
|
if (vgdev->num_scanouts) {
|
||||||
virtio_gpu_notify(vgdev);
|
virtio_gpu_cmd_get_display_info(vgdev);
|
||||||
wait_event_timeout(vgdev->resp_wq, !vgdev->display_info_pending,
|
virtio_gpu_notify(vgdev);
|
||||||
5 * HZ);
|
wait_event_timeout(vgdev->resp_wq, !vgdev->display_info_pending,
|
||||||
|
5 * HZ);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_scanouts:
|
err_scanouts:
|
||||||
|
|
Loading…
Add table
Reference in a new issue