From 0891d88a03acefb37b63bb28395d8b93b923d1c3 Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Thu, 25 May 2023 12:04:22 +0000 Subject: [PATCH] drm: Allow DRM_IOCTL_GET_UNIQUE on render nodes. On NetBSD, libdrm uses this to discover what kind of bus the device is on, without which it refuses to expose the render node at all, rendering it useless. With this change, libdrm is able to use render nodes on NetBSD. Since this is just reading out information about the bus type and bus/dev/func numbers, I don't think it's problematic to expose to render nodes. This requires tweaking the access path to the master. XXX pullup-10 --- sys/external/bsd/drm2/dist/drm/drm_ioctl.c | 36 ++++++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/sys/external/bsd/drm2/dist/drm/drm_ioctl.c b/sys/external/bsd/drm2/dist/drm/drm_ioctl.c index c2eb8e9a5fd2..1c9f57f2d311 100644 --- a/sys/external/bsd/drm2/dist/drm/drm_ioctl.c +++ b/sys/external/bsd/drm2/dist/drm/drm_ioctl.c @@ -129,19 +129,35 @@ int drm_getunique(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_unique *u = data; - struct drm_master *master = file_priv->master; + struct drm_master *master; + int ret; - mutex_lock(&master->dev->master_mutex); - if (u->unique_len >= master->unique_len) { - if (copy_to_user(u->unique, master->unique, master->unique_len)) { - mutex_unlock(&master->dev->master_mutex); - return -EFAULT; - } + mutex_lock(&dev->master_mutex); + master = dev->master; + if (master == NULL) { + ret = -ENXIO; + goto out; + } + + /* + * Copy out only if the user allocated enough space. Either + * way, on success, report the actual size -- so the user can + * allocate enough space if they didn't before, or so they know + * exactly how much we copied out. + */ + if (u->unique_len < master->unique_len) { + ret = 0; + } else { + ret = copy_to_user(u->unique, master->unique, + master->unique_len); + if (ret) + goto out; } u->unique_len = master->unique_len; - mutex_unlock(&master->dev->master_mutex); - return 0; +out: mutex_unlock(&dev->master_mutex); + + return ret; } static void @@ -597,7 +613,7 @@ EXPORT_SYMBOL(drm_ioctl_permit); /* Ioctl table */ static const struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, DRM_RENDER_ALLOW), - DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0), + DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, DRM_RENDER_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0), DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY),