Sun Apr 21 03:02:51 2024 UTC (31d)
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.

PR kern/58180


(riastradh)
diff -r1.24 -r1.25 src/sys/external/bsd/drm2/dist/drm/drm_ioctl.c

cvs diff -r1.24 -r1.25 src/sys/external/bsd/drm2/dist/drm/drm_ioctl.c (expand / switch to context diff)
--- src/sys/external/bsd/drm2/dist/drm/drm_ioctl.c 2022/10/15 15:19:28 1.24
+++ src/sys/external/bsd/drm2/dist/drm/drm_ioctl.c 2024/04/21 03:02:51 1.25
@@ -1,4 +1,4 @@
-/*	$NetBSD: drm_ioctl.c,v 1.24 2022/10/15 15:19:28 riastradh Exp $	*/
+/*	$NetBSD: drm_ioctl.c,v 1.25 2024/04/21 03:02:51 riastradh Exp $	*/
 
 /*
  * Created: Fri Jan  8 09:01:26 1999 by faith@valinux.com
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: drm_ioctl.c,v 1.24 2022/10/15 15:19:28 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: drm_ioctl.c,v 1.25 2024/04/21 03:02:51 riastradh Exp $");
 
 #include <linux/export.h>
 #include <linux/nospec.h>
@@ -129,19 +129,35 @@
 		  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 @@
 /* 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),