mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Jocelyn Falempe <jfalempe@redhat.com>
To: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
	Maxime Ripard <mripard@kernel.org>,
	Thomas Zimmermann <tzimmermann@suse.de>,
	David Airlie <airlied@gmail.com>, Simona Vetter <simona@ffwll.ch>,
	Jocelyn Falempe <jfalempe@redhat.com>,
	Javier Martinez Canillas <javierm@redhat.com>,
	linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org
Subject: [PATCH v2 3/3] drm/panic: Add a drm_panic/draw_test in debugfs
Date: Mon,  8 Sep 2025 11:00:31 +0200	[thread overview]
Message-ID: <20250908090341.762049-4-jfalempe@redhat.com> (raw)
In-Reply-To: <20250908090341.762049-1-jfalempe@redhat.com>

This adds a new drm_panic/draw_test file in debugfs.
This file allows to test the panic screen rendering at different
resolution and pixel format.
It's useful only for kernel developers that want to create or
customize a panic screen.

If you want to check the result at 1024x768 using XRGB8888:

cd /sys/kernel/debug/drm_panic/
exec 3<> draw_test
echo 1024x768:XR24 >&3
cat <&3 > ~/panic_screen.raw
exec 3<&-

Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
---

v2:
 * Use debugfs instead of sending the framebuffer through the kunit logs. (Thomas Zimmermann).

 drivers/gpu/drm/Kconfig     |   2 +
 drivers/gpu/drm/drm_panic.c | 117 ++++++++++++++++++++++++++++++++++++
 2 files changed, 119 insertions(+)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index f7ea8e895c0c..0d3146070d9c 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -83,6 +83,8 @@ config DRM_PANIC_DEBUG
 	  Add dri/[device]/drm_panic_plane_x in the kernel debugfs, to force the
 	  panic handler to write the panic message to this plane scanout buffer.
 	  This is unsafe and should not be enabled on a production build.
+	  Also adds a drm_panic/draw_test file in debugfs, to easily test the
+	  panic screen rendering.
 	  If in doubt, say "N".
 
 config DRM_PANIC_SCREEN
diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
index d89812ff1935..0c01d6067eab 100644
--- a/drivers/gpu/drm/drm_panic.c
+++ b/drivers/gpu/drm/drm_panic.c
@@ -873,6 +873,7 @@ static void drm_panic(struct kmsg_dumper *dumper, struct kmsg_dump_detail *detai
  */
 #ifdef CONFIG_DRM_PANIC_DEBUG
 #include <linux/debugfs.h>
+#include <linux/vmalloc.h>
 
 static ssize_t debugfs_trigger_write(struct file *file, const char __user *user_buf,
 				     size_t count, loff_t *ppos)
@@ -901,8 +902,122 @@ static void debugfs_register_plane(struct drm_plane *plane, int index)
 	debugfs_create_file(fname, 0200, plane->dev->debugfs_root,
 			    plane, &dbg_drm_panic_ops);
 }
+
+/*
+ * Draw test interface
+ * This can be used to check the panic screen at any resolution/pixel format.
+ * The framebuffer memory is freed when the file is closed, so use this sh
+ * script to write the parameters and read the result without closing the file.
+ * cd /sys/kernel/debug/drm_panic/
+ * exec 3<> draw_test
+ * echo 1024x768:XR24 >&3
+ * cat <&3 > ~/panic_screen.raw
+ * exec 3<&-
+ */
+static ssize_t debugfs_drawtest_write(struct file *file, const char __user *user_buf,
+				      size_t count, loff_t *ppos)
+{
+	struct drm_scanout_buffer *sb = (struct drm_scanout_buffer *) file->private_data;
+	size_t fb_size;
+	void *fb;
+	char buf[64];
+	int width;
+	int height;
+	char cc1, cc2, cc3, cc4;
+	u32 drm_format;
+
+	if (count >= sizeof(buf))
+		return -EINVAL;
+
+	if (copy_from_user(buf, user_buf, count))
+		return -EFAULT;
+
+	if (sscanf(buf, "%dx%d:%c%c%c%c", &width, &height, &cc1, &cc2, &cc3, &cc4) != 6) {
+		pr_err("Invalid format. Expected: <width>x<height>:<fourcc>\n");
+		return -EINVAL;
+	}
+
+	drm_format = fourcc_code(cc1, cc2, cc3, cc4);
+	sb->format = drm_format_info(drm_format);
+	if (!sb->format)
+		return -EINVAL;
+
+	drm_panic_set_description("Test drawing from debugfs");
+
+	sb->width = width;
+	sb->height = height;
+	sb->pitch[0] = width * sb->format->cpp[0];
+
+	if (sb->map[0].vaddr)
+		vfree(sb->map[0].vaddr);
+
+	fb_size = height * sb->pitch[0];
+	fb = vmalloc(fb_size);
+	iosys_map_set_vaddr(&sb->map[0], fb);
+
+	draw_panic_dispatch(sb);
+
+	drm_panic_clear_description();
+	return count;
+}
+
+static ssize_t debugfs_drawtest_read(struct file *file, char __user *user_buf,
+				      size_t count, loff_t *ppos)
+{
+	struct drm_scanout_buffer *sb = (struct drm_scanout_buffer *) file->private_data;
+	int fb_size = sb->height * sb->pitch[0];
+
+	if (!sb->map[0].vaddr)
+		return 0;
+	return simple_read_from_buffer(user_buf, count, ppos, sb->map[0].vaddr, fb_size);
+}
+
+static int debugfs_drawtest_open(struct inode *inode, struct file *file)
+{
+	struct drm_scanout_buffer *sb = kzalloc(sizeof(*sb), GFP_KERNEL);
+
+	if (!sb)
+		return -ENOMEM;
+
+	file->private_data = sb;
+	return 0;
+}
+
+static int debugfs_drawtest_release(struct inode *inode, struct file *file)
+{
+	struct drm_scanout_buffer *sb = (struct drm_scanout_buffer *) file->private_data;
+
+	vfree(sb->map[0].vaddr);
+	kfree(sb);
+	return 0;
+}
+
+static const struct file_operations dbg_drm_panic_test_ops = {
+	.owner = THIS_MODULE,
+	.write = debugfs_drawtest_write,
+	.read = debugfs_drawtest_read,
+	.open = debugfs_drawtest_open,
+	.release = debugfs_drawtest_release,
+};
+
+static struct dentry *drm_panic_debugfs_dir;
+
+static void debugfs_register_drawtest(void)
+{
+	drm_panic_debugfs_dir = debugfs_create_dir("drm_panic", NULL);
+	debugfs_create_file("draw_test", 0600, drm_panic_debugfs_dir,
+			    NULL, &dbg_drm_panic_test_ops);
+}
+
+static void debugfs_unregister_drawtest(void)
+{
+	debugfs_remove(drm_panic_debugfs_dir);
+}
+
 #else
 static void debugfs_register_plane(struct drm_plane *plane, int index) {}
+static void debugfs_register_drawtest(void) {}
+static void debugfs_unregister_drawtest(void) {}
 #endif /* CONFIG_DRM_PANIC_DEBUG */
 
 /**
@@ -977,6 +1092,7 @@ void drm_panic_unregister(struct drm_device *dev)
 void __init drm_panic_init(void)
 {
 	drm_panic_qr_init();
+	debugfs_register_drawtest();
 }
 
 /**
@@ -985,6 +1101,7 @@ void __init drm_panic_init(void)
 void drm_panic_exit(void)
 {
 	drm_panic_qr_exit();
+	debugfs_unregister_drawtest();
 }
 
 #ifdef CONFIG_DRM_KUNIT_TEST
-- 
2.51.0


  parent reply	other threads:[~2025-09-08  9:04 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-08  9:00 [PATCH v2 0/3] drm/panic: Add kunit tests for drm_panic Jocelyn Falempe
2025-09-08  9:00 ` [PATCH v2 1/3] drm/panic: Rename draw_panic_static_* to draw_panic_screen_* Jocelyn Falempe
2025-09-08  9:00 ` [PATCH v2 2/3] drm/panic: Add kunit tests for drm_panic Jocelyn Falempe
2025-09-10  8:33   ` Maxime Ripard
2025-09-10 15:16     ` Jocelyn Falempe
2025-09-23  9:57       ` Maxime Ripard
2025-09-25 15:50         ` Jocelyn Falempe
2025-09-08  9:00 ` Jocelyn Falempe [this message]
2025-09-10 10:49   ` [PATCH v2 3/3] drm/panic: Add a drm_panic/draw_test in debugfs Maxime Ripard
2025-09-11 12:00     ` Jocelyn Falempe
2025-09-23 10:15       ` Maxime Ripard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250908090341.762049-4-jfalempe@redhat.com \
    --to=jfalempe@redhat.com \
    --cc=airlied@gmail.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=javierm@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=mripard@kernel.org \
    --cc=simona@ffwll.ch \
    --cc=tzimmermann@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®