* [PATCH v3 00/14] drm/panic: Split into core and helpers
@ 2026-09-02 12:13 Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 01/14] drm/panic: Do not use un-escaped URL as format string Thomas Zimmermann
` (17 more replies)
0 siblings, 18 replies; 19+ messages in thread
From: Thomas Zimmermann @ 2026-09-02 12:13 UTC (permalink / raw)
To: jfalempe, javierm, airlied, simona, maarten.lankhorst, mripard,
geert, rdunlap
Cc: dri-devel, linux-doc, amd-gfx, rust-for-linux, linux-hyperv,
intel-gfx, intel-xe, imx, linux-arm-kernel, nouveau,
linux-renesas-soc, virtualization, sashiko-reviews,
Thomas Zimmermann
Split DRM's current panic handling into a core and a helper module.
The core is still part of DRM's core library. The panic helpers are
part of DRM's KMS helper module (for now).
The motivation behind this series is to get panic handling's drawing
code out of the DRM core. At some point it should share a single
module with DRM's other drawing and format conversion.
With the series applied, panic handling follows DRM's established
design pattern of having a DRM core interface with a dedicated
implementation in each driver. Drivers share common code in helper
modules. For panic handling, the DRM core still contains the panic
entry points, the parameters and the debugfs interface. All drawing
is now located in the panic helpers.
Patches 1 to 4 improve several issues in the current panic code. It
makes sense to fix them before moving the core around.
Patches 5 to 8 put handling of all panic state and locking into a
single place, drm_panic_display_panic_screen(). It is maintained by
panic handling's DRM core code. This also enables the test cases to
work more independently from the kernel's configuration.
Patches 9 to 13 split the panic-handling code into the core and panic
helpers. The former maintains all state, locking and public interfaces.
The latter handles drawing and details of the involved framebuffers.
DRM devices that offer panic handling provide a single callback, struct
drm_plane_funcs.display_panic_screen. A new initializer macro makes it
point to the existing panic-drawing implementation. Hence there's no
change in features or functionality. If panic handling is configured
off, it all clears out to NULL.
Patch 14 reworks the test cases slighly, so that they can be build as
a separate module. Do 'modprobe drm_panic_helper_test' to run them.
Tested under bochs, i915, amdgpu with debugfs and test cases.
Future directions:
- Panic handling shares drawing code with format conversion and
clients. There's even more drawing code in vkms. Later series' can
attempt to unify and harmonize all these implementations in a single
draw module.
- The drawing helper drm_plane_helper_display_panic_screen() still
implements various access schemes (map, set_pixel, memcpy) in a single
function. It could be split up into specialized helpers.
- If we ever need a driver-specific helper, it is now possible to
implement a custom version of display_panic_screen.
v3:
- keep qrbuf allocation as-is (Jocelyn)
- handle kmap failures gracefully
- handle unescaped URL strings correctly
- fix per-plane panic testing
- clean up after test cases
v2:
- resolve the various Kconfig issues (Randy)
- remove changes to qrbuf allocation (Jocelyn, Geert)
- fix possible URL format-string attack
- make test cases work again uder certain edge cases
- add better error reporting from failed draw_screen
- filter out non-primary planes from panic handling
Thomas Zimmermann (14):
drm/panic: Do not use un-escaped URL as format string
drm/panic: Test address from kmap op for NULL
drm/panic: Return -EINVAL if font is not available
drm/panic: Return errno codes if panic output fails
drm/panic: Pass colors to draw_panic_dispatch()
drm/panic: Pass global module parameters to drm_panic_dispatch()
drm/panic: Return from screen_user if display is too small
drm/panic: Retry in dispatch function if panic output fails
drm/panic: Split draw_panic_plane()
drm/panic: Restrict to primary planes
drm/panic: Display panic screen via per-plane callback
drm/panic: Internalize panic locking in DRM core and helpers
drm/panic: Move panic display code into helper library
drm/panic: Compile KUnit tests as module
Documentation/gpu/drm-kms-helpers.rst | 11 +-
Documentation/gpu/drm-kms.rst | 3 +
MAINTAINERS | 11 +-
drivers/gpu/drm/Kconfig | 9 +-
drivers/gpu/drm/Kconfig.debug | 1 +
drivers/gpu/drm/Makefile | 3 +-
.../amd/display/amdgpu_dm/amdgpu_dm_plane.c | 2 +
drivers/gpu/drm/ast/ast_mode.c | 2 +
drivers/gpu/drm/drm_atomic_helper.c | 2 +-
drivers/gpu/drm/drm_crtc_internal.h | 2 -
drivers/gpu/drm/drm_drv.c | 3 +-
drivers/gpu/drm/drm_kms_helper_common.c | 14 +
drivers/gpu/drm/drm_modeset_helper.c | 2 +
drivers/gpu/drm/drm_panic.c | 926 +-----------------
drivers/gpu/drm/drm_panic_helper.c | 918 +++++++++++++++++
...drm_panic_qr.rs => drm_panic_helper_qr.rs} | 4 +-
drivers/gpu/drm/drm_panic_internal.h | 69 ++
drivers/gpu/drm/hyperv/hyperv_drm_modeset.c | 2 +
drivers/gpu/drm/i915/display/i9xx_plane.c | 3 +
.../drm/i915/display/skl_universal_plane.c | 4 +
drivers/gpu/drm/imx/ipuv3/ipuv3-plane.c | 2 +
drivers/gpu/drm/mgag200/mgag200_drv.h | 4 +-
drivers/gpu/drm/nouveau/dispnv50/wndw.c | 2 +
.../gpu/drm/renesas/rcar-du/rcar_du_plane.c | 2 +
.../drm/renesas/shmobile/shmob_drm_plane.c | 2 +
drivers/gpu/drm/sysfb/drm_sysfb_helper.h | 4 +-
drivers/gpu/drm/sysfb/vesadrm.c | 1 +
drivers/gpu/drm/tests/Makefile | 1 +
...m_panic_test.c => drm_panic_helper_test.c} | 73 +-
drivers/gpu/drm/tidss/tidss_plane.c | 2 +
drivers/gpu/drm/tiny/bochs.c | 4 +-
drivers/gpu/drm/virtio/virtgpu_plane.c | 2 +
include/drm/drm_mode_config.h | 4 +-
include/drm/drm_modeset_helper_vtables.h | 11 +-
include/drm/drm_panic.h | 117 +--
include/drm/drm_panic_helper.h | 40 +
include/drm/drm_plane.h | 57 ++
rust/bindings/bindings_helper.h | 4 +-
38 files changed, 1287 insertions(+), 1036 deletions(-)
create mode 100644 drivers/gpu/drm/drm_panic_helper.c
rename drivers/gpu/drm/{drm_panic_qr.rs => drm_panic_helper_qr.rs} (99%)
create mode 100644 drivers/gpu/drm/drm_panic_internal.h
rename drivers/gpu/drm/tests/{drm_panic_test.c => drm_panic_helper_test.c} (77%)
create mode 100644 include/drm/drm_panic_helper.h
base-commit: aa389a514292b196ae89c6515568b3329abeec63
prerequisite-patch-id: c67e5d886a47b7d0266d81100837557fda34cb24
prerequisite-patch-id: a5a973e527c88a5b47053d7a72aefe0b550197cb
prerequisite-patch-id: b9adc9622920a3e70168e672c2c92795b3e3a106
prerequisite-patch-id: 5030de433a01c2e99056cadb676a8e2ba35f055a
--
2.55.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v3 01/14] drm/panic: Do not use un-escaped URL as format string
2026-09-02 12:13 [PATCH v3 00/14] drm/panic: Split into core and helpers Thomas Zimmermann
@ 2026-09-02 12:13 ` Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 02/14] drm/panic: Test address from kmap op for NULL Thomas Zimmermann
` (16 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Thomas Zimmermann @ 2026-09-02 12:13 UTC (permalink / raw)
To: jfalempe, javierm, airlied, simona, maarten.lankhorst, mripard,
geert, rdunlap
Cc: dri-devel, linux-doc, amd-gfx, rust-for-linux, linux-hyperv,
intel-gfx, intel-xe, imx, linux-arm-kernel, nouveau,
linux-renesas-soc, virtualization, sashiko-reviews,
Thomas Zimmermann, stable
Replace the direct use of DRM_PANIC_SCREEN_QR_CODE_URL in snprintf()
with a %s conversion specifier. Avoids a possible vulnerabilty from
a crafted URL string.
As the attacker needs to control the kernel at the Kconfig level, the
potential for an exploit is likely low.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Fixes: cb5164ac43d0 ("drm/panic: Add a QR code panic screen")
Cc: Javier Martinez Canillas <javierm@redhat.com>
Cc: Jocelyn Falempe <jfalempe@redhat.com>
Cc: dri-devel@lists.freedesktop.org
Cc: <stable@vger.kernel.org> # v6.12+
---
drivers/gpu/drm/drm_panic.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
index e576c4791861..ba21df4be338 100644
--- a/drivers/gpu/drm/drm_panic.c
+++ b/drivers/gpu/drm/drm_panic.c
@@ -658,7 +658,8 @@ static int drm_panic_get_qr_code_url(u8 **qr_image)
char *kmsg;
int max_qr_data_size, url_len;
- url_len = snprintf(url, sizeof(url), CONFIG_DRM_PANIC_SCREEN_QR_CODE_URL "?a=%s&v=%s&z=",
+ url_len = snprintf(url, sizeof(url), "%s?a=%s&v=%s&z=",
+ CONFIG_DRM_PANIC_SCREEN_QR_CODE_URL,
utsname()->machine, utsname()->release);
max_qr_data_size = drm_panic_qr_max_data_size(panic_qr_version, url_len);
--
2.55.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v3 02/14] drm/panic: Test address from kmap op for NULL
2026-09-02 12:13 [PATCH v3 00/14] drm/panic: Split into core and helpers Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 01/14] drm/panic: Do not use un-escaped URL as format string Thomas Zimmermann
@ 2026-09-02 12:13 ` Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 03/14] drm/panic: Return -EINVAL if font is not available Thomas Zimmermann
` (15 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Thomas Zimmermann @ 2026-09-02 12:13 UTC (permalink / raw)
To: jfalempe, javierm, airlied, simona, maarten.lankhorst, mripard,
geert, rdunlap
Cc: dri-devel, linux-doc, amd-gfx, rust-for-linux, linux-hyperv,
intel-gfx, intel-xe, imx, linux-arm-kernel, nouveau,
linux-renesas-soc, virtualization, sashiko-reviews,
Thomas Zimmermann, stable
Do nothing if kmap_local_page_try_from_panic() returns NULL. This is
not likely to hapen, as the previous page from the same memory area
has been mapped successfully.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Fixes: 23437509a694 ("drm/panic: Fix 24bit pixel crossing page boundaries")
Cc: Javier Martinez Canillas <javierm@redhat.com>
Cc: Jocelyn Falempe <jfalempe@redhat.com>
Cc: dri-devel@lists.freedesktop.org
Cc: <stable@vger.kernel.org> # v6.18+
---
drivers/gpu/drm/drm_panic.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
index ba21df4be338..d28ce8878e05 100644
--- a/drivers/gpu/drm/drm_panic.c
+++ b/drivers/gpu/drm/drm_panic.c
@@ -178,6 +178,8 @@ static void drm_panic_write_pixel24_xpage(void *vaddr, struct page *next_page,
u8 *p = vaddr + offset;
vaddr2 = kmap_local_page_try_from_panic(next_page);
+ if (!vaddr2)
+ return;
*p++ = color & 0xff;
color >>= 8;
--
2.55.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v3 03/14] drm/panic: Return -EINVAL if font is not available
2026-09-02 12:13 [PATCH v3 00/14] drm/panic: Split into core and helpers Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 01/14] drm/panic: Do not use un-escaped URL as format string Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 02/14] drm/panic: Test address from kmap op for NULL Thomas Zimmermann
@ 2026-09-02 12:13 ` Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 04/14] drm/panic: Return errno codes if panic output fails Thomas Zimmermann
` (14 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Thomas Zimmermann @ 2026-09-02 12:13 UTC (permalink / raw)
To: jfalempe, javierm, airlied, simona, maarten.lankhorst, mripard,
geert, rdunlap
Cc: dri-devel, linux-doc, amd-gfx, rust-for-linux, linux-hyperv,
intel-gfx, intel-xe, imx, linux-arm-kernel, nouveau,
linux-renesas-soc, virtualization, sashiko-reviews,
Thomas Zimmermann
Font lookup does not allocate memory. Hence reporting ENOMEM on
failed lookups is misleading. Report EINVAL instead.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
---
drivers/gpu/drm/drm_panic.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
index d28ce8878e05..62490d32019c 100644
--- a/drivers/gpu/drm/drm_panic.c
+++ b/drivers/gpu/drm/drm_panic.c
@@ -751,8 +751,10 @@ static int _draw_panic_screen_qr_code(struct drm_scanout_buffer *sb)
int qr_width, qr_canvas_width, qr_pitch, v_margin;
u8 *qr_image;
- if (!font || !qrbuf1 || !qrbuf2 || !stream.workspace)
+ if (!qrbuf1 || !qrbuf2 || !stream.workspace)
return -ENOMEM;
+ if (!font)
+ return -EINVAL;
r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height);
--
2.55.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v3 04/14] drm/panic: Return errno codes if panic output fails
2026-09-02 12:13 [PATCH v3 00/14] drm/panic: Split into core and helpers Thomas Zimmermann
` (2 preceding siblings ...)
2026-09-02 12:13 ` [PATCH v3 03/14] drm/panic: Return -EINVAL if font is not available Thomas Zimmermann
@ 2026-09-02 12:13 ` Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 05/14] drm/panic: Pass colors to draw_panic_dispatch() Thomas Zimmermann
` (13 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Thomas Zimmermann @ 2026-09-02 12:13 UTC (permalink / raw)
To: jfalempe, javierm, airlied, simona, maarten.lankhorst, mripard,
geert, rdunlap
Cc: dri-devel, linux-doc, amd-gfx, rust-for-linux, linux-hyperv,
intel-gfx, intel-xe, imx, linux-arm-kernel, nouveau,
linux-renesas-soc, virtualization, sashiko-reviews,
Thomas Zimmermann
Return errno codes from the panic output helpers to detect invalid
panic handling. Avoid flushing the display if an error ocured. The
unflushed display output might be helpful in debugging.
For now, test the result values in the panic test cases. A later patch
will add support for retrying failed panic output.
v2:
- forward return value of draw_panic_screen_user() (Sashiko)
- forward errno code from drm_panic_get_qr_code
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
---
drivers/gpu/drm/drm_panic.c | 47 +++++++++++++++++---------
drivers/gpu/drm/tests/drm_panic_test.c | 16 +++++----
2 files changed, 41 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
index 62490d32019c..cc33a2b4bb52 100644
--- a/drivers/gpu/drm/drm_panic.c
+++ b/drivers/gpu/drm/drm_panic.c
@@ -480,7 +480,7 @@ static void drm_panic_logo_draw(struct drm_scanout_buffer *sb, struct drm_rect *
fg_color);
}
-static void draw_panic_screen_user(struct drm_scanout_buffer *sb)
+static int draw_panic_screen_user(struct drm_scanout_buffer *sb)
{
u32 fg_color = drm_draw_color_from_xrgb8888(CONFIG_DRM_PANIC_FOREGROUND_COLOR,
sb->format->format);
@@ -491,7 +491,7 @@ static void draw_panic_screen_user(struct drm_scanout_buffer *sb)
unsigned int msg_width, msg_height;
if (!font)
- return;
+ return -EINVAL;
r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height);
drm_panic_logo_rect(&r_logo, font);
@@ -510,6 +510,8 @@ static void draw_panic_screen_user(struct drm_scanout_buffer *sb)
drm_panic_logo_draw(sb, &r_logo, font, fg_color);
draw_txt_rectangle(sb, font, panic_msg, panic_msg_lines, true, &r_msg, fg_color);
+
+ return 0;
}
/*
@@ -549,7 +551,7 @@ static int draw_line_with_wrap(struct drm_scanout_buffer *sb, const struct font_
* Draw the kmsg buffer to the screen, starting from the youngest message at the bottom,
* and going up until reaching the top of the screen.
*/
-static void draw_panic_screen_kmsg(struct drm_scanout_buffer *sb)
+static int draw_panic_screen_kmsg(struct drm_scanout_buffer *sb)
{
u32 fg_color = drm_draw_color_from_xrgb8888(CONFIG_DRM_PANIC_FOREGROUND_COLOR,
sb->format->format);
@@ -564,7 +566,7 @@ static void draw_panic_screen_kmsg(struct drm_scanout_buffer *sb)
int yoffset;
if (!font || font->width > sb->width)
- return;
+ return -EINVAL;
yoffset = sb->height - font->height - (sb->height % font->height) / 2;
@@ -591,6 +593,8 @@ static void draw_panic_screen_kmsg(struct drm_scanout_buffer *sb)
start--;
}
}
+
+ return 0;
}
#if defined(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
@@ -767,7 +771,9 @@ static int _draw_panic_screen_qr_code(struct drm_scanout_buffer *sb)
max_qr_size = min(3 * sb->width / 4, 3 * sb->height / 4);
qr_width = drm_panic_get_qr_code(&qr_image);
- if (qr_width <= 0)
+ if (qr_width < 0)
+ return qr_width;
+ else if (!qr_width)
return -ENOSPC;
qr_canvas_width = qr_width + QR_MARGIN * 2;
@@ -808,10 +814,11 @@ static int _draw_panic_screen_qr_code(struct drm_scanout_buffer *sb)
return 0;
}
-static void draw_panic_screen_qr_code(struct drm_scanout_buffer *sb)
+static int draw_panic_screen_qr_code(struct drm_scanout_buffer *sb)
{
if (_draw_panic_screen_qr_code(sb))
- draw_panic_screen_user(sb);
+ return draw_panic_screen_user(sb);
+ return 0;
}
#else
static void drm_panic_qr_init(void) {};
@@ -882,23 +889,25 @@ static bool drm_panic_is_format_supported(const struct drm_format_info *format)
return drm_draw_can_convert_from_xrgb8888(format->format);
}
-static void draw_panic_dispatch(struct drm_scanout_buffer *sb)
+static int draw_panic_dispatch(struct drm_scanout_buffer *sb)
{
+ int ret;
+
switch (drm_panic_type) {
case DRM_PANIC_TYPE_KMSG:
- draw_panic_screen_kmsg(sb);
+ ret = draw_panic_screen_kmsg(sb);
break;
-
#if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
case DRM_PANIC_TYPE_QR:
- draw_panic_screen_qr_code(sb);
+ ret = draw_panic_screen_qr_code(sb);
break;
#endif
-
case DRM_PANIC_TYPE_USER:
default:
- draw_panic_screen_user(sb);
+ ret = draw_panic_screen_user(sb);
}
+
+ return ret;
}
static void drm_panic_set_description(const char *description)
@@ -945,9 +954,15 @@ static void draw_panic_plane(struct drm_plane *plane, const char *description)
drm_panic_set_description(description);
- draw_panic_dispatch(&sb);
- if (plane->helper_private->panic_flush)
- plane->helper_private->panic_flush(plane);
+ ret = draw_panic_dispatch(&sb);
+ if (!ret) {
+ /*
+ * Only flush if we have a panic screen to display. Otherwise
+ * it's probably better to leave the display output as-is.
+ */
+ if (plane->helper_private->panic_flush)
+ plane->helper_private->panic_flush(plane);
+ }
drm_panic_clear_description();
diff --git a/drivers/gpu/drm/tests/drm_panic_test.c b/drivers/gpu/drm/tests/drm_panic_test.c
index ad2f3a2f93b6..fdd77b0cc54c 100644
--- a/drivers/gpu/drm/tests/drm_panic_test.c
+++ b/drivers/gpu/drm/tests/drm_panic_test.c
@@ -30,7 +30,7 @@ struct drm_test_mode {
const int width;
const int height;
const u32 format;
- void (*draw_screen)(struct drm_scanout_buffer *sb);
+ int (*draw_screen)(struct drm_scanout_buffer *sb);
const char *fname;
};
@@ -87,7 +87,7 @@ static void drm_test_panic_screen_user_map(struct kunit *test)
const struct drm_test_mode *params = test->param_value;
char *fb;
int fb_size;
- int i;
+ int i, ret;
sb->format = drm_format_info(params->format);
fb_size = params->width * params->height * sb->format->cpp[0];
@@ -102,7 +102,8 @@ static void drm_test_panic_screen_user_map(struct kunit *test)
sb->height = params->height;
sb->pitch[0] = params->width * sb->format->cpp[0];
- params->draw_screen(sb);
+ ret = params->draw_screen(sb);
+ KUNIT_ASSERT_EQ(test, ret, 0);
for (i = 0; i < fb_size; i++)
drm_panic_check_color_byte(test, fb[i]);
@@ -119,7 +120,7 @@ static void drm_test_panic_screen_user_page(struct kunit *test)
{
struct drm_scanout_buffer *sb = test->priv;
const struct drm_test_mode *params = test->param_value;
- int fb_size, p, i, npages;
+ int fb_size, p, i, npages, ret;
struct page **pages;
u8 *vaddr;
@@ -146,7 +147,8 @@ static void drm_test_panic_screen_user_page(struct kunit *test)
sb->height = params->height;
sb->pitch[0] = params->width * sb->format->cpp[0];
- params->draw_screen(sb);
+ ret = params->draw_screen(sb);
+ KUNIT_ASSERT_EQ(test, ret, 0);
for (p = 0; p < npages; p++) {
int bytes_in_page = (p == npages - 1) ? fb_size - p * PAGE_SIZE : PAGE_SIZE;
@@ -182,6 +184,7 @@ static void drm_test_panic_screen_user_set_pixel(struct kunit *test)
{
struct drm_scanout_buffer *sb = test->priv;
const struct drm_test_mode *params = test->param_value;
+ int ret;
sb->format = drm_format_info(params->format);
sb->set_pixel = drm_test_panic_set_pixel;
@@ -189,7 +192,8 @@ static void drm_test_panic_screen_user_set_pixel(struct kunit *test)
sb->height = params->height;
sb->private = test;
- params->draw_screen(sb);
+ ret = params->draw_screen(sb);
+ KUNIT_ASSERT_EQ(test, ret, 0);
}
static void drm_test_panic_desc(const struct drm_test_mode *t, char *desc)
--
2.55.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v3 05/14] drm/panic: Pass colors to draw_panic_dispatch()
2026-09-02 12:13 [PATCH v3 00/14] drm/panic: Split into core and helpers Thomas Zimmermann
` (3 preceding siblings ...)
2026-09-02 12:13 ` [PATCH v3 04/14] drm/panic: Return errno codes if panic output fails Thomas Zimmermann
@ 2026-09-02 12:13 ` Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 06/14] drm/panic: Pass global module parameters to drm_panic_dispatch() Thomas Zimmermann
` (12 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Thomas Zimmermann @ 2026-09-02 12:13 UTC (permalink / raw)
To: jfalempe, javierm, airlied, simona, maarten.lankhorst, mripard,
geert, rdunlap
Cc: dri-devel, linux-doc, amd-gfx, rust-for-linux, linux-hyperv,
intel-gfx, intel-xe, imx, linux-arm-kernel, nouveau,
linux-renesas-soc, virtualization, sashiko-reviews,
Thomas Zimmermann
Set the panic-screen colors in draw_panic_plane() as a single point
of truth. Pass the values into the individual drawing functions.
In the test cases, replace the Kconfig-defined colors with white and
black. Allows for removal of the tests' limitations and dependency on
the exact values. All tests now always verify the generated output.
Hardcoding the test colors will later also allow for building the
test case without having DRM panic handling enabled.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
---
drivers/gpu/drm/drm_panic.c | 54 +++++++++++++++-----------
drivers/gpu/drm/tests/drm_panic_test.c | 26 +++++++++----
2 files changed, 49 insertions(+), 31 deletions(-)
diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
index cc33a2b4bb52..834653d288a9 100644
--- a/drivers/gpu/drm/drm_panic.c
+++ b/drivers/gpu/drm/drm_panic.c
@@ -480,12 +480,8 @@ static void drm_panic_logo_draw(struct drm_scanout_buffer *sb, struct drm_rect *
fg_color);
}
-static int draw_panic_screen_user(struct drm_scanout_buffer *sb)
+static int draw_panic_screen_user(struct drm_scanout_buffer *sb, u32 fg_color, u32 bg_color)
{
- u32 fg_color = drm_draw_color_from_xrgb8888(CONFIG_DRM_PANIC_FOREGROUND_COLOR,
- sb->format->format);
- u32 bg_color = drm_draw_color_from_xrgb8888(CONFIG_DRM_PANIC_BACKGROUND_COLOR,
- sb->format->format);
const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL);
struct drm_rect r_screen, r_logo, r_msg;
unsigned int msg_width, msg_height;
@@ -493,6 +489,9 @@ static int draw_panic_screen_user(struct drm_scanout_buffer *sb)
if (!font)
return -EINVAL;
+ fg_color = drm_draw_color_from_xrgb8888(fg_color, sb->format->format);
+ bg_color = drm_draw_color_from_xrgb8888(bg_color, sb->format->format);
+
r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height);
drm_panic_logo_rect(&r_logo, font);
@@ -551,12 +550,8 @@ static int draw_line_with_wrap(struct drm_scanout_buffer *sb, const struct font_
* Draw the kmsg buffer to the screen, starting from the youngest message at the bottom,
* and going up until reaching the top of the screen.
*/
-static int draw_panic_screen_kmsg(struct drm_scanout_buffer *sb)
+static int draw_panic_screen_kmsg(struct drm_scanout_buffer *sb, u32 fg_color, u32 bg_color)
{
- u32 fg_color = drm_draw_color_from_xrgb8888(CONFIG_DRM_PANIC_FOREGROUND_COLOR,
- sb->format->format);
- u32 bg_color = drm_draw_color_from_xrgb8888(CONFIG_DRM_PANIC_BACKGROUND_COLOR,
- sb->format->format);
const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL);
struct drm_rect r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height);
struct kmsg_dump_iter iter;
@@ -568,6 +563,9 @@ static int draw_panic_screen_kmsg(struct drm_scanout_buffer *sb)
if (!font || font->width > sb->width)
return -EINVAL;
+ fg_color = drm_draw_color_from_xrgb8888(fg_color, sb->format->format);
+ bg_color = drm_draw_color_from_xrgb8888(bg_color, sb->format->format);
+
yoffset = sb->height - font->height - (sb->height % font->height) / 2;
/* Fill with the background color, and draw text on top */
@@ -742,12 +740,9 @@ static int drm_panic_get_qr_code(u8 **qr_image)
/*
* Draw the panic message at the center of the screen, with a QR Code
*/
-static int _draw_panic_screen_qr_code(struct drm_scanout_buffer *sb)
+static int _draw_panic_screen_qr_code(struct drm_scanout_buffer *sb,
+ u32 fg_color, u32 bg_color)
{
- u32 fg_color = drm_draw_color_from_xrgb8888(CONFIG_DRM_PANIC_FOREGROUND_COLOR,
- sb->format->format);
- u32 bg_color = drm_draw_color_from_xrgb8888(CONFIG_DRM_PANIC_BACKGROUND_COLOR,
- sb->format->format);
const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL);
struct drm_rect r_screen, r_logo, r_msg, r_qr, r_qr_canvas;
unsigned int max_qr_size, scale;
@@ -760,6 +755,9 @@ static int _draw_panic_screen_qr_code(struct drm_scanout_buffer *sb)
if (!font)
return -EINVAL;
+ fg_color = drm_draw_color_from_xrgb8888(fg_color, sb->format->format);
+ bg_color = drm_draw_color_from_xrgb8888(bg_color, sb->format->format);
+
r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height);
drm_panic_logo_rect(&r_logo, font);
@@ -814,10 +812,10 @@ static int _draw_panic_screen_qr_code(struct drm_scanout_buffer *sb)
return 0;
}
-static int draw_panic_screen_qr_code(struct drm_scanout_buffer *sb)
+static int draw_panic_screen_qr_code(struct drm_scanout_buffer *sb, u32 fg_color, u32 bg_color)
{
- if (_draw_panic_screen_qr_code(sb))
- return draw_panic_screen_user(sb);
+ if (_draw_panic_screen_qr_code(sb, fg_color, bg_color))
+ return draw_panic_screen_user(sb, fg_color, bg_color);
return 0;
}
#else
@@ -889,22 +887,22 @@ static bool drm_panic_is_format_supported(const struct drm_format_info *format)
return drm_draw_can_convert_from_xrgb8888(format->format);
}
-static int draw_panic_dispatch(struct drm_scanout_buffer *sb)
+static int draw_panic_dispatch(struct drm_scanout_buffer *sb, u32 fg_color, u32 bg_color)
{
int ret;
switch (drm_panic_type) {
case DRM_PANIC_TYPE_KMSG:
- ret = draw_panic_screen_kmsg(sb);
+ ret = draw_panic_screen_kmsg(sb, fg_color, bg_color);
break;
#if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
case DRM_PANIC_TYPE_QR:
- ret = draw_panic_screen_qr_code(sb);
+ ret = draw_panic_screen_qr_code(sb, fg_color, bg_color);
break;
#endif
case DRM_PANIC_TYPE_USER:
default:
- ret = draw_panic_screen_user(sb);
+ ret = draw_panic_screen_user(sb, fg_color, bg_color);
}
return ret;
@@ -939,6 +937,16 @@ static void draw_panic_plane(struct drm_plane *plane, const char *description)
struct drm_scanout_buffer sb = { };
int ret;
unsigned long flags;
+#if defined(CONFIG_DRM_PANIC_FOREGROUND_COLOR)
+ u32 fg_color = CONFIG_DRM_PANIC_FOREGROUND_COLOR;
+#else
+ u32 fg_color = 0x00ffffff;
+#endif
+#if defined(CONFIG_DRM_PANIC_BACKGROUND_COLOR)
+ u32 bg_color = CONFIG_DRM_PANIC_BACKGROUND_COLOR;
+#else
+ u32 bg_color = 0x00000000;
+#endif
if (!drm_panic_trylock(plane->dev, flags))
return;
@@ -954,7 +962,7 @@ static void draw_panic_plane(struct drm_plane *plane, const char *description)
drm_panic_set_description(description);
- ret = draw_panic_dispatch(&sb);
+ ret = draw_panic_dispatch(&sb, fg_color, bg_color);
if (!ret) {
/*
* Only flush if we have a panic screen to display. Otherwise
diff --git a/drivers/gpu/drm/tests/drm_panic_test.c b/drivers/gpu/drm/tests/drm_panic_test.c
index fdd77b0cc54c..969a096ec840 100644
--- a/drivers/gpu/drm/tests/drm_panic_test.c
+++ b/drivers/gpu/drm/tests/drm_panic_test.c
@@ -14,17 +14,10 @@
#include <linux/units.h>
#include <linux/vmalloc.h>
-/* Check the framebuffer color only if the panic colors are the default */
-#if (CONFIG_DRM_PANIC_BACKGROUND_COLOR == 0 && \
- CONFIG_DRM_PANIC_FOREGROUND_COLOR == 0xffffff)
-
static void drm_panic_check_color_byte(struct kunit *test, u8 b)
{
KUNIT_EXPECT_TRUE(test, (b == 0 || b == 0xff));
}
-#else
-static void drm_panic_check_color_byte(struct kunit *test, u8 b) {}
-#endif
struct drm_test_mode {
const int width;
@@ -48,10 +41,27 @@ struct drm_test_mode {
.width = w, \
.height = h, \
.format = f, \
- .draw_screen = draw_panic_screen_##name, \
+ .draw_screen = draw_panic_screen_ ## name ## _default, \
.fname = #name, \
}, \
+static int draw_panic_screen_user_default(struct drm_scanout_buffer *sb)
+{
+ return draw_panic_screen_user(sb, 0x00ffffff, 0x00000000);
+}
+
+static int draw_panic_screen_kmsg_default(struct drm_scanout_buffer *sb)
+{
+ return draw_panic_screen_kmsg(sb, 0x00ffffff, 0x00000000);
+}
+
+#if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
+static int draw_panic_screen_qr_code_default(struct drm_scanout_buffer *sb)
+{
+ return draw_panic_screen_qr_code(sb, 0x00ffffff, 0x00000000);
+}
+#endif
+
static const struct drm_test_mode drm_test_modes_cases[] = {
DRM_TEST_MODE_LIST(user)
DRM_TEST_MODE_LIST(kmsg)
--
2.55.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v3 06/14] drm/panic: Pass global module parameters to drm_panic_dispatch()
2026-09-02 12:13 [PATCH v3 00/14] drm/panic: Split into core and helpers Thomas Zimmermann
` (4 preceding siblings ...)
2026-09-02 12:13 ` [PATCH v3 05/14] drm/panic: Pass colors to draw_panic_dispatch() Thomas Zimmermann
@ 2026-09-02 12:13 ` Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 07/14] drm/panic: Return from screen_user if display is too small Thomas Zimmermann
` (11 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Thomas Zimmermann @ 2026-09-02 12:13 UTC (permalink / raw)
To: jfalempe, javierm, airlied, simona, maarten.lankhorst, mripard,
geert, rdunlap
Cc: dri-devel, linux-doc, amd-gfx, rust-for-linux, linux-hyperv,
intel-gfx, intel-xe, imx, linux-arm-kernel, nouveau,
linux-renesas-soc, virtualization, sashiko-reviews,
Thomas Zimmermann
Set the panic type and QR version in draw_panic_plane() as a single
point of truth. Pass the values into the individual drawing functions.
In the test case, always create a QR code with version 40 (i.e., the
highest supported version).
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
---
drivers/gpu/drm/drm_panic.c | 39 ++++++++++++++++----------
drivers/gpu/drm/tests/drm_panic_test.c | 2 +-
2 files changed, 25 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
index 834653d288a9..f597ef04c5bc 100644
--- a/drivers/gpu/drm/drm_panic.c
+++ b/drivers/gpu/drm/drm_panic.c
@@ -654,7 +654,7 @@ static void drm_panic_qr_exit(void)
stream.workspace = NULL;
}
-static int drm_panic_get_qr_code_url(u8 **qr_image)
+static int drm_panic_get_qr_code_url(u8 **qr_image, unsigned int qr_version)
{
struct kmsg_dump_iter iter;
char url[256];
@@ -666,7 +666,7 @@ static int drm_panic_get_qr_code_url(u8 **qr_image)
CONFIG_DRM_PANIC_SCREEN_QR_CODE_URL,
utsname()->machine, utsname()->release);
- max_qr_data_size = drm_panic_qr_max_data_size(panic_qr_version, url_len);
+ max_qr_data_size = drm_panic_qr_max_data_size(qr_version, url_len);
max_kmsg_size = min(MAX_ZLIB_RATIO * max_qr_data_size, QR_BUFFER1_SIZE);
/* get kmsg to buffer 1 */
@@ -712,11 +712,11 @@ static int drm_panic_get_qr_code_url(u8 **qr_image)
qrbuf1, QR_BUFFER1_SIZE);
}
-static int drm_panic_get_qr_code_raw(u8 **qr_image)
+static int drm_panic_get_qr_code_raw(u8 **qr_image, unsigned int qr_version)
{
struct kmsg_dump_iter iter;
size_t kmsg_len;
- size_t max_kmsg_size = min(drm_panic_qr_max_data_size(panic_qr_version, 0),
+ size_t max_kmsg_size = min(drm_panic_qr_max_data_size(qr_version, 0),
QR_BUFFER1_SIZE);
kmsg_dump_rewind(&iter);
@@ -729,19 +729,20 @@ static int drm_panic_get_qr_code_raw(u8 **qr_image)
qrbuf2, QR_BUFFER2_SIZE);
}
-static int drm_panic_get_qr_code(u8 **qr_image)
+static int drm_panic_get_qr_code(u8 **qr_image, unsigned int qr_version)
{
if (strlen(CONFIG_DRM_PANIC_SCREEN_QR_CODE_URL) > 0)
- return drm_panic_get_qr_code_url(qr_image);
+ return drm_panic_get_qr_code_url(qr_image, qr_version);
else
- return drm_panic_get_qr_code_raw(qr_image);
+ return drm_panic_get_qr_code_raw(qr_image, qr_version);
}
/*
* Draw the panic message at the center of the screen, with a QR Code
*/
static int _draw_panic_screen_qr_code(struct drm_scanout_buffer *sb,
- u32 fg_color, u32 bg_color)
+ u32 fg_color, u32 bg_color,
+ unsigned int qr_version)
{
const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL);
struct drm_rect r_screen, r_logo, r_msg, r_qr, r_qr_canvas;
@@ -768,7 +769,7 @@ static int _draw_panic_screen_qr_code(struct drm_scanout_buffer *sb,
max_qr_size = min(3 * sb->width / 4, 3 * sb->height / 4);
- qr_width = drm_panic_get_qr_code(&qr_image);
+ qr_width = drm_panic_get_qr_code(&qr_image, qr_version);
if (qr_width < 0)
return qr_width;
else if (!qr_width)
@@ -812,9 +813,11 @@ static int _draw_panic_screen_qr_code(struct drm_scanout_buffer *sb,
return 0;
}
-static int draw_panic_screen_qr_code(struct drm_scanout_buffer *sb, u32 fg_color, u32 bg_color)
+static int draw_panic_screen_qr_code(struct drm_scanout_buffer *sb,
+ u32 fg_color, u32 bg_color,
+ unsigned int qr_version)
{
- if (_draw_panic_screen_qr_code(sb, fg_color, bg_color))
+ if (_draw_panic_screen_qr_code(sb, fg_color, bg_color, qr_version))
return draw_panic_screen_user(sb, fg_color, bg_color);
return 0;
}
@@ -887,17 +890,18 @@ static bool drm_panic_is_format_supported(const struct drm_format_info *format)
return drm_draw_can_convert_from_xrgb8888(format->format);
}
-static int draw_panic_dispatch(struct drm_scanout_buffer *sb, u32 fg_color, u32 bg_color)
+static int draw_panic_dispatch(struct drm_scanout_buffer *sb, enum drm_panic_type panic_type,
+ u32 fg_color, u32 bg_color, unsigned int qr_version)
{
int ret;
- switch (drm_panic_type) {
+ switch (panic_type) {
case DRM_PANIC_TYPE_KMSG:
ret = draw_panic_screen_kmsg(sb, fg_color, bg_color);
break;
#if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
case DRM_PANIC_TYPE_QR:
- ret = draw_panic_screen_qr_code(sb, fg_color, bg_color);
+ ret = draw_panic_screen_qr_code(sb, fg_color, bg_color, qr_version);
break;
#endif
case DRM_PANIC_TYPE_USER:
@@ -947,6 +951,11 @@ static void draw_panic_plane(struct drm_plane *plane, const char *description)
#else
u32 bg_color = 0x00000000;
#endif
+#if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
+ unsigned int qr_version = panic_qr_version;
+#else
+ unsigned int qr_version = 0;
+#endif
if (!drm_panic_trylock(plane->dev, flags))
return;
@@ -962,7 +971,7 @@ static void draw_panic_plane(struct drm_plane *plane, const char *description)
drm_panic_set_description(description);
- ret = draw_panic_dispatch(&sb, fg_color, bg_color);
+ ret = draw_panic_dispatch(&sb, drm_panic_type, fg_color, bg_color, qr_version);
if (!ret) {
/*
* Only flush if we have a panic screen to display. Otherwise
diff --git a/drivers/gpu/drm/tests/drm_panic_test.c b/drivers/gpu/drm/tests/drm_panic_test.c
index 969a096ec840..196496238d23 100644
--- a/drivers/gpu/drm/tests/drm_panic_test.c
+++ b/drivers/gpu/drm/tests/drm_panic_test.c
@@ -58,7 +58,7 @@ static int draw_panic_screen_kmsg_default(struct drm_scanout_buffer *sb)
#if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
static int draw_panic_screen_qr_code_default(struct drm_scanout_buffer *sb)
{
- return draw_panic_screen_qr_code(sb, 0x00ffffff, 0x00000000);
+ return draw_panic_screen_qr_code(sb, 0x00ffffff, 0x00000000, 40);
}
#endif
--
2.55.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v3 07/14] drm/panic: Return from screen_user if display is too small
2026-09-02 12:13 [PATCH v3 00/14] drm/panic: Split into core and helpers Thomas Zimmermann
` (5 preceding siblings ...)
2026-09-02 12:13 ` [PATCH v3 06/14] drm/panic: Pass global module parameters to drm_panic_dispatch() Thomas Zimmermann
@ 2026-09-02 12:13 ` Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 08/14] drm/panic: Retry in dispatch function if panic output fails Thomas Zimmermann
` (10 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Thomas Zimmermann @ 2026-09-02 12:13 UTC (permalink / raw)
To: jfalempe, javierm, airlied, simona, maarten.lankhorst, mripard,
geert, rdunlap
Cc: dri-devel, linux-doc, amd-gfx, rust-for-linux, linux-hyperv,
intel-gfx, intel-xe, imx, linux-arm-kernel, nouveau,
linux-renesas-soc, virtualization, sashiko-reviews,
Thomas Zimmermann
Return an error if the display is too small to display at least a
single character. If the panic handler cannot display any message
it does at least not destroy the current output, which might help
with identifying the problem.
This change duplicates the logic from screen_kmsg output.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
drivers/gpu/drm/drm_panic.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
index f597ef04c5bc..c317afc76669 100644
--- a/drivers/gpu/drm/drm_panic.c
+++ b/drivers/gpu/drm/drm_panic.c
@@ -486,7 +486,7 @@ static int draw_panic_screen_user(struct drm_scanout_buffer *sb, u32 fg_color, u
struct drm_rect r_screen, r_logo, r_msg;
unsigned int msg_width, msg_height;
- if (!font)
+ if (!font || font->width > sb->width)
return -EINVAL;
fg_color = drm_draw_color_from_xrgb8888(fg_color, sb->format->format);
--
2.55.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v3 08/14] drm/panic: Retry in dispatch function if panic output fails
2026-09-02 12:13 [PATCH v3 00/14] drm/panic: Split into core and helpers Thomas Zimmermann
` (6 preceding siblings ...)
2026-09-02 12:13 ` [PATCH v3 07/14] drm/panic: Return from screen_user if display is too small Thomas Zimmermann
@ 2026-09-02 12:13 ` Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 09/14] drm/panic: Split draw_panic_plane() Thomas Zimmermann
` (9 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Thomas Zimmermann @ 2026-09-02 12:13 UTC (permalink / raw)
To: jfalempe, javierm, airlied, simona, maarten.lankhorst, mripard,
geert, rdunlap
Cc: dri-devel, linux-doc, amd-gfx, rust-for-linux, linux-hyperv,
intel-gfx, intel-xe, imx, linux-arm-kernel, nouveau,
linux-renesas-soc, virtualization, sashiko-reviews,
Thomas Zimmermann
On failed output of QR codes and kmsg buffers, fall back to a user
message. QR-code output already did this internally, but now formally
support it in drm_panic_dispatch(). Streamlines the existing logic.
With the implicit fallback removed from QR-code support, the tests
cases fail for thr smallest output size (300x200). This is because the
QR code requires a minimal output size. Increase the size to 494x494,
which is the minimum supported size for QR output.
v3:
- update outdated commit description (Sashiko)
v2:
- fix minimum test size (Sashiko)
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
---
drivers/gpu/drm/drm_panic.c | 24 ++++++++++++------------
drivers/gpu/drm/tests/drm_panic_test.c | 2 +-
2 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
index c317afc76669..690e96e8f1f9 100644
--- a/drivers/gpu/drm/drm_panic.c
+++ b/drivers/gpu/drm/drm_panic.c
@@ -740,9 +740,9 @@ static int drm_panic_get_qr_code(u8 **qr_image, unsigned int qr_version)
/*
* Draw the panic message at the center of the screen, with a QR Code
*/
-static int _draw_panic_screen_qr_code(struct drm_scanout_buffer *sb,
- u32 fg_color, u32 bg_color,
- unsigned int qr_version)
+static int draw_panic_screen_qr_code(struct drm_scanout_buffer *sb,
+ u32 fg_color, u32 bg_color,
+ unsigned int qr_version)
{
const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL);
struct drm_rect r_screen, r_logo, r_msg, r_qr, r_qr_canvas;
@@ -812,15 +812,6 @@ static int _draw_panic_screen_qr_code(struct drm_scanout_buffer *sb,
drm_panic_blit(sb, &r_qr, qr_image, qr_pitch, scale, fg_color);
return 0;
}
-
-static int draw_panic_screen_qr_code(struct drm_scanout_buffer *sb,
- u32 fg_color, u32 bg_color,
- unsigned int qr_version)
-{
- if (_draw_panic_screen_qr_code(sb, fg_color, bg_color, qr_version))
- return draw_panic_screen_user(sb, fg_color, bg_color);
- return 0;
-}
#else
static void drm_panic_qr_init(void) {};
static void drm_panic_qr_exit(void) {};
@@ -895,13 +886,22 @@ static int draw_panic_dispatch(struct drm_scanout_buffer *sb, enum drm_panic_typ
{
int ret;
+retry:
switch (panic_type) {
case DRM_PANIC_TYPE_KMSG:
ret = draw_panic_screen_kmsg(sb, fg_color, bg_color);
+ if (ret) {
+ panic_type = DRM_PANIC_TYPE_USER;
+ goto retry;
+ }
break;
#if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
case DRM_PANIC_TYPE_QR:
ret = draw_panic_screen_qr_code(sb, fg_color, bg_color, qr_version);
+ if (ret) {
+ panic_type = DRM_PANIC_TYPE_USER;
+ goto retry;
+ }
break;
#endif
case DRM_PANIC_TYPE_USER:
diff --git a/drivers/gpu/drm/tests/drm_panic_test.c b/drivers/gpu/drm/tests/drm_panic_test.c
index 196496238d23..55d77bc203df 100644
--- a/drivers/gpu/drm/tests/drm_panic_test.c
+++ b/drivers/gpu/drm/tests/drm_panic_test.c
@@ -32,7 +32,7 @@ struct drm_test_mode {
*/
#define DRM_TEST_MODE_LIST(func) \
DRM_PANIC_TEST_MODE(1024, 768, DRM_FORMAT_XRGB8888, func) \
- DRM_PANIC_TEST_MODE(300, 200, DRM_FORMAT_XRGB8888, func) \
+ DRM_PANIC_TEST_MODE(494, 494, DRM_FORMAT_XRGB8888, func) \
DRM_PANIC_TEST_MODE(1920, 1080, DRM_FORMAT_XRGB8888, func) \
DRM_PANIC_TEST_MODE(1024, 768, DRM_FORMAT_RGB565, func) \
DRM_PANIC_TEST_MODE(1024, 768, DRM_FORMAT_RGB888, func) \
--
2.55.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v3 09/14] drm/panic: Split draw_panic_plane()
2026-09-02 12:13 [PATCH v3 00/14] drm/panic: Split into core and helpers Thomas Zimmermann
` (7 preceding siblings ...)
2026-09-02 12:13 ` [PATCH v3 08/14] drm/panic: Retry in dispatch function if panic output fails Thomas Zimmermann
@ 2026-09-02 12:13 ` Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 10/14] drm/panic: Restrict to primary planes Thomas Zimmermann
` (8 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Thomas Zimmermann @ 2026-09-02 12:13 UTC (permalink / raw)
To: jfalempe, javierm, airlied, simona, maarten.lankhorst, mripard,
geert, rdunlap
Cc: dri-devel, linux-doc, amd-gfx, rust-for-linux, linux-hyperv,
intel-gfx, intel-xe, imx, linux-arm-kernel, nouveau,
linux-renesas-soc, virtualization, sashiko-reviews,
Thomas Zimmermann
Move locking and parameters from draw_panic_plane() into the new
helper drm_panic_display_panic_screen(). Call draw_panic_plane() from
there.
The new helper drm_panic_display_panic_screen() is now the DRM core's
interface for displaying a panic screen. The code remaining in
draw_panic_plane() still does all the heavy lifting. It will become a
plane helper for DRM drivers.
v2:
- use panic_type argument in draw_panic_plane() (Sashiko)
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
drivers/gpu/drm/drm_panic.c | 62 ++++++++++++++++++++-----------------
1 file changed, 34 insertions(+), 28 deletions(-)
diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
index 690e96e8f1f9..624042c42a7f 100644
--- a/drivers/gpu/drm/drm_panic.c
+++ b/drivers/gpu/drm/drm_panic.c
@@ -936,42 +936,25 @@ static void drm_panic_clear_description(void)
desc_line->txt = NULL;
}
-static void draw_panic_plane(struct drm_plane *plane, const char *description)
+static void draw_panic_plane(struct drm_plane *plane, const char *description,
+ enum drm_panic_type panic_type, u32 fg_color, u32 bg_color,
+ unsigned int qr_version)
{
struct drm_scanout_buffer sb = { };
int ret;
- unsigned long flags;
-#if defined(CONFIG_DRM_PANIC_FOREGROUND_COLOR)
- u32 fg_color = CONFIG_DRM_PANIC_FOREGROUND_COLOR;
-#else
- u32 fg_color = 0x00ffffff;
-#endif
-#if defined(CONFIG_DRM_PANIC_BACKGROUND_COLOR)
- u32 bg_color = CONFIG_DRM_PANIC_BACKGROUND_COLOR;
-#else
- u32 bg_color = 0x00000000;
-#endif
-#if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
- unsigned int qr_version = panic_qr_version;
-#else
- unsigned int qr_version = 0;
-#endif
-
- if (!drm_panic_trylock(plane->dev, flags))
- return;
ret = plane->helper_private->get_scanout_buffer(plane, &sb);
if (ret || !drm_panic_is_format_supported(sb.format))
- goto unlock;
+ return;
/* One of these should be set, or it can't draw pixels */
if (!sb.set_pixel && !sb.pages && iosys_map_is_null(&sb.map[0]))
- goto unlock;
+ return;
drm_panic_set_description(description);
- ret = draw_panic_dispatch(&sb, drm_panic_type, fg_color, bg_color, qr_version);
+ ret = draw_panic_dispatch(&sb, panic_type, fg_color, bg_color, qr_version);
if (!ret) {
/*
* Only flush if we have a panic screen to display. Otherwise
@@ -982,9 +965,33 @@ static void draw_panic_plane(struct drm_plane *plane, const char *description)
}
drm_panic_clear_description();
+}
-unlock:
- drm_panic_unlock(plane->dev, flags);
+static void drm_panic_display_panic_screen(struct drm_plane *plane, const char *description)
+{
+#if defined(CONFIG_DRM_PANIC_FOREGROUND_COLOR)
+ u32 fg_color = CONFIG_DRM_PANIC_FOREGROUND_COLOR;
+#else
+ u32 fg_color = 0x00ffffff;
+#endif
+#if defined(CONFIG_DRM_PANIC_BACKGROUND_COLOR)
+ u32 bg_color = CONFIG_DRM_PANIC_BACKGROUND_COLOR;
+#else
+ u32 bg_color = 0x00000000;
+#endif
+#if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
+ unsigned int qr_version = panic_qr_version;
+#else
+ unsigned int qr_version = 0;
+#endif
+ struct drm_device *dev = plane->dev;
+ unsigned long flags;
+
+ if (drm_panic_trylock(dev, flags)) {
+ draw_panic_plane(plane, description, drm_panic_type,
+ fg_color, bg_color, qr_version);
+ drm_panic_unlock(dev, flags);
+ }
}
static struct drm_plane *to_drm_plane(struct kmsg_dumper *kd)
@@ -997,10 +1004,9 @@ static void drm_panic(struct kmsg_dumper *dumper, struct kmsg_dump_detail *detai
struct drm_plane *plane = to_drm_plane(dumper);
if (detail->reason == KMSG_DUMP_PANIC)
- draw_panic_plane(plane, detail->description);
+ drm_panic_display_panic_screen(plane, detail->description);
}
-
/*
* DEBUG FS, This is currently unsafe.
* Create one file per plane, so it's possible to debug one plane at a time.
@@ -1017,7 +1023,7 @@ static ssize_t debugfs_trigger_write(struct file *file, const char __user *user_
if (kstrtobool_from_user(user_buf, count, &run) == 0 && run) {
struct drm_plane *plane = file->private_data;
- draw_panic_plane(plane, "Test from debugfs");
+ drm_panic_display_panic_screen(plane, "Test from debugfs");
}
return count;
}
--
2.55.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v3 10/14] drm/panic: Restrict to primary planes
2026-09-02 12:13 [PATCH v3 00/14] drm/panic: Split into core and helpers Thomas Zimmermann
` (8 preceding siblings ...)
2026-09-02 12:13 ` [PATCH v3 09/14] drm/panic: Split draw_panic_plane() Thomas Zimmermann
@ 2026-09-02 12:13 ` Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 11/14] drm/panic: Display panic screen via per-plane callback Thomas Zimmermann
` (7 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Thomas Zimmermann @ 2026-09-02 12:13 UTC (permalink / raw)
To: jfalempe, javierm, airlied, simona, maarten.lankhorst, mripard,
geert, rdunlap
Cc: dri-devel, linux-doc, amd-gfx, rust-for-linux, linux-hyperv,
intel-gfx, intel-xe, imx, linux-arm-kernel, nouveau,
linux-renesas-soc, virtualization, sashiko-reviews,
Thomas Zimmermann
Restrict panic handling to primary displays. Overlays and cursors
should not display panic output. If there are exceptions, they can
be registered by the driver itself.
v3:
- also update drm_panic_is_enabled() (Sashiko)
- still do some testing when unregistering (Sashiko)
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
---
drivers/gpu/drm/drm_panic.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
index 624042c42a7f..381f8aab3661 100644
--- a/drivers/gpu/drm/drm_panic.c
+++ b/drivers/gpu/drm/drm_panic.c
@@ -1059,9 +1059,13 @@ bool drm_panic_is_enabled(struct drm_device *dev)
if (!dev->mode_config.num_total_plane)
return false;
- drm_for_each_plane(plane, dev)
- if (plane->helper_private && plane->helper_private->get_scanout_buffer)
- return true;
+ drm_for_each_plane(plane, dev) {
+ if (plane->type != DRM_PLANE_TYPE_PRIMARY)
+ continue;
+ if (!plane->helper_private || !plane->helper_private->get_scanout_buffer)
+ continue;
+ return true;
+ }
return false;
}
EXPORT_SYMBOL(drm_panic_is_enabled);
@@ -1079,6 +1083,8 @@ void drm_panic_register(struct drm_device *dev)
return;
drm_for_each_plane(plane, dev) {
+ if (plane->type != DRM_PLANE_TYPE_PRIMARY)
+ continue;
if (!plane->helper_private || !plane->helper_private->get_scanout_buffer)
continue;
plane->kmsg_panic.dump = drm_panic;
@@ -1106,6 +1112,8 @@ void drm_panic_unregister(struct drm_device *dev)
return;
drm_for_each_plane(plane, dev) {
+ if (plane->type != DRM_PLANE_TYPE_PRIMARY)
+ continue;
if (!plane->helper_private || !plane->helper_private->get_scanout_buffer)
continue;
kmsg_dump_unregister(&plane->kmsg_panic);
--
2.55.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v3 11/14] drm/panic: Display panic screen via per-plane callback
2026-09-02 12:13 [PATCH v3 00/14] drm/panic: Split into core and helpers Thomas Zimmermann
` (9 preceding siblings ...)
2026-09-02 12:13 ` [PATCH v3 10/14] drm/panic: Restrict to primary planes Thomas Zimmermann
@ 2026-09-02 12:13 ` Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 12/14] drm/panic: Internalize panic locking in DRM core and helpers Thomas Zimmermann
` (6 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Thomas Zimmermann @ 2026-09-02 12:13 UTC (permalink / raw)
To: jfalempe, javierm, airlied, simona, maarten.lankhorst, mripard,
geert, rdunlap
Cc: dri-devel, linux-doc, amd-gfx, rust-for-linux, linux-hyperv,
intel-gfx, intel-xe, imx, linux-arm-kernel, nouveau,
linux-renesas-soc, virtualization, sashiko-reviews,
Thomas Zimmermann
Add display_panic_screen to struct drm_plane_funcs. If set on a plane,
register a panic handler for the plane from the DRM core's panic
handling. Invoke this helper from the core to display a panic screen.
The new callback replaces get_scanout_buffer as signal for panic
support in a plane. Using get_scanout_buffer is now merely a detail
of the implementation. This will also free struct drm_scanout_buffer
for use cases besides panic handling.
With display_panic_screen in place, rename draw_panic_plane() to
drm_plane_helper_display_panic_screen() and make it available to DRM
drivers via drm_panic_helper.h. Do not change the implementation or
functionality of this code. drm_plane_helper_display_panic_screen()
still supports kernel messages, user messages and QR codes on various
color formats.
Then update all drivers that implement panic support. Provide the
initializer macro DRM_PANIC_PLANE_FUNCS that sets display_panic_screen
to drm_plane_helper_display_panic_screen(). If panic handling has
been disabled, it instead clears the callback. There's again no change
in functionality.
This logically splits panic handling into a set of entry points in the
DRM code and a set of helper functions provided by drivers. The core
invokes the driver's helper via callback, while the driver can tailor
the implementation to its needs. Panic handling now works like most
other interfaces in the DRM framework.
Locking and state-handling happens in the DRM core or helpers. Drivers
that receive a call to display_panic_screen can assume that no concurrent
modeset takes place on the plane or its CRTC.
Also update the documentation. Move information about locking and state
guarantees from drm_panic_trylock() to display_panic_screen, where
drivers authors can find it easily. Move information about the features
of the current implementation to drm_panic_helper_display_panic_screen().
v2:
- only consider planes with get_scanout_buffer (Sashiko)
- set callback for planes create with drm_crtc_init() (Sashiko)
- return errno code from display_panic_screen
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
MAINTAINERS | 3 +-
.../amd/display/amdgpu_dm/amdgpu_dm_plane.c | 2 +
drivers/gpu/drm/ast/ast_mode.c | 2 +
drivers/gpu/drm/drm_modeset_helper.c | 2 +
drivers/gpu/drm/drm_panic.c | 91 ++++++++++---------
drivers/gpu/drm/hyperv/hyperv_drm_modeset.c | 2 +
drivers/gpu/drm/i915/display/i9xx_plane.c | 3 +
.../drm/i915/display/skl_universal_plane.c | 4 +
drivers/gpu/drm/imx/ipuv3/ipuv3-plane.c | 2 +
drivers/gpu/drm/mgag200/mgag200_drv.h | 4 +-
drivers/gpu/drm/nouveau/dispnv50/wndw.c | 2 +
.../gpu/drm/renesas/rcar-du/rcar_du_plane.c | 2 +
.../drm/renesas/shmobile/shmob_drm_plane.c | 2 +
drivers/gpu/drm/sysfb/drm_sysfb_helper.h | 4 +-
drivers/gpu/drm/sysfb/vesadrm.c | 1 +
drivers/gpu/drm/tidss/tidss_plane.c | 2 +
drivers/gpu/drm/tiny/bochs.c | 4 +-
drivers/gpu/drm/virtio/virtgpu_plane.c | 2 +
include/drm/drm_mode_config.h | 4 +-
include/drm/drm_modeset_helper_vtables.h | 11 ++-
include/drm/drm_panic.h | 49 ++--------
include/drm/drm_panic_helper.h | 27 ++++++
include/drm/drm_plane.h | 57 ++++++++++++
23 files changed, 192 insertions(+), 90 deletions(-)
create mode 100644 include/drm/drm_panic_helper.h
diff --git a/MAINTAINERS b/MAINTAINERS
index bedbb8557a1d..c66c3fe93f3d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9113,7 +9113,8 @@ F: drivers/gpu/drm/drm_draw.c
F: drivers/gpu/drm/drm_draw_internal.h
F: drivers/gpu/drm/drm_panic*.c
F: drivers/gpu/drm/tests/drm_panic_test.c
-F: include/drm/drm_panic*
+F: include/drm/drm_panic.h
+F: include/drm/drm_panic_helper.h
DRM PANIC QR CODE
M: Jocelyn Falempe <jfalempe@redhat.com>
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 824ef3ce5de0..eadc22a255bb 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -28,6 +28,7 @@
#include <drm/drm_blend.h>
#include "drm/drm_framebuffer.h"
#include <drm/drm_gem_atomic_helper.h>
+#include <drm/drm_panic_helper.h>
#include <drm/drm_plane_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_fourcc.h>
@@ -2177,6 +2178,7 @@ static const struct drm_plane_funcs dm_plane_funcs = {
.atomic_set_property = dm_atomic_plane_set_property,
.atomic_get_property = dm_atomic_plane_get_property,
#endif
+ DRM_PANIC_PLANE_FUNCS,
};
int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index d5ed8c5c7925..ceebf9421100 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -43,6 +43,7 @@
#include <drm/drm_gem_shmem_helper.h>
#include <drm/drm_managed.h>
#include <drm/drm_panic.h>
+#include <drm/drm_panic_helper.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
@@ -652,6 +653,7 @@ static const struct drm_plane_funcs ast_primary_plane_funcs = {
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = drm_plane_cleanup,
DRM_GEM_SHADOW_PLANE_FUNCS,
+ DRM_PANIC_PLANE_FUNCS,
};
static int ast_primary_plane_init(struct ast_device *ast)
diff --git a/drivers/gpu/drm/drm_modeset_helper.c b/drivers/gpu/drm/drm_modeset_helper.c
index e54584da4c3d..cca623eb23e5 100644
--- a/drivers/gpu/drm/drm_modeset_helper.c
+++ b/drivers/gpu/drm/drm_modeset_helper.c
@@ -27,6 +27,7 @@
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_modeset_helper.h>
+#include <drm/drm_panic_helper.h>
#include <drm/drm_plane_helper.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
@@ -113,6 +114,7 @@ static const uint32_t safe_modeset_formats[] = {
static const struct drm_plane_funcs primary_plane_funcs = {
DRM_PLANE_NON_ATOMIC_FUNCS,
+ DRM_PANIC_PLANE_FUNCS,
};
/**
diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
index 381f8aab3661..7b9864857577 100644
--- a/drivers/gpu/drm/drm_panic.c
+++ b/drivers/gpu/drm/drm_panic.c
@@ -28,6 +28,7 @@
#include <drm/drm_framebuffer.h>
#include <drm/drm_modeset_helper_vtables.h>
#include <drm/drm_panic.h>
+#include <drm/drm_panic_helper.h>
#include <drm/drm_plane.h>
#include <drm/drm_print.h>
#include <drm/drm_rect.h>
@@ -42,32 +43,18 @@ MODULE_LICENSE("GPL");
/**
* DOC: overview
*
- * To enable DRM panic for a driver, the primary plane must implement a
- * &drm_plane_helper_funcs.get_scanout_buffer helper function. It is then
- * automatically registered to the drm panic handler.
- * When a panic occurs, the &drm_plane_helper_funcs.get_scanout_buffer will be
- * called, and the driver can provide a framebuffer so the panic handler can
- * draw the panic screen on it. Currently only linear buffer and a few color
- * formats are supported.
- * Optionally the driver can also provide a &drm_plane_helper_funcs.panic_flush
- * callback, that will be called after that, to send additional commands to the
- * hardware to make the scanout buffer visible.
- */
-
-/*
- * This module displays a user friendly message on screen when a kernel panic
- * occurs. This is conflicting with fbcon, so you can only enable it when fbcon
- * is disabled.
- * It's intended for end-user, so have minimal technical/debug information.
+ * This module displays a user friendly message on screen when a kernel
+ * panic occurs. This is conflicting with fbcon, so you can only enable
+ * it when fbcon is disabled. It's intended for end users and therefore
+ * have minimal technical/debug information.
*
- * Implementation details:
+ * To enable DRM panic for a driver, the at least one primary plane must
+ * implement struct &drm_plane_funcs.display_panic_screen. The plane is
+ * then automatically registered to the drm panic handler.
*
- * It is a panic handler, so it can't take lock, allocate memory, run tasks/irq,
- * or attempt to sleep. It's a best effort, and it may not be able to display
- * the message in all situations (like if the panic occurs in the middle of a
- * modesetting).
- * It will display only one static frame, so performance optimizations are low
- * priority as the machine is already in an unusable state.
+ * When a panic occurs, the DRM panic handler calls struct
+ * &drm_plane_funcs.display_panic_screen. See
+ * drm_plane_helper_display_panic_screen() for a generic implementation.
*/
struct drm_panic_line {
@@ -817,12 +804,6 @@ static void drm_panic_qr_init(void) {};
static void drm_panic_qr_exit(void) {};
#endif
-enum drm_panic_type {
- DRM_PANIC_TYPE_KMSG,
- DRM_PANIC_TYPE_USER,
- DRM_PANIC_TYPE_QR,
-};
-
static enum drm_panic_type drm_panic_type = -1;
static const char *drm_panic_type_map[] = {
@@ -936,21 +917,46 @@ static void drm_panic_clear_description(void)
desc_line->txt = NULL;
}
-static void draw_panic_plane(struct drm_plane *plane, const char *description,
- enum drm_panic_type panic_type, u32 fg_color, u32 bg_color,
- unsigned int qr_version)
+/**
+ * drm_plane_helper_display_panic_screen - Displays a panic screen according to the given settings
+ * @plane: the DRM plane to display to
+ * @description: error message to display
+ * @panic_type: type of panic screen
+ * @fg_color: text foreground color
+ * @bg_color: text background color
+ * @qr_version: version of the QR code, if any
+ *
+ * This helper display a panic screen on common primary planes. The panic
+ * screen can either display a kernel message, a user message or a QR code.
+ *
+ * The helper uses struct drm_plane_helper_funcs.get_scanout_buffer, where
+ * the plane can provide a scanout buffer that the panic handler can draw to.
+ * Currently only linear buffer and a few color formats are supported.
+ *
+ * Optionally the plane can also provide a &drm_plane_helper_funcs.panic_flush
+ * callback, which the DRM panic handler calls after drawing to send additional
+ * commands to the hardware to make the scanout buffer visible.
+ *
+ * Returns:
+ * 0 on success, or a negative errno code otherwise
+ */
+int drm_plane_helper_display_panic_screen(struct drm_plane *plane, const char *description,
+ enum drm_panic_type panic_type,
+ u32 fg_color, u32 bg_color, unsigned int qr_version)
{
struct drm_scanout_buffer sb = { };
int ret;
ret = plane->helper_private->get_scanout_buffer(plane, &sb);
+ if (ret)
+ return ret;
- if (ret || !drm_panic_is_format_supported(sb.format))
- return;
+ if (!drm_panic_is_format_supported(sb.format))
+ return -EINVAL;
/* One of these should be set, or it can't draw pixels */
if (!sb.set_pixel && !sb.pages && iosys_map_is_null(&sb.map[0]))
- return;
+ return -EINVAL;
drm_panic_set_description(description);
@@ -965,7 +971,10 @@ static void draw_panic_plane(struct drm_plane *plane, const char *description,
}
drm_panic_clear_description();
+
+ return ret;
}
+EXPORT_SYMBOL(drm_plane_helper_display_panic_screen);
static void drm_panic_display_panic_screen(struct drm_plane *plane, const char *description)
{
@@ -988,8 +997,8 @@ static void drm_panic_display_panic_screen(struct drm_plane *plane, const char *
unsigned long flags;
if (drm_panic_trylock(dev, flags)) {
- draw_panic_plane(plane, description, drm_panic_type,
- fg_color, bg_color, qr_version);
+ plane->funcs->display_panic_screen(plane, description, drm_panic_type,
+ fg_color, bg_color, qr_version);
drm_panic_unlock(dev, flags);
}
}
@@ -1062,7 +1071,7 @@ bool drm_panic_is_enabled(struct drm_device *dev)
drm_for_each_plane(plane, dev) {
if (plane->type != DRM_PLANE_TYPE_PRIMARY)
continue;
- if (!plane->helper_private || !plane->helper_private->get_scanout_buffer)
+ if (!plane->funcs || !plane->funcs->display_panic_screen)
continue;
return true;
}
@@ -1085,7 +1094,7 @@ void drm_panic_register(struct drm_device *dev)
drm_for_each_plane(plane, dev) {
if (plane->type != DRM_PLANE_TYPE_PRIMARY)
continue;
- if (!plane->helper_private || !plane->helper_private->get_scanout_buffer)
+ if (!plane->funcs || !plane->funcs->display_panic_screen)
continue;
plane->kmsg_panic.dump = drm_panic;
plane->kmsg_panic.max_reason = KMSG_DUMP_PANIC;
@@ -1114,7 +1123,7 @@ void drm_panic_unregister(struct drm_device *dev)
drm_for_each_plane(plane, dev) {
if (plane->type != DRM_PLANE_TYPE_PRIMARY)
continue;
- if (!plane->helper_private || !plane->helper_private->get_scanout_buffer)
+ if (!plane->funcs || !plane->funcs->display_panic_screen)
continue;
kmsg_dump_unregister(&plane->kmsg_panic);
}
diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c b/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c
index 1855749c1e41..3bf228ef97ff 100644
--- a/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c
+++ b/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c
@@ -18,6 +18,7 @@
#include <drm/drm_gem_shmem_helper.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_panic.h>
+#include <drm/drm_panic_helper.h>
#include <drm/drm_plane.h>
#include <drm/drm_print.h>
#include <drm/drm_vblank.h>
@@ -237,6 +238,7 @@ static const struct drm_plane_funcs hv_drm_plane_funcs = {
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = drm_plane_cleanup,
DRM_GEM_SHADOW_PLANE_FUNCS,
+ DRM_PANIC_PLANE_FUNCS,
};
static const struct drm_encoder_funcs hv_drm_simple_encoder_funcs_cleanup = {
diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c
index df6da1c6a359..0902b17d0269 100644
--- a/drivers/gpu/drm/i915/display/i9xx_plane.c
+++ b/drivers/gpu/drm/i915/display/i9xx_plane.c
@@ -8,6 +8,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_blend.h>
#include <drm/drm_fourcc.h>
+#include <drm/drm_panic_helper.h>
#include <drm/drm_print.h>
#include "i9xx_plane.h"
@@ -887,6 +888,7 @@ static const struct drm_plane_funcs i965_plane_funcs = {
.atomic_destroy_state = intel_plane_destroy_state,
.format_mod_supported = i965_plane_format_mod_supported,
.format_mod_supported_async = intel_plane_format_mod_supported_async,
+ DRM_PANIC_PLANE_FUNCS,
};
static const struct drm_plane_funcs i8xx_plane_funcs = {
@@ -897,6 +899,7 @@ static const struct drm_plane_funcs i8xx_plane_funcs = {
.atomic_destroy_state = intel_plane_destroy_state,
.format_mod_supported = i8xx_plane_format_mod_supported,
.format_mod_supported_async = intel_plane_format_mod_supported_async,
+ DRM_PANIC_PLANE_FUNCS,
};
static void i9xx_disable_tiling(struct intel_plane *plane)
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 5cda1ab90e40..8c0f414badf3 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -7,6 +7,7 @@
#include <drm/drm_blend.h>
#include <drm/drm_damage_helper.h>
#include <drm/drm_fourcc.h>
+#include <drm/drm_panic_helper.h>
#include <drm/drm_print.h>
#include <drm/intel/step.h>
@@ -2712,6 +2713,7 @@ static const struct drm_plane_funcs skl_plane_funcs = {
.atomic_destroy_state = intel_plane_destroy_state,
.format_mod_supported = skl_plane_format_mod_supported,
.format_mod_supported_async = intel_plane_format_mod_supported_async,
+ DRM_PANIC_PLANE_FUNCS,
};
static const struct drm_plane_funcs icl_plane_funcs = {
@@ -2722,6 +2724,7 @@ static const struct drm_plane_funcs icl_plane_funcs = {
.atomic_destroy_state = intel_plane_destroy_state,
.format_mod_supported = icl_plane_format_mod_supported,
.format_mod_supported_async = intel_plane_format_mod_supported_async,
+ DRM_PANIC_PLANE_FUNCS,
};
static const struct drm_plane_funcs tgl_plane_funcs = {
@@ -2732,6 +2735,7 @@ static const struct drm_plane_funcs tgl_plane_funcs = {
.atomic_destroy_state = intel_plane_destroy_state,
.format_mod_supported = tgl_plane_format_mod_supported,
.format_mod_supported_async = intel_plane_format_mod_supported_async,
+ DRM_PANIC_PLANE_FUNCS,
};
static void
diff --git a/drivers/gpu/drm/imx/ipuv3/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3/ipuv3-plane.c
index c7ec09e557c1..377db7cea726 100644
--- a/drivers/gpu/drm/imx/ipuv3/ipuv3-plane.c
+++ b/drivers/gpu/drm/imx/ipuv3/ipuv3-plane.c
@@ -14,6 +14,7 @@
#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_managed.h>
+#include <drm/drm_panic_helper.h>
#include <drm/drm_print.h>
#include <video/imx-ipu-v3.h>
@@ -362,6 +363,7 @@ static const struct drm_plane_funcs ipu_plane_funcs = {
.atomic_duplicate_state = ipu_plane_duplicate_state,
.atomic_destroy_state = ipu_plane_destroy_state,
.format_mod_supported = ipu_plane_format_mod_supported,
+ DRM_PANIC_PLANE_FUNCS,
};
static int ipu_plane_atomic_check(struct drm_plane *plane,
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
index 3732c62351bb..d3995ce876f4 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -17,6 +17,7 @@
#include <drm/drm_encoder.h>
#include <drm/drm_gem.h>
#include <drm/drm_gem_shmem_helper.h>
+#include <drm/drm_panic_helper.h>
#include <drm/drm_plane.h>
#include "mgag200_reg.h"
@@ -386,7 +387,8 @@ int mgag200_primary_plane_helper_get_scanout_buffer(struct drm_plane *plane,
.update_plane = drm_atomic_helper_update_plane, \
.disable_plane = drm_atomic_helper_disable_plane, \
.destroy = drm_plane_cleanup, \
- DRM_GEM_SHADOW_PLANE_FUNCS
+ DRM_GEM_SHADOW_PLANE_FUNCS, \
+ DRM_PANIC_PLANE_FUNCS
void mgag200_crtc_fill_gamma(struct mga_device *mdev, const struct drm_format_info *format);
void mgag200_crtc_load_gamma(struct mga_device *mdev,
diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c
index 15a322422f4e..fc29a291e96f 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c
@@ -39,6 +39,7 @@
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_panic.h>
+#include <drm/drm_panic_helper.h>
#include <drm/ttm/ttm_bo.h>
#include "nouveau_bo.h"
@@ -841,6 +842,7 @@ nv50_wndw = {
.atomic_duplicate_state = nv50_wndw_atomic_duplicate_state,
.atomic_destroy_state = nv50_wndw_atomic_destroy_state,
.format_mod_supported = nv50_plane_format_mod_supported,
+ DRM_PANIC_PLANE_FUNCS,
};
static const u64 nv50_cursor_format_modifiers[] = {
diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/renesas/rcar-du/rcar_du_plane.c
index 8870766b9e54..f4b0e5b70c7d 100644
--- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_plane.c
+++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_plane.c
@@ -16,6 +16,7 @@
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_dma_helper.h>
+#include <drm/drm_panic_helper.h>
#include "rcar_du_drv.h"
#include "rcar_du_group.h"
@@ -773,6 +774,7 @@ static const struct drm_plane_funcs rcar_du_plane_funcs = {
.atomic_destroy_state = rcar_du_plane_atomic_destroy_state,
.atomic_set_property = rcar_du_plane_atomic_set_property,
.atomic_get_property = rcar_du_plane_atomic_get_property,
+ DRM_PANIC_PLANE_FUNCS,
};
static const uint32_t formats[] = {
diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
index 148de34af785..907f85462fa0 100644
--- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
+++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c
@@ -14,6 +14,7 @@
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_dma_helper.h>
+#include <drm/drm_panic_helper.h>
#include "shmob_drm_drv.h"
#include "shmob_drm_kms.h"
@@ -286,6 +287,7 @@ static const struct drm_plane_funcs shmob_drm_plane_funcs = {
.reset = shmob_drm_plane_reset,
.atomic_duplicate_state = shmob_drm_plane_atomic_duplicate_state,
.atomic_destroy_state = shmob_drm_plane_atomic_destroy_state,
+ DRM_PANIC_PLANE_FUNCS,
};
static const uint32_t formats[] = {
diff --git a/drivers/gpu/drm/sysfb/drm_sysfb_helper.h b/drivers/gpu/drm/sysfb/drm_sysfb_helper.h
index 1c31267daa00..520f60daf6ef 100644
--- a/drivers/gpu/drm/sysfb/drm_sysfb_helper.h
+++ b/drivers/gpu/drm/sysfb/drm_sysfb_helper.h
@@ -12,6 +12,7 @@
#include <drm/drm_device.h>
#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_modes.h>
+#include <drm/drm_panic_helper.h>
struct drm_format_info;
struct drm_scanout_buffer;
@@ -144,7 +145,8 @@ void drm_sysfb_plane_atomic_destroy_state(struct drm_plane *plane,
.disable_plane = drm_atomic_helper_disable_plane, \
.atomic_create_state = drm_sysfb_plane_atomic_create_state, \
.atomic_duplicate_state = drm_sysfb_plane_atomic_duplicate_state, \
- .atomic_destroy_state = drm_sysfb_plane_atomic_destroy_state
+ .atomic_destroy_state = drm_sysfb_plane_atomic_destroy_state, \
+ DRM_PANIC_PLANE_FUNCS
/*
* CRTC
diff --git a/drivers/gpu/drm/sysfb/vesadrm.c b/drivers/gpu/drm/sysfb/vesadrm.c
index 6a67b2d2e451..14d2e6ab88aa 100644
--- a/drivers/gpu/drm/sysfb/vesadrm.c
+++ b/drivers/gpu/drm/sysfb/vesadrm.c
@@ -24,6 +24,7 @@
#include <drm/drm_managed.h>
#include <drm/drm_modeset_helper.h>
#include <drm/drm_modeset_helper_vtables.h>
+#include <drm/drm_panic_helper.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
diff --git a/drivers/gpu/drm/tidss/tidss_plane.c b/drivers/gpu/drm/tidss/tidss_plane.c
index 6d82976c2db1..b0d5d6959b88 100644
--- a/drivers/gpu/drm/tidss/tidss_plane.c
+++ b/drivers/gpu/drm/tidss/tidss_plane.c
@@ -12,6 +12,7 @@
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_atomic_helper.h>
+#include <drm/drm_panic_helper.h>
#include "tidss_crtc.h"
#include "tidss_dispc.h"
@@ -182,6 +183,7 @@ static const struct drm_plane_funcs tidss_plane_funcs = {
.atomic_create_state = drm_atomic_helper_plane_create_state,
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
+ DRM_PANIC_PLANE_FUNCS,
};
struct tidss_plane *tidss_plane_create(struct tidss_device *tidss,
diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c
index e2d957e51505..076d19b26511 100644
--- a/drivers/gpu/drm/tiny/bochs.c
+++ b/drivers/gpu/drm/tiny/bochs.c
@@ -20,6 +20,7 @@
#include <drm/drm_managed.h>
#include <drm/drm_module.h>
#include <drm/drm_panic.h>
+#include <drm/drm_panic_helper.h>
#include <drm/drm_plane_helper.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
@@ -501,7 +502,8 @@ static const struct drm_plane_funcs bochs_primary_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = drm_plane_cleanup,
- DRM_GEM_SHADOW_PLANE_FUNCS
+ DRM_GEM_SHADOW_PLANE_FUNCS,
+ DRM_PANIC_PLANE_FUNCS,
};
static void bochs_crtc_helper_mode_set_nofb(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c
index 1d1b27ece62a..108b5b93f130 100644
--- a/drivers/gpu/drm/virtio/virtgpu_plane.c
+++ b/drivers/gpu/drm/virtio/virtgpu_plane.c
@@ -30,6 +30,7 @@
#include <linux/virtio_dma_buf.h>
#include <drm/drm_managed.h>
#include <drm/drm_panic.h>
+#include <drm/drm_panic_helper.h>
#include <drm/drm_print.h>
#include "virtgpu_drv.h"
@@ -94,6 +95,7 @@ static const struct drm_plane_funcs virtio_gpu_plane_funcs = {
.reset = drm_atomic_helper_plane_reset,
.atomic_duplicate_state = virtio_gpu_plane_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
+ DRM_PANIC_PLANE_FUNCS,
};
static int virtio_gpu_plane_atomic_check(struct drm_plane *plane,
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index d8f5b7e9673e..084517beb924 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -495,8 +495,8 @@ struct drm_mode_config {
*
* Raw spinlock used to protect critical sections of code that access
* the display hardware or modeset software state, which the panic
- * printing code must be protected against. See drm_panic_trylock(),
- * drm_panic_lock() and drm_panic_unlock().
+ * printing code must be protected against. See the documentation on
+ * DRM panic handling for more information.
*/
struct raw_spinlock panic_lock;
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
index ca6268945c28..614bdee0c1ed 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -1442,17 +1442,20 @@ struct drm_plane_helper_funcs {
/**
* @get_scanout_buffer:
*
- * Get the current scanout buffer, to display a message with drm_panic.
+ * Get the current scanout buffer to display a message with drm_panic.
* The driver should do the minimum changes to provide a buffer,
* that can be used to display the panic screen. Currently only linear
* buffers are supported. Non-linear buffer support is on the TODO list.
* The device &dev.mode_config.panic_lock is taken before calling this
* function, so you can safely access the &plane.state
* It is called from a panic callback, and must follow its restrictions.
- * Please look the documentation at drm_panic_trylock() for an in-depth
+ * Please look the documentation on DRM panic handling for an in-depth
* discussions of what's safe and what is not allowed.
+ *
* It's a best effort mode, so it's expected that in some complex cases
- * the panic screen won't be displayed.
+ * the panic screen won't be displayed. Drivers must not make any
+ * assumptions about the actual state of the hardware.
+ *
* The returned &drm_scanout_buffer.map must be valid if no error code is
* returned.
*
@@ -1472,7 +1475,7 @@ struct drm_plane_helper_funcs {
* It is only called if get_scanout_buffer() returned successfully, and
* the &dev.mode_config.panic_lock is held during the entire sequence.
* It is called from a panic callback, and must follow its restrictions.
- * Please look the documentation at drm_panic_trylock() for an in-depth
+ * Please look the documentation on DRM panic handling for an in-depth
* discussions of what's safe and what is not allowed.
*/
void (*panic_flush)(struct drm_plane *plane);
diff --git a/include/drm/drm_panic.h b/include/drm/drm_panic.h
index ac0e46b73436..430df536de14 100644
--- a/include/drm/drm_panic.h
+++ b/include/drm/drm_panic.h
@@ -15,6 +15,14 @@
#include <drm/drm_device.h>
#include <drm/drm_fourcc.h>
+struct page;
+
+enum drm_panic_type {
+ DRM_PANIC_TYPE_KMSG,
+ DRM_PANIC_TYPE_USER,
+ DRM_PANIC_TYPE_QR,
+};
+
/**
* struct drm_scanout_buffer - DRM scanout buffer
*
@@ -87,45 +95,8 @@ struct drm_scanout_buffer {
* @dev: struct drm_device
* @flags: unsigned long irq flags you need to pass to the unlock() counterpart
*
- * This function must be called by any panic printing code. The panic printing
- * attempt must be aborted if the trylock fails.
- *
- * Panic printing code can make the following assumptions while holding the
- * panic lock:
- *
- * - Anything protected by drm_panic_lock() and drm_panic_unlock() pairs is safe
- * to access.
- *
- * - Furthermore the panic printing code only registers in drm_dev_unregister()
- * and gets removed in drm_dev_unregister(). This allows the panic code to
- * safely access any state which is invariant in between these two function
- * calls, like the list of planes &drm_mode_config.plane_list or most of the
- * struct drm_plane structure.
- *
- * Specifically thanks to the protection around plane updates in
- * drm_atomic_helper_swap_state() the following additional guarantees hold:
- *
- * - It is safe to deference the drm_plane.state pointer.
- *
- * - Anything in struct drm_plane_state or the driver's subclass thereof which
- * stays invariant after the atomic check code has finished is safe to access.
- * Specifically this includes the reference counted pointers to framebuffer
- * and buffer objects.
- *
- * - Anything set up by &drm_plane_helper_funcs.fb_prepare and cleaned up
- * &drm_plane_helper_funcs.fb_cleanup is safe to access, as long as it stays
- * invariant between these two calls. This also means that for drivers using
- * dynamic buffer management the framebuffer is pinned, and therefer all
- * relevant datastructures can be accessed without taking any further locks
- * (which would be impossible in panic context anyway).
- *
- * - Importantly, software and hardware state set up by
- * &drm_plane_helper_funcs.begin_fb_access and
- * &drm_plane_helper_funcs.end_fb_access is not safe to access.
- *
- * Drivers must not make any assumptions about the actual state of the hardware,
- * unless they explicitly protected these hardware access with drm_panic_lock()
- * and drm_panic_unlock().
+ * The panic-printing code calls this function. The panic printing attempt must
+ * be aborted if the trylock fails.
*
* Return:
* %0 when failing to acquire the raw spinlock, nonzero on success.
diff --git a/include/drm/drm_panic_helper.h b/include/drm/drm_panic_helper.h
new file mode 100644
index 000000000000..0b6ad8f61821
--- /dev/null
+++ b/include/drm/drm_panic_helper.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0 or MIT */
+
+#ifndef __DRM_DRM_PANIC_HELPER_H_
+#define __DRM_DRM_PANIC_HELPER_H_
+
+#include <linux/types.h>
+
+enum drm_panic_type;
+
+struct drm_plane;
+
+/* drm_panic_helper.c */
+int drm_plane_helper_display_panic_screen(struct drm_plane *plane,
+ const char *description,
+ enum drm_panic_type panic_type,
+ u32 fg_color, u32 bg_color,
+ unsigned int qr_version);
+
+#if IS_ENABLED(CONFIG_DRM_PANIC)
+#define DRM_PANIC_PLANE_FUNCS \
+ .display_panic_screen = drm_plane_helper_display_panic_screen
+#else
+#define DRM_PANIC_PLANE_FUNCS \
+ .display_panic_screen = NULL
+#endif
+
+#endif
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 2c5a5a70a71b..7fee602d94e9 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -32,6 +32,8 @@
#include <drm/drm_modeset_lock.h>
#include <drm/drm_util.h>
+enum drm_panic_type;
+
struct drm_crtc;
struct drm_plane_size_hint;
struct drm_printer;
@@ -590,6 +592,61 @@ struct drm_plane_funcs {
bool (*format_mod_supported_async)(struct drm_plane *plane,
u32 format, u64 modifier);
+ /**
+ * @display_panic_screen:
+ *
+ * DRM panic handling invokes this callback on panics.
+ *
+ * It is a panic handler, so it can't take locks, allocate memory, run tasks/irq,
+ * or attempt to sleep. It's a best effort, and it may not be able to display
+ * the message in all situations (like if the panic occurs in the middle of a
+ * modesetting).
+ *
+ * Panic-printing code must acquire the panic lock before interacting with the
+ * scanout buffer. Such helpers can make the following assumptions while holding
+ * the panic lock:
+ *
+ * - Anything protected by drm_panic_lock() and drm_panic_unlock() pairs is safe
+ * to access.
+ *
+ * - Furthermore the panic printing code only registers in drm_dev_unregister()
+ * and gets removed in drm_dev_unregister(). This allows the panic code to
+ * safely access any state which is invariant in between these two function
+ * calls, like the list of planes &drm_mode_config.plane_list or most of the
+ * struct drm_plane structure.
+ *
+ * Specifically thanks to the protection around plane updates in
+ * drm_atomic_helper_swap_state() the following additional guarantees hold:
+ *
+ * - It is safe to deference the drm_plane.state pointer.
+ *
+ * - Anything in struct drm_plane_state or the driver's subclass thereof which
+ * stays invariant after the atomic check code has finished is safe to access.
+ * Specifically this includes the reference counted pointers to framebuffer
+ * and buffer objects.
+ *
+ * - Anything set up by &drm_plane_helper_funcs.fb_prepare and cleaned up
+ * &drm_plane_helper_funcs.fb_cleanup is safe to access, as long as it stays
+ * invariant between these two calls. This also means that for drivers using
+ * dynamic buffer management the framebuffer is pinned, and therefer all
+ * relevant datastructures can be accessed without taking any further locks
+ * (which would be impossible in panic context anyway).
+ *
+ * - Importantly, software and hardware state set up by
+ * &drm_plane_helper_funcs.begin_fb_access and
+ * &drm_plane_helper_funcs.end_fb_access is not safe to access.
+ *
+ * It will display only one static frame, so performance optimizations are
+ * low priority as the machine is already in an unusable state.
+ *
+ * This callback is optional. Planes without will not be considered
+ * for panic output.
+ */
+ int (*display_panic_screen)(struct drm_plane *plane,
+ const char *description,
+ enum drm_panic_type panic_type,
+ u32 fg_color, u32 bg_color,
+ unsigned int qr_version);
};
/**
--
2.55.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v3 12/14] drm/panic: Internalize panic locking in DRM core and helpers
2026-09-02 12:13 [PATCH v3 00/14] drm/panic: Split into core and helpers Thomas Zimmermann
` (10 preceding siblings ...)
2026-09-02 12:13 ` [PATCH v3 11/14] drm/panic: Display panic screen via per-plane callback Thomas Zimmermann
@ 2026-09-02 12:13 ` Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 13/14] drm/panic: Move panic display code into helper library Thomas Zimmermann
` (5 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Thomas Zimmermann @ 2026-09-02 12:13 UTC (permalink / raw)
To: jfalempe, javierm, airlied, simona, maarten.lankhorst, mripard,
geert, rdunlap
Cc: dri-devel, linux-doc, amd-gfx, rust-for-linux, linux-hyperv,
intel-gfx, intel-xe, imx, linux-arm-kernel, nouveau,
linux-renesas-soc, virtualization, sashiko-reviews,
Thomas Zimmermann
None of the DRM drivers handles panic locking. Declare the interfaces
in an internal header file. Move the trylock required during the panic
into the DRM core's sources.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
Documentation/gpu/drm-kms.rst | 3 ++
MAINTAINERS | 3 +-
drivers/gpu/drm/drm_atomic_helper.c | 2 +-
drivers/gpu/drm/drm_drv.c | 2 +-
drivers/gpu/drm/drm_panic.c | 4 ++
drivers/gpu/drm/drm_panic_internal.h | 55 +++++++++++++++++++++++
include/drm/drm_panic.h | 65 ----------------------------
7 files changed, 66 insertions(+), 68 deletions(-)
create mode 100644 drivers/gpu/drm/drm_panic_internal.h
diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst
index 0dd440a14946..8988fd64369b 100644
--- a/Documentation/gpu/drm-kms.rst
+++ b/Documentation/gpu/drm-kms.rst
@@ -421,6 +421,9 @@ Plane Panic Functions Reference
.. kernel-doc:: include/drm/drm_panic.h
:internal:
+.. kernel-doc:: drivers/gpu/drm/drm_panic_internal.h
+ :internal:
+
.. kernel-doc:: drivers/gpu/drm/drm_panic.c
:export:
diff --git a/MAINTAINERS b/MAINTAINERS
index c66c3fe93f3d..ccc5dc0a01ae 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9111,7 +9111,8 @@ S: Supported
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: drivers/gpu/drm/drm_draw.c
F: drivers/gpu/drm/drm_draw_internal.h
-F: drivers/gpu/drm/drm_panic*.c
+F: drivers/gpu/drm/drm_panic.c
+F: drivers/gpu/drm/drm_panic_internal.h
F: drivers/gpu/drm/tests/drm_panic_test.c
F: include/drm/drm_panic.h
F: include/drm/drm_panic_helper.h
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 285aac3554df..af3934df3313 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -41,7 +41,6 @@
#include <drm/drm_drv.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_atomic_helper.h>
-#include <drm/drm_panic.h>
#include <drm/drm_print.h>
#include <drm/drm_self_refresh_helper.h>
#include <drm/drm_vblank.h>
@@ -49,6 +48,7 @@
#include "drm_crtc_helper_internal.h"
#include "drm_crtc_internal.h"
+#include "drm_panic_internal.h"
/**
* DOC: overview
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 8c0879c336e5..64055514acbf 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -51,13 +51,13 @@
#include <drm/drm_file.h>
#include <drm/drm_managed.h>
#include <drm/drm_mode_object.h>
-#include <drm/drm_panic.h>
#include <drm/drm_print.h>
#include <drm/drm_privacy_screen_machine.h>
#include <drm/drm_ras_genl_family.h>
#include "drm_crtc_internal.h"
#include "drm_internal.h"
+#include "drm_panic_internal.h"
MODULE_AUTHOR("Gareth Hughes, Leif Delgass, José Fonseca, Jon Smirl");
MODULE_DESCRIPTION("DRM shared core routines");
diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
index 7b9864857577..41ba0c4b050e 100644
--- a/drivers/gpu/drm/drm_panic.c
+++ b/drivers/gpu/drm/drm_panic.c
@@ -35,6 +35,7 @@
#include "drm_crtc_internal.h"
#include "drm_draw_internal.h"
+#include "drm_panic_internal.h"
MODULE_AUTHOR("Jocelyn Falempe");
MODULE_DESCRIPTION("DRM panic handler");
@@ -976,6 +977,9 @@ int drm_plane_helper_display_panic_screen(struct drm_plane *plane, const char *d
}
EXPORT_SYMBOL(drm_plane_helper_display_panic_screen);
+#define drm_panic_trylock(dev, flags) \
+ raw_spin_trylock_irqsave(&(dev)->mode_config.panic_lock, flags)
+
static void drm_panic_display_panic_screen(struct drm_plane *plane, const char *description)
{
#if defined(CONFIG_DRM_PANIC_FOREGROUND_COLOR)
diff --git a/drivers/gpu/drm/drm_panic_internal.h b/drivers/gpu/drm/drm_panic_internal.h
new file mode 100644
index 000000000000..c68d64c56e15
--- /dev/null
+++ b/drivers/gpu/drm/drm_panic_internal.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0 or MIT */
+
+/*
+ * Copyright (c) 2024 Intel
+ * Copyright (c) 2024 Red Hat
+ */
+
+#ifndef __DRM_PANIC_INTERNAL_H__
+#define __DRM_PANIC_INTERNAL_H__
+
+#include <linux/spinlock.h>
+
+struct drm_device;
+
+#ifdef CONFIG_DRM_PANIC
+
+/**
+ * drm_panic_lock - protect panic printing relevant state
+ * @dev: struct drm_device
+ * @flags: unsigned long irq flags you need to pass to the unlock() counterpart
+ *
+ * This function must be called to protect software and hardware state that the
+ * panic printing code must be able to rely on. The protected sections must be
+ * as small as possible. It uses the irqsave/irqrestore variant, and can be
+ * called from irq handler. Examples include:
+ *
+ * - Access to peek/poke or other similar registers, if that is the way the
+ * driver prints the pixels into the scanout buffer at panic time.
+ *
+ * - Updates to pointers like &drm_plane.state, allowing the panic handler to
+ * safely deference these. This is done in drm_atomic_helper_swap_state().
+ *
+ * - An state that isn't invariant and that the driver must be able to access
+ * during panic printing.
+ */
+#define drm_panic_lock(dev, flags) \
+ raw_spin_lock_irqsave(&(dev)->mode_config.panic_lock, flags)
+
+/**
+ * drm_panic_unlock - end of the panic printing critical section
+ * @dev: struct drm_device
+ * @flags: irq flags that were returned when acquiring the lock
+ *
+ * Unlocks the raw spinlock acquired by either drm_panic_lock() or
+ * drm_panic_trylock().
+ */
+#define drm_panic_unlock(dev, flags) \
+ raw_spin_unlock_irqrestore(&(dev)->mode_config.panic_lock, flags)
+
+#else
+static inline void drm_panic_lock(struct drm_device *dev, unsigned long flags) {}
+static inline void drm_panic_unlock(struct drm_device *dev, unsigned long flags) {}
+#endif
+
+#endif /* __DRM_PANIC_INTERNAL_H__ */
diff --git a/include/drm/drm_panic.h b/include/drm/drm_panic.h
index 430df536de14..99572b7eeab9 100644
--- a/include/drm/drm_panic.h
+++ b/include/drm/drm_panic.h
@@ -8,11 +8,9 @@
#ifndef __DRM_PANIC_H__
#define __DRM_PANIC_H__
-#include <linux/module.h>
#include <linux/types.h>
#include <linux/iosys-map.h>
-#include <drm/drm_device.h>
#include <drm/drm_fourcc.h>
struct page;
@@ -85,71 +83,8 @@ struct drm_scanout_buffer {
* set_pixel()
*/
void *private;
-
};
-#ifdef CONFIG_DRM_PANIC
-
-/**
- * drm_panic_trylock - try to enter the panic printing critical section
- * @dev: struct drm_device
- * @flags: unsigned long irq flags you need to pass to the unlock() counterpart
- *
- * The panic-printing code calls this function. The panic printing attempt must
- * be aborted if the trylock fails.
- *
- * Return:
- * %0 when failing to acquire the raw spinlock, nonzero on success.
- */
-#define drm_panic_trylock(dev, flags) \
- raw_spin_trylock_irqsave(&(dev)->mode_config.panic_lock, flags)
-
-/**
- * drm_panic_lock - protect panic printing relevant state
- * @dev: struct drm_device
- * @flags: unsigned long irq flags you need to pass to the unlock() counterpart
- *
- * This function must be called to protect software and hardware state that the
- * panic printing code must be able to rely on. The protected sections must be
- * as small as possible. It uses the irqsave/irqrestore variant, and can be
- * called from irq handler. Examples include:
- *
- * - Access to peek/poke or other similar registers, if that is the way the
- * driver prints the pixels into the scanout buffer at panic time.
- *
- * - Updates to pointers like &drm_plane.state, allowing the panic handler to
- * safely deference these. This is done in drm_atomic_helper_swap_state().
- *
- * - An state that isn't invariant and that the driver must be able to access
- * during panic printing.
- */
-
-#define drm_panic_lock(dev, flags) \
- raw_spin_lock_irqsave(&(dev)->mode_config.panic_lock, flags)
-
-/**
- * drm_panic_unlock - end of the panic printing critical section
- * @dev: struct drm_device
- * @flags: irq flags that were returned when acquiring the lock
- *
- * Unlocks the raw spinlock acquired by either drm_panic_lock() or
- * drm_panic_trylock().
- */
-#define drm_panic_unlock(dev, flags) \
- raw_spin_unlock_irqrestore(&(dev)->mode_config.panic_lock, flags)
-
-#else
-
-static inline bool drm_panic_trylock(struct drm_device *dev, unsigned long flags)
-{
- return true;
-}
-
-static inline void drm_panic_lock(struct drm_device *dev, unsigned long flags) {}
-static inline void drm_panic_unlock(struct drm_device *dev, unsigned long flags) {}
-
-#endif
-
#if defined(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
size_t drm_panic_qr_max_data_size(u8 version, size_t url_len);
--
2.55.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v3 13/14] drm/panic: Move panic display code into helper library
2026-09-02 12:13 [PATCH v3 00/14] drm/panic: Split into core and helpers Thomas Zimmermann
` (11 preceding siblings ...)
2026-09-02 12:13 ` [PATCH v3 12/14] drm/panic: Internalize panic locking in DRM core and helpers Thomas Zimmermann
@ 2026-09-02 12:13 ` Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 14/14] drm/panic: Compile KUnit tests as module Thomas Zimmermann
` (4 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Thomas Zimmermann @ 2026-09-02 12:13 UTC (permalink / raw)
To: jfalempe, javierm, airlied, simona, maarten.lankhorst, mripard,
geert, rdunlap
Cc: dri-devel, linux-doc, amd-gfx, rust-for-linux, linux-hyperv,
intel-gfx, intel-xe, imx, linux-arm-kernel, nouveau,
linux-renesas-soc, virtualization, sashiko-reviews,
Thomas Zimmermann
Move drm_plane_helper_display_panic_screen() and the existing panic-
display code into drm_panic_helper.c. Rename symbols accordingly.
Also update the QR-related code and the bindings accordingly.
Link the rsp. object file into drm_kms_helper.ko. Eventually the code
will become a DRM drawing library, together with DRM's format and draw
helpers. This requires more preparation. until then, KMS helpers serve
as a module. All DRM drivers link it anyway.
Add a new section about drawing helpers to the documentation of the KMS
helpers. List format and panic helpers there.
v2:
- fix dependencies on other DRM modules (Randy, Sashiko)
- provide placeholders for drm_panic_helper_{init,exit}() (Sashiko)
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
Documentation/gpu/drm-kms-helpers.rst | 11 +-
MAINTAINERS | 5 +-
drivers/gpu/drm/Kconfig | 9 +-
drivers/gpu/drm/Makefile | 3 +-
drivers/gpu/drm/drm_crtc_internal.h | 2 -
drivers/gpu/drm/drm_drv.c | 1 -
drivers/gpu/drm/drm_kms_helper_common.c | 14 +
drivers/gpu/drm/drm_panic.c | 894 -----------------
drivers/gpu/drm/drm_panic_helper.c | 916 ++++++++++++++++++
...drm_panic_qr.rs => drm_panic_helper_qr.rs} | 4 +-
drivers/gpu/drm/drm_panic_internal.h | 14 +
...m_panic_test.c => drm_panic_helper_test.c} | 24 +-
include/drm/drm_panic.h | 7 -
include/drm/drm_panic_helper.h | 5 +
rust/bindings/bindings_helper.h | 4 +-
15 files changed, 987 insertions(+), 926 deletions(-)
create mode 100644 drivers/gpu/drm/drm_panic_helper.c
rename drivers/gpu/drm/{drm_panic_qr.rs => drm_panic_helper_qr.rs} (99%)
rename drivers/gpu/drm/tests/{drm_panic_test.c => drm_panic_helper_test.c} (88%)
diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst
index 94cfc26acecc..400cd0112713 100644
--- a/Documentation/gpu/drm-kms-helpers.rst
+++ b/Documentation/gpu/drm-kms-helpers.rst
@@ -118,12 +118,21 @@ fbdev Helper Functions Reference
.. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c
:export:
-format Helper Functions Reference
+Draw Helper Functions Reference
=================================
+Format-Conversion Helper Reference
+----------------------------------
+
.. kernel-doc:: drivers/gpu/drm/drm_format_helper.c
:export:
+Panic Helper Reference
+----------------------
+
+.. kernel-doc:: drivers/gpu/drm/drm_panic_helper.c
+ :export:
+
Framebuffer DMA Helper Functions Reference
==========================================
diff --git a/MAINTAINERS b/MAINTAINERS
index ccc5dc0a01ae..3c41e2730a37 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9112,8 +9112,9 @@ T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: drivers/gpu/drm/drm_draw.c
F: drivers/gpu/drm/drm_draw_internal.h
F: drivers/gpu/drm/drm_panic.c
+F: drivers/gpu/drm/drm_panic_helper.c
F: drivers/gpu/drm/drm_panic_internal.h
-F: drivers/gpu/drm/tests/drm_panic_test.c
+F: drivers/gpu/drm/tests/drm_panic_helper_test.c
F: include/drm/drm_panic.h
F: include/drm/drm_panic_helper.h
@@ -9124,7 +9125,7 @@ L: dri-devel@lists.freedesktop.org
L: rust-for-linux@vger.kernel.org
S: Supported
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
-F: drivers/gpu/drm/drm_panic_qr.rs
+F: drivers/gpu/drm/drm_panic_helper_qr.rs
DRM PRIVACY-SCREEN CLASS
M: Hans de Goede <hansg@kernel.org>
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 323422861e8f..65d46dfa7266 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -45,6 +45,7 @@ config DRM_MIPI_DSI
config DRM_KMS_HELPER
tristate
depends on DRM
+ select DRM_PANIC_HELPER if DRM_PANIC
select FB_CORE if DRM_FBDEV_EMULATION
help
CRTC helpers for KMS drivers.
@@ -56,8 +57,6 @@ config DRM_DRAW
config DRM_PANIC
bool "Display a user-friendly message when a kernel panic occurs"
depends on DRM && PRINTK
- select FONT_SUPPORT
- select DRM_DRAW
help
Enable a drm panic handler, which will display a user-friendly message
when a kernel panic occurs. It's useful when using a user-space
@@ -130,6 +129,12 @@ config DRM_PANIC_SCREEN_QR_VERSION
Smaller QR code are easier to read, but will contain less debugging
data. Default is 40.
+config DRM_PANIC_HELPER
+ bool
+ depends on DRM
+ select DRM_DRAW
+ select FONT_SUPPORT
+
config DRM_RAS
bool "DRM RAS support"
depends on DRM
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index e635fcffd379..f0c340aa2ec6 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -92,7 +92,6 @@ drm-$(CONFIG_DRM_PRIVACY_SCREEN) += \
drm-$(CONFIG_DRM_ACCEL) += ../../accel/drm_accel.o
drm-$(CONFIG_DRM_PANIC) += drm_panic.o
drm-$(CONFIG_DRM_DRAW) += drm_draw.o
-drm-$(CONFIG_DRM_PANIC_SCREEN_QR_CODE) += drm_panic_qr.o
drm-$(CONFIG_DRM_RAS) += drm_ras.o drm_ras_nl.o drm_ras_genl_family.o
obj-$(CONFIG_DRM) += drm.o
@@ -157,6 +156,8 @@ drm_kms_helper-y := \
drm_simple_kms_helper.o \
drm_vblank_helper.o
drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o
+drm_kms_helper-$(CONFIG_DRM_PANIC_HELPER) += drm_panic_helper.o
+drm_kms_helper-$(CONFIG_DRM_PANIC_SCREEN_QR_CODE) += drm_panic_helper_qr.o
drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
index 83146ffef00c..3492787c3697 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -322,13 +322,11 @@ bool drm_panic_is_enabled(struct drm_device *dev);
void drm_panic_register(struct drm_device *dev);
void drm_panic_unregister(struct drm_device *dev);
void drm_panic_init(void);
-void drm_panic_exit(void);
#else
static inline bool drm_panic_is_enabled(struct drm_device *dev) { return false; }
static inline void drm_panic_register(struct drm_device *dev) {}
static inline void drm_panic_unregister(struct drm_device *dev) {}
static inline void drm_panic_init(void) {}
-static inline void drm_panic_exit(void) {}
#endif
#endif /* __DRM_CRTC_INTERNAL_H__ */
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 64055514acbf..0cdc606af8d1 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -1255,7 +1255,6 @@ static void drm_core_exit(void)
{
drm_ras_genl_family_unregister();
drm_privacy_screen_lookup_exit();
- drm_panic_exit();
accel_core_exit();
unregister_chrdev(DRM_MAJOR, "drm");
drm_debugfs_remove_root();
diff --git a/drivers/gpu/drm/drm_kms_helper_common.c b/drivers/gpu/drm/drm_kms_helper_common.c
index 0c7550c0462b..b5d5b469b444 100644
--- a/drivers/gpu/drm/drm_kms_helper_common.c
+++ b/drivers/gpu/drm/drm_kms_helper_common.c
@@ -27,6 +27,20 @@
#include <linux/module.h>
+#include "drm_panic_internal.h"
+
+static int __init drm_kms_helper_init(void)
+{
+ return drm_panic_helper_init();
+}
+module_init(drm_kms_helper_init);
+
+static void __exit drm_kms_helper_exit(void)
+{
+ drm_panic_helper_exit();
+}
+module_exit(drm_kms_helper_exit);
+
MODULE_AUTHOR("David Airlie, Jesse Barnes");
MODULE_DESCRIPTION("DRM KMS helper");
MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
index 41ba0c4b050e..a1e80449a990 100644
--- a/drivers/gpu/drm/drm_panic.c
+++ b/drivers/gpu/drm/drm_panic.c
@@ -7,34 +7,22 @@
*/
#include <linux/export.h>
-#include <linux/font.h>
-#include <linux/highmem.h>
#include <linux/init.h>
-#include <linux/iosys-map.h>
#include <linux/kdebug.h>
#include <linux/kmsg_dump.h>
-#include <linux/linux_logo.h>
#include <linux/list.h>
#include <linux/math.h>
#include <linux/module.h>
#include <linux/overflow.h>
#include <linux/printk.h>
#include <linux/types.h>
-#include <linux/utsname.h>
-#include <linux/zlib.h>
#include <drm/drm_drv.h>
-#include <drm/drm_fourcc.h>
-#include <drm/drm_framebuffer.h>
-#include <drm/drm_modeset_helper_vtables.h>
#include <drm/drm_panic.h>
-#include <drm/drm_panic_helper.h>
#include <drm/drm_plane.h>
#include <drm/drm_print.h>
-#include <drm/drm_rect.h>
#include "drm_crtc_internal.h"
-#include "drm_draw_internal.h"
#include "drm_panic_internal.h"
MODULE_AUTHOR("Jocelyn Falempe");
@@ -58,751 +46,10 @@ MODULE_LICENSE("GPL");
* drm_plane_helper_display_panic_screen() for a generic implementation.
*/
-struct drm_panic_line {
- u32 len;
- const char *txt;
-};
-
-#define PANIC_LINE(s) {.len = sizeof(s) - 1, .txt = s}
-
-static struct drm_panic_line panic_msg[] = {
- PANIC_LINE("KERNEL PANIC!"),
- PANIC_LINE(""),
- PANIC_LINE("Please reboot your computer."),
- PANIC_LINE(""),
- PANIC_LINE(""), /* will be replaced by the panic description */
-};
-
-static const size_t panic_msg_lines = ARRAY_SIZE(panic_msg);
-
-static const struct drm_panic_line logo_ascii[] = {
- PANIC_LINE(" .--. _"),
- PANIC_LINE(" |o_o | | |"),
- PANIC_LINE(" |:_/ | | |"),
- PANIC_LINE(" // \\ \\ |_|"),
- PANIC_LINE(" (| | ) _"),
- PANIC_LINE(" /'\\_ _/`\\ (_)"),
- PANIC_LINE(" \\___)=(___/"),
-};
-
-static const size_t logo_ascii_lines = ARRAY_SIZE(logo_ascii);
-
-#if defined(CONFIG_LOGO) && !defined(MODULE)
-static const struct linux_logo *logo_mono;
-
-static int drm_panic_setup_logo(void)
-{
- const struct linux_logo *logo = fb_find_logo(1);
- const unsigned char *logo_data;
- struct linux_logo *logo_dup;
-
- if (!logo || logo->type != LINUX_LOGO_MONO)
- return 0;
-
- /* The logo is __init, so we must make a copy for later use */
- logo_data = kmemdup(logo->data,
- size_mul(DIV_ROUND_UP(logo->width, BITS_PER_BYTE), logo->height),
- GFP_KERNEL);
- if (!logo_data)
- return -ENOMEM;
-
- logo_dup = kmemdup(logo, sizeof(*logo), GFP_KERNEL);
- if (!logo_dup) {
- kfree(logo_data);
- return -ENOMEM;
- }
-
- logo_dup->data = logo_data;
- logo_mono = logo_dup;
-
- return 0;
-}
-
-device_initcall(drm_panic_setup_logo);
-#else
-#define logo_mono ((const struct linux_logo *)NULL)
-#endif
-
-/*
- * Blit & Fill functions
- */
-static void drm_panic_blit_pixel(struct drm_scanout_buffer *sb, struct drm_rect *clip,
- const u8 *sbuf8, unsigned int spitch, unsigned int scale,
- u32 fg_color)
-{
- unsigned int y, x;
-
- for (y = 0; y < drm_rect_height(clip); y++)
- for (x = 0; x < drm_rect_width(clip); x++)
- if (drm_draw_is_pixel_fg(sbuf8, spitch, x / scale, y / scale))
- sb->set_pixel(sb, clip->x1 + x, clip->y1 + y, fg_color);
-}
-
-static void drm_panic_write_pixel16(void *vaddr, unsigned int offset, u16 color)
-{
- u16 *p = vaddr + offset;
-
- *p = color;
-}
-
-static void drm_panic_write_pixel24(void *vaddr, unsigned int offset, u32 color)
-{
- u8 *p = vaddr + offset;
-
- *p++ = color & 0xff;
- color >>= 8;
- *p++ = color & 0xff;
- color >>= 8;
- *p = color & 0xff;
-}
-
-/*
- * Special case if the pixel crosses page boundaries
- */
-static void drm_panic_write_pixel24_xpage(void *vaddr, struct page *next_page,
- unsigned int offset, u32 color)
-{
- u8 *vaddr2;
- u8 *p = vaddr + offset;
-
- vaddr2 = kmap_local_page_try_from_panic(next_page);
- if (!vaddr2)
- return;
-
- *p++ = color & 0xff;
- color >>= 8;
-
- if (offset == PAGE_SIZE - 1)
- p = vaddr2;
-
- *p++ = color & 0xff;
- color >>= 8;
-
- if (offset == PAGE_SIZE - 2)
- p = vaddr2;
-
- *p = color & 0xff;
- kunmap_local(vaddr2);
-}
-
-static void drm_panic_write_pixel32(void *vaddr, unsigned int offset, u32 color)
-{
- u32 *p = vaddr + offset;
-
- *p = color;
-}
-
-static void drm_panic_write_pixel(void *vaddr, unsigned int offset, u32 color, unsigned int cpp)
-{
- switch (cpp) {
- case 2:
- drm_panic_write_pixel16(vaddr, offset, color);
- break;
- case 3:
- drm_panic_write_pixel24(vaddr, offset, color);
- break;
- case 4:
- drm_panic_write_pixel32(vaddr, offset, color);
- break;
- default:
- pr_debug_once("Can't blit with pixel width %d\n", cpp);
- }
-}
-
-/*
- * The scanout buffer pages are not mapped, so for each pixel,
- * use kmap_local_page_try_from_panic() to map the page, and write the pixel.
- * Try to keep the map from the previous pixel, to avoid too much map/unmap.
- */
-static void drm_panic_blit_page(struct page **pages, unsigned int dpitch,
- unsigned int cpp, const u8 *sbuf8,
- unsigned int spitch, struct drm_rect *clip,
- unsigned int scale, u32 fg32)
-{
- unsigned int y, x;
- unsigned int page = ~0;
- unsigned int height = drm_rect_height(clip);
- unsigned int width = drm_rect_width(clip);
- void *vaddr = NULL;
-
- for (y = 0; y < height; y++) {
- for (x = 0; x < width; x++) {
- if (drm_draw_is_pixel_fg(sbuf8, spitch, x / scale, y / scale)) {
- unsigned int new_page;
- unsigned int offset;
-
- offset = (y + clip->y1) * dpitch + (x + clip->x1) * cpp;
- new_page = offset >> PAGE_SHIFT;
- offset = offset % PAGE_SIZE;
- if (new_page != page) {
- if (!pages[new_page])
- continue;
- if (vaddr)
- kunmap_local(vaddr);
- page = new_page;
- vaddr = kmap_local_page_try_from_panic(pages[page]);
- }
- if (!vaddr)
- continue;
-
- // Special case for 24bit, as a pixel might cross page boundaries
- if (cpp == 3 && offset + 3 > PAGE_SIZE)
- drm_panic_write_pixel24_xpage(vaddr, pages[page + 1],
- offset, fg32);
- else
- drm_panic_write_pixel(vaddr, offset, fg32, cpp);
- }
- }
- }
- if (vaddr)
- kunmap_local(vaddr);
-}
-
-/*
- * drm_panic_blit - convert a monochrome image to a linear framebuffer
- * @sb: destination scanout buffer
- * @clip: destination rectangle
- * @sbuf8: source buffer, in monochrome format, 8 pixels per byte.
- * @spitch: source pitch in bytes
- * @scale: integer scale, source buffer is scale time smaller than destination
- * rectangle
- * @fg_color: foreground color, in destination format
- *
- * This can be used to draw a font character, which is a monochrome image, to a
- * framebuffer in other supported format.
- */
-static void drm_panic_blit(struct drm_scanout_buffer *sb, struct drm_rect *clip,
- const u8 *sbuf8, unsigned int spitch,
- unsigned int scale, u32 fg_color)
-
-{
- struct iosys_map map;
-
- if (sb->set_pixel)
- return drm_panic_blit_pixel(sb, clip, sbuf8, spitch, scale, fg_color);
-
- if (sb->pages)
- return drm_panic_blit_page(sb->pages, sb->pitch[0], sb->format->cpp[0],
- sbuf8, spitch, clip, scale, fg_color);
-
- map = sb->map[0];
- iosys_map_incr(&map, clip->y1 * sb->pitch[0] + clip->x1 * sb->format->cpp[0]);
-
- switch (sb->format->cpp[0]) {
- case 2:
- drm_draw_blit16(&map, sb->pitch[0], sbuf8, spitch,
- drm_rect_height(clip), drm_rect_width(clip), scale, fg_color);
- break;
- case 3:
- drm_draw_blit24(&map, sb->pitch[0], sbuf8, spitch,
- drm_rect_height(clip), drm_rect_width(clip), scale, fg_color);
- break;
- case 4:
- drm_draw_blit32(&map, sb->pitch[0], sbuf8, spitch,
- drm_rect_height(clip), drm_rect_width(clip), scale, fg_color);
- break;
- default:
- WARN_ONCE(1, "Can't blit with pixel width %d\n", sb->format->cpp[0]);
- }
-}
-
-static void drm_panic_fill_pixel(struct drm_scanout_buffer *sb,
- struct drm_rect *clip,
- u32 color)
-{
- unsigned int y, x;
-
- for (y = 0; y < drm_rect_height(clip); y++)
- for (x = 0; x < drm_rect_width(clip); x++)
- sb->set_pixel(sb, clip->x1 + x, clip->y1 + y, color);
-}
-
-static void drm_panic_fill_page(struct page **pages, unsigned int dpitch,
- unsigned int cpp, struct drm_rect *clip,
- u32 color)
-{
- unsigned int y, x;
- unsigned int page = ~0;
- void *vaddr = NULL;
-
- for (y = clip->y1; y < clip->y2; y++) {
- for (x = clip->x1; x < clip->x2; x++) {
- unsigned int new_page;
- unsigned int offset;
-
- offset = y * dpitch + x * cpp;
- new_page = offset >> PAGE_SHIFT;
- offset = offset % PAGE_SIZE;
- if (new_page != page) {
- if (vaddr)
- kunmap_local(vaddr);
- page = new_page;
- vaddr = kmap_local_page_try_from_panic(pages[page]);
- }
- if (!vaddr)
- continue;
-
- // Special case for 24bit, as a pixel might cross page boundaries
- if (cpp == 3 && offset + 3 > PAGE_SIZE)
- drm_panic_write_pixel24_xpage(vaddr, pages[page + 1],
- offset, color);
- else
- drm_panic_write_pixel(vaddr, offset, color, cpp);
- }
- }
- if (vaddr)
- kunmap_local(vaddr);
-}
-
-/*
- * drm_panic_fill - Fill a rectangle with a color
- * @sb: destination scanout buffer
- * @clip: destination rectangle
- * @color: foreground color, in destination format
- *
- * Fill a rectangle with a color, in a linear framebuffer.
- */
-static void drm_panic_fill(struct drm_scanout_buffer *sb, struct drm_rect *clip,
- u32 color)
-{
- struct iosys_map map;
-
- if (sb->set_pixel)
- return drm_panic_fill_pixel(sb, clip, color);
-
- if (sb->pages)
- return drm_panic_fill_page(sb->pages, sb->pitch[0], sb->format->cpp[0],
- clip, color);
-
- map = sb->map[0];
- iosys_map_incr(&map, clip->y1 * sb->pitch[0] + clip->x1 * sb->format->cpp[0]);
-
- switch (sb->format->cpp[0]) {
- case 2:
- drm_draw_fill16(&map, sb->pitch[0], drm_rect_height(clip),
- drm_rect_width(clip), color);
- break;
- case 3:
- drm_draw_fill24(&map, sb->pitch[0], drm_rect_height(clip),
- drm_rect_width(clip), color);
- break;
- case 4:
- drm_draw_fill32(&map, sb->pitch[0], drm_rect_height(clip),
- drm_rect_width(clip), color);
- break;
- default:
- WARN_ONCE(1, "Can't fill with pixel width %d\n", sb->format->cpp[0]);
- }
-}
-
-static unsigned int get_max_line_len(const struct drm_panic_line *lines, int len)
-{
- int i;
- unsigned int max = 0;
-
- for (i = 0; i < len; i++)
- max = max(lines[i].len, max);
- return max;
-}
-
-/*
- * Draw a text in a rectangle on a framebuffer. The text is truncated if it overflows the rectangle
- */
-static void draw_txt_rectangle(struct drm_scanout_buffer *sb,
- const struct font_desc *font,
- const struct drm_panic_line *msg,
- unsigned int msg_lines,
- bool centered,
- struct drm_rect *clip,
- u32 color)
-{
- int i, j;
- const u8 *src;
- size_t font_pitch = DIV_ROUND_UP(font->width, 8);
- struct drm_rect rec;
-
- msg_lines = min(msg_lines, drm_rect_height(clip) / font->height);
- for (i = 0; i < msg_lines; i++) {
- size_t line_len = min(msg[i].len, drm_rect_width(clip) / font->width);
-
- rec.y1 = clip->y1 + i * font->height;
- rec.y2 = rec.y1 + font->height;
- rec.x1 = clip->x1;
-
- if (centered)
- rec.x1 += (drm_rect_width(clip) - (line_len * font->width)) / 2;
-
- for (j = 0; j < line_len; j++) {
- src = font_data_glyph_buf(font->data, font->width, font->height,
- (unsigned char)msg[i].txt[j]);
- rec.x2 = rec.x1 + font->width;
- if (src)
- drm_panic_blit(sb, &rec, src, font_pitch, 1, color);
- rec.x1 += font->width;
- }
- }
-}
-
-static void drm_panic_logo_rect(struct drm_rect *rect, const struct font_desc *font)
-{
- if (logo_mono) {
- drm_rect_init(rect, 0, 0, logo_mono->width, logo_mono->height);
- } else {
- int logo_width = get_max_line_len(logo_ascii, logo_ascii_lines) * font->width;
-
- drm_rect_init(rect, 0, 0, logo_width, logo_ascii_lines * font->height);
- }
-}
-
-static void drm_panic_logo_draw(struct drm_scanout_buffer *sb, struct drm_rect *rect,
- const struct font_desc *font, u32 fg_color)
-{
- if (rect->x2 > sb->width || rect->y2 > sb->height)
- return;
-
- if (logo_mono)
- drm_panic_blit(sb, rect, logo_mono->data,
- DIV_ROUND_UP(drm_rect_width(rect), 8), 1, fg_color);
- else
- draw_txt_rectangle(sb, font, logo_ascii, logo_ascii_lines, false, rect,
- fg_color);
-}
-
-static int draw_panic_screen_user(struct drm_scanout_buffer *sb, u32 fg_color, u32 bg_color)
-{
- const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL);
- struct drm_rect r_screen, r_logo, r_msg;
- unsigned int msg_width, msg_height;
-
- if (!font || font->width > sb->width)
- return -EINVAL;
-
- fg_color = drm_draw_color_from_xrgb8888(fg_color, sb->format->format);
- bg_color = drm_draw_color_from_xrgb8888(bg_color, sb->format->format);
-
- r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height);
- drm_panic_logo_rect(&r_logo, font);
-
- msg_width = min(get_max_line_len(panic_msg, panic_msg_lines) * font->width, sb->width);
- msg_height = min(panic_msg_lines * font->height, sb->height);
- r_msg = DRM_RECT_INIT(0, 0, msg_width, msg_height);
-
- /* Center the panic message */
- drm_rect_translate(&r_msg, (sb->width - r_msg.x2) / 2, (sb->height - r_msg.y2) / 2);
-
- /* Fill with the background color, and draw text on top */
- drm_panic_fill(sb, &r_screen, bg_color);
-
- if (!drm_rect_overlap(&r_logo, &r_msg))
- drm_panic_logo_draw(sb, &r_logo, font, fg_color);
-
- draw_txt_rectangle(sb, font, panic_msg, panic_msg_lines, true, &r_msg, fg_color);
-
- return 0;
-}
-
-/*
- * Draw one line of kmsg, and handle wrapping if it won't fit in the screen width.
- * Return the y-offset of the next line.
- */
-static int draw_line_with_wrap(struct drm_scanout_buffer *sb, const struct font_desc *font,
- struct drm_panic_line *line, int yoffset, u32 fg_color)
-{
- int chars_per_row = sb->width / font->width;
- struct drm_rect r_txt = DRM_RECT_INIT(0, yoffset, sb->width, font->height);
- struct drm_panic_line line_wrap;
-
- if (line->len > chars_per_row) {
- line_wrap.len = line->len % chars_per_row;
- line_wrap.txt = line->txt + line->len - line_wrap.len;
- draw_txt_rectangle(sb, font, &line_wrap, 1, false, &r_txt, fg_color);
- r_txt.y1 -= font->height;
- if (r_txt.y1 < 0)
- return r_txt.y1;
- while (line_wrap.txt > line->txt) {
- line_wrap.txt -= chars_per_row;
- line_wrap.len = chars_per_row;
- draw_txt_rectangle(sb, font, &line_wrap, 1, false, &r_txt, fg_color);
- r_txt.y1 -= font->height;
- if (r_txt.y1 < 0)
- return r_txt.y1;
- }
- } else {
- draw_txt_rectangle(sb, font, line, 1, false, &r_txt, fg_color);
- r_txt.y1 -= font->height;
- }
- return r_txt.y1;
-}
-
-/*
- * Draw the kmsg buffer to the screen, starting from the youngest message at the bottom,
- * and going up until reaching the top of the screen.
- */
-static int draw_panic_screen_kmsg(struct drm_scanout_buffer *sb, u32 fg_color, u32 bg_color)
-{
- const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL);
- struct drm_rect r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height);
- struct kmsg_dump_iter iter;
- char kmsg_buf[512];
- size_t kmsg_len;
- struct drm_panic_line line;
- int yoffset;
-
- if (!font || font->width > sb->width)
- return -EINVAL;
-
- fg_color = drm_draw_color_from_xrgb8888(fg_color, sb->format->format);
- bg_color = drm_draw_color_from_xrgb8888(bg_color, sb->format->format);
-
- yoffset = sb->height - font->height - (sb->height % font->height) / 2;
-
- /* Fill with the background color, and draw text on top */
- drm_panic_fill(sb, &r_screen, bg_color);
-
- kmsg_dump_rewind(&iter);
- while (kmsg_dump_get_buffer(&iter, false, kmsg_buf, sizeof(kmsg_buf), &kmsg_len)) {
- char *start;
- char *end;
-
- /* ignore terminating NUL and newline */
- start = kmsg_buf + kmsg_len - 2;
- end = kmsg_buf + kmsg_len - 1;
- while (start > kmsg_buf && yoffset >= 0) {
- while (start > kmsg_buf && *start != '\n')
- start--;
- /* don't count the newline character */
- line.txt = start + (start == kmsg_buf ? 0 : 1);
- line.len = end - line.txt;
-
- yoffset = draw_line_with_wrap(sb, font, &line, yoffset, fg_color);
- end = start;
- start--;
- }
- }
-
- return 0;
-}
-
#if defined(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
-/*
- * It is unwise to allocate memory in the panic callback, so the buffers are
- * pre-allocated. Only 2 buffers and the zlib workspace are needed.
- * Two buffers are enough, using the following buffer usage:
- * 1) kmsg messages are dumped in buffer1
- * 2) kmsg is zlib-compressed into buffer2
- * 3) compressed kmsg is encoded as QR-code Numeric stream in buffer1
- * 4) QR-code image is generated in buffer2
- * The Max QR code size is V40, 177x177, 4071 bytes for image, 2956 bytes for
- * data segments.
- *
- * Typically, ~7500 bytes of kmsg, are compressed into 2800 bytes, which fits in
- * a V40 QR-code (177x177).
- *
- * If CONFIG_DRM_PANIC_SCREEN_QR_CODE_URL is not set, the kmsg data will be put
- * directly in the QR code.
- * 1) kmsg messages are dumped in buffer1
- * 2) kmsg message is encoded as byte stream in buffer2
- * 3) QR-code image is generated in buffer1
- */
-
static uint panic_qr_version = CONFIG_DRM_PANIC_SCREEN_QR_VERSION;
module_param(panic_qr_version, uint, 0644);
MODULE_PARM_DESC(panic_qr_version, "maximum version (size) of the QR code");
-
-#define MAX_QR_DATA 2956
-#define MAX_ZLIB_RATIO 3
-#define QR_BUFFER1_SIZE (MAX_ZLIB_RATIO * MAX_QR_DATA) /* Must also be > 4071 */
-#define QR_BUFFER2_SIZE 4096
-#define QR_MARGIN 4 /* 4 modules of foreground color around the qr code */
-
-/* Compression parameters */
-#define COMPR_LEVEL 6
-#define WINDOW_BITS 12
-#define MEM_LEVEL 4
-
-static char *qrbuf1;
-static char *qrbuf2;
-static struct z_stream_s stream;
-
-static void __init drm_panic_qr_init(void)
-{
- qrbuf1 = kmalloc(QR_BUFFER1_SIZE, GFP_KERNEL);
- qrbuf2 = kmalloc(QR_BUFFER2_SIZE, GFP_KERNEL);
- stream.workspace = kmalloc(zlib_deflate_workspacesize(WINDOW_BITS, MEM_LEVEL),
- GFP_KERNEL);
-}
-
-static void drm_panic_qr_exit(void)
-{
- kfree(qrbuf1);
- qrbuf1 = NULL;
- kfree(qrbuf2);
- qrbuf2 = NULL;
- kfree(stream.workspace);
- stream.workspace = NULL;
-}
-
-static int drm_panic_get_qr_code_url(u8 **qr_image, unsigned int qr_version)
-{
- struct kmsg_dump_iter iter;
- char url[256];
- size_t kmsg_len, max_kmsg_size;
- char *kmsg;
- int max_qr_data_size, url_len;
-
- url_len = snprintf(url, sizeof(url), "%s?a=%s&v=%s&z=",
- CONFIG_DRM_PANIC_SCREEN_QR_CODE_URL,
- utsname()->machine, utsname()->release);
-
- max_qr_data_size = drm_panic_qr_max_data_size(qr_version, url_len);
- max_kmsg_size = min(MAX_ZLIB_RATIO * max_qr_data_size, QR_BUFFER1_SIZE);
-
- /* get kmsg to buffer 1 */
- kmsg_dump_rewind(&iter);
- kmsg_dump_get_buffer(&iter, false, qrbuf1, max_kmsg_size, &kmsg_len);
-
- if (!kmsg_len)
- return -ENODATA;
- kmsg = qrbuf1;
-
-try_again:
- if (zlib_deflateInit2(&stream, COMPR_LEVEL, Z_DEFLATED, WINDOW_BITS,
- MEM_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK)
- return -EINVAL;
-
- stream.next_in = kmsg;
- stream.avail_in = kmsg_len;
- stream.total_in = 0;
- stream.next_out = qrbuf2;
- stream.avail_out = QR_BUFFER2_SIZE;
- stream.total_out = 0;
-
- if (zlib_deflate(&stream, Z_FINISH) != Z_STREAM_END)
- return -EINVAL;
-
- if (zlib_deflateEnd(&stream) != Z_OK)
- return -EINVAL;
-
- if (stream.total_out > max_qr_data_size) {
- /* too much data for the QR code, so skip the first line and try again */
- kmsg = strchr(kmsg, '\n');
- if (!kmsg)
- return -EINVAL;
- /* skip the first \n */
- kmsg += 1;
- kmsg_len = strlen(kmsg);
- goto try_again;
- }
- *qr_image = qrbuf2;
-
- /* generate qr code image in buffer2 */
- return drm_panic_qr_generate(url, qrbuf2, stream.total_out, QR_BUFFER2_SIZE,
- qrbuf1, QR_BUFFER1_SIZE);
-}
-
-static int drm_panic_get_qr_code_raw(u8 **qr_image, unsigned int qr_version)
-{
- struct kmsg_dump_iter iter;
- size_t kmsg_len;
- size_t max_kmsg_size = min(drm_panic_qr_max_data_size(qr_version, 0),
- QR_BUFFER1_SIZE);
-
- kmsg_dump_rewind(&iter);
- kmsg_dump_get_buffer(&iter, false, qrbuf1, max_kmsg_size, &kmsg_len);
- if (!kmsg_len)
- return -ENODATA;
-
- *qr_image = qrbuf1;
- return drm_panic_qr_generate(NULL, qrbuf1, kmsg_len, QR_BUFFER1_SIZE,
- qrbuf2, QR_BUFFER2_SIZE);
-}
-
-static int drm_panic_get_qr_code(u8 **qr_image, unsigned int qr_version)
-{
- if (strlen(CONFIG_DRM_PANIC_SCREEN_QR_CODE_URL) > 0)
- return drm_panic_get_qr_code_url(qr_image, qr_version);
- else
- return drm_panic_get_qr_code_raw(qr_image, qr_version);
-}
-
-/*
- * Draw the panic message at the center of the screen, with a QR Code
- */
-static int draw_panic_screen_qr_code(struct drm_scanout_buffer *sb,
- u32 fg_color, u32 bg_color,
- unsigned int qr_version)
-{
- const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL);
- struct drm_rect r_screen, r_logo, r_msg, r_qr, r_qr_canvas;
- unsigned int max_qr_size, scale;
- unsigned int msg_width, msg_height;
- int qr_width, qr_canvas_width, qr_pitch, v_margin;
- u8 *qr_image;
-
- if (!qrbuf1 || !qrbuf2 || !stream.workspace)
- return -ENOMEM;
- if (!font)
- return -EINVAL;
-
- fg_color = drm_draw_color_from_xrgb8888(fg_color, sb->format->format);
- bg_color = drm_draw_color_from_xrgb8888(bg_color, sb->format->format);
-
- r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height);
-
- drm_panic_logo_rect(&r_logo, font);
-
- msg_width = min(get_max_line_len(panic_msg, panic_msg_lines) * font->width, sb->width);
- msg_height = min(panic_msg_lines * font->height, sb->height);
- r_msg = DRM_RECT_INIT(0, 0, msg_width, msg_height);
-
- max_qr_size = min(3 * sb->width / 4, 3 * sb->height / 4);
-
- qr_width = drm_panic_get_qr_code(&qr_image, qr_version);
- if (qr_width < 0)
- return qr_width;
- else if (!qr_width)
- return -ENOSPC;
-
- qr_canvas_width = qr_width + QR_MARGIN * 2;
- scale = max_qr_size / qr_canvas_width;
- /* QR code is not readable if not scaled at least by 2 */
- if (scale < 2)
- return -ENOSPC;
-
- pr_debug("QR width %d and scale %d\n", qr_width, scale);
- r_qr_canvas = DRM_RECT_INIT(0, 0, qr_canvas_width * scale, qr_canvas_width * scale);
-
- v_margin = sb->height - drm_rect_height(&r_qr_canvas) - drm_rect_height(&r_msg);
- if (v_margin < 0)
- return -ENOSPC;
- v_margin /= 5;
-
- drm_rect_translate(&r_qr_canvas, (sb->width - r_qr_canvas.x2) / 2, 2 * v_margin);
- r_qr = DRM_RECT_INIT(r_qr_canvas.x1 + QR_MARGIN * scale, r_qr_canvas.y1 + QR_MARGIN * scale,
- qr_width * scale, qr_width * scale);
-
- /* Center the panic message */
- drm_rect_translate(&r_msg, (sb->width - r_msg.x2) / 2,
- 3 * v_margin + drm_rect_height(&r_qr_canvas));
-
- /* Fill with the background color, and draw text on top */
- drm_panic_fill(sb, &r_screen, bg_color);
-
- if (!drm_rect_overlap(&r_logo, &r_msg) && !drm_rect_overlap(&r_logo, &r_qr_canvas))
- drm_panic_logo_draw(sb, &r_logo, font, fg_color);
-
- draw_txt_rectangle(sb, font, panic_msg, panic_msg_lines, true, &r_msg, fg_color);
-
- /* Draw the qr code */
- qr_pitch = DIV_ROUND_UP(qr_width, 8);
- drm_panic_fill(sb, &r_qr_canvas, fg_color);
- drm_panic_fill(sb, &r_qr, bg_color);
- drm_panic_blit(sb, &r_qr, qr_image, qr_pitch, scale, fg_color);
- return 0;
-}
-#else
-static void drm_panic_qr_init(void) {};
-static void drm_panic_qr_exit(void) {};
#endif
static enum drm_panic_type drm_panic_type = -1;
@@ -849,134 +96,6 @@ MODULE_PARM_DESC(panic_screen,
#endif
CONFIG_DRM_PANIC_SCREEN "]");
-/*
- * drm_panic_is_format_supported()
- * @format: a fourcc color code
- * Returns: true if supported, false otherwise.
- *
- * Check if drm_panic will be able to use this color format.
- */
-static bool drm_panic_is_format_supported(const struct drm_format_info *format)
-{
- if (format->num_planes != 1)
- return false;
- return drm_draw_can_convert_from_xrgb8888(format->format);
-}
-
-static int draw_panic_dispatch(struct drm_scanout_buffer *sb, enum drm_panic_type panic_type,
- u32 fg_color, u32 bg_color, unsigned int qr_version)
-{
- int ret;
-
-retry:
- switch (panic_type) {
- case DRM_PANIC_TYPE_KMSG:
- ret = draw_panic_screen_kmsg(sb, fg_color, bg_color);
- if (ret) {
- panic_type = DRM_PANIC_TYPE_USER;
- goto retry;
- }
- break;
-#if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
- case DRM_PANIC_TYPE_QR:
- ret = draw_panic_screen_qr_code(sb, fg_color, bg_color, qr_version);
- if (ret) {
- panic_type = DRM_PANIC_TYPE_USER;
- goto retry;
- }
- break;
-#endif
- case DRM_PANIC_TYPE_USER:
- default:
- ret = draw_panic_screen_user(sb, fg_color, bg_color);
- }
-
- return ret;
-}
-
-static void drm_panic_set_description(const char *description)
-{
- u32 len;
-
- if (description) {
- struct drm_panic_line *desc_line = &panic_msg[panic_msg_lines - 1];
-
- desc_line->txt = description;
- len = strlen(description);
- /* ignore the last newline character */
- if (len && description[len - 1] == '\n')
- len -= 1;
- desc_line->len = len;
- }
-}
-
-static void drm_panic_clear_description(void)
-{
- struct drm_panic_line *desc_line = &panic_msg[panic_msg_lines - 1];
-
- desc_line->len = 0;
- desc_line->txt = NULL;
-}
-
-/**
- * drm_plane_helper_display_panic_screen - Displays a panic screen according to the given settings
- * @plane: the DRM plane to display to
- * @description: error message to display
- * @panic_type: type of panic screen
- * @fg_color: text foreground color
- * @bg_color: text background color
- * @qr_version: version of the QR code, if any
- *
- * This helper display a panic screen on common primary planes. The panic
- * screen can either display a kernel message, a user message or a QR code.
- *
- * The helper uses struct drm_plane_helper_funcs.get_scanout_buffer, where
- * the plane can provide a scanout buffer that the panic handler can draw to.
- * Currently only linear buffer and a few color formats are supported.
- *
- * Optionally the plane can also provide a &drm_plane_helper_funcs.panic_flush
- * callback, which the DRM panic handler calls after drawing to send additional
- * commands to the hardware to make the scanout buffer visible.
- *
- * Returns:
- * 0 on success, or a negative errno code otherwise
- */
-int drm_plane_helper_display_panic_screen(struct drm_plane *plane, const char *description,
- enum drm_panic_type panic_type,
- u32 fg_color, u32 bg_color, unsigned int qr_version)
-{
- struct drm_scanout_buffer sb = { };
- int ret;
-
- ret = plane->helper_private->get_scanout_buffer(plane, &sb);
- if (ret)
- return ret;
-
- if (!drm_panic_is_format_supported(sb.format))
- return -EINVAL;
-
- /* One of these should be set, or it can't draw pixels */
- if (!sb.set_pixel && !sb.pages && iosys_map_is_null(&sb.map[0]))
- return -EINVAL;
-
- drm_panic_set_description(description);
-
- ret = draw_panic_dispatch(&sb, panic_type, fg_color, bg_color, qr_version);
- if (!ret) {
- /*
- * Only flush if we have a panic screen to display. Otherwise
- * it's probably better to leave the display output as-is.
- */
- if (plane->helper_private->panic_flush)
- plane->helper_private->panic_flush(plane);
- }
-
- drm_panic_clear_description();
-
- return ret;
-}
-EXPORT_SYMBOL(drm_plane_helper_display_panic_screen);
-
#define drm_panic_trylock(dev, flags) \
raw_spin_trylock_irqsave(&(dev)->mode_config.panic_lock, flags)
@@ -1143,17 +262,4 @@ void __init drm_panic_init(void)
CONFIG_DRM_PANIC_SCREEN);
drm_panic_type = DRM_PANIC_TYPE_USER;
}
- drm_panic_qr_init();
-}
-
-/**
- * drm_panic_exit() - Free the resources taken by drm_panic_exit()
- */
-void drm_panic_exit(void)
-{
- drm_panic_qr_exit();
}
-
-#ifdef CONFIG_DRM_KUNIT_TEST
-#include "tests/drm_panic_test.c"
-#endif
diff --git a/drivers/gpu/drm/drm_panic_helper.c b/drivers/gpu/drm/drm_panic_helper.c
new file mode 100644
index 000000000000..f64a3ca38467
--- /dev/null
+++ b/drivers/gpu/drm/drm_panic_helper.c
@@ -0,0 +1,916 @@
+// SPDX-License-Identifier: GPL-2.0 or MIT
+
+#include <linux/export.h>
+#include <linux/font.h>
+#include <linux/highmem.h>
+#include <linux/iosys-map.h>
+#include <linux/linux_logo.h>
+#include <linux/utsname.h>
+#include <linux/zlib.h>
+
+#include <drm/drm_fourcc.h>
+#include <drm/drm_framebuffer.h>
+#include <drm/drm_modeset_helper_vtables.h>
+#include <drm/drm_panic.h>
+#include <drm/drm_panic_helper.h>
+#include <drm/drm_plane.h>
+#include <drm/drm_rect.h>
+
+#include "drm_draw_internal.h"
+#include "drm_panic_internal.h"
+
+struct drm_panic_line {
+ u32 len;
+ const char *txt;
+};
+
+#define PANIC_LINE(s) {.len = sizeof(s) - 1, .txt = s}
+
+static struct drm_panic_line panic_msg[] = {
+ PANIC_LINE("KERNEL PANIC!"),
+ PANIC_LINE(""),
+ PANIC_LINE("Please reboot your computer."),
+ PANIC_LINE(""),
+ PANIC_LINE(""), /* will be replaced by the panic description */
+};
+
+static const size_t panic_msg_lines = ARRAY_SIZE(panic_msg);
+
+static const struct drm_panic_line logo_ascii[] = {
+ PANIC_LINE(" .--. _"),
+ PANIC_LINE(" |o_o | | |"),
+ PANIC_LINE(" |:_/ | | |"),
+ PANIC_LINE(" // \\ \\ |_|"),
+ PANIC_LINE(" (| | ) _"),
+ PANIC_LINE(" /'\\_ _/`\\ (_)"),
+ PANIC_LINE(" \\___)=(___/"),
+};
+
+static const size_t logo_ascii_lines = ARRAY_SIZE(logo_ascii);
+
+#if defined(CONFIG_LOGO) && !defined(MODULE)
+static const struct linux_logo *logo_mono;
+
+static int __init drm_panic_helper_setup_logo(void)
+{
+ const struct linux_logo *logo = fb_find_logo(1);
+ const unsigned char *logo_data;
+ struct linux_logo *logo_dup;
+
+ if (!logo || logo->type != LINUX_LOGO_MONO)
+ return 0;
+
+ /* The logo is __init, so we must make a copy for later use */
+ logo_data = kmemdup(logo->data,
+ size_mul(DIV_ROUND_UP(logo->width, BITS_PER_BYTE), logo->height),
+ GFP_KERNEL);
+ if (!logo_data)
+ return -ENOMEM;
+
+ logo_dup = kmemdup(logo, sizeof(*logo), GFP_KERNEL);
+ if (!logo_dup) {
+ kfree(logo_data);
+ return -ENOMEM;
+ }
+
+ logo_dup->data = logo_data;
+ logo_mono = logo_dup;
+
+ return 0;
+}
+#else
+#define logo_mono ((const struct linux_logo *)NULL)
+static int __init drm_panic_helper_setup_logo(void)
+{
+ return 0;
+}
+#endif
+
+/*
+ * Blit & Fill functions
+ */
+static void drm_panic_helper_blit_pixel(struct drm_scanout_buffer *sb, struct drm_rect *clip,
+ const u8 *sbuf8, unsigned int spitch, unsigned int scale,
+ u32 fg_color)
+{
+ unsigned int y, x;
+
+ for (y = 0; y < drm_rect_height(clip); y++)
+ for (x = 0; x < drm_rect_width(clip); x++)
+ if (drm_draw_is_pixel_fg(sbuf8, spitch, x / scale, y / scale))
+ sb->set_pixel(sb, clip->x1 + x, clip->y1 + y, fg_color);
+}
+
+static void drm_panic_helper_write_pixel16(void *vaddr, unsigned int offset, u16 color)
+{
+ u16 *p = vaddr + offset;
+
+ *p = color;
+}
+
+static void drm_panic_helper_write_pixel24(void *vaddr, unsigned int offset, u32 color)
+{
+ u8 *p = vaddr + offset;
+
+ *p++ = color & 0xff;
+ color >>= 8;
+ *p++ = color & 0xff;
+ color >>= 8;
+ *p = color & 0xff;
+}
+
+/*
+ * Special case if the pixel crosses page boundaries
+ */
+static void drm_panic_helper_write_pixel24_xpage(void *vaddr, struct page *next_page,
+ unsigned int offset, u32 color)
+{
+ u8 *vaddr2;
+ u8 *p = vaddr + offset;
+
+ vaddr2 = kmap_local_page_try_from_panic(next_page);
+ if (!vaddr2)
+ return;
+
+ *p++ = color & 0xff;
+ color >>= 8;
+
+ if (offset == PAGE_SIZE - 1)
+ p = vaddr2;
+
+ *p++ = color & 0xff;
+ color >>= 8;
+
+ if (offset == PAGE_SIZE - 2)
+ p = vaddr2;
+
+ *p = color & 0xff;
+ kunmap_local(vaddr2);
+}
+
+static void drm_panic_helper_write_pixel32(void *vaddr, unsigned int offset, u32 color)
+{
+ u32 *p = vaddr + offset;
+
+ *p = color;
+}
+
+static void drm_panic_helper_write_pixel(void *vaddr, unsigned int offset, u32 color,
+ unsigned int cpp)
+{
+ switch (cpp) {
+ case 2:
+ drm_panic_helper_write_pixel16(vaddr, offset, color);
+ break;
+ case 3:
+ drm_panic_helper_write_pixel24(vaddr, offset, color);
+ break;
+ case 4:
+ drm_panic_helper_write_pixel32(vaddr, offset, color);
+ break;
+ default:
+ pr_debug_once("Can't blit with pixel width %d\n", cpp);
+ }
+}
+
+/*
+ * The scanout buffer pages are not mapped, so for each pixel,
+ * use kmap_local_page_try_from_panic() to map the page, and write the pixel.
+ * Try to keep the map from the previous pixel, to avoid too much map/unmap.
+ */
+static void drm_panic_helper_blit_page(struct page **pages, unsigned int dpitch,
+ unsigned int cpp, const u8 *sbuf8,
+ unsigned int spitch, struct drm_rect *clip,
+ unsigned int scale, u32 fg32)
+{
+ unsigned int y, x;
+ unsigned int page = ~0;
+ unsigned int height = drm_rect_height(clip);
+ unsigned int width = drm_rect_width(clip);
+ void *vaddr = NULL;
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ if (drm_draw_is_pixel_fg(sbuf8, spitch, x / scale, y / scale)) {
+ unsigned int new_page;
+ unsigned int offset;
+
+ offset = (y + clip->y1) * dpitch + (x + clip->x1) * cpp;
+ new_page = offset >> PAGE_SHIFT;
+ offset = offset % PAGE_SIZE;
+ if (new_page != page) {
+ if (!pages[new_page])
+ continue;
+ if (vaddr)
+ kunmap_local(vaddr);
+ page = new_page;
+ vaddr = kmap_local_page_try_from_panic(pages[page]);
+ }
+ if (!vaddr)
+ continue;
+
+ // Special case for 24bit, as a pixel might cross page boundaries
+ if (cpp == 3 && offset + 3 > PAGE_SIZE)
+ drm_panic_helper_write_pixel24_xpage(vaddr,
+ pages[page + 1],
+ offset, fg32);
+ else
+ drm_panic_helper_write_pixel(vaddr, offset, fg32, cpp);
+ }
+ }
+ }
+ if (vaddr)
+ kunmap_local(vaddr);
+}
+
+/*
+ * drm_panic_helper_blit - convert a monochrome image to a linear framebuffer
+ * @sb: destination scanout buffer
+ * @clip: destination rectangle
+ * @sbuf8: source buffer, in monochrome format, 8 pixels per byte.
+ * @spitch: source pitch in bytes
+ * @scale: integer scale, source buffer is scale time smaller than destination
+ * rectangle
+ * @fg_color: foreground color, in destination format
+ *
+ * This can be used to draw a font character, which is a monochrome image, to a
+ * framebuffer in other supported format.
+ */
+static void drm_panic_helper_blit(struct drm_scanout_buffer *sb, struct drm_rect *clip,
+ const u8 *sbuf8, unsigned int spitch,
+ unsigned int scale, u32 fg_color)
+
+{
+ struct iosys_map map;
+
+ if (sb->set_pixel)
+ return drm_panic_helper_blit_pixel(sb, clip, sbuf8, spitch, scale, fg_color);
+
+ if (sb->pages)
+ return drm_panic_helper_blit_page(sb->pages, sb->pitch[0], sb->format->cpp[0],
+ sbuf8, spitch, clip, scale, fg_color);
+
+ map = sb->map[0];
+ iosys_map_incr(&map, clip->y1 * sb->pitch[0] + clip->x1 * sb->format->cpp[0]);
+
+ switch (sb->format->cpp[0]) {
+ case 2:
+ drm_draw_blit16(&map, sb->pitch[0], sbuf8, spitch,
+ drm_rect_height(clip), drm_rect_width(clip), scale, fg_color);
+ break;
+ case 3:
+ drm_draw_blit24(&map, sb->pitch[0], sbuf8, spitch,
+ drm_rect_height(clip), drm_rect_width(clip), scale, fg_color);
+ break;
+ case 4:
+ drm_draw_blit32(&map, sb->pitch[0], sbuf8, spitch,
+ drm_rect_height(clip), drm_rect_width(clip), scale, fg_color);
+ break;
+ default:
+ WARN_ONCE(1, "Can't blit with pixel width %d\n", sb->format->cpp[0]);
+ }
+}
+
+static void drm_panic_helper_fill_pixel(struct drm_scanout_buffer *sb,
+ struct drm_rect *clip,
+ u32 color)
+{
+ unsigned int y, x;
+
+ for (y = 0; y < drm_rect_height(clip); y++)
+ for (x = 0; x < drm_rect_width(clip); x++)
+ sb->set_pixel(sb, clip->x1 + x, clip->y1 + y, color);
+}
+
+static void drm_panic_helper_fill_page(struct page **pages, unsigned int dpitch,
+ unsigned int cpp, struct drm_rect *clip,
+ u32 color)
+{
+ unsigned int y, x;
+ unsigned int page = ~0;
+ void *vaddr = NULL;
+
+ for (y = clip->y1; y < clip->y2; y++) {
+ for (x = clip->x1; x < clip->x2; x++) {
+ unsigned int new_page;
+ unsigned int offset;
+
+ offset = y * dpitch + x * cpp;
+ new_page = offset >> PAGE_SHIFT;
+ offset = offset % PAGE_SIZE;
+ if (new_page != page) {
+ if (vaddr)
+ kunmap_local(vaddr);
+ page = new_page;
+ vaddr = kmap_local_page_try_from_panic(pages[page]);
+ }
+ if (!vaddr)
+ continue;
+
+ // Special case for 24bit, as a pixel might cross page boundaries
+ if (cpp == 3 && offset + 3 > PAGE_SIZE)
+ drm_panic_helper_write_pixel24_xpage(vaddr, pages[page + 1],
+ offset, color);
+ else
+ drm_panic_helper_write_pixel(vaddr, offset, color, cpp);
+ }
+ }
+ if (vaddr)
+ kunmap_local(vaddr);
+}
+
+/*
+ * drm_panic_helper_fill - Fill a rectangle with a color
+ * @sb: destination scanout buffer
+ * @clip: destination rectangle
+ * @color: foreground color, in destination format
+ *
+ * Fill a rectangle with a color, in a linear framebuffer.
+ */
+static void drm_panic_helper_fill(struct drm_scanout_buffer *sb, struct drm_rect *clip,
+ u32 color)
+{
+ struct iosys_map map;
+
+ if (sb->set_pixel)
+ return drm_panic_helper_fill_pixel(sb, clip, color);
+
+ if (sb->pages)
+ return drm_panic_helper_fill_page(sb->pages, sb->pitch[0], sb->format->cpp[0],
+ clip, color);
+
+ map = sb->map[0];
+ iosys_map_incr(&map, clip->y1 * sb->pitch[0] + clip->x1 * sb->format->cpp[0]);
+
+ switch (sb->format->cpp[0]) {
+ case 2:
+ drm_draw_fill16(&map, sb->pitch[0], drm_rect_height(clip),
+ drm_rect_width(clip), color);
+ break;
+ case 3:
+ drm_draw_fill24(&map, sb->pitch[0], drm_rect_height(clip),
+ drm_rect_width(clip), color);
+ break;
+ case 4:
+ drm_draw_fill32(&map, sb->pitch[0], drm_rect_height(clip),
+ drm_rect_width(clip), color);
+ break;
+ default:
+ WARN_ONCE(1, "Can't fill with pixel width %d\n", sb->format->cpp[0]);
+ }
+}
+
+static unsigned int get_max_line_len(const struct drm_panic_line *lines, int len)
+{
+ int i;
+ unsigned int max = 0;
+
+ for (i = 0; i < len; i++)
+ max = max(lines[i].len, max);
+ return max;
+}
+
+/*
+ * Draw a text in a rectangle on a framebuffer. The text is truncated if it overflows the rectangle
+ */
+static void draw_txt_rectangle(struct drm_scanout_buffer *sb,
+ const struct font_desc *font,
+ const struct drm_panic_line *msg,
+ unsigned int msg_lines,
+ bool centered,
+ struct drm_rect *clip,
+ u32 color)
+{
+ int i, j;
+ const u8 *src;
+ size_t font_pitch = DIV_ROUND_UP(font->width, 8);
+ struct drm_rect rec;
+
+ msg_lines = min(msg_lines, drm_rect_height(clip) / font->height);
+ for (i = 0; i < msg_lines; i++) {
+ size_t line_len = min(msg[i].len, drm_rect_width(clip) / font->width);
+
+ rec.y1 = clip->y1 + i * font->height;
+ rec.y2 = rec.y1 + font->height;
+ rec.x1 = clip->x1;
+
+ if (centered)
+ rec.x1 += (drm_rect_width(clip) - (line_len * font->width)) / 2;
+
+ for (j = 0; j < line_len; j++) {
+ src = font_data_glyph_buf(font->data, font->width, font->height,
+ (unsigned char)msg[i].txt[j]);
+ rec.x2 = rec.x1 + font->width;
+ if (src)
+ drm_panic_helper_blit(sb, &rec, src, font_pitch, 1, color);
+ rec.x1 += font->width;
+ }
+ }
+}
+
+static void drm_panic_helper_logo_rect(struct drm_rect *rect, const struct font_desc *font)
+{
+ if (logo_mono) {
+ drm_rect_init(rect, 0, 0, logo_mono->width, logo_mono->height);
+ } else {
+ int logo_width = get_max_line_len(logo_ascii, logo_ascii_lines) * font->width;
+
+ drm_rect_init(rect, 0, 0, logo_width, logo_ascii_lines * font->height);
+ }
+}
+
+static void drm_panic_helper_logo_draw(struct drm_scanout_buffer *sb, struct drm_rect *rect,
+ const struct font_desc *font, u32 fg_color)
+{
+ if (rect->x2 > sb->width || rect->y2 > sb->height)
+ return;
+
+ if (logo_mono)
+ drm_panic_helper_blit(sb, rect, logo_mono->data,
+ DIV_ROUND_UP(drm_rect_width(rect), 8), 1, fg_color);
+ else
+ draw_txt_rectangle(sb, font, logo_ascii, logo_ascii_lines, false, rect,
+ fg_color);
+}
+
+static int drm_panic_helper_draw_screen_user(struct drm_scanout_buffer *sb,
+ u32 fg_color, u32 bg_color)
+{
+ const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL);
+ struct drm_rect r_screen, r_logo, r_msg;
+ unsigned int msg_width, msg_height;
+
+ if (!font || font->width > sb->width)
+ return -EINVAL;
+
+ fg_color = drm_draw_color_from_xrgb8888(fg_color, sb->format->format);
+ bg_color = drm_draw_color_from_xrgb8888(bg_color, sb->format->format);
+
+ r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height);
+ drm_panic_helper_logo_rect(&r_logo, font);
+
+ msg_width = min(get_max_line_len(panic_msg, panic_msg_lines) * font->width, sb->width);
+ msg_height = min(panic_msg_lines * font->height, sb->height);
+ r_msg = DRM_RECT_INIT(0, 0, msg_width, msg_height);
+
+ /* Center the panic message */
+ drm_rect_translate(&r_msg, (sb->width - r_msg.x2) / 2, (sb->height - r_msg.y2) / 2);
+
+ /* Fill with the background color, and draw text on top */
+ drm_panic_helper_fill(sb, &r_screen, bg_color);
+
+ if (!drm_rect_overlap(&r_logo, &r_msg))
+ drm_panic_helper_logo_draw(sb, &r_logo, font, fg_color);
+
+ draw_txt_rectangle(sb, font, panic_msg, panic_msg_lines, true, &r_msg, fg_color);
+
+ return 0;
+}
+
+/*
+ * Draw one line of kmsg, and handle wrapping if it won't fit in the screen width.
+ * Return the y-offset of the next line.
+ */
+static int draw_line_with_wrap(struct drm_scanout_buffer *sb, const struct font_desc *font,
+ struct drm_panic_line *line, int yoffset, u32 fg_color)
+{
+ int chars_per_row = sb->width / font->width;
+ struct drm_rect r_txt = DRM_RECT_INIT(0, yoffset, sb->width, font->height);
+ struct drm_panic_line line_wrap;
+
+ if (line->len > chars_per_row) {
+ line_wrap.len = line->len % chars_per_row;
+ line_wrap.txt = line->txt + line->len - line_wrap.len;
+ draw_txt_rectangle(sb, font, &line_wrap, 1, false, &r_txt, fg_color);
+ r_txt.y1 -= font->height;
+ if (r_txt.y1 < 0)
+ return r_txt.y1;
+ while (line_wrap.txt > line->txt) {
+ line_wrap.txt -= chars_per_row;
+ line_wrap.len = chars_per_row;
+ draw_txt_rectangle(sb, font, &line_wrap, 1, false, &r_txt, fg_color);
+ r_txt.y1 -= font->height;
+ if (r_txt.y1 < 0)
+ return r_txt.y1;
+ }
+ } else {
+ draw_txt_rectangle(sb, font, line, 1, false, &r_txt, fg_color);
+ r_txt.y1 -= font->height;
+ }
+ return r_txt.y1;
+}
+
+/*
+ * Draw the kmsg buffer to the screen, starting from the youngest message at the bottom,
+ * and going up until reaching the top of the screen.
+ */
+static int drm_panic_helper_draw_screen_kmsg(struct drm_scanout_buffer *sb,
+ u32 fg_color, u32 bg_color)
+{
+ const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL);
+ struct drm_rect r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height);
+ struct kmsg_dump_iter iter;
+ char kmsg_buf[512];
+ size_t kmsg_len;
+ struct drm_panic_line line;
+ int yoffset;
+
+ if (!font || font->width > sb->width)
+ return -EINVAL;
+
+ fg_color = drm_draw_color_from_xrgb8888(fg_color, sb->format->format);
+ bg_color = drm_draw_color_from_xrgb8888(bg_color, sb->format->format);
+
+ yoffset = sb->height - font->height - (sb->height % font->height) / 2;
+
+ /* Fill with the background color, and draw text on top */
+ drm_panic_helper_fill(sb, &r_screen, bg_color);
+
+ kmsg_dump_rewind(&iter);
+ while (kmsg_dump_get_buffer(&iter, false, kmsg_buf, sizeof(kmsg_buf), &kmsg_len)) {
+ char *start;
+ char *end;
+
+ /* ignore terminating NUL and newline */
+ start = kmsg_buf + kmsg_len - 2;
+ end = kmsg_buf + kmsg_len - 1;
+ while (start > kmsg_buf && yoffset >= 0) {
+ while (start > kmsg_buf && *start != '\n')
+ start--;
+ /* don't count the newline character */
+ line.txt = start + (start == kmsg_buf ? 0 : 1);
+ line.len = end - line.txt;
+
+ yoffset = draw_line_with_wrap(sb, font, &line, yoffset, fg_color);
+ end = start;
+ start--;
+ }
+ }
+
+ return 0;
+}
+
+#if defined(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
+/*
+ * It is unwise to allocate memory in the panic callback, so the buffers are
+ * pre-allocated. Only 2 buffers and the zlib workspace are needed.
+ * Two buffers are enough, using the following buffer usage:
+ * 1) kmsg messages are dumped in buffer1
+ * 2) kmsg is zlib-compressed into buffer2
+ * 3) compressed kmsg is encoded as QR-code Numeric stream in buffer1
+ * 4) QR-code image is generated in buffer2
+ * The Max QR code size is V40, 177x177, 4071 bytes for image, 2956 bytes for
+ * data segments.
+ *
+ * Typically, ~7500 bytes of kmsg, are compressed into 2800 bytes, which fits in
+ * a V40 QR-code (177x177).
+ *
+ * If CONFIG_DRM_PANIC_SCREEN_QR_CODE_URL is not set, the kmsg data will be put
+ * directly in the QR code.
+ * 1) kmsg messages are dumped in buffer1
+ * 2) kmsg message is encoded as byte stream in buffer2
+ * 3) QR-code image is generated in buffer1
+ */
+
+#define MAX_QR_DATA 2956
+#define MAX_ZLIB_RATIO 3
+#define QR_BUFFER1_SIZE (MAX_ZLIB_RATIO * MAX_QR_DATA) /* Must also be > 4071 */
+#define QR_BUFFER2_SIZE 4096
+#define QR_MARGIN 4 /* 4 modules of foreground color around the qr code */
+
+/* Compression parameters */
+#define COMPR_LEVEL 6
+#define WINDOW_BITS 12
+#define MEM_LEVEL 4
+
+static char *qrbuf1;
+static char *qrbuf2;
+static struct z_stream_s stream;
+
+static void __init drm_panic_helper_qr_init(void)
+{
+ qrbuf1 = kmalloc(QR_BUFFER1_SIZE, GFP_KERNEL);
+ qrbuf2 = kmalloc(QR_BUFFER2_SIZE, GFP_KERNEL);
+ stream.workspace = kmalloc(zlib_deflate_workspacesize(WINDOW_BITS, MEM_LEVEL),
+ GFP_KERNEL);
+}
+
+static void drm_panic_helper_qr_exit(void)
+{
+ kfree(qrbuf1);
+ qrbuf1 = NULL;
+ kfree(qrbuf2);
+ qrbuf2 = NULL;
+ kfree(stream.workspace);
+ stream.workspace = NULL;
+}
+
+static int drm_panic_helper_get_qr_code_url(u8 **qr_image, unsigned int qr_version)
+{
+ struct kmsg_dump_iter iter;
+ char url[256];
+ size_t kmsg_len, max_kmsg_size;
+ char *kmsg;
+ int max_qr_data_size, url_len;
+
+ url_len = snprintf(url, sizeof(url), "%s?a=%s&v=%s&z=",
+ CONFIG_DRM_PANIC_SCREEN_QR_CODE_URL,
+ utsname()->machine, utsname()->release);
+
+ max_qr_data_size = drm_panic_helper_qr_max_data_size(qr_version, url_len);
+ max_kmsg_size = min(MAX_ZLIB_RATIO * max_qr_data_size, QR_BUFFER1_SIZE);
+
+ /* get kmsg to buffer 1 */
+ kmsg_dump_rewind(&iter);
+ kmsg_dump_get_buffer(&iter, false, qrbuf1, max_kmsg_size, &kmsg_len);
+
+ if (!kmsg_len)
+ return -ENODATA;
+ kmsg = qrbuf1;
+
+try_again:
+ if (zlib_deflateInit2(&stream, COMPR_LEVEL, Z_DEFLATED, WINDOW_BITS,
+ MEM_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK)
+ return -EINVAL;
+
+ stream.next_in = kmsg;
+ stream.avail_in = kmsg_len;
+ stream.total_in = 0;
+ stream.next_out = qrbuf2;
+ stream.avail_out = QR_BUFFER2_SIZE;
+ stream.total_out = 0;
+
+ if (zlib_deflate(&stream, Z_FINISH) != Z_STREAM_END)
+ return -EINVAL;
+
+ if (zlib_deflateEnd(&stream) != Z_OK)
+ return -EINVAL;
+
+ if (stream.total_out > max_qr_data_size) {
+ /* too much data for the QR code, so skip the first line and try again */
+ kmsg = strchr(kmsg, '\n');
+ if (!kmsg)
+ return -EINVAL;
+ /* skip the first \n */
+ kmsg += 1;
+ kmsg_len = strlen(kmsg);
+ goto try_again;
+ }
+ *qr_image = qrbuf2;
+
+ /* generate qr code image in buffer2 */
+ return drm_panic_helper_qr_generate(url, qrbuf2, stream.total_out, QR_BUFFER2_SIZE,
+ qrbuf1, QR_BUFFER1_SIZE);
+}
+
+static int drm_panic_helper_get_qr_code_raw(u8 **qr_image, unsigned int qr_version)
+{
+ struct kmsg_dump_iter iter;
+ size_t kmsg_len;
+ size_t max_kmsg_size = min(drm_panic_helper_qr_max_data_size(qr_version, 0),
+ QR_BUFFER1_SIZE);
+
+ kmsg_dump_rewind(&iter);
+ kmsg_dump_get_buffer(&iter, false, qrbuf1, max_kmsg_size, &kmsg_len);
+ if (!kmsg_len)
+ return -ENODATA;
+
+ *qr_image = qrbuf1;
+ return drm_panic_helper_qr_generate(NULL, qrbuf1, kmsg_len, QR_BUFFER1_SIZE,
+ qrbuf2, QR_BUFFER2_SIZE);
+}
+
+static int drm_panic_helper_get_qr_code(u8 **qr_image, unsigned int qr_version)
+{
+ if (strlen(CONFIG_DRM_PANIC_SCREEN_QR_CODE_URL) > 0)
+ return drm_panic_helper_get_qr_code_url(qr_image, qr_version);
+ else
+ return drm_panic_helper_get_qr_code_raw(qr_image, qr_version);
+}
+
+/*
+ * Draw the panic message at the center of the screen, with a QR Code
+ */
+static int drm_panic_helper_draw_screen_qr_code(struct drm_scanout_buffer *sb,
+ u32 fg_color, u32 bg_color,
+ unsigned int qr_version)
+{
+ const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL);
+ struct drm_rect r_screen, r_logo, r_msg, r_qr, r_qr_canvas;
+ unsigned int max_qr_size, scale;
+ unsigned int msg_width, msg_height;
+ int qr_width, qr_canvas_width, qr_pitch, v_margin;
+ u8 *qr_image;
+
+ if (!qrbuf1 || !qrbuf2 || !stream.workspace)
+ return -ENOMEM;
+ if (!font)
+ return -EINVAL;
+
+ fg_color = drm_draw_color_from_xrgb8888(fg_color, sb->format->format);
+ bg_color = drm_draw_color_from_xrgb8888(bg_color, sb->format->format);
+
+ r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height);
+
+ drm_panic_helper_logo_rect(&r_logo, font);
+
+ msg_width = min(get_max_line_len(panic_msg, panic_msg_lines) * font->width, sb->width);
+ msg_height = min(panic_msg_lines * font->height, sb->height);
+ r_msg = DRM_RECT_INIT(0, 0, msg_width, msg_height);
+
+ max_qr_size = min(3 * sb->width / 4, 3 * sb->height / 4);
+
+ qr_width = drm_panic_helper_get_qr_code(&qr_image, qr_version);
+ if (qr_width < 0)
+ return qr_width;
+ else if (!qr_width)
+ return -ENOSPC;
+
+ qr_canvas_width = qr_width + QR_MARGIN * 2;
+ scale = max_qr_size / qr_canvas_width;
+ /* QR code is not readable if not scaled at least by 2 */
+ if (scale < 2)
+ return -ENOSPC;
+
+ pr_debug("QR width %d and scale %d\n", qr_width, scale);
+ r_qr_canvas = DRM_RECT_INIT(0, 0, qr_canvas_width * scale, qr_canvas_width * scale);
+
+ v_margin = sb->height - drm_rect_height(&r_qr_canvas) - drm_rect_height(&r_msg);
+ if (v_margin < 0)
+ return -ENOSPC;
+ v_margin /= 5;
+
+ drm_rect_translate(&r_qr_canvas, (sb->width - r_qr_canvas.x2) / 2, 2 * v_margin);
+ r_qr = DRM_RECT_INIT(r_qr_canvas.x1 + QR_MARGIN * scale, r_qr_canvas.y1 + QR_MARGIN * scale,
+ qr_width * scale, qr_width * scale);
+
+ /* Center the panic message */
+ drm_rect_translate(&r_msg, (sb->width - r_msg.x2) / 2,
+ 3 * v_margin + drm_rect_height(&r_qr_canvas));
+
+ /* Fill with the background color, and draw text on top */
+ drm_panic_helper_fill(sb, &r_screen, bg_color);
+
+ if (!drm_rect_overlap(&r_logo, &r_msg) && !drm_rect_overlap(&r_logo, &r_qr_canvas))
+ drm_panic_helper_logo_draw(sb, &r_logo, font, fg_color);
+
+ draw_txt_rectangle(sb, font, panic_msg, panic_msg_lines, true, &r_msg, fg_color);
+
+ /* Draw the qr code */
+ qr_pitch = DIV_ROUND_UP(qr_width, 8);
+ drm_panic_helper_fill(sb, &r_qr_canvas, fg_color);
+ drm_panic_helper_fill(sb, &r_qr, bg_color);
+ drm_panic_helper_blit(sb, &r_qr, qr_image, qr_pitch, scale, fg_color);
+ return 0;
+}
+#else
+static void __init drm_panic_helper_qr_init(void) { };
+static void __exit drm_panic_helper_qr_exit(void) { };
+#endif
+
+/*
+ * drm_panic_helper_format_is_supported()
+ * @format: a fourcc color code
+ * Returns: true if supported, false otherwise.
+ *
+ * Check if drm_panic will be able to use this color format.
+ */
+static bool drm_panic_helper_format_is_supported(const struct drm_format_info *format)
+{
+ if (format->num_planes != 1)
+ return false;
+ return drm_draw_can_convert_from_xrgb8888(format->format);
+}
+
+static int draw_panic_helper_dispatch(struct drm_scanout_buffer *sb,
+ enum drm_panic_type panic_type,
+ u32 fg_color, u32 bg_color,
+ unsigned int qr_version)
+{
+ int ret;
+
+retry:
+ switch (panic_type) {
+ case DRM_PANIC_TYPE_KMSG:
+ ret = drm_panic_helper_draw_screen_kmsg(sb, fg_color, bg_color);
+ if (ret) {
+ panic_type = DRM_PANIC_TYPE_USER;
+ goto retry;
+ }
+ break;
+#if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
+ case DRM_PANIC_TYPE_QR:
+ ret = drm_panic_helper_draw_screen_qr_code(sb, fg_color, bg_color, qr_version);
+ if (ret) {
+ panic_type = DRM_PANIC_TYPE_USER;
+ goto retry;
+ }
+ break;
+#endif
+ case DRM_PANIC_TYPE_USER:
+ default:
+ ret = drm_panic_helper_draw_screen_user(sb, fg_color, bg_color);
+ }
+
+ return ret;
+}
+
+static void drm_panic_helper_set_description(const char *description)
+{
+ u32 len;
+
+ if (description) {
+ struct drm_panic_line *desc_line = &panic_msg[panic_msg_lines - 1];
+
+ desc_line->txt = description;
+ len = strlen(description);
+ /* ignore the last newline character */
+ if (len && description[len - 1] == '\n')
+ len -= 1;
+ desc_line->len = len;
+ }
+}
+
+static void drm_panic_helper_clear_description(void)
+{
+ struct drm_panic_line *desc_line = &panic_msg[panic_msg_lines - 1];
+
+ desc_line->len = 0;
+ desc_line->txt = NULL;
+}
+
+/**
+ * drm_plane_helper_display_panic_screen - Displays a panic screen according to the given settings
+ * @plane: the DRM plane to display to
+ * @description: error message to display
+ * @panic_type: type of panic screen
+ * @fg_color: text foreground color
+ * @bg_color: text background color
+ * @qr_version: version of the QR code, if any
+ *
+ * This helper display a panic screen on common primary planes. The panic
+ * screen can either display a kernel message, a user message or a QR code.
+ *
+ * The helper uses struct drm_plane_helper_funcs.get_scanout_buffer, where
+ * the plane can provide a scanout buffer that the panic handler can draw to.
+ * Currently only linear buffer and a few color formats are supported.
+ *
+ * Optionally the plane can also provide a &drm_plane_helper_funcs.panic_flush
+ * callback, which the DRM panic handler calls after drawing to send additional
+ * commands to the hardware to make the scanout buffer visible.
+ */
+int drm_plane_helper_display_panic_screen(struct drm_plane *plane, const char *description,
+ enum drm_panic_type panic_type,
+ u32 fg_color, u32 bg_color, unsigned int qr_version)
+{
+ struct drm_scanout_buffer sb = { };
+ int ret;
+
+ if (!plane->helper_private || !plane->helper_private->get_scanout_buffer)
+ return -EINVAL;
+
+ ret = plane->helper_private->get_scanout_buffer(plane, &sb);
+ if (ret)
+ return ret;
+
+ if (!drm_panic_helper_format_is_supported(sb.format))
+ return -EINVAL;
+
+ /* One of these should be set, or it can't draw pixels */
+ if (!sb.set_pixel && !sb.pages && iosys_map_is_null(&sb.map[0]))
+ return -EINVAL;
+
+ drm_panic_helper_set_description(description);
+
+ ret = draw_panic_helper_dispatch(&sb, panic_type, fg_color, bg_color, qr_version);
+ if (!ret) {
+ /*
+ * Only flush if we have a panic screen to display. Otherwise
+ * it's probably better to leave the display output as-is.
+ */
+ if (plane->helper_private->panic_flush)
+ plane->helper_private->panic_flush(plane);
+ }
+
+ drm_panic_helper_clear_description();
+
+ return ret;
+}
+EXPORT_SYMBOL(drm_plane_helper_display_panic_screen);
+
+int __init drm_panic_helper_init(void)
+{
+ drm_panic_helper_setup_logo();
+ drm_panic_helper_qr_init();
+
+ return 0;
+}
+
+void __exit drm_panic_helper_exit(void)
+{
+ drm_panic_helper_qr_exit();
+}
+
+#ifdef CONFIG_DRM_KUNIT_TEST
+#include "tests/drm_panic_helper_test.c"
+#endif
diff --git a/drivers/gpu/drm/drm_panic_qr.rs b/drivers/gpu/drm/drm_panic_helper_qr.rs
similarity index 99%
rename from drivers/gpu/drm/drm_panic_qr.rs
rename to drivers/gpu/drm/drm_panic_helper_qr.rs
index ac27e86c601c..22966956331e 100644
--- a/drivers/gpu/drm/drm_panic_qr.rs
+++ b/drivers/gpu/drm/drm_panic_helper_qr.rs
@@ -938,7 +938,7 @@ fn draw_all(&mut self, data: impl Iterator<Item = u8>) {
///
/// They must remain valid for the duration of the function call.
#[export]
-pub unsafe extern "C" fn drm_panic_qr_generate(
+pub unsafe extern "C" fn drm_panic_helper_qr_generate(
url: *const kernel::ffi::c_char,
data: *mut u8,
data_len: usize,
@@ -994,7 +994,7 @@ fn draw_all(&mut self, data: impl Iterator<Item = u8>) {
/// Always safe to call.
// Required to be unsafe due to the `#[export]` annotation.
#[export]
-pub unsafe extern "C" fn drm_panic_qr_max_data_size(version: u8, url_len: usize) -> usize {
+pub unsafe extern "C" fn drm_panic_helper_qr_max_data_size(version: u8, url_len: usize) -> usize {
#[expect(clippy::manual_range_contains)]
if version < 1 || version > 40 {
return 0;
diff --git a/drivers/gpu/drm/drm_panic_internal.h b/drivers/gpu/drm/drm_panic_internal.h
index c68d64c56e15..fe6d514a0833 100644
--- a/drivers/gpu/drm/drm_panic_internal.h
+++ b/drivers/gpu/drm/drm_panic_internal.h
@@ -52,4 +52,18 @@ static inline void drm_panic_lock(struct drm_device *dev, unsigned long flags) {
static inline void drm_panic_unlock(struct drm_device *dev, unsigned long flags) {}
#endif
+#if IS_ENABLED(CONFIG_DRM_PANIC_HELPER)
+/* drm_panic_helper.c */
+int __init drm_panic_helper_init(void);
+void __exit drm_panic_helper_exit(void);
+#else
+static inline int __init drm_panic_helper_init(void)
+{
+ return 0;
+}
+
+static inline void __exit drm_panic_helper_exit(void)
+{ }
+#endif
+
#endif /* __DRM_PANIC_INTERNAL_H__ */
diff --git a/drivers/gpu/drm/tests/drm_panic_test.c b/drivers/gpu/drm/tests/drm_panic_helper_test.c
similarity index 88%
rename from drivers/gpu/drm/tests/drm_panic_test.c
rename to drivers/gpu/drm/tests/drm_panic_helper_test.c
index 55d77bc203df..e6befe0f1c83 100644
--- a/drivers/gpu/drm/tests/drm_panic_test.c
+++ b/drivers/gpu/drm/tests/drm_panic_helper_test.c
@@ -3,7 +3,7 @@
* Copyright (c) 2025 Red Hat.
* Author: Jocelyn Falempe <jfalempe@redhat.com>
*
- * KUNIT tests for drm panic
+ * KUNIT tests for DRM panic helpers
*/
#include <drm/drm_fourcc.h>
@@ -41,24 +41,24 @@ struct drm_test_mode {
.width = w, \
.height = h, \
.format = f, \
- .draw_screen = draw_panic_screen_ ## name ## _default, \
+ .draw_screen = drm_panic_helper_draw_screen_ ## name ## _default, \
.fname = #name, \
}, \
-static int draw_panic_screen_user_default(struct drm_scanout_buffer *sb)
+static int drm_panic_helper_draw_screen_user_default(struct drm_scanout_buffer *sb)
{
- return draw_panic_screen_user(sb, 0x00ffffff, 0x00000000);
+ return drm_panic_helper_draw_screen_user(sb, 0x00ffffff, 0x00000000);
}
-static int draw_panic_screen_kmsg_default(struct drm_scanout_buffer *sb)
+static int drm_panic_helper_draw_screen_kmsg_default(struct drm_scanout_buffer *sb)
{
- return draw_panic_screen_kmsg(sb, 0x00ffffff, 0x00000000);
+ return drm_panic_helper_draw_screen_kmsg(sb, 0x00ffffff, 0x00000000);
}
#if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
-static int draw_panic_screen_qr_code_default(struct drm_scanout_buffer *sb)
+static int drm_panic_helper_draw_screen_qr_code_default(struct drm_scanout_buffer *sb)
{
- return draw_panic_screen_qr_code(sb, 0x00ffffff, 0x00000000, 40);
+ return drm_panic_helper_draw_screen_qr_code(sb, 0x00ffffff, 0x00000000, 40);
}
#endif
@@ -81,7 +81,7 @@ static int drm_test_panic_init(struct kunit *test)
test->priv = priv;
- drm_panic_set_description("Kunit testing");
+ drm_panic_helper_set_description("Kunit testing");
return 0;
}
@@ -226,10 +226,10 @@ static struct kunit_case drm_panic_screen_user_test[] = {
{ }
};
-static struct kunit_suite drm_panic_suite = {
- .name = "drm_panic",
+static struct kunit_suite drm_panic_helper_suite = {
+ .name = "drm_panic_helper",
.init = drm_test_panic_init,
.test_cases = drm_panic_screen_user_test,
};
-kunit_test_suite(drm_panic_suite);
+kunit_test_suite(drm_panic_helper_suite);
diff --git a/include/drm/drm_panic.h b/include/drm/drm_panic.h
index 99572b7eeab9..3e628cbaffca 100644
--- a/include/drm/drm_panic.h
+++ b/include/drm/drm_panic.h
@@ -85,11 +85,4 @@ struct drm_scanout_buffer {
void *private;
};
-#if defined(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
-size_t drm_panic_qr_max_data_size(u8 version, size_t url_len);
-
-u8 drm_panic_qr_generate(const char *url, u8 *data, size_t data_len, size_t data_size,
- u8 *tmp, size_t tmp_size);
-#endif
-
#endif /* __DRM_PANIC_H__ */
diff --git a/include/drm/drm_panic_helper.h b/include/drm/drm_panic_helper.h
index 0b6ad8f61821..6cc9a0eba077 100644
--- a/include/drm/drm_panic_helper.h
+++ b/include/drm/drm_panic_helper.h
@@ -16,6 +16,11 @@ int drm_plane_helper_display_panic_screen(struct drm_plane *plane,
u32 fg_color, u32 bg_color,
unsigned int qr_version);
+/* drm_panic_helper_qr.rs */
+size_t drm_panic_helper_qr_max_data_size(u8 version, size_t url_len);
+u8 drm_panic_helper_qr_generate(const char *url, u8 *data, size_t data_len, size_t data_size,
+ u8 *tmp, size_t tmp_size);
+
#if IS_ENABLED(CONFIG_DRM_PANIC)
#define DRM_PANIC_PLANE_FUNCS \
.display_panic_screen = drm_plane_helper_display_panic_screen
diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
index 4b31aa7f432f..d14d076ac883 100644
--- a/rust/bindings/bindings_helper.h
+++ b/rust/bindings/bindings_helper.h
@@ -106,8 +106,8 @@
#include <../../drivers/base/base.h>
#if defined(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
-// Used by `#[export]` in `drivers/gpu/drm/drm_panic_qr.rs`.
-#include <drm/drm_panic.h>
+// Used by `#[export]` in `drivers/gpu/drm/drm_panic_helper_qr.rs`.
+#include <drm/drm_panic_helper.h>
#endif
/* `bindgen` gets confused at certain things. */
--
2.55.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v3 14/14] drm/panic: Compile KUnit tests as module
2026-09-02 12:13 [PATCH v3 00/14] drm/panic: Split into core and helpers Thomas Zimmermann
` (12 preceding siblings ...)
2026-09-02 12:13 ` [PATCH v3 13/14] drm/panic: Move panic display code into helper library Thomas Zimmermann
@ 2026-09-02 12:13 ` Thomas Zimmermann
2026-09-02 12:52 ` ✗ CI.checkpatch: warning for drm/panic: Split into core and helpers (rev3) Patchwork
` (3 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Thomas Zimmermann @ 2026-09-02 12:13 UTC (permalink / raw)
To: jfalempe, javierm, airlied, simona, maarten.lankhorst, mripard,
geert, rdunlap
Cc: dri-devel, linux-doc, amd-gfx, rust-for-linux, linux-hyperv,
intel-gfx, intel-xe, imx, linux-arm-kernel, nouveau,
linux-renesas-soc, virtualization, sashiko-reviews,
Thomas Zimmermann
Fix dependency of the panic-helper KUnit tests on CONFIG_DRM_KUNIT_TEST=y
and make them build as a module. Export the necessary interfaces from the
panic helpers iff the KUnit framework has been enabled.
Select DRM_PANIC_HELPER from DRM_KUNIT_TEST to meet the dependencies of
the panic-helper tests.
It is now possible to run the tests by modprobe-ing drm_panic_helper_test
at runtime.
v3:
- clean up after each test case (Sashiko)
v2:
- fix parameter order in decl of drm_panic_helper_draw_screen_qr()
(Sashiko)
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
drivers/gpu/drm/Kconfig.debug | 1 +
drivers/gpu/drm/drm_panic_helper.c | 26 ++++++++++---------
drivers/gpu/drm/tests/Makefile | 1 +
drivers/gpu/drm/tests/drm_panic_helper_test.c | 21 ++++++++++++---
include/drm/drm_panic_helper.h | 8 ++++++
5 files changed, 41 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/Kconfig.debug b/drivers/gpu/drm/Kconfig.debug
index 1f4c98cbf090..b909cd0a619f 100644
--- a/drivers/gpu/drm/Kconfig.debug
+++ b/drivers/gpu/drm/Kconfig.debug
@@ -69,6 +69,7 @@ config DRM_KUNIT_TEST
select DRM_EXPORT_FOR_TESTS if m
select DRM_GEM_SHMEM_HELPER
select DRM_KUNIT_TEST_HELPERS
+ select DRM_PANIC_HELPER
select DRM_SYSFB_HELPER
select PRIME_NUMBERS
default KUNIT_ALL_TESTS
diff --git a/drivers/gpu/drm/drm_panic_helper.c b/drivers/gpu/drm/drm_panic_helper.c
index f64a3ca38467..683af48de38c 100644
--- a/drivers/gpu/drm/drm_panic_helper.c
+++ b/drivers/gpu/drm/drm_panic_helper.c
@@ -8,6 +8,8 @@
#include <linux/utsname.h>
#include <linux/zlib.h>
+#include <kunit/visibility.h>
+
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_modeset_helper_vtables.h>
@@ -433,8 +435,8 @@ static void drm_panic_helper_logo_draw(struct drm_scanout_buffer *sb, struct drm
fg_color);
}
-static int drm_panic_helper_draw_screen_user(struct drm_scanout_buffer *sb,
- u32 fg_color, u32 bg_color)
+VISIBLE_IF_KUNIT int drm_panic_helper_draw_screen_user(struct drm_scanout_buffer *sb,
+ u32 fg_color, u32 bg_color)
{
const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL);
struct drm_rect r_screen, r_logo, r_msg;
@@ -466,6 +468,7 @@ static int drm_panic_helper_draw_screen_user(struct drm_scanout_buffer *sb,
return 0;
}
+EXPORT_SYMBOL_IF_KUNIT(drm_panic_helper_draw_screen_user);
/*
* Draw one line of kmsg, and handle wrapping if it won't fit in the screen width.
@@ -504,8 +507,8 @@ static int draw_line_with_wrap(struct drm_scanout_buffer *sb, const struct font_
* Draw the kmsg buffer to the screen, starting from the youngest message at the bottom,
* and going up until reaching the top of the screen.
*/
-static int drm_panic_helper_draw_screen_kmsg(struct drm_scanout_buffer *sb,
- u32 fg_color, u32 bg_color)
+VISIBLE_IF_KUNIT int drm_panic_helper_draw_screen_kmsg(struct drm_scanout_buffer *sb,
+ u32 fg_color, u32 bg_color)
{
const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL);
struct drm_rect r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height);
@@ -549,6 +552,7 @@ static int drm_panic_helper_draw_screen_kmsg(struct drm_scanout_buffer *sb,
return 0;
}
+EXPORT_SYMBOL_IF_KUNIT(drm_panic_helper_draw_screen_kmsg);
#if defined(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
/*
@@ -691,9 +695,9 @@ static int drm_panic_helper_get_qr_code(u8 **qr_image, unsigned int qr_version)
/*
* Draw the panic message at the center of the screen, with a QR Code
*/
-static int drm_panic_helper_draw_screen_qr_code(struct drm_scanout_buffer *sb,
- u32 fg_color, u32 bg_color,
- unsigned int qr_version)
+VISIBLE_IF_KUNIT int drm_panic_helper_draw_screen_qr_code(struct drm_scanout_buffer *sb,
+ u32 fg_color, u32 bg_color,
+ unsigned int qr_version)
{
const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL);
struct drm_rect r_screen, r_logo, r_msg, r_qr, r_qr_canvas;
@@ -763,6 +767,7 @@ static int drm_panic_helper_draw_screen_qr_code(struct drm_scanout_buffer *sb,
drm_panic_helper_blit(sb, &r_qr, qr_image, qr_pitch, scale, fg_color);
return 0;
}
+EXPORT_SYMBOL_IF_KUNIT(drm_panic_helper_draw_screen_qr_code);
#else
static void __init drm_panic_helper_qr_init(void) { };
static void __exit drm_panic_helper_qr_exit(void) { };
@@ -815,7 +820,7 @@ static int draw_panic_helper_dispatch(struct drm_scanout_buffer *sb,
return ret;
}
-static void drm_panic_helper_set_description(const char *description)
+VISIBLE_IF_KUNIT void drm_panic_helper_set_description(const char *description)
{
u32 len;
@@ -830,6 +835,7 @@ static void drm_panic_helper_set_description(const char *description)
desc_line->len = len;
}
}
+EXPORT_SYMBOL_IF_KUNIT(drm_panic_helper_set_description);
static void drm_panic_helper_clear_description(void)
{
@@ -910,7 +916,3 @@ void __exit drm_panic_helper_exit(void)
{
drm_panic_helper_qr_exit();
}
-
-#ifdef CONFIG_DRM_KUNIT_TEST
-#include "tests/drm_panic_helper_test.c"
-#endif
diff --git a/drivers/gpu/drm/tests/Makefile b/drivers/gpu/drm/tests/Makefile
index e7193b49cf91..42207df1d1c8 100644
--- a/drivers/gpu/drm/tests/Makefile
+++ b/drivers/gpu/drm/tests/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_DRM_KUNIT_TEST) += \
drm_managed_test.o \
drm_mm_test.o \
drm_modes_test.o \
+ drm_panic_helper_test.o \
drm_plane_helper_test.o \
drm_probe_helper_test.o \
drm_rect_test.o \
diff --git a/drivers/gpu/drm/tests/drm_panic_helper_test.c b/drivers/gpu/drm/tests/drm_panic_helper_test.c
index e6befe0f1c83..6184a6fc7eb8 100644
--- a/drivers/gpu/drm/tests/drm_panic_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_panic_helper_test.c
@@ -6,13 +6,17 @@
* KUNIT tests for DRM panic helpers
*/
-#include <drm/drm_fourcc.h>
-#include <drm/drm_panic.h>
+#include <linux/highmem.h>
+#include <linux/units.h>
+#include <linux/vmalloc.h>
#include <kunit/test.h>
-#include <linux/units.h>
-#include <linux/vmalloc.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_panic.h>
+#include <drm/drm_panic_helper.h>
+
+MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
static void drm_panic_check_color_byte(struct kunit *test, u8 b)
{
@@ -86,6 +90,11 @@ static int drm_test_panic_init(struct kunit *test)
return 0;
}
+static void drm_test_panic_exit(struct kunit *test)
+{
+ drm_panic_helper_set_description(NULL);
+}
+
/*
* Test drawing the panic screen, using a memory mapped framebuffer
* Set the whole buffer to 0xa5, and then check that all pixels have been
@@ -229,7 +238,11 @@ static struct kunit_case drm_panic_screen_user_test[] = {
static struct kunit_suite drm_panic_helper_suite = {
.name = "drm_panic_helper",
.init = drm_test_panic_init,
+ .exit = drm_test_panic_exit,
.test_cases = drm_panic_screen_user_test,
};
kunit_test_suite(drm_panic_helper_suite);
+
+MODULE_DESCRIPTION("KUnit test suite for DRM panic handling");
+MODULE_LICENSE("GPL");
diff --git a/include/drm/drm_panic_helper.h b/include/drm/drm_panic_helper.h
index 6cc9a0eba077..6b19607e0784 100644
--- a/include/drm/drm_panic_helper.h
+++ b/include/drm/drm_panic_helper.h
@@ -8,6 +8,7 @@
enum drm_panic_type;
struct drm_plane;
+struct drm_scanout_buffer;
/* drm_panic_helper.c */
int drm_plane_helper_display_panic_screen(struct drm_plane *plane,
@@ -15,6 +16,13 @@ int drm_plane_helper_display_panic_screen(struct drm_plane *plane,
enum drm_panic_type panic_type,
u32 fg_color, u32 bg_color,
unsigned int qr_version);
+#if IS_ENABLED(CONFIG_KUNIT)
+int drm_panic_helper_draw_screen_user(struct drm_scanout_buffer *sb, u32 fg_color, u32 bg_color);
+int drm_panic_helper_draw_screen_kmsg(struct drm_scanout_buffer *sb, u32 fg_color, u32 bg_color);
+int drm_panic_helper_draw_screen_qr_code(struct drm_scanout_buffer *sb,
+ u32 fg_color, u32 bg_color, unsigned int qr_version);
+void drm_panic_helper_set_description(const char *description);
+#endif
/* drm_panic_helper_qr.rs */
size_t drm_panic_helper_qr_max_data_size(u8 version, size_t url_len);
--
2.55.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* ✗ CI.checkpatch: warning for drm/panic: Split into core and helpers (rev3)
2026-09-02 12:13 [PATCH v3 00/14] drm/panic: Split into core and helpers Thomas Zimmermann
` (13 preceding siblings ...)
2026-09-02 12:13 ` [PATCH v3 14/14] drm/panic: Compile KUnit tests as module Thomas Zimmermann
@ 2026-09-02 12:52 ` Patchwork
2026-09-02 12:54 ` ✓ CI.KUnit: success " Patchwork
` (2 subsequent siblings)
17 siblings, 0 replies; 19+ messages in thread
From: Patchwork @ 2026-09-02 12:52 UTC (permalink / raw)
To: Thomas Zimmermann; +Cc: intel-xe
== Series Details ==
Series: drm/panic: Split into core and helpers (rev3)
URL : https://patchwork.freedesktop.org/series/172394/
State : warning
== Summary ==
+ KERNEL=/kernel
+ git clone https://gitlab.freedesktop.org/drm/maintainer-tools mt
Cloning into 'mt'...
warning: redirecting to https://gitlab.freedesktop.org/drm/maintainer-tools.git/
+ git -C mt rev-list -n1 origin/master
d875049d2b299159a272bd5151994970cdcd1e31
+ cd /kernel
+ git config --global --add safe.directory /kernel
+ git log -n1
commit b8aec30966b2cf44aeeefdfeae6ac1e991274382
Author: Thomas Zimmermann <tzimmermann@suse.de>
Date: Wed Sep 2 14:13:22 2026 +0200
drm/panic: Compile KUnit tests as module
Fix dependency of the panic-helper KUnit tests on CONFIG_DRM_KUNIT_TEST=y
and make them build as a module. Export the necessary interfaces from the
panic helpers iff the KUnit framework has been enabled.
Select DRM_PANIC_HELPER from DRM_KUNIT_TEST to meet the dependencies of
the panic-helper tests.
It is now possible to run the tests by modprobe-ing drm_panic_helper_test
at runtime.
v3:
- clean up after each test case (Sashiko)
v2:
- fix parameter order in decl of drm_panic_helper_draw_screen_qr()
(Sashiko)
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+ /mt/dim checkpatch 69771454478b3dc773dee91f76cef9220ea1ce93 drm-intel
b315ab118ce1 drm/panic: Do not use un-escaped URL as format string
caea2823c14d drm/panic: Test address from kmap op for NULL
918fb3da2bfe drm/panic: Return -EINVAL if font is not available
73c3f3a8ce3b drm/panic: Return errno codes if panic output fails
96b43c6b6f65 drm/panic: Pass colors to draw_panic_dispatch()
aa6c5bccef68 drm/panic: Pass global module parameters to drm_panic_dispatch()
34d6f446335d drm/panic: Return from screen_user if display is too small
33a177c6f823 drm/panic: Retry in dispatch function if panic output fails
1a2e1c9bc1c6 drm/panic: Split draw_panic_plane()
1afc5cd7f2b0 drm/panic: Restrict to primary planes
f6d1b1ec60b8 drm/panic: Display panic screen via per-plane callback
-:696: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#696:
new file mode 100644
total: 0 errors, 1 warnings, 0 checks, 608 lines checked
37b91766f1f3 drm/panic: Internalize panic locking in DRM core and helpers
-:102: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#102:
new file mode 100644
total: 0 errors, 1 warnings, 0 checks, 199 lines checked
9cb3f8f968ae drm/panic: Move panic display code into helper library
-:1130: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#1130:
new file mode 100644
total: 0 errors, 1 warnings, 0 checks, 2096 lines checked
b8aec30966b2 drm/panic: Compile KUnit tests as module
^ permalink raw reply [flat|nested] 19+ messages in thread
* ✓ CI.KUnit: success for drm/panic: Split into core and helpers (rev3)
2026-09-02 12:13 [PATCH v3 00/14] drm/panic: Split into core and helpers Thomas Zimmermann
` (14 preceding siblings ...)
2026-09-02 12:52 ` ✗ CI.checkpatch: warning for drm/panic: Split into core and helpers (rev3) Patchwork
@ 2026-09-02 12:54 ` Patchwork
2026-09-02 13:37 ` ✓ Xe.CI.BAT: " Patchwork
2026-09-03 0:02 ` ✓ Xe.CI.FULL: " Patchwork
17 siblings, 0 replies; 19+ messages in thread
From: Patchwork @ 2026-09-02 12:54 UTC (permalink / raw)
To: Thomas Zimmermann; +Cc: intel-xe
== Series Details ==
Series: drm/panic: Split into core and helpers (rev3)
URL : https://patchwork.freedesktop.org/series/172394/
State : success
== Summary ==
+ trap cleanup EXIT
+ kunitconfigs=('/kernel/drivers/gpu/tests/.kunitconfig' '/kernel/drivers/gpu/drm/xe/.kunitconfig' '/kernel/drivers/gpu/drm/tests/.kunitconfig' '/kernel/drivers/gpu/drm/ttm/tests/.kunitconfig' '/kernel/drivers/dma-buf/.kunitconfig')
+ for kcfg in "${kunitconfigs[@]}"
+ [[ ! -f /kernel/drivers/gpu/tests/.kunitconfig ]]
+ /kernel/tools/testing/kunit/kunit.py run --kunitconfig /kernel/drivers/gpu/tests/.kunitconfig
[12:52:47] Configuring KUnit Kernel ...
Generating .config ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
[12:52:51] Building KUnit Kernel ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
Building with:
$ make all compile_commands.json scripts_gdb ARCH=um O=.kunit --jobs=48
[12:53:12] Starting KUnit Kernel (1/1)...
[12:53:12] ============================================================
Running tests with:
$ .kunit/linux kunit.enable=1 mem=1G console=tty kunit_shutdown=halt
[12:53:12] ============= refcount_interrupt (4 subtests) ==============
[12:53:12] [PASSED] test_single_irq_change
[12:53:12] [PASSED] test_nested_irq_change
[12:53:12] [PASSED] test_multiple_irq_change
[12:53:12] [PASSED] test_irq_save
[12:53:12] =============== [PASSED] refcount_interrupt ================
[12:53:12] ================= gpu_buddy (14 subtests) ==================
[12:53:12] [PASSED] gpu_test_buddy_alloc_limit
[12:53:12] [PASSED] gpu_test_buddy_alloc_optimistic
[12:53:12] [PASSED] gpu_test_buddy_alloc_pessimistic
[12:53:12] [PASSED] gpu_test_buddy_alloc_pathological
[12:53:12] [PASSED] gpu_test_buddy_alloc_contiguous
[12:53:12] [PASSED] gpu_test_buddy_alloc_clear
[12:53:12] [PASSED] gpu_test_buddy_alloc_range
[12:53:12] [PASSED] gpu_test_buddy_alloc_range_bias
[12:53:13] [PASSED] gpu_test_buddy_fragmentation_performance
[12:53:14] [PASSED] gpu_test_buddy_dirty_tracker_performance
[12:53:14] [PASSED] gpu_test_buddy_alloc_exceeds_max_order
[12:53:14] [PASSED] gpu_test_buddy_offset_aligned_allocation
[12:53:14] [PASSED] gpu_test_buddy_subtree_offset_alignment_stress
[12:53:14] [PASSED] gpu_test_buddy_addr_to_block
[12:53:14] ==================== [PASSED] gpu_buddy ====================
[12:53:14] ============================================================
[12:53:14] Testing complete. Ran 18 tests: passed: 18
[12:53:14] Elapsed time: 27.034s total, 4.388s configuring, 20.679s building, 1.913s running
+ for kcfg in "${kunitconfigs[@]}"
+ [[ ! -f /kernel/drivers/gpu/drm/xe/.kunitconfig ]]
+ /kernel/tools/testing/kunit/kunit.py run --kunitconfig /kernel/drivers/gpu/drm/xe/.kunitconfig
[12:53:14] Configuring KUnit Kernel ...
Regenerating .config ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
[12:53:16] Building KUnit Kernel ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
Building with:
$ make all compile_commands.json scripts_gdb ARCH=um O=.kunit --jobs=48
[12:53:50] Starting KUnit Kernel (1/1)...
[12:53:50] ============================================================
Running tests with:
$ .kunit/linux kunit.enable=1 mem=1G console=tty kunit_shutdown=halt
[12:53:50] ============= refcount_interrupt (4 subtests) ==============
[12:53:50] [PASSED] test_single_irq_change
[12:53:50] [PASSED] test_nested_irq_change
[12:53:50] [PASSED] test_multiple_irq_change
[12:53:50] [PASSED] test_irq_save
[12:53:50] =============== [PASSED] refcount_interrupt ================
[12:53:50] ================== guc_buf (11 subtests) ===================
[12:53:50] [PASSED] test_smallest
[12:53:50] [PASSED] test_largest
[12:53:50] [PASSED] test_granular
[12:53:50] [PASSED] test_unique
[12:53:50] [PASSED] test_overlap
[12:53:50] [PASSED] test_reusable
[12:53:50] [PASSED] test_too_big
[12:53:50] [PASSED] test_flush
[12:53:50] [PASSED] test_lookup
[12:53:50] [PASSED] test_data
[12:53:50] [PASSED] test_class
[12:53:50] ===================== [PASSED] guc_buf =====================
[12:53:50] =================== guc_dbm (7 subtests) ===================
[12:53:50] [PASSED] test_empty
[12:53:50] [PASSED] test_default
[12:53:50] ======================== test_size ========================
[12:53:50] [PASSED] 4
[12:53:50] [PASSED] 8
[12:53:50] [PASSED] 32
[12:53:50] [PASSED] 256
[12:53:50] ==================== [PASSED] test_size ====================
[12:53:50] ======================= test_reuse ========================
[12:53:50] [PASSED] 4
[12:53:50] [PASSED] 8
[12:53:50] [PASSED] 32
[12:53:50] [PASSED] 256
[12:53:50] =================== [PASSED] test_reuse ====================
[12:53:50] =================== test_range_overlap ====================
[12:53:50] [PASSED] 4
[12:53:50] [PASSED] 8
[12:53:50] [PASSED] 32
[12:53:50] [PASSED] 256
[12:53:50] =============== [PASSED] test_range_overlap ================
[12:53:50] =================== test_range_compact ====================
[12:53:50] [PASSED] 4
[12:53:50] [PASSED] 8
[12:53:50] [PASSED] 32
[12:53:50] [PASSED] 256
[12:53:50] =============== [PASSED] test_range_compact ================
[12:53:50] ==================== test_range_spare =====================
[12:53:50] [PASSED] 4
[12:53:50] [PASSED] 8
[12:53:50] [PASSED] 32
[12:53:50] [PASSED] 256
[12:53:50] ================ [PASSED] test_range_spare =================
[12:53:50] ===================== [PASSED] guc_dbm =====================
[12:53:50] =================== guc_idm (6 subtests) ===================
[12:53:50] [PASSED] bad_init
[12:53:50] [PASSED] no_init
[12:53:50] [PASSED] init_fini
[12:53:50] [PASSED] check_used
[12:53:50] [PASSED] check_quota
[12:53:50] [PASSED] check_all
[12:53:50] ===================== [PASSED] guc_idm =====================
[12:53:50] =============== guc_klv_helpers (9 subtests) ===============
[12:53:50] [PASSED] test_count
[12:53:50] [PASSED] test_encode_u32
[12:53:50] [PASSED] test_encode_u64
[12:53:50] [PASSED] test_encode_string
[12:53:50] [PASSED] test_encode_object_raw
[12:53:50] [PASSED] test_encode_object_klv
[12:53:50] [PASSED] test_encode_object_nested
[12:53:50] [PASSED] test_encode_object_basic
[12:53:50] [PASSED] test_print
[12:53:50] ================= [PASSED] guc_klv_helpers =================
[12:53:50] =================== xe_log (4 subtests) ====================
[12:53:50] [PASSED] demo_cper
[12:53:50] [PASSED] demo_dmesg
[12:53:50] ======================= test_dmesg ========================
[12:53:50] [PASSED] test_fatal
[12:53:50] [PASSED] test_fatal_tile
[12:53:50] [PASSED] test_fatal_gt
[12:53:50] [PASSED] test_fatal_comp
[12:53:50] [PASSED] test_fatal_comp_tile
[12:53:50] [PASSED] test_fatal_comp_gt
[12:53:50] [PASSED] test_fatal_all
[12:53:50] [PASSED] test_recoverable
[12:53:50] [PASSED] test_recoverable_tile
[12:53:50] [PASSED] test_recoverable_gt
[12:53:50] [PASSED] test_recoverable_comp
[12:53:50] [PASSED] test_recoverable_comp_tile
[12:53:50] [PASSED] test_recoverable_comp_gt
[12:53:50] [PASSED] test_recoverable_all
[12:53:50] [PASSED] test_info
[12:53:50] [PASSED] test_info_tile
[12:53:50] [PASSED] test_info_gt
[12:53:50] [PASSED] test_info_err
[12:53:50] [PASSED] test_info_comp
[12:53:50] [PASSED] test_info_comp_tile
[12:53:50] [PASSED] test_info_comp_gt
[12:53:50] [PASSED] test_info_all
[12:53:50] [PASSED] test_hw_fatal
[12:53:50] [PASSED] test_hw_recoverable
[12:53:50] [PASSED] test_hw_corrected
[12:53:50] [PASSED] test_hw_informational
[12:53:50] =================== [PASSED] test_dmesg ====================
[12:53:50] ====================== test_invalid =======================
[12:53:50] [SKIPPED] no-component no-location no-warn (requires CONFIG_DRM_XE_DEBUG)
[12:53:50] [SKIPPED] reserved location (requires CONFIG_DRM_XE_DEBUG)
[12:53:50] [SKIPPED] unknown location (requires CONFIG_DRM_XE_DEBUG)
[12:53:50] [SKIPPED] nonzero-device-id location (requires CONFIG_DRM_XE_DEBUG)
[12:53:50] [SKIPPED] invalid-tile-id location (requires CONFIG_DRM_XE_DEBUG)
[12:53:50] [SKIPPED] invalid-gt-id location (requires CONFIG_DRM_XE_DEBUG)
[12:53:50] [SKIPPED] unknown component class (requires CONFIG_DRM_XE_DEBUG)
[12:53:50] [SKIPPED] unknown system component (requires CONFIG_DRM_XE_DEBUG)
[12:53:50] [SKIPPED] unknown hardware component (requires CONFIG_DRM_XE_DEBUG)
[12:53:50] [SKIPPED] unknown component and location (requires CONFIG_DRM_XE_DEBUG)
[12:53:50] ================== [SKIPPED] test_invalid ==================
[12:53:50] ===================== [PASSED] xe_log ======================
[12:53:50] ================== no_relay (3 subtests) ===================
[12:53:50] [PASSED] xe_drops_guc2pf_if_not_ready
[12:53:50] [PASSED] xe_drops_guc2vf_if_not_ready
[12:53:50] [PASSED] xe_rejects_send_if_not_ready
[12:53:50] ==================== [PASSED] no_relay =====================
[12:53:50] ================== pf_relay (14 subtests) ==================
[12:53:50] [PASSED] pf_rejects_guc2pf_too_short
[12:53:50] [PASSED] pf_rejects_guc2pf_too_long
[12:53:50] [PASSED] pf_rejects_guc2pf_no_payload
[12:53:50] [PASSED] pf_fails_no_payload
[12:53:50] [PASSED] pf_fails_bad_origin
[12:53:50] [PASSED] pf_fails_bad_type
[12:53:50] [PASSED] pf_txn_reports_error
[12:53:50] [PASSED] pf_txn_sends_pf2guc
[12:53:50] [PASSED] pf_sends_pf2guc
[12:53:50] [SKIPPED] pf_loopback_nop (requires CONFIG_DRM_XE_DEBUG_SRIOV)
[12:53:50] [SKIPPED] pf_loopback_echo (requires CONFIG_DRM_XE_DEBUG_SRIOV)
[12:53:50] [SKIPPED] pf_loopback_fail (requires CONFIG_DRM_XE_DEBUG_SRIOV)
[12:53:50] [SKIPPED] pf_loopback_busy (requires CONFIG_DRM_XE_DEBUG_SRIOV)
[12:53:50] [SKIPPED] pf_loopback_retry (requires CONFIG_DRM_XE_DEBUG_SRIOV)
[12:53:50] ==================== [PASSED] pf_relay =====================
[12:53:50] ================== vf_relay (3 subtests) ===================
[12:53:50] [PASSED] vf_rejects_guc2vf_too_short
[12:53:50] [PASSED] vf_rejects_guc2vf_too_long
[12:53:50] [PASSED] vf_rejects_guc2vf_no_payload
[12:53:50] ==================== [PASSED] vf_relay =====================
[12:53:50] ================ pf_gt_config (9 subtests) =================
[12:53:50] [PASSED] fair_contexts_1vf
[12:53:50] [PASSED] fair_doorbells_1vf
[12:53:50] [PASSED] fair_ggtt_1vf
[12:53:50] ====================== fair_vram_1vf ======================
[12:53:50] [PASSED] 3.50 GiB
[12:53:50] [PASSED] 11.5 GiB
[12:53:50] [PASSED] 15.5 GiB
[12:53:50] [PASSED] 31.5 GiB
[12:53:50] [PASSED] 63.5 GiB
[12:53:50] [PASSED] 1.91 GiB
[12:53:50] ================== [PASSED] fair_vram_1vf ==================
[12:53:50] ================ fair_vram_1vf_admin_only =================
[12:53:50] [PASSED] 3.50 GiB
[12:53:50] [PASSED] 11.5 GiB
[12:53:50] [PASSED] 15.5 GiB
[12:53:50] [PASSED] 31.5 GiB
[12:53:50] [PASSED] 63.5 GiB
[12:53:50] [PASSED] 1.91 GiB
[12:53:50] ============ [PASSED] fair_vram_1vf_admin_only =============
[12:53:50] ====================== fair_contexts ======================
[12:53:50] [PASSED] 1 VF
[12:53:50] [PASSED] 2 VFs
[12:53:50] [PASSED] 3 VFs
[12:53:50] [PASSED] 4 VFs
[12:53:50] [PASSED] 5 VFs
[12:53:50] [PASSED] 6 VFs
[12:53:50] [PASSED] 7 VFs
[12:53:50] [PASSED] 8 VFs
[12:53:50] [PASSED] 9 VFs
[12:53:50] [PASSED] 10 VFs
[12:53:50] [PASSED] 11 VFs
[12:53:50] [PASSED] 12 VFs
[12:53:50] [PASSED] 13 VFs
[12:53:50] [PASSED] 14 VFs
[12:53:50] [PASSED] 15 VFs
[12:53:50] [PASSED] 16 VFs
[12:53:50] [PASSED] 17 VFs
[12:53:50] [PASSED] 18 VFs
[12:53:50] [PASSED] 19 VFs
[12:53:50] [PASSED] 20 VFs
[12:53:50] [PASSED] 21 VFs
[12:53:50] [PASSED] 22 VFs
[12:53:50] [PASSED] 23 VFs
[12:53:50] [PASSED] 24 VFs
[12:53:50] [PASSED] 25 VFs
[12:53:50] [PASSED] 26 VFs
[12:53:50] [PASSED] 27 VFs
[12:53:50] [PASSED] 28 VFs
[12:53:50] [PASSED] 29 VFs
[12:53:50] [PASSED] 30 VFs
[12:53:50] [PASSED] 31 VFs
[12:53:50] [PASSED] 32 VFs
[12:53:50] [PASSED] 33 VFs
[12:53:50] [PASSED] 34 VFs
[12:53:50] [PASSED] 35 VFs
[12:53:50] [PASSED] 36 VFs
[12:53:50] [PASSED] 37 VFs
[12:53:50] [PASSED] 38 VFs
[12:53:50] [PASSED] 39 VFs
[12:53:50] [PASSED] 40 VFs
[12:53:50] [PASSED] 41 VFs
[12:53:50] [PASSED] 42 VFs
[12:53:50] [PASSED] 43 VFs
[12:53:50] [PASSED] 44 VFs
[12:53:50] [PASSED] 45 VFs
[12:53:50] [PASSED] 46 VFs
[12:53:50] [PASSED] 47 VFs
[12:53:50] [PASSED] 48 VFs
[12:53:51] [PASSED] 49 VFs
[12:53:51] [PASSED] 50 VFs
[12:53:51] [PASSED] 51 VFs
[12:53:51] [PASSED] 52 VFs
[12:53:51] [PASSED] 53 VFs
[12:53:51] [PASSED] 54 VFs
[12:53:51] [PASSED] 55 VFs
[12:53:51] [PASSED] 56 VFs
[12:53:51] [PASSED] 57 VFs
[12:53:51] [PASSED] 58 VFs
[12:53:51] [PASSED] 59 VFs
[12:53:51] [PASSED] 60 VFs
[12:53:51] [PASSED] 61 VFs
[12:53:51] [PASSED] 62 VFs
[12:53:51] [PASSED] 63 VFs
[12:53:51] ================== [PASSED] fair_contexts ==================
[12:53:51] ===================== fair_doorbells ======================
[12:53:51] [PASSED] 1 VF
[12:53:51] [PASSED] 2 VFs
[12:53:51] [PASSED] 3 VFs
[12:53:51] [PASSED] 4 VFs
[12:53:51] [PASSED] 5 VFs
[12:53:51] [PASSED] 6 VFs
[12:53:51] [PASSED] 7 VFs
[12:53:51] [PASSED] 8 VFs
[12:53:51] [PASSED] 9 VFs
[12:53:51] [PASSED] 10 VFs
[12:53:51] [PASSED] 11 VFs
[12:53:51] [PASSED] 12 VFs
[12:53:51] [PASSED] 13 VFs
[12:53:51] [PASSED] 14 VFs
[12:53:51] [PASSED] 15 VFs
[12:53:51] [PASSED] 16 VFs
[12:53:51] [PASSED] 17 VFs
[12:53:51] [PASSED] 18 VFs
[12:53:51] [PASSED] 19 VFs
[12:53:51] [PASSED] 20 VFs
[12:53:51] [PASSED] 21 VFs
[12:53:51] [PASSED] 22 VFs
[12:53:51] [PASSED] 23 VFs
[12:53:51] [PASSED] 24 VFs
[12:53:51] [PASSED] 25 VFs
[12:53:51] [PASSED] 26 VFs
[12:53:51] [PASSED] 27 VFs
[12:53:51] [PASSED] 28 VFs
[12:53:51] [PASSED] 29 VFs
[12:53:51] [PASSED] 30 VFs
[12:53:51] [PASSED] 31 VFs
[12:53:51] [PASSED] 32 VFs
[12:53:51] [PASSED] 33 VFs
[12:53:51] [PASSED] 34 VFs
[12:53:51] [PASSED] 35 VFs
[12:53:51] [PASSED] 36 VFs
[12:53:51] [PASSED] 37 VFs
[12:53:51] [PASSED] 38 VFs
[12:53:51] [PASSED] 39 VFs
[12:53:51] [PASSED] 40 VFs
[12:53:51] [PASSED] 41 VFs
[12:53:51] [PASSED] 42 VFs
[12:53:51] [PASSED] 43 VFs
[12:53:51] [PASSED] 44 VFs
[12:53:51] [PASSED] 45 VFs
[12:53:51] [PASSED] 46 VFs
[12:53:51] [PASSED] 47 VFs
[12:53:51] [PASSED] 48 VFs
[12:53:51] [PASSED] 49 VFs
[12:53:51] [PASSED] 50 VFs
[12:53:51] [PASSED] 51 VFs
[12:53:51] [PASSED] 52 VFs
[12:53:51] [PASSED] 53 VFs
[12:53:51] [PASSED] 54 VFs
[12:53:51] [PASSED] 55 VFs
[12:53:51] [PASSED] 56 VFs
[12:53:51] [PASSED] 57 VFs
[12:53:51] [PASSED] 58 VFs
[12:53:51] [PASSED] 59 VFs
[12:53:51] [PASSED] 60 VFs
[12:53:51] [PASSED] 61 VFs
[12:53:51] [PASSED] 62 VFs
[12:53:51] [PASSED] 63 VFs
[12:53:51] ================= [PASSED] fair_doorbells ==================
[12:53:51] ======================== fair_ggtt ========================
[12:53:51] [PASSED] 1 VF
[12:53:51] [PASSED] 2 VFs
[12:53:51] [PASSED] 3 VFs
[12:53:51] [PASSED] 4 VFs
[12:53:51] [PASSED] 5 VFs
[12:53:51] [PASSED] 6 VFs
[12:53:51] [PASSED] 7 VFs
[12:53:51] [PASSED] 8 VFs
[12:53:51] [PASSED] 9 VFs
[12:53:51] [PASSED] 10 VFs
[12:53:51] [PASSED] 11 VFs
[12:53:51] [PASSED] 12 VFs
[12:53:51] [PASSED] 13 VFs
[12:53:51] [PASSED] 14 VFs
[12:53:51] [PASSED] 15 VFs
[12:53:51] [PASSED] 16 VFs
[12:53:51] [PASSED] 17 VFs
[12:53:51] [PASSED] 18 VFs
[12:53:51] [PASSED] 19 VFs
[12:53:51] [PASSED] 20 VFs
[12:53:51] [PASSED] 21 VFs
[12:53:51] [PASSED] 22 VFs
[12:53:51] [PASSED] 23 VFs
[12:53:51] [PASSED] 24 VFs
[12:53:51] [PASSED] 25 VFs
[12:53:51] [PASSED] 26 VFs
[12:53:51] [PASSED] 27 VFs
[12:53:51] [PASSED] 28 VFs
[12:53:51] [PASSED] 29 VFs
[12:53:51] [PASSED] 30 VFs
[12:53:51] [PASSED] 31 VFs
[12:53:51] [PASSED] 32 VFs
[12:53:51] [PASSED] 33 VFs
[12:53:51] [PASSED] 34 VFs
[12:53:51] [PASSED] 35 VFs
[12:53:51] [PASSED] 36 VFs
[12:53:51] [PASSED] 37 VFs
[12:53:51] [PASSED] 38 VFs
[12:53:51] [PASSED] 39 VFs
[12:53:51] [PASSED] 40 VFs
[12:53:51] [PASSED] 41 VFs
[12:53:51] [PASSED] 42 VFs
[12:53:51] [PASSED] 43 VFs
[12:53:51] [PASSED] 44 VFs
[12:53:51] [PASSED] 45 VFs
[12:53:51] [PASSED] 46 VFs
[12:53:51] [PASSED] 47 VFs
[12:53:51] [PASSED] 48 VFs
[12:53:51] [PASSED] 49 VFs
[12:53:51] [PASSED] 50 VFs
[12:53:51] [PASSED] 51 VFs
[12:53:51] [PASSED] 52 VFs
[12:53:51] [PASSED] 53 VFs
[12:53:51] [PASSED] 54 VFs
[12:53:51] [PASSED] 55 VFs
[12:53:51] [PASSED] 56 VFs
[12:53:51] [PASSED] 57 VFs
[12:53:51] [PASSED] 58 VFs
[12:53:51] [PASSED] 59 VFs
[12:53:51] [PASSED] 60 VFs
[12:53:51] [PASSED] 61 VFs
[12:53:51] [PASSED] 62 VFs
[12:53:51] [PASSED] 63 VFs
[12:53:51] ==================== [PASSED] fair_ggtt ====================
[12:53:51] ======================== fair_vram ========================
[12:53:51] [PASSED] 1 VF
[12:53:51] [PASSED] 2 VFs
[12:53:51] [PASSED] 3 VFs
[12:53:51] [PASSED] 4 VFs
[12:53:51] [PASSED] 5 VFs
[12:53:51] [PASSED] 6 VFs
[12:53:51] [PASSED] 7 VFs
[12:53:51] [PASSED] 8 VFs
[12:53:51] [PASSED] 9 VFs
[12:53:51] [PASSED] 10 VFs
[12:53:51] [PASSED] 11 VFs
[12:53:51] [PASSED] 12 VFs
[12:53:51] [PASSED] 13 VFs
[12:53:51] [PASSED] 14 VFs
[12:53:51] [PASSED] 15 VFs
[12:53:51] [PASSED] 16 VFs
[12:53:51] [PASSED] 17 VFs
[12:53:51] [PASSED] 18 VFs
[12:53:51] [PASSED] 19 VFs
[12:53:51] [PASSED] 20 VFs
[12:53:51] [PASSED] 21 VFs
[12:53:51] [PASSED] 22 VFs
[12:53:51] [PASSED] 23 VFs
[12:53:51] [PASSED] 24 VFs
[12:53:51] [PASSED] 25 VFs
[12:53:51] [PASSED] 26 VFs
[12:53:51] [PASSED] 27 VFs
[12:53:51] [PASSED] 28 VFs
[12:53:51] [PASSED] 29 VFs
[12:53:51] [PASSED] 30 VFs
[12:53:51] [PASSED] 31 VFs
[12:53:51] [PASSED] 32 VFs
[12:53:51] [PASSED] 33 VFs
[12:53:51] [PASSED] 34 VFs
[12:53:51] [PASSED] 35 VFs
[12:53:51] [PASSED] 36 VFs
[12:53:51] [PASSED] 37 VFs
[12:53:51] [PASSED] 38 VFs
[12:53:51] [PASSED] 39 VFs
[12:53:51] [PASSED] 40 VFs
[12:53:51] [PASSED] 41 VFs
[12:53:51] [PASSED] 42 VFs
[12:53:51] [PASSED] 43 VFs
[12:53:51] [PASSED] 44 VFs
[12:53:51] [PASSED] 45 VFs
[12:53:51] [PASSED] 46 VFs
[12:53:51] [PASSED] 47 VFs
[12:53:51] [PASSED] 48 VFs
[12:53:51] [PASSED] 49 VFs
[12:53:51] [PASSED] 50 VFs
[12:53:51] [PASSED] 51 VFs
[12:53:51] [PASSED] 52 VFs
[12:53:51] [PASSED] 53 VFs
[12:53:51] [PASSED] 54 VFs
[12:53:51] [PASSED] 55 VFs
[12:53:51] [PASSED] 56 VFs
[12:53:51] [PASSED] 57 VFs
[12:53:51] [PASSED] 58 VFs
[12:53:51] [PASSED] 59 VFs
[12:53:51] [PASSED] 60 VFs
[12:53:51] [PASSED] 61 VFs
[12:53:51] [PASSED] 62 VFs
[12:53:51] [PASSED] 63 VFs
[12:53:51] ==================== [PASSED] fair_vram ====================
[12:53:51] ================== [PASSED] pf_gt_config ===================
[12:53:51] ===================== lmtt (1 subtest) =====================
[12:53:51] ======================== test_ops =========================
[12:53:51] [PASSED] 2-level
[12:53:51] [PASSED] multi-level
[12:53:51] ==================== [PASSED] test_ops =====================
[12:53:51] ====================== [PASSED] lmtt =======================
[12:53:51] ================= sriov_packet (1 subtest) =================
[12:53:51] [PASSED] test_descriptor_init
[12:53:51] ================== [PASSED] sriov_packet ===================
[12:53:51] ================= pf_service (11 subtests) =================
[12:53:51] [PASSED] pf_negotiate_any
[12:53:51] [PASSED] pf_negotiate_base_match
[12:53:51] [PASSED] pf_negotiate_base_newer
[12:53:51] [PASSED] pf_negotiate_base_next
[12:53:51] [SKIPPED] pf_negotiate_base_older (no older minor)
[12:53:51] [PASSED] pf_negotiate_base_prev
[12:53:51] [PASSED] pf_negotiate_latest_match
[12:53:51] [PASSED] pf_negotiate_latest_newer
[12:53:51] [PASSED] pf_negotiate_latest_next
[12:53:51] [SKIPPED] pf_negotiate_latest_older (no older minor)
[12:53:51] [SKIPPED] pf_negotiate_latest_prev (no prev major)
[12:53:51] =================== [PASSED] pf_service ====================
[12:53:51] ================= xe_guc_g2g (2 subtests) ==================
[12:53:51] ============== xe_live_guc_g2g_kunit_default ==============
[12:53:51] ========= [SKIPPED] xe_live_guc_g2g_kunit_default ==========
[12:53:51] ============== xe_live_guc_g2g_kunit_allmem ===============
[12:53:51] ========== [SKIPPED] xe_live_guc_g2g_kunit_allmem ==========
[12:53:51] =================== [SKIPPED] xe_guc_g2g ===================
[12:53:51] =================== xe_mocs (2 subtests) ===================
[12:53:51] ================ xe_live_mocs_kernel_kunit ================
[12:53:51] =========== [SKIPPED] xe_live_mocs_kernel_kunit ============
[12:53:51] ================ xe_live_mocs_reset_kunit =================
[12:53:51] ============ [SKIPPED] xe_live_mocs_reset_kunit ============
[12:53:51] ==================== [SKIPPED] xe_mocs =====================
[12:53:51] ================= xe_migrate (2 subtests) ==================
[12:53:51] ================= xe_migrate_sanity_kunit =================
[12:53:51] ============ [SKIPPED] xe_migrate_sanity_kunit =============
[12:53:51] ================== xe_validate_ccs_kunit ==================
[12:53:51] ============= [SKIPPED] xe_validate_ccs_kunit ==============
[12:53:51] =================== [SKIPPED] xe_migrate ===================
[12:53:51] ================== xe_dma_buf (1 subtest) ==================
[12:53:51] ==================== xe_dma_buf_kunit =====================
[12:53:51] ================ [SKIPPED] xe_dma_buf_kunit ================
[12:53:51] =================== [SKIPPED] xe_dma_buf ===================
[12:53:51] ================= xe_bo_shrink (1 subtest) =================
[12:53:51] =================== xe_bo_shrink_kunit ====================
[12:53:51] =============== [SKIPPED] xe_bo_shrink_kunit ===============
[12:53:51] ================== [SKIPPED] xe_bo_shrink ==================
[12:53:51] ==================== xe_bo (2 subtests) ====================
[12:53:51] ================== xe_ccs_migrate_kunit ===================
[12:53:51] ============== [SKIPPED] xe_ccs_migrate_kunit ==============
[12:53:51] ==================== xe_bo_evict_kunit ====================
[12:53:51] =============== [SKIPPED] xe_bo_evict_kunit ================
[12:53:51] ===================== [SKIPPED] xe_bo ======================
[12:53:51] =================== xe_any (9 subtests) ====================
[12:53:51] [PASSED] test_to_xe
[12:53:51] [PASSED] test_to_dev
[12:53:51] [PASSED] test_to_pdev
[12:53:51] [PASSED] test_to_drm
[12:53:51] [PASSED] test_if_pdev
[12:53:51] [PASSED] test_if_xe
[12:53:51] [PASSED] test_if_tile
[12:53:51] [PASSED] test_if_gt
[12:53:51] [PASSED] test_to_id
[12:53:51] ===================== [PASSED] xe_any ======================
[12:53:51] ==================== args (13 subtests) ====================
[12:53:51] [PASSED] count_args_test
[12:53:51] [PASSED] call_args_example
[12:53:51] [PASSED] call_args_test
[12:53:51] [PASSED] drop_first_arg_example
[12:53:51] [PASSED] drop_first_arg_test
[12:53:51] [PASSED] first_arg_example
[12:53:51] [PASSED] first_arg_test
[12:53:51] [PASSED] last_arg_example
[12:53:51] [PASSED] last_arg_test
[12:53:51] [PASSED] pick_arg_example
[12:53:51] [PASSED] if_args_example
[12:53:51] [PASSED] if_args_test
[12:53:51] [PASSED] sep_comma_example
[12:53:51] ====================== [PASSED] args =======================
[12:53:51] =================== xe_pci (3 subtests) ====================
[12:53:51] ==================== check_graphics_ip ====================
[12:53:51] [PASSED] 12.00 Xe_LP
[12:53:51] [PASSED] 12.10 Xe_LP+
[12:53:51] [PASSED] 12.55 Xe_HPG
[12:53:51] [PASSED] 12.60 Xe_HPC
[12:53:51] [PASSED] 12.70 Xe_LPG
[12:53:51] [PASSED] 12.71 Xe_LPG
[12:53:51] [PASSED] 12.74 Xe_LPG+
[12:53:51] [PASSED] 20.01 Xe2_HPG
[12:53:51] [PASSED] 20.02 Xe2_HPG
[12:53:51] [PASSED] 20.04 Xe2_LPG
[12:53:51] [PASSED] 30.00 Xe3_LPG
[12:53:51] [PASSED] 30.01 Xe3_LPG
[12:53:51] [PASSED] 30.03 Xe3_LPG
[12:53:51] [PASSED] 30.04 Xe3_LPG
[12:53:51] [PASSED] 30.05 Xe3_LPG
[12:53:51] [PASSED] 35.10 Xe3p_LPG
[12:53:51] [PASSED] 35.11 Xe3p_XPC
[12:53:51] ================ [PASSED] check_graphics_ip ================
[12:53:51] ===================== check_media_ip ======================
[12:53:51] [PASSED] 12.00 Xe_M
[12:53:51] [PASSED] 12.55 Xe_HPM
[12:53:51] [PASSED] 13.00 Xe_LPM+
[12:53:51] [PASSED] 13.01 Xe2_HPM
[12:53:51] [PASSED] 20.00 Xe2_LPM
[12:53:51] [PASSED] 30.00 Xe3_LPM
[12:53:51] [PASSED] 30.02 Xe3_LPM
[12:53:51] [PASSED] 35.00 Xe3p_LPM
[12:53:51] [PASSED] 35.03 Xe3p_HPM
[12:53:51] ================= [PASSED] check_media_ip ==================
[12:53:51] =================== check_platform_desc ===================
[12:53:51] [PASSED] 0x9A60 (TIGERLAKE)
[12:53:51] [PASSED] 0x9A68 (TIGERLAKE)
[12:53:51] [PASSED] 0x9A70 (TIGERLAKE)
[12:53:51] [PASSED] 0x9A40 (TIGERLAKE)
[12:53:51] [PASSED] 0x9A49 (TIGERLAKE)
[12:53:51] [PASSED] 0x9A59 (TIGERLAKE)
[12:53:51] [PASSED] 0x9A78 (TIGERLAKE)
[12:53:51] [PASSED] 0x9AC0 (TIGERLAKE)
[12:53:51] [PASSED] 0x9AC9 (TIGERLAKE)
[12:53:51] [PASSED] 0x9AD9 (TIGERLAKE)
[12:53:51] [PASSED] 0x9AF8 (TIGERLAKE)
[12:53:51] [PASSED] 0x4C80 (ROCKETLAKE)
[12:53:51] [PASSED] 0x4C8A (ROCKETLAKE)
[12:53:51] [PASSED] 0x4C8B (ROCKETLAKE)
[12:53:51] [PASSED] 0x4C8C (ROCKETLAKE)
[12:53:51] [PASSED] 0x4C90 (ROCKETLAKE)
[12:53:51] [PASSED] 0x4C9A (ROCKETLAKE)
[12:53:51] [PASSED] 0x4680 (ALDERLAKE_S)
[12:53:51] [PASSED] 0x4682 (ALDERLAKE_S)
[12:53:51] [PASSED] 0x4688 (ALDERLAKE_S)
[12:53:51] [PASSED] 0x468A (ALDERLAKE_S)
[12:53:51] [PASSED] 0x468B (ALDERLAKE_S)
[12:53:51] [PASSED] 0x4690 (ALDERLAKE_S)
[12:53:51] [PASSED] 0x4692 (ALDERLAKE_S)
[12:53:51] [PASSED] 0x4693 (ALDERLAKE_S)
[12:53:51] [PASSED] 0x46A0 (ALDERLAKE_P)
[12:53:51] [PASSED] 0x46A1 (ALDERLAKE_P)
[12:53:51] [PASSED] 0x46A2 (ALDERLAKE_P)
[12:53:51] [PASSED] 0x46A3 (ALDERLAKE_P)
[12:53:51] [PASSED] 0x46A6 (ALDERLAKE_P)
[12:53:51] [PASSED] 0x46A8 (ALDERLAKE_P)
[12:53:51] [PASSED] 0x46AA (ALDERLAKE_P)
[12:53:51] [PASSED] 0x462A (ALDERLAKE_P)
[12:53:51] [PASSED] 0x4626 (ALDERLAKE_P)
[12:53:51] [PASSED] 0x4628 (ALDERLAKE_P)
[12:53:51] [PASSED] 0x46B0 (ALDERLAKE_P)
[12:53:51] [PASSED] 0x46B1 (ALDERLAKE_P)
[12:53:51] [PASSED] 0x46B2 (ALDERLAKE_P)
[12:53:51] [PASSED] 0x46B3 (ALDERLAKE_P)
[12:53:51] [PASSED] 0x46C0 (ALDERLAKE_P)
[12:53:51] [PASSED] 0x46C1 (ALDERLAKE_P)
[12:53:51] [PASSED] 0x46C2 (ALDERLAKE_P)
[12:53:51] [PASSED] 0x46C3 (ALDERLAKE_P)
[12:53:51] [PASSED] 0x46D0 (ALDERLAKE_N)
[12:53:51] [PASSED] 0x46D1 (ALDERLAKE_N)
[12:53:51] [PASSED] 0x46D2 (ALDERLAKE_N)
[12:53:51] [PASSED] 0x46D3 (ALDERLAKE_N)
[12:53:51] [PASSED] 0x46D4 (ALDERLAKE_N)
[12:53:51] [PASSED] 0xA721 (ALDERLAKE_P)
[12:53:51] [PASSED] 0xA7A1 (ALDERLAKE_P)
[12:53:51] [PASSED] 0xA7A9 (ALDERLAKE_P)
[12:53:51] [PASSED] 0xA7AC (ALDERLAKE_P)
[12:53:51] [PASSED] 0xA7AD (ALDERLAKE_P)
[12:53:51] [PASSED] 0xA720 (ALDERLAKE_P)
[12:53:51] [PASSED] 0xA7A0 (ALDERLAKE_P)
[12:53:51] [PASSED] 0xA7A8 (ALDERLAKE_P)
[12:53:51] [PASSED] 0xA7AA (ALDERLAKE_P)
[12:53:51] [PASSED] 0xA7AB (ALDERLAKE_P)
[12:53:51] [PASSED] 0xA780 (ALDERLAKE_S)
[12:53:51] [PASSED] 0xA781 (ALDERLAKE_S)
[12:53:51] [PASSED] 0xA782 (ALDERLAKE_S)
[12:53:51] [PASSED] 0xA783 (ALDERLAKE_S)
[12:53:51] [PASSED] 0xA788 (ALDERLAKE_S)
[12:53:51] [PASSED] 0xA789 (ALDERLAKE_S)
[12:53:51] [PASSED] 0xA78A (ALDERLAKE_S)
[12:53:51] [PASSED] 0xA78B (ALDERLAKE_S)
[12:53:51] [PASSED] 0x4905 (DG1)
[12:53:51] [PASSED] 0x4906 (DG1)
[12:53:51] [PASSED] 0x4907 (DG1)
[12:53:51] [PASSED] 0x4908 (DG1)
[12:53:51] [PASSED] 0x4909 (DG1)
[12:53:51] [PASSED] 0x56C0 (DG2)
[12:53:51] [PASSED] 0x56C2 (DG2)
[12:53:51] [PASSED] 0x56C1 (DG2)
[12:53:51] [PASSED] 0x7D51 (METEORLAKE)
[12:53:51] [PASSED] 0x7DD1 (METEORLAKE)
[12:53:51] [PASSED] 0x7D41 (METEORLAKE)
[12:53:51] [PASSED] 0x7D67 (METEORLAKE)
[12:53:51] [PASSED] 0xB640 (METEORLAKE)
[12:53:51] [PASSED] 0x56A0 (DG2)
[12:53:51] [PASSED] 0x56A1 (DG2)
[12:53:51] [PASSED] 0x56A2 (DG2)
[12:53:51] [PASSED] 0x56BE (DG2)
[12:53:51] [PASSED] 0x56BF (DG2)
[12:53:51] [PASSED] 0x5690 (DG2)
[12:53:51] [PASSED] 0x5691 (DG2)
[12:53:51] [PASSED] 0x5692 (DG2)
[12:53:51] [PASSED] 0x56A5 (DG2)
[12:53:51] [PASSED] 0x56A6 (DG2)
[12:53:51] [PASSED] 0x56B0 (DG2)
[12:53:51] [PASSED] 0x56B1 (DG2)
[12:53:51] [PASSED] 0x56BA (DG2)
[12:53:51] [PASSED] 0x56BB (DG2)
[12:53:51] [PASSED] 0x56BC (DG2)
[12:53:51] [PASSED] 0x56BD (DG2)
[12:53:51] [PASSED] 0x5693 (DG2)
[12:53:51] [PASSED] 0x5694 (DG2)
[12:53:51] [PASSED] 0x5695 (DG2)
[12:53:51] [PASSED] 0x56A3 (DG2)
[12:53:51] [PASSED] 0x56A4 (DG2)
[12:53:51] [PASSED] 0x56B2 (DG2)
[12:53:51] [PASSED] 0x56B3 (DG2)
[12:53:51] [PASSED] 0x5696 (DG2)
[12:53:51] [PASSED] 0x5697 (DG2)
[12:53:51] [PASSED] 0xB69 (PVC)
[12:53:51] [PASSED] 0xB6E (PVC)
[12:53:51] [PASSED] 0xBD4 (PVC)
[12:53:51] [PASSED] 0xBD5 (PVC)
[12:53:51] [PASSED] 0xBD6 (PVC)
[12:53:51] [PASSED] 0xBD7 (PVC)
[12:53:51] [PASSED] 0xBD8 (PVC)
[12:53:51] [PASSED] 0xBD9 (PVC)
[12:53:51] [PASSED] 0xBDA (PVC)
[12:53:51] [PASSED] 0xBDB (PVC)
[12:53:51] [PASSED] 0xBE0 (PVC)
[12:53:51] [PASSED] 0xBE1 (PVC)
[12:53:51] [PASSED] 0xBE5 (PVC)
[12:53:51] [PASSED] 0x7D40 (METEORLAKE)
[12:53:51] [PASSED] 0x7D45 (METEORLAKE)
[12:53:51] [PASSED] 0x7D55 (METEORLAKE)
[12:53:51] [PASSED] 0x7D60 (METEORLAKE)
[12:53:51] [PASSED] 0x7DD5 (METEORLAKE)
[12:53:51] [PASSED] 0x6420 (LUNARLAKE)
[12:53:51] [PASSED] 0x64A0 (LUNARLAKE)
[12:53:51] [PASSED] 0x64B0 (LUNARLAKE)
[12:53:51] [PASSED] 0xE202 (BATTLEMAGE)
[12:53:51] [PASSED] 0xE209 (BATTLEMAGE)
[12:53:51] [PASSED] 0xE20B (BATTLEMAGE)
[12:53:51] [PASSED] 0xE20C (BATTLEMAGE)
[12:53:51] [PASSED] 0xE20D (BATTLEMAGE)
[12:53:51] [PASSED] 0xE210 (BATTLEMAGE)
[12:53:51] [PASSED] 0xE211 (BATTLEMAGE)
[12:53:51] [PASSED] 0xE212 (BATTLEMAGE)
[12:53:51] [PASSED] 0xE216 (BATTLEMAGE)
[12:53:51] [PASSED] 0xE220 (BATTLEMAGE)
[12:53:51] [PASSED] 0xE221 (BATTLEMAGE)
[12:53:51] [PASSED] 0xE222 (BATTLEMAGE)
[12:53:51] [PASSED] 0xE223 (BATTLEMAGE)
[12:53:51] [PASSED] 0xB080 (PANTHERLAKE)
[12:53:51] [PASSED] 0xB081 (PANTHERLAKE)
[12:53:51] [PASSED] 0xB082 (PANTHERLAKE)
[12:53:51] [PASSED] 0xB083 (PANTHERLAKE)
[12:53:51] [PASSED] 0xB084 (PANTHERLAKE)
[12:53:51] [PASSED] 0xB085 (PANTHERLAKE)
[12:53:51] [PASSED] 0xB086 (PANTHERLAKE)
[12:53:51] [PASSED] 0xB087 (PANTHERLAKE)
[12:53:51] [PASSED] 0xB08F (PANTHERLAKE)
[12:53:51] [PASSED] 0xB090 (PANTHERLAKE)
[12:53:51] [PASSED] 0xB0A0 (PANTHERLAKE)
[12:53:51] [PASSED] 0xB0B0 (PANTHERLAKE)
[12:53:51] [PASSED] 0xFD80 (PANTHERLAKE)
[12:53:51] [PASSED] 0xFD81 (PANTHERLAKE)
[12:53:51] [PASSED] 0xD740 (NOVALAKE_S)
[12:53:51] [PASSED] 0xD741 (NOVALAKE_S)
[12:53:51] [PASSED] 0xD742 (NOVALAKE_S)
[12:53:51] [PASSED] 0xD743 (NOVALAKE_S)
[12:53:51] [PASSED] 0xD745 (NOVALAKE_S)
[12:53:51] [PASSED] 0xD74A (NOVALAKE_S)
[12:53:51] [PASSED] 0xD74B (NOVALAKE_S)
[12:53:51] [PASSED] 0x674C (CRESCENTISLAND)
[12:53:51] [PASSED] 0x674D (CRESCENTISLAND)
[12:53:51] [PASSED] 0x674E (CRESCENTISLAND)
[12:53:51] [PASSED] 0x674F (CRESCENTISLAND)
[12:53:51] [PASSED] 0x6750 (CRESCENTISLAND)
[12:53:51] [PASSED] 0xD750 (NOVALAKE_P)
[12:53:51] [PASSED] 0xD751 (NOVALAKE_P)
[12:53:51] [PASSED] 0xD752 (NOVALAKE_P)
[12:53:51] [PASSED] 0xD753 (NOVALAKE_P)
[12:53:51] [PASSED] 0xD754 (NOVALAKE_P)
[12:53:51] [PASSED] 0xD755 (NOVALAKE_P)
[12:53:51] [PASSED] 0xD756 (NOVALAKE_P)
[12:53:51] [PASSED] 0xD757 (NOVALAKE_P)
[12:53:51] [PASSED] 0xD75F (NOVALAKE_P)
[12:53:51] =============== [PASSED] check_platform_desc ===============
[12:53:51] ===================== [PASSED] xe_pci ======================
[12:53:51] ============= xe_rtp_tables_test (5 subtests) ==============
[12:53:51] ================== xe_rtp_table_gt_test ===================
[12:53:51] [PASSED] gt_was/14011060649
[12:53:51] [PASSED] gt_was/14011059788
[12:53:51] [PASSED] gt_was/14015795083
[12:53:51] [PASSED] gt_was/16021867713
[12:53:51] [PASSED] gt_was/14019449301
[12:53:51] [PASSED] gt_was/16028005424
[12:53:51] [PASSED] gt_was/14026578760
[12:53:51] [PASSED] gt_was/1409420604
[12:53:51] [PASSED] gt_was/1408615072
[12:53:51] [PASSED] gt_was/22010523718
[12:53:51] [PASSED] gt_was/14011006942
[12:53:51] [PASSED] gt_was/14014830051
[12:53:51] [PASSED] gt_was/18018781329
[12:53:51] [PASSED] gt_was/1509235366
[12:53:51] [PASSED] gt_was/18018781329
[12:53:51] [PASSED] gt_was/16016694945
[12:53:51] [PASSED] gt_was/14018575942
[12:53:51] [PASSED] gt_was/22016670082
[12:53:51] [PASSED] gt_was/22016670082
[12:53:51] [PASSED] gt_was/14017421178
[12:53:51] [PASSED] gt_was/16025250150
[12:53:51] [PASSED] gt_was/14021871409
[12:53:51] [PASSED] gt_was/16021865536
[12:53:51] [PASSED] gt_was/14021486841
[12:53:51] [PASSED] gt_was/14025160223
[12:53:51] [PASSED] gt_was/14026144927, 16029437861, 14026127056
[12:53:51] [PASSED] gt_was/14025635424
[12:53:51] [PASSED] gt_was/16028005424
[12:53:51] ============== [PASSED] xe_rtp_table_gt_test ===============
[12:53:51] ================== xe_rtp_table_gt_test ===================
[12:53:51] [PASSED] gt_tunings/Tuning: Blend Fill Caching Optimization Disable
[12:53:51] [PASSED] gt_tunings/Tuning: 32B Access Enable
[12:53:51] [PASSED] gt_tunings/Tuning: L3 cache
[12:53:51] [PASSED] gt_tunings/Tuning: L3 cache - media
[12:53:51] [PASSED] gt_tunings/Tuning: Compression Overfetch
[12:53:51] [PASSED] gt_tunings/Tuning: Compression Overfetch - media
[12:53:51] [PASSED] gt_tunings/Tuning: Enable compressible partial write overfetch in L3
[12:53:51] [PASSED] gt_tunings/Tuning: Enable compressible partial write overfetch in L3 - media
[12:53:51] [PASSED] gt_tunings/Tuning: L2 Overfetch Compressible Only
[12:53:51] [PASSED] gt_tunings/Tuning: L2 Overfetch Compressible Only - media
[12:53:51] [PASSED] gt_tunings/Tuning: Stateless compression control
[12:53:51] [PASSED] gt_tunings/Tuning: Stateless compression control - media
[12:53:51] [PASSED] gt_tunings/Tuning: L3 RW flush all Cache
[12:53:51] [PASSED] gt_tunings/Tuning: L3 RW flush all cache - media
[12:53:51] [PASSED] gt_tunings/Tuning: Set STLB Bank Hash Mode to 4KB
[12:53:51] ============== [PASSED] xe_rtp_table_gt_test ===============
[12:53:51] ================== xe_rtp_table_oob_test ==================
[12:53:51] [PASSED] oob_was/1607983814
[12:53:51] [PASSED] oob_was/16010904313
[12:53:51] [PASSED] oob_was/18022495364
[12:53:51] [PASSED] oob_was/22012773006
[12:53:51] [PASSED] oob_was/14014475959
[12:53:51] [PASSED] oob_was/22011391025
[12:53:51] [PASSED] oob_was/22012727170
[12:53:51] [PASSED] oob_was/22012727685
[12:53:51] [PASSED] oob_was/22016596838
[12:53:51] [PASSED] oob_was/18020744125
[12:53:51] [PASSED] oob_was/1409600907
[12:53:51] [PASSED] oob_was/22014953428
[12:53:51] [PASSED] oob_was/16017236439
[12:53:51] [PASSED] oob_was/14019821291
[12:53:51] [PASSED] oob_was/14015076503
[12:53:51] [PASSED] oob_was/14018913170
[12:53:51] [PASSED] oob_was/14018094691
[12:53:51] [PASSED] oob_was/18024947630
[12:53:51] [PASSED] oob_was/16022287689
[12:53:51] [PASSED] oob_was/13011645652
[12:53:51] [PASSED] oob_was/14022293748
[12:53:51] [PASSED] oob_was/22019794406
[12:53:51] [PASSED] oob_was/22019338487
[12:53:51] [PASSED] oob_was/16023588340
[12:53:51] [PASSED] oob_was/14019789679
[12:53:51] [PASSED] oob_was/14022866841
[12:53:51] [PASSED] oob_was/16021333562
[12:53:51] [PASSED] oob_was/14016712196
[12:53:51] [PASSED] oob_was/14015568240
[12:53:51] [PASSED] oob_was/18013179988
[12:53:51] [PASSED] oob_was/1508761755
[12:53:51] [PASSED] oob_was/16023105232
[12:53:51] [PASSED] oob_was/16026508708
[12:53:51] [PASSED] oob_was/14020001231
[12:53:51] [PASSED] oob_was/16023683509
[12:53:51] [PASSED] oob_was/14025515070
[12:53:51] [PASSED] oob_was/15015404425_disable
[12:53:51] [PASSED] oob_was/16026007364
[12:53:51] [PASSED] oob_was/14020316580
[12:53:51] [PASSED] oob_was/14025883347
[12:53:51] [PASSED] oob_was/16029380221
[12:53:51] [PASSED] oob_was/22022079272
[12:53:51] [PASSED] oob_was/16029897822
[12:53:51] [PASSED] oob_was/14027054324
[12:53:51] ============== [PASSED] xe_rtp_table_oob_test ==============
[12:53:51] ================ xe_rtp_table_dev_oob_test ================
[12:53:51] [PASSED] device_oob_was/22010954014
[12:53:51] [PASSED] device_oob_was/15015404425
[12:53:51] [PASSED] device_oob_was/22019338487_display
[12:53:51] [PASSED] device_oob_was/14022085890
[12:53:51] [PASSED] device_oob_was/14026539277
[12:53:51] [PASSED] device_oob_was/14026633728
[12:53:51] [PASSED] device_oob_was/14026746987
[12:53:51] [PASSED] device_oob_was/14026779378
[12:53:51] ============ [PASSED] xe_rtp_table_dev_oob_test ============
[12:53:51] ========== xe_rtp_table_missing_upper_bound_test ==========
[12:53:51] [PASSED] register_whitelist/WaAllowPMDepthAndInvocationCountAccessFromUMD, 1408556865
[12:53:51] [PASSED] register_whitelist/1508744258, 14012131227, 1808121037
[12:53:51] [PASSED] register_whitelist/1806527549
[12:53:51] [PASSED] register_whitelist/allow_read_ctx_timestamp
[12:53:51] [PASSED] register_whitelist/allow_read_queue_timestamp
[12:53:51] [PASSED] register_whitelist/16014440446
[12:53:51] [PASSED] register_whitelist/16017236439
[12:53:51] [PASSED] register_whitelist/16020183090
[12:53:51] [PASSED] register_whitelist/14024997852
[12:53:51] [PASSED] register_whitelist/14024997852
[12:53:51] ====== [PASSED] xe_rtp_table_missing_upper_bound_test ======
[12:53:51] =============== [PASSED] xe_rtp_tables_test ================
[12:53:51] =================== xe_rtp (3 subtests) ====================
[12:53:51] =================== xe_rtp_rules_tests ====================
[12:53:51] [PASSED] no
[12:53:51] [PASSED] yes
[12:53:51] [PASSED] no-and-no
[12:53:51] [PASSED] no-and-yes
[12:53:51] [PASSED] yes-and-no
[12:53:51] [PASSED] yes-and-yes
[12:53:51] [PASSED] no-or-no
[12:53:51] [PASSED] no-or-yes
[12:53:51] [PASSED] yes-or-no
[12:53:51] [PASSED] yes-or-yes
[12:53:51] [PASSED] no-yes-or-yes-no
[12:53:51] [PASSED] no-yes-or-yes-yes
[12:53:51] [PASSED] yes-yes-or-no-yes
[12:53:51] [PASSED] yes-yes-or-yes-yes
[12:53:51] [PASSED] no-no-or-yes-or-no
[12:53:51] [PASSED] or
[12:53:51] [PASSED] or-yes
[12:53:51] [PASSED] or-no
[12:53:51] [PASSED] yes-or
[12:53:51] [PASSED] no-or
[12:53:51] [PASSED] no-or-or-yes
[12:53:51] [PASSED] yes-or-or-no
[12:53:51] [PASSED] no-or-or-no
[12:53:51] [PASSED] missing-context-engine-class
[12:53:51] [PASSED] missing-context-engine-class-or-yes
[12:53:51] [PASSED] missing-context-engine-class-or-or-yes
[12:53:51] =============== [PASSED] xe_rtp_rules_tests ================
[12:53:51] =============== xe_rtp_process_to_sr_tests ================
[12:53:51] [PASSED] coalesce-same-reg
[12:53:51] [PASSED] coalesce-same-reg-literal-and-func
[12:53:51] [PASSED] no-match-no-add
[12:53:51] [PASSED] two-regs-two-entries
[12:53:51] [PASSED] clr-one-set-other
[12:53:51] [PASSED] set-field
[12:53:51] [PASSED] conflict-duplicate
[12:53:51] [PASSED] conflict-not-disjoint
[12:53:51] [PASSED] conflict-not-disjoint-literal-and-func
[12:53:51] [PASSED] conflict-reg-type
[12:53:51] [PASSED] bad-mcr-reg-forced-to-regular
[12:53:51] [PASSED] bad-regular-reg-forced-to-mcr
[12:53:51] =========== [PASSED] xe_rtp_process_to_sr_tests ============
[12:53:51] ================== xe_rtp_process_tests ===================
[12:53:51] [PASSED] active1
[12:53:51] [PASSED] active2
[12:53:51] [PASSED] active-inactive
[12:53:51] [PASSED] inactive-active
[12:53:51] [PASSED] inactive-active-inactive
[12:53:51] [PASSED] inactive-inactive-inactive
[12:53:51] ============== [PASSED] xe_rtp_process_tests ===============
[12:53:51] ===================== [PASSED] xe_rtp ======================
[12:53:51] ==================== xe_wa (1 subtest) =====================
[12:53:51] ======================== xe_wa_gt =========================
[12:53:51] [PASSED] TIGERLAKE B0
[12:53:51] [PASSED] DG1 A0
[12:53:51] [PASSED] DG1 B0
[12:53:51] [PASSED] ALDERLAKE_S A0
[12:53:51] [PASSED] ALDERLAKE_S B0
[12:53:51] [PASSED] ALDERLAKE_S C0
[12:53:51] [PASSED] ALDERLAKE_S D0
[12:53:51] [PASSED] ALDERLAKE_P A0
[12:53:51] [PASSED] ALDERLAKE_P B0
[12:53:51] [PASSED] ALDERLAKE_P C0
[12:53:51] [PASSED] ALDERLAKE_S RPLS D0
[12:53:51] [PASSED] ALDERLAKE_P RPLU E0
[12:53:51] [PASSED] DG2 G10 C0
[12:53:51] [PASSED] DG2 G11 B1
[12:53:51] [PASSED] DG2 G12 A1
[12:53:51] [PASSED] METEORLAKE 12.70(Xe_LPG) A0 13.00(Xe_LPM+) A0
[12:53:51] [PASSED] METEORLAKE 12.71(Xe_LPG) A0 13.00(Xe_LPM+) A0
[12:53:51] [PASSED] METEORLAKE 12.74(Xe_LPG+) A0 13.00(Xe_LPM+) A0
[12:53:51] [PASSED] LUNARLAKE 20.04(Xe2_LPG) A0 20.00(Xe2_LPM) A0
[12:53:51] [PASSED] LUNARLAKE 20.04(Xe2_LPG) B0 20.00(Xe2_LPM) A0
[12:53:51] [PASSED] BATTLEMAGE 20.01(Xe2_HPG) A0 13.01(Xe2_HPM) A1
[12:53:51] [PASSED] PANTHERLAKE 30.00(Xe3_LPG) A0 30.00(Xe3_LPM) A0
[12:53:51] ==================== [PASSED] xe_wa_gt =====================
[12:53:51] ====================== [PASSED] xe_wa ======================
[12:53:51] ============================================================
[12:53:51] Testing complete. Ran 793 tests: passed: 765, skipped: 28
[12:53:51] Elapsed time: 36.876s total, 1.830s configuring, 34.330s building, 0.698s running
+ for kcfg in "${kunitconfigs[@]}"
+ [[ ! -f /kernel/drivers/gpu/drm/tests/.kunitconfig ]]
+ /kernel/tools/testing/kunit/kunit.py run --kunitconfig /kernel/drivers/gpu/drm/tests/.kunitconfig
[12:53:51] Configuring KUnit Kernel ...
Regenerating .config ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
[12:53:53] Building KUnit Kernel ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
Building with:
$ make all compile_commands.json scripts_gdb ARCH=um O=.kunit --jobs=48
[12:54:18] Starting KUnit Kernel (1/1)...
[12:54:18] ============================================================
Running tests with:
$ .kunit/linux kunit.enable=1 mem=1G console=tty kunit_shutdown=halt
[12:54:18] ============= refcount_interrupt (4 subtests) ==============
[12:54:18] [PASSED] test_single_irq_change
[12:54:18] [PASSED] test_nested_irq_change
[12:54:18] [PASSED] test_multiple_irq_change
[12:54:18] [PASSED] test_irq_save
[12:54:18] =============== [PASSED] refcount_interrupt ================
[12:54:18] ============ drm_test_pick_cmdline (2 subtests) ============
[12:54:18] [PASSED] drm_test_pick_cmdline_res_1920_1080_60
[12:54:18] =============== drm_test_pick_cmdline_named ===============
[12:54:18] [PASSED] NTSC
[12:54:18] [PASSED] NTSC-J
[12:54:18] [PASSED] PAL
[12:54:18] [PASSED] PAL-M
[12:54:18] =========== [PASSED] drm_test_pick_cmdline_named ===========
[12:54:18] ============== [PASSED] drm_test_pick_cmdline ==============
[12:54:18] == drm_test_atomic_get_connector_for_encoder (1 subtest) ===
[12:54:18] [PASSED] drm_test_drm_atomic_get_connector_for_encoder
[12:54:18] ==== [PASSED] drm_test_atomic_get_connector_for_encoder ====
[12:54:18] =========== drm_validate_clone_mode (2 subtests) ===========
[12:54:18] ============== drm_test_check_in_clone_mode ===============
[12:54:18] [PASSED] in_clone_mode
[12:54:18] [PASSED] not_in_clone_mode
[12:54:18] ========== [PASSED] drm_test_check_in_clone_mode ===========
[12:54:18] =============== drm_test_check_valid_clones ===============
[12:54:18] [PASSED] not_in_clone_mode
[12:54:18] [PASSED] valid_clone
[12:54:18] [PASSED] invalid_clone
[12:54:18] =========== [PASSED] drm_test_check_valid_clones ===========
[12:54:18] ============= [PASSED] drm_validate_clone_mode =============
[12:54:18] ============= drm_validate_modeset (1 subtest) =============
[12:54:18] [PASSED] drm_test_check_connector_changed_modeset
[12:54:18] ============== [PASSED] drm_validate_modeset ===============
[12:54:18] ====== drm_test_bridge_get_current_state (1 subtest) =======
[12:54:18] [PASSED] drm_test_drm_bridge_get_current_state_atomic
[12:54:18] ======== [PASSED] drm_test_bridge_get_current_state ========
[12:54:18] ====== drm_test_bridge_helper_reset_crtc (3 subtests) ======
[12:54:18] [PASSED] drm_test_drm_bridge_helper_reset_crtc_atomic
[12:54:18] [PASSED] drm_test_drm_bridge_helper_reset_crtc_atomic_disabled
[12:54:18] [PASSED] drm_test_drm_bridge_helper_hdmi_output_bus_fmts
[12:54:18] ======== [PASSED] drm_test_bridge_helper_reset_crtc ========
[12:54:18] ============== drm_bridge_alloc (2 subtests) ===============
[12:54:18] [PASSED] drm_test_drm_bridge_alloc_basic
[12:54:18] [PASSED] drm_test_drm_bridge_alloc_get_put
[12:54:18] ================ [PASSED] drm_bridge_alloc =================
[12:54:18] ============= drm_bridge_bus_fmt (5 subtests) ==============
[12:54:18] [PASSED] drm_test_bridge_rgb_yuv_rgb
[12:54:18] [PASSED] drm_test_bridge_must_convert_to_yuv444
[12:54:18] [PASSED] drm_test_bridge_hdmi_auto_rgb
[12:54:18] [PASSED] drm_test_bridge_auto_first
[12:54:18] [PASSED] drm_test_bridge_rgb_yuv_no_path
[12:54:18] =============== [PASSED] drm_bridge_bus_fmt ================
[12:54:18] ============= drm_cmdline_parser (40 subtests) =============
[12:54:18] [PASSED] drm_test_cmdline_force_d_only
[12:54:18] [PASSED] drm_test_cmdline_force_D_only_dvi
[12:54:18] [PASSED] drm_test_cmdline_force_D_only_hdmi
[12:54:18] [PASSED] drm_test_cmdline_force_D_only_not_digital
[12:54:18] [PASSED] drm_test_cmdline_force_e_only
[12:54:18] [PASSED] drm_test_cmdline_res
[12:54:18] [PASSED] drm_test_cmdline_res_vesa
[12:54:18] [PASSED] drm_test_cmdline_res_vesa_rblank
[12:54:18] [PASSED] drm_test_cmdline_res_rblank
[12:54:18] [PASSED] drm_test_cmdline_res_bpp
[12:54:18] [PASSED] drm_test_cmdline_res_refresh
[12:54:18] [PASSED] drm_test_cmdline_res_bpp_refresh
[12:54:18] [PASSED] drm_test_cmdline_res_bpp_refresh_interlaced
[12:54:18] [PASSED] drm_test_cmdline_res_bpp_refresh_margins
[12:54:18] [PASSED] drm_test_cmdline_res_bpp_refresh_force_off
[12:54:18] [PASSED] drm_test_cmdline_res_bpp_refresh_force_on
[12:54:18] [PASSED] drm_test_cmdline_res_bpp_refresh_force_on_analog
[12:54:18] [PASSED] drm_test_cmdline_res_bpp_refresh_force_on_digital
[12:54:18] [PASSED] drm_test_cmdline_res_bpp_refresh_interlaced_margins_force_on
[12:54:18] [PASSED] drm_test_cmdline_res_margins_force_on
[12:54:18] [PASSED] drm_test_cmdline_res_vesa_margins
[12:54:18] [PASSED] drm_test_cmdline_name
[12:54:18] [PASSED] drm_test_cmdline_name_bpp
[12:54:18] [PASSED] drm_test_cmdline_name_option
[12:54:18] [PASSED] drm_test_cmdline_name_bpp_option
[12:54:18] [PASSED] drm_test_cmdline_rotate_0
[12:54:18] [PASSED] drm_test_cmdline_rotate_90
[12:54:18] [PASSED] drm_test_cmdline_rotate_180
[12:54:18] [PASSED] drm_test_cmdline_rotate_270
[12:54:18] [PASSED] drm_test_cmdline_hmirror
[12:54:18] [PASSED] drm_test_cmdline_vmirror
[12:54:18] [PASSED] drm_test_cmdline_margin_options
[12:54:18] [PASSED] drm_test_cmdline_multiple_options
[12:54:18] [PASSED] drm_test_cmdline_bpp_extra_and_option
[12:54:18] [PASSED] drm_test_cmdline_extra_and_option
[12:54:18] [PASSED] drm_test_cmdline_freestanding_options
[12:54:18] [PASSED] drm_test_cmdline_freestanding_force_e_and_options
[12:54:18] [PASSED] drm_test_cmdline_panel_orientation
[12:54:18] ================ drm_test_cmdline_invalid =================
[12:54:18] [PASSED] margin_only
[12:54:18] [PASSED] interlace_only
[12:54:18] [PASSED] res_missing_x
[12:54:18] [PASSED] res_missing_y
[12:54:18] [PASSED] res_bad_y
[12:54:18] [PASSED] res_missing_y_bpp
[12:54:18] [PASSED] res_bad_bpp
[12:54:18] [PASSED] res_bad_refresh
[12:54:18] [PASSED] res_bpp_refresh_force_on_off
[12:54:18] [PASSED] res_invalid_mode
[12:54:18] [PASSED] res_bpp_wrong_place_mode
[12:54:18] [PASSED] name_bpp_refresh
[12:54:18] [PASSED] name_refresh
[12:54:18] [PASSED] name_refresh_wrong_mode
[12:54:18] [PASSED] name_refresh_invalid_mode
[12:54:18] [PASSED] rotate_multiple
[12:54:18] [PASSED] rotate_invalid_val
[12:54:18] [PASSED] rotate_truncated
[12:54:18] [PASSED] invalid_option
[12:54:18] [PASSED] invalid_tv_option
[12:54:18] [PASSED] truncated_tv_option
[12:54:18] ============ [PASSED] drm_test_cmdline_invalid =============
[12:54:18] =============== drm_test_cmdline_tv_options ===============
[12:54:18] [PASSED] NTSC
[12:54:18] [PASSED] NTSC_443
[12:54:18] [PASSED] NTSC_J
[12:54:18] [PASSED] PAL
[12:54:18] [PASSED] PAL_M
[12:54:18] [PASSED] PAL_N
[12:54:18] [PASSED] SECAM
[12:54:18] [PASSED] MONO_525
[12:54:18] [PASSED] MONO_625
[12:54:18] =========== [PASSED] drm_test_cmdline_tv_options ===========
[12:54:18] =============== [PASSED] drm_cmdline_parser ================
[12:54:18] ========== drmm_connector_hdmi_init (20 subtests) ==========
[12:54:18] [PASSED] drm_test_connector_hdmi_init_valid
[12:54:18] [PASSED] drm_test_connector_hdmi_init_bpc_8
[12:54:18] [PASSED] drm_test_connector_hdmi_init_bpc_10
[12:54:18] [PASSED] drm_test_connector_hdmi_init_bpc_12
[12:54:18] [PASSED] drm_test_connector_hdmi_init_bpc_invalid
[12:54:18] [PASSED] drm_test_connector_hdmi_init_bpc_null
[12:54:18] [PASSED] drm_test_connector_hdmi_init_formats_empty
[12:54:18] [PASSED] drm_test_connector_hdmi_init_formats_no_rgb
[12:54:18] === drm_test_connector_hdmi_init_formats_yuv420_allowed ===
[12:54:18] [PASSED] supported_formats=0x9 yuv420_allowed=1
[12:54:18] [PASSED] supported_formats=0x9 yuv420_allowed=0
[12:54:18] [PASSED] supported_formats=0x5 yuv420_allowed=1
[12:54:18] [PASSED] supported_formats=0x5 yuv420_allowed=0
[12:54:18] === [PASSED] drm_test_connector_hdmi_init_formats_yuv420_allowed ===
[12:54:18] [PASSED] drm_test_connector_hdmi_init_null_ddc
[12:54:18] [PASSED] drm_test_connector_hdmi_init_null_product
[12:54:18] [PASSED] drm_test_connector_hdmi_init_null_vendor
[12:54:18] [PASSED] drm_test_connector_hdmi_init_product_length_exact
[12:54:18] [PASSED] drm_test_connector_hdmi_init_product_length_too_long
[12:54:18] [PASSED] drm_test_connector_hdmi_init_product_valid
[12:54:18] [PASSED] drm_test_connector_hdmi_init_vendor_length_exact
[12:54:18] [PASSED] drm_test_connector_hdmi_init_vendor_length_too_long
[12:54:18] [PASSED] drm_test_connector_hdmi_init_vendor_valid
[12:54:18] ========= drm_test_connector_hdmi_init_type_valid =========
[12:54:18] [PASSED] HDMI-A
[12:54:18] [PASSED] HDMI-B
[12:54:18] ===== [PASSED] drm_test_connector_hdmi_init_type_valid =====
[12:54:18] ======== drm_test_connector_hdmi_init_type_invalid ========
[12:54:18] [PASSED] Unknown
[12:54:18] [PASSED] VGA
[12:54:18] [PASSED] DVI-I
[12:54:18] [PASSED] DVI-D
[12:54:18] [PASSED] DVI-A
[12:54:18] [PASSED] Composite
[12:54:18] [PASSED] SVIDEO
[12:54:18] [PASSED] LVDS
[12:54:18] [PASSED] Component
[12:54:18] [PASSED] DIN
[12:54:18] [PASSED] DP
[12:54:18] [PASSED] TV
[12:54:18] [PASSED] eDP
[12:54:18] [PASSED] Virtual
[12:54:18] [PASSED] DSI
[12:54:18] [PASSED] DPI
[12:54:18] [PASSED] Writeback
[12:54:18] [PASSED] SPI
[12:54:18] [PASSED] USB
[12:54:18] ==== [PASSED] drm_test_connector_hdmi_init_type_invalid ====
[12:54:18] ============ [PASSED] drmm_connector_hdmi_init =============
[12:54:18] ============= drmm_connector_init (3 subtests) =============
[12:54:18] [PASSED] drm_test_drmm_connector_init
[12:54:18] [PASSED] drm_test_drmm_connector_init_null_ddc
[12:54:18] ========= drm_test_drmm_connector_init_type_valid =========
[12:54:18] [PASSED] Unknown
[12:54:18] [PASSED] VGA
[12:54:18] [PASSED] DVI-I
[12:54:18] [PASSED] DVI-D
[12:54:18] [PASSED] DVI-A
[12:54:18] [PASSED] Composite
[12:54:18] [PASSED] SVIDEO
[12:54:18] [PASSED] LVDS
[12:54:18] [PASSED] Component
[12:54:18] [PASSED] DIN
[12:54:18] [PASSED] DP
[12:54:18] [PASSED] HDMI-A
[12:54:18] [PASSED] HDMI-B
[12:54:18] [PASSED] TV
[12:54:18] [PASSED] eDP
[12:54:18] [PASSED] Virtual
[12:54:18] [PASSED] DSI
[12:54:18] [PASSED] DPI
[12:54:18] [PASSED] Writeback
[12:54:18] [PASSED] SPI
[12:54:18] [PASSED] USB
[12:54:18] ===== [PASSED] drm_test_drmm_connector_init_type_valid =====
[12:54:18] =============== [PASSED] drmm_connector_init ===============
[12:54:18] ========= drm_connector_dynamic_init (6 subtests) ==========
[12:54:18] [PASSED] drm_test_drm_connector_dynamic_init
[12:54:18] [PASSED] drm_test_drm_connector_dynamic_init_null_ddc
[12:54:18] [PASSED] drm_test_drm_connector_dynamic_init_not_added
[12:54:18] [PASSED] drm_test_drm_connector_dynamic_init_properties
[12:54:18] ===== drm_test_drm_connector_dynamic_init_type_valid ======
[12:54:18] [PASSED] Unknown
[12:54:18] [PASSED] VGA
[12:54:18] [PASSED] DVI-I
[12:54:18] [PASSED] DVI-D
[12:54:18] [PASSED] DVI-A
[12:54:18] [PASSED] Composite
[12:54:18] [PASSED] SVIDEO
[12:54:18] [PASSED] LVDS
[12:54:18] [PASSED] Component
[12:54:18] [PASSED] DIN
[12:54:18] [PASSED] DP
[12:54:18] [PASSED] HDMI-A
[12:54:18] [PASSED] HDMI-B
[12:54:18] [PASSED] TV
[12:54:18] [PASSED] eDP
[12:54:18] [PASSED] Virtual
[12:54:18] [PASSED] DSI
[12:54:18] [PASSED] DPI
[12:54:18] [PASSED] Writeback
[12:54:18] [PASSED] SPI
[12:54:18] [PASSED] USB
[12:54:18] = [PASSED] drm_test_drm_connector_dynamic_init_type_valid ==
[12:54:18] ======== drm_test_drm_connector_dynamic_init_name =========
[12:54:18] [PASSED] Unknown
[12:54:18] [PASSED] VGA
[12:54:18] [PASSED] DVI-I
[12:54:18] [PASSED] DVI-D
[12:54:18] [PASSED] DVI-A
[12:54:18] [PASSED] Composite
[12:54:18] [PASSED] SVIDEO
[12:54:18] [PASSED] LVDS
[12:54:18] [PASSED] Component
[12:54:18] [PASSED] DIN
[12:54:18] [PASSED] DP
[12:54:18] [PASSED] HDMI-A
[12:54:18] [PASSED] HDMI-B
[12:54:18] [PASSED] TV
[12:54:18] [PASSED] eDP
[12:54:18] [PASSED] Virtual
[12:54:18] [PASSED] DSI
[12:54:18] [PASSED] DPI
[12:54:18] [PASSED] Writeback
[12:54:18] [PASSED] SPI
[12:54:18] [PASSED] USB
[12:54:18] ==== [PASSED] drm_test_drm_connector_dynamic_init_name =====
[12:54:18] =========== [PASSED] drm_connector_dynamic_init ============
[12:54:18] ==== drm_connector_dynamic_register_early (4 subtests) =====
[12:54:18] [PASSED] drm_test_drm_connector_dynamic_register_early_on_list
[12:54:18] [PASSED] drm_test_drm_connector_dynamic_register_early_defer
[12:54:18] [PASSED] drm_test_drm_connector_dynamic_register_early_no_init
[12:54:18] [PASSED] drm_test_drm_connector_dynamic_register_early_no_mode_object
[12:54:18] ====== [PASSED] drm_connector_dynamic_register_early =======
[12:54:18] ======= drm_connector_dynamic_register (7 subtests) ========
[12:54:18] [PASSED] drm_test_drm_connector_dynamic_register_on_list
[12:54:18] [PASSED] drm_test_drm_connector_dynamic_register_no_defer
[12:54:18] [PASSED] drm_test_drm_connector_dynamic_register_no_init
[12:54:18] [PASSED] drm_test_drm_connector_dynamic_register_mode_object
[12:54:18] [PASSED] drm_test_drm_connector_dynamic_register_sysfs
[12:54:18] [PASSED] drm_test_drm_connector_dynamic_register_sysfs_name
[12:54:18] [PASSED] drm_test_drm_connector_dynamic_register_debugfs
[12:54:18] ========= [PASSED] drm_connector_dynamic_register ==========
[12:54:18] = drm_connector_attach_broadcast_rgb_property (2 subtests) =
[12:54:18] [PASSED] drm_test_drm_connector_attach_broadcast_rgb_property
[12:54:18] [PASSED] drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector
[12:54:18] === [PASSED] drm_connector_attach_broadcast_rgb_property ===
[12:54:18] ========== drm_get_tv_mode_from_name (2 subtests) ==========
[12:54:18] ========== drm_test_get_tv_mode_from_name_valid ===========
[12:54:18] [PASSED] NTSC
[12:54:18] [PASSED] NTSC-443
[12:54:18] [PASSED] NTSC-J
[12:54:18] [PASSED] PAL
[12:54:18] [PASSED] PAL-M
[12:54:18] [PASSED] PAL-N
[12:54:18] [PASSED] SECAM
[12:54:18] [PASSED] Mono
[12:54:18] ====== [PASSED] drm_test_get_tv_mode_from_name_valid =======
[12:54:18] [PASSED] drm_test_get_tv_mode_from_name_truncated
[12:54:18] ============ [PASSED] drm_get_tv_mode_from_name ============
[12:54:18] = drm_test_connector_hdmi_compute_mode_clock (12 subtests) =
[12:54:18] [PASSED] drm_test_drm_hdmi_compute_mode_clock_rgb
[12:54:18] [PASSED] drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc
[12:54:18] [PASSED] drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1
[12:54:18] [PASSED] drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc
[12:54:18] [PASSED] drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1
[12:54:18] [PASSED] drm_test_drm_hdmi_compute_mode_clock_rgb_double
[12:54:18] = drm_test_connector_hdmi_compute_mode_clock_yuv420_valid =
[12:54:18] [PASSED] VIC 96
[12:54:18] [PASSED] VIC 97
[12:54:18] [PASSED] VIC 101
[12:54:18] [PASSED] VIC 102
[12:54:18] [PASSED] VIC 106
[12:54:18] [PASSED] VIC 107
[12:54:18] === [PASSED] drm_test_connector_hdmi_compute_mode_clock_yuv420_valid ===
[12:54:18] [PASSED] drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc
[12:54:18] [PASSED] drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc
[12:54:18] [PASSED] drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc
[12:54:18] [PASSED] drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc
[12:54:18] [PASSED] drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc
[12:54:18] === [PASSED] drm_test_connector_hdmi_compute_mode_clock ====
[12:54:18] == drm_hdmi_connector_get_broadcast_rgb_name (2 subtests) ==
[12:54:18] === drm_test_drm_hdmi_connector_get_broadcast_rgb_name ====
[12:54:18] [PASSED] Automatic
[12:54:18] [PASSED] Full
[12:54:18] [PASSED] Limited 16:235
[12:54:18] === [PASSED] drm_test_drm_hdmi_connector_get_broadcast_rgb_name ===
[12:54:18] [PASSED] drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid
[12:54:18] ==== [PASSED] drm_hdmi_connector_get_broadcast_rgb_name ====
[12:54:18] == drm_hdmi_connector_get_output_format_name (2 subtests) ==
[12:54:18] === drm_test_drm_hdmi_connector_get_output_format_name ====
[12:54:18] [PASSED] RGB
[12:54:18] [PASSED] YUV 4:2:0
[12:54:18] [PASSED] YUV 4:2:2
[12:54:18] [PASSED] YUV 4:4:4
[12:54:18] === [PASSED] drm_test_drm_hdmi_connector_get_output_format_name ===
[12:54:18] [PASSED] drm_test_drm_hdmi_connector_get_output_format_name_invalid
[12:54:18] ==== [PASSED] drm_hdmi_connector_get_output_format_name ====
[12:54:18] ============= drm_damage_helper (21 subtests) ==============
[12:54:18] [PASSED] drm_test_damage_iter_no_damage
[12:54:18] [PASSED] drm_test_damage_iter_no_damage_fractional_src
[12:54:18] [PASSED] drm_test_damage_iter_no_damage_src_moved
[12:54:18] [PASSED] drm_test_damage_iter_no_damage_fractional_src_moved
[12:54:18] [PASSED] drm_test_damage_iter_no_damage_not_visible
[12:54:18] [PASSED] drm_test_damage_iter_no_damage_no_crtc
[12:54:18] [PASSED] drm_test_damage_iter_no_damage_no_fb
[12:54:18] [PASSED] drm_test_damage_iter_simple_damage
[12:54:18] [PASSED] drm_test_damage_iter_single_damage
[12:54:18] [PASSED] drm_test_damage_iter_single_damage_intersect_src
[12:54:18] [PASSED] drm_test_damage_iter_single_damage_outside_src
[12:54:18] [PASSED] drm_test_damage_iter_single_damage_fractional_src
[12:54:18] [PASSED] drm_test_damage_iter_single_damage_intersect_fractional_src
[12:54:18] [PASSED] drm_test_damage_iter_single_damage_outside_fractional_src
[12:54:18] [PASSED] drm_test_damage_iter_single_damage_src_moved
[12:54:18] [PASSED] drm_test_damage_iter_single_damage_fractional_src_moved
[12:54:18] [PASSED] drm_test_damage_iter_damage
[12:54:18] [PASSED] drm_test_damage_iter_damage_one_intersect
[12:54:18] [PASSED] drm_test_damage_iter_damage_one_outside
[12:54:18] [PASSED] drm_test_damage_iter_damage_src_moved
[12:54:18] [PASSED] drm_test_damage_iter_damage_not_visible
[12:54:18] ================ [PASSED] drm_damage_helper ================
[12:54:18] ============== drm_dp_mst_helper (3 subtests) ==============
[12:54:18] ============== drm_test_dp_mst_calc_pbn_mode ==============
[12:54:18] [PASSED] Clock 154000 BPP 30 DSC disabled
[12:54:18] [PASSED] Clock 234000 BPP 30 DSC disabled
[12:54:18] [PASSED] Clock 297000 BPP 24 DSC disabled
[12:54:18] [PASSED] Clock 332880 BPP 24 DSC enabled
[12:54:18] [PASSED] Clock 324540 BPP 24 DSC enabled
[12:54:18] ========== [PASSED] drm_test_dp_mst_calc_pbn_mode ==========
[12:54:18] ============== drm_test_dp_mst_calc_pbn_div ===============
[12:54:18] [PASSED] Link rate 2000000 lane count 4
[12:54:18] [PASSED] Link rate 2000000 lane count 2
[12:54:18] [PASSED] Link rate 2000000 lane count 1
[12:54:18] [PASSED] Link rate 1350000 lane count 4
[12:54:18] [PASSED] Link rate 1350000 lane count 2
[12:54:18] [PASSED] Link rate 1350000 lane count 1
[12:54:18] [PASSED] Link rate 1000000 lane count 4
[12:54:18] [PASSED] Link rate 1000000 lane count 2
[12:54:18] [PASSED] Link rate 1000000 lane count 1
[12:54:18] [PASSED] Link rate 810000 lane count 4
[12:54:18] [PASSED] Link rate 810000 lane count 2
[12:54:18] [PASSED] Link rate 810000 lane count 1
[12:54:18] [PASSED] Link rate 540000 lane count 4
[12:54:18] [PASSED] Link rate 540000 lane count 2
[12:54:18] [PASSED] Link rate 540000 lane count 1
[12:54:18] [PASSED] Link rate 270000 lane count 4
[12:54:18] [PASSED] Link rate 270000 lane count 2
[12:54:18] [PASSED] Link rate 270000 lane count 1
[12:54:18] [PASSED] Link rate 162000 lane count 4
[12:54:18] [PASSED] Link rate 162000 lane count 2
[12:54:18] [PASSED] Link rate 162000 lane count 1
[12:54:18] ========== [PASSED] drm_test_dp_mst_calc_pbn_div ===========
[12:54:18] ========= drm_test_dp_mst_sideband_msg_req_decode =========
[12:54:18] [PASSED] DP_ENUM_PATH_RESOURCES with port number
[12:54:18] [PASSED] DP_POWER_UP_PHY with port number
[12:54:18] [PASSED] DP_POWER_DOWN_PHY with port number
[12:54:18] [PASSED] DP_ALLOCATE_PAYLOAD with SDP stream sinks
[12:54:18] [PASSED] DP_ALLOCATE_PAYLOAD with port number
[12:54:18] [PASSED] DP_ALLOCATE_PAYLOAD with VCPI
[12:54:18] [PASSED] DP_ALLOCATE_PAYLOAD with PBN
[12:54:18] [PASSED] DP_QUERY_PAYLOAD with port number
[12:54:18] [PASSED] DP_QUERY_PAYLOAD with VCPI
[12:54:18] [PASSED] DP_REMOTE_DPCD_READ with port number
[12:54:18] [PASSED] DP_REMOTE_DPCD_READ with DPCD address
[12:54:18] [PASSED] DP_REMOTE_DPCD_READ with max number of bytes
[12:54:18] [PASSED] DP_REMOTE_DPCD_WRITE with port number
[12:54:18] [PASSED] DP_REMOTE_DPCD_WRITE with DPCD address
[12:54:18] [PASSED] DP_REMOTE_DPCD_WRITE with data array
[12:54:18] [PASSED] DP_REMOTE_I2C_READ with port number
[12:54:18] [PASSED] DP_REMOTE_I2C_READ with I2C device ID
[12:54:18] [PASSED] DP_REMOTE_I2C_READ with transactions array
[12:54:18] [PASSED] DP_REMOTE_I2C_WRITE with port number
[12:54:18] [PASSED] DP_REMOTE_I2C_WRITE with I2C device ID
[12:54:18] [PASSED] DP_REMOTE_I2C_WRITE with data array
[12:54:18] [PASSED] DP_QUERY_STREAM_ENC_STATUS with stream ID
[12:54:18] [PASSED] DP_QUERY_STREAM_ENC_STATUS with client ID
[12:54:18] [PASSED] DP_QUERY_STREAM_ENC_STATUS with stream event
[12:54:18] [PASSED] DP_QUERY_STREAM_ENC_STATUS with valid stream event
[12:54:18] [PASSED] DP_QUERY_STREAM_ENC_STATUS with stream behavior
[12:54:18] [PASSED] DP_QUERY_STREAM_ENC_STATUS with a valid stream behavior
[12:54:18] ===== [PASSED] drm_test_dp_mst_sideband_msg_req_decode =====
[12:54:18] ================ [PASSED] drm_dp_mst_helper ================
[12:54:18] ================== drm_exec (7 subtests) ===================
[12:54:18] [PASSED] sanitycheck
[12:54:18] [PASSED] test_lock
[12:54:18] [PASSED] test_lock_unlock
[12:54:18] [PASSED] test_duplicates
[12:54:18] [PASSED] test_prepare
[12:54:18] [PASSED] test_prepare_array
[12:54:18] [PASSED] test_multiple_loops
[12:54:18] ==================== [PASSED] drm_exec =====================
[12:54:18] =========== drm_format_helper_test (17 subtests) ===========
[12:54:18] ============== drm_test_fb_xrgb8888_to_gray8 ==============
[12:54:18] [PASSED] single_pixel_source_buffer
[12:54:18] [PASSED] single_pixel_clip_rectangle
[12:54:18] [PASSED] well_known_colors
[12:54:18] [PASSED] destination_pitch
[12:54:18] ========== [PASSED] drm_test_fb_xrgb8888_to_gray8 ==========
[12:54:18] ============= drm_test_fb_xrgb8888_to_rgb332 ==============
[12:54:18] [PASSED] single_pixel_source_buffer
[12:54:18] [PASSED] single_pixel_clip_rectangle
[12:54:18] [PASSED] well_known_colors
[12:54:18] [PASSED] destination_pitch
[12:54:18] ========= [PASSED] drm_test_fb_xrgb8888_to_rgb332 ==========
[12:54:18] ============= drm_test_fb_xrgb8888_to_rgb565 ==============
[12:54:18] [PASSED] single_pixel_source_buffer
[12:54:18] [PASSED] single_pixel_clip_rectangle
[12:54:18] [PASSED] well_known_colors
[12:54:18] [PASSED] destination_pitch
[12:54:18] ========= [PASSED] drm_test_fb_xrgb8888_to_rgb565 ==========
[12:54:18] ============ drm_test_fb_xrgb8888_to_xrgb1555 =============
[12:54:18] [PASSED] single_pixel_source_buffer
[12:54:18] [PASSED] single_pixel_clip_rectangle
[12:54:18] [PASSED] well_known_colors
[12:54:18] [PASSED] destination_pitch
[12:54:18] ======== [PASSED] drm_test_fb_xrgb8888_to_xrgb1555 =========
[12:54:18] ============ drm_test_fb_xrgb8888_to_argb1555 =============
[12:54:18] [PASSED] single_pixel_source_buffer
[12:54:18] [PASSED] single_pixel_clip_rectangle
[12:54:18] [PASSED] well_known_colors
[12:54:18] [PASSED] destination_pitch
[12:54:18] ======== [PASSED] drm_test_fb_xrgb8888_to_argb1555 =========
[12:54:18] ============ drm_test_fb_xrgb8888_to_rgba5551 =============
[12:54:18] [PASSED] single_pixel_source_buffer
[12:54:18] [PASSED] single_pixel_clip_rectangle
[12:54:18] [PASSED] well_known_colors
[12:54:18] [PASSED] destination_pitch
[12:54:18] ======== [PASSED] drm_test_fb_xrgb8888_to_rgba5551 =========
[12:54:18] ============= drm_test_fb_xrgb8888_to_rgb888 ==============
[12:54:18] [PASSED] single_pixel_source_buffer
[12:54:18] [PASSED] single_pixel_clip_rectangle
[12:54:18] [PASSED] well_known_colors
[12:54:18] [PASSED] destination_pitch
[12:54:18] ========= [PASSED] drm_test_fb_xrgb8888_to_rgb888 ==========
[12:54:18] ============= drm_test_fb_xrgb8888_to_bgr888 ==============
[12:54:18] [PASSED] single_pixel_source_buffer
[12:54:18] [PASSED] single_pixel_clip_rectangle
[12:54:18] [PASSED] well_known_colors
[12:54:18] [PASSED] destination_pitch
[12:54:18] ========= [PASSED] drm_test_fb_xrgb8888_to_bgr888 ==========
[12:54:18] ============ drm_test_fb_xrgb8888_to_argb8888 =============
[12:54:18] [PASSED] single_pixel_source_buffer
[12:54:18] [PASSED] single_pixel_clip_rectangle
[12:54:18] [PASSED] well_known_colors
[12:54:18] [PASSED] destination_pitch
[12:54:18] ======== [PASSED] drm_test_fb_xrgb8888_to_argb8888 =========
[12:54:18] =========== drm_test_fb_xrgb8888_to_xrgb2101010 ===========
[12:54:18] [PASSED] single_pixel_source_buffer
[12:54:18] [PASSED] single_pixel_clip_rectangle
[12:54:18] [PASSED] well_known_colors
[12:54:18] [PASSED] destination_pitch
[12:54:18] ======= [PASSED] drm_test_fb_xrgb8888_to_xrgb2101010 =======
[12:54:18] =========== drm_test_fb_xrgb8888_to_argb2101010 ===========
[12:54:18] [PASSED] single_pixel_source_buffer
[12:54:18] [PASSED] single_pixel_clip_rectangle
[12:54:18] [PASSED] well_known_colors
[12:54:18] [PASSED] destination_pitch
[12:54:18] ======= [PASSED] drm_test_fb_xrgb8888_to_argb2101010 =======
[12:54:18] ============== drm_test_fb_xrgb8888_to_mono ===============
[12:54:18] [PASSED] single_pixel_source_buffer
[12:54:18] [PASSED] single_pixel_clip_rectangle
[12:54:18] [PASSED] well_known_colors
[12:54:18] [PASSED] destination_pitch
[12:54:18] ========== [PASSED] drm_test_fb_xrgb8888_to_mono ===========
[12:54:18] ==================== drm_test_fb_swab =====================
[12:54:18] [PASSED] single_pixel_source_buffer
[12:54:18] [PASSED] single_pixel_clip_rectangle
[12:54:18] [PASSED] well_known_colors
[12:54:18] [PASSED] destination_pitch
[12:54:18] ================ [PASSED] drm_test_fb_swab =================
[12:54:18] ============ drm_test_fb_xrgb8888_to_xbgr8888 =============
[12:54:18] [PASSED] single_pixel_source_buffer
[12:54:18] [PASSED] single_pixel_clip_rectangle
[12:54:18] [PASSED] well_known_colors
[12:54:18] [PASSED] destination_pitch
[12:54:18] ======== [PASSED] drm_test_fb_xrgb8888_to_xbgr8888 =========
[12:54:18] ============ drm_test_fb_xrgb8888_to_abgr8888 =============
[12:54:18] [PASSED] single_pixel_source_buffer
[12:54:18] [PASSED] single_pixel_clip_rectangle
[12:54:18] [PASSED] well_known_colors
[12:54:18] [PASSED] destination_pitch
[12:54:18] ======== [PASSED] drm_test_fb_xrgb8888_to_abgr8888 =========
[12:54:18] ================= drm_test_fb_clip_offset =================
[12:54:18] [PASSED] pass through
[12:54:18] [PASSED] horizontal offset
[12:54:18] [PASSED] vertical offset
[12:54:18] [PASSED] horizontal and vertical offset
[12:54:18] [PASSED] horizontal offset (custom pitch)
[12:54:18] [PASSED] vertical offset (custom pitch)
[12:54:18] [PASSED] horizontal and vertical offset (custom pitch)
[12:54:18] ============= [PASSED] drm_test_fb_clip_offset =============
[12:54:18] =================== drm_test_fb_memcpy ====================
[12:54:18] [PASSED] single_pixel_source_buffer: XR24 little-endian (0x34325258)
[12:54:18] [PASSED] single_pixel_source_buffer: XRA8 little-endian (0x38415258)
[12:54:18] [PASSED] single_pixel_source_buffer: YU24 little-endian (0x34325559)
[12:54:18] [PASSED] single_pixel_clip_rectangle: XB24 little-endian (0x34324258)
[12:54:18] [PASSED] single_pixel_clip_rectangle: XRA8 little-endian (0x38415258)
[12:54:18] [PASSED] single_pixel_clip_rectangle: YU24 little-endian (0x34325559)
[12:54:18] [PASSED] well_known_colors: XB24 little-endian (0x34324258)
[12:54:18] [PASSED] well_known_colors: XRA8 little-endian (0x38415258)
[12:54:18] [PASSED] well_known_colors: YU24 little-endian (0x34325559)
[12:54:18] [PASSED] destination_pitch: XB24 little-endian (0x34324258)
[12:54:18] [PASSED] destination_pitch: XRA8 little-endian (0x38415258)
[12:54:18] [PASSED] destination_pitch: YU24 little-endian (0x34325559)
[12:54:18] =============== [PASSED] drm_test_fb_memcpy ================
[12:54:18] ============= [PASSED] drm_format_helper_test ==============
[12:54:18] ================= drm_format (18 subtests) =================
[12:54:18] [PASSED] drm_test_format_block_width_invalid
[12:54:18] [PASSED] drm_test_format_block_width_one_plane
[12:54:18] [PASSED] drm_test_format_block_width_two_plane
[12:54:18] [PASSED] drm_test_format_block_width_three_plane
[12:54:18] [PASSED] drm_test_format_block_width_tiled
[12:54:18] [PASSED] drm_test_format_block_height_invalid
[12:54:18] [PASSED] drm_test_format_block_height_one_plane
[12:54:18] [PASSED] drm_test_format_block_height_two_plane
[12:54:18] [PASSED] drm_test_format_block_height_three_plane
[12:54:18] [PASSED] drm_test_format_block_height_tiled
[12:54:18] [PASSED] drm_test_format_min_pitch_invalid
[12:54:18] [PASSED] drm_test_format_min_pitch_one_plane_8bpp
[12:54:18] [PASSED] drm_test_format_min_pitch_one_plane_16bpp
[12:54:18] [PASSED] drm_test_format_min_pitch_one_plane_24bpp
[12:54:18] [PASSED] drm_test_format_min_pitch_one_plane_32bpp
[12:54:18] [PASSED] drm_test_format_min_pitch_two_plane
[12:54:18] [PASSED] drm_test_format_min_pitch_three_plane_8bpp
[12:54:18] [PASSED] drm_test_format_min_pitch_tiled
[12:54:18] =================== [PASSED] drm_format ====================
[12:54:18] ============== drm_framebuffer (10 subtests) ===============
[12:54:18] ========== drm_test_framebuffer_check_src_coords ==========
[12:54:18] [PASSED] Success: source fits into fb
[12:54:18] [PASSED] Fail: overflowing fb with x-axis coordinate
[12:54:18] [PASSED] Fail: overflowing fb with y-axis coordinate
[12:54:18] [PASSED] Fail: overflowing fb with source width
[12:54:18] [PASSED] Fail: overflowing fb with source height
[12:54:18] ====== [PASSED] drm_test_framebuffer_check_src_coords ======
[12:54:18] [PASSED] drm_test_framebuffer_cleanup
[12:54:18] =============== drm_test_framebuffer_create ===============
[12:54:18] [PASSED] ABGR8888 normal sizes
[12:54:18] [PASSED] ABGR8888 max sizes
[12:54:18] [PASSED] ABGR8888 pitch greater than min required
[12:54:18] [PASSED] ABGR8888 pitch less than min required
[12:54:18] [PASSED] ABGR8888 Invalid width
[12:54:18] [PASSED] ABGR8888 Invalid buffer handle
[12:54:18] [PASSED] No pixel format
[12:54:18] [PASSED] ABGR8888 Width 0
[12:54:18] [PASSED] ABGR8888 Height 0
[12:54:18] [PASSED] ABGR8888 Out of bound height * pitch combination
[12:54:18] [PASSED] ABGR8888 Large buffer offset
[12:54:18] [PASSED] ABGR8888 Buffer offset for inexistent plane
[12:54:18] [PASSED] ABGR8888 Invalid flag
[12:54:18] [PASSED] ABGR8888 Set DRM_MODE_FB_MODIFIERS without modifiers
[12:54:18] [PASSED] ABGR8888 Valid buffer modifier
[12:54:18] [PASSED] ABGR8888 Invalid buffer modifier(DRM_FORMAT_MOD_SAMSUNG_64_32_TILE)
[12:54:18] [PASSED] ABGR8888 Extra pitches without DRM_MODE_FB_MODIFIERS
[12:54:18] [PASSED] ABGR8888 Extra pitches with DRM_MODE_FB_MODIFIERS
[12:54:18] [PASSED] NV12 Normal sizes
[12:54:18] [PASSED] NV12 Max sizes
[12:54:18] [PASSED] NV12 Invalid pitch
[12:54:18] [PASSED] NV12 Invalid modifier/missing DRM_MODE_FB_MODIFIERS flag
[12:54:18] [PASSED] NV12 different modifier per-plane
[12:54:18] [PASSED] NV12 with DRM_FORMAT_MOD_SAMSUNG_64_32_TILE
[12:54:18] [PASSED] NV12 Valid modifiers without DRM_MODE_FB_MODIFIERS
[12:54:18] [PASSED] NV12 Modifier for inexistent plane
[12:54:18] [PASSED] NV12 Handle for inexistent plane
[12:54:18] [PASSED] NV12 Handle for inexistent plane without DRM_MODE_FB_MODIFIERS
[12:54:18] [PASSED] YVU420 DRM_MODE_FB_MODIFIERS set without modifier
[12:54:18] [PASSED] YVU420 Normal sizes
[12:54:18] [PASSED] YVU420 Max sizes
[12:54:18] [PASSED] YVU420 Invalid pitch
[12:54:18] [PASSED] YVU420 Different pitches
[12:54:18] [PASSED] YVU420 Different buffer offsets/pitches
[12:54:18] [PASSED] YVU420 Modifier set just for plane 0, without DRM_MODE_FB_MODIFIERS
[12:54:18] [PASSED] YVU420 Modifier set just for planes 0, 1, without DRM_MODE_FB_MODIFIERS
[12:54:18] [PASSED] YVU420 Modifier set just for plane 0, 1, with DRM_MODE_FB_MODIFIERS
[12:54:18] [PASSED] YVU420 Valid modifier
[12:54:18] [PASSED] YVU420 Different modifiers per plane
[12:54:18] [PASSED] YVU420 Modifier for inexistent plane
[12:54:18] [PASSED] YUV420_10BIT Invalid modifier(DRM_FORMAT_MOD_LINEAR)
[12:54:18] [PASSED] X0L2 Normal sizes
[12:54:18] [PASSED] X0L2 Max sizes
[12:54:18] [PASSED] X0L2 Invalid pitch
[12:54:18] [PASSED] X0L2 Pitch greater than minimum required
[12:54:18] [PASSED] X0L2 Handle for inexistent plane
[12:54:18] [PASSED] X0L2 Offset for inexistent plane, without DRM_MODE_FB_MODIFIERS set
[12:54:18] [PASSED] X0L2 Modifier without DRM_MODE_FB_MODIFIERS set
[12:54:18] [PASSED] X0L2 Valid modifier
[12:54:18] [PASSED] X0L2 Modifier for inexistent plane
[12:54:18] =========== [PASSED] drm_test_framebuffer_create ===========
[12:54:18] [PASSED] drm_test_framebuffer_free
[12:54:18] [PASSED] drm_test_framebuffer_init
[12:54:18] [PASSED] drm_test_framebuffer_init_bad_format
[12:54:18] [PASSED] drm_test_framebuffer_init_dev_mismatch
[12:54:18] [PASSED] drm_test_framebuffer_lookup
[12:54:18] [PASSED] drm_test_framebuffer_lookup_inexistent
[12:54:18] [PASSED] drm_test_framebuffer_modifiers_not_supported
[12:54:18] ================= [PASSED] drm_framebuffer =================
[12:54:18] ================ drm_gem_shmem (8 subtests) ================
[12:54:18] [PASSED] drm_gem_shmem_test_obj_create
[12:54:18] [PASSED] drm_gem_shmem_test_obj_create_private
[12:54:18] [PASSED] drm_gem_shmem_test_pin_pages
[12:54:18] [PASSED] drm_gem_shmem_test_vmap
[12:54:18] [PASSED] drm_gem_shmem_test_get_sg_table
[12:54:18] [PASSED] drm_gem_shmem_test_get_pages_sgt
[12:54:18] [PASSED] drm_gem_shmem_test_madvise
[12:54:18] [PASSED] drm_gem_shmem_test_purge
[12:54:18] ================== [PASSED] drm_gem_shmem ==================
[12:54:18] === drm_atomic_helper_connector_hdmi_check (29 subtests) ===
[12:54:18] [PASSED] drm_test_check_broadcast_rgb_auto_cea_mode
[12:54:18] [PASSED] drm_test_check_broadcast_rgb_auto_cea_mode_vic_1
[12:54:18] [PASSED] drm_test_check_broadcast_rgb_full_cea_mode
[12:54:18] [PASSED] drm_test_check_broadcast_rgb_full_cea_mode_vic_1
[12:54:18] [PASSED] drm_test_check_broadcast_rgb_limited_cea_mode
[12:54:18] [PASSED] drm_test_check_broadcast_rgb_limited_cea_mode_vic_1
[12:54:18] ====== drm_test_check_broadcast_rgb_cea_mode_yuv420 =======
[12:54:18] [PASSED] Automatic
[12:54:18] [PASSED] Full
[12:54:18] [PASSED] Limited 16:235
[12:54:18] == [PASSED] drm_test_check_broadcast_rgb_cea_mode_yuv420 ===
[12:54:18] [PASSED] drm_test_check_broadcast_rgb_crtc_mode_changed
[12:54:18] [PASSED] drm_test_check_broadcast_rgb_crtc_mode_not_changed
[12:54:18] [PASSED] drm_test_check_disable_connector
[12:54:18] [PASSED] drm_test_check_hdmi_funcs_reject_rate
[12:54:18] [PASSED] drm_test_check_max_tmds_rate_bpc_fallback_rgb
[12:54:18] [PASSED] drm_test_check_max_tmds_rate_bpc_fallback_yuv420
[12:54:18] [PASSED] drm_test_check_max_tmds_rate_bpc_fallback_ignore_yuv422
[12:54:18] [PASSED] drm_test_check_max_tmds_rate_bpc_fallback_ignore_yuv420
[12:54:18] [PASSED] drm_test_check_driver_unsupported_fallback_yuv420
[12:54:18] [PASSED] drm_test_check_output_bpc_crtc_mode_changed
[12:54:18] [PASSED] drm_test_check_output_bpc_crtc_mode_not_changed
[12:54:18] [PASSED] drm_test_check_output_bpc_dvi
[12:54:18] [PASSED] drm_test_check_output_bpc_format_vic_1
[12:54:18] [PASSED] drm_test_check_output_bpc_format_display_8bpc_only
[12:54:18] [PASSED] drm_test_check_output_bpc_format_display_rgb_only
[12:54:18] [PASSED] drm_test_check_output_bpc_format_driver_8bpc_only
[12:54:18] [PASSED] drm_test_check_output_bpc_format_driver_rgb_only
[12:54:18] [PASSED] drm_test_check_tmds_char_rate_rgb_8bpc
[12:54:18] [PASSED] drm_test_check_tmds_char_rate_rgb_10bpc
[12:54:18] [PASSED] drm_test_check_tmds_char_rate_rgb_12bpc
[12:54:18] ============ drm_test_check_hdmi_color_format =============
[12:54:18] [PASSED] AUTO -> RGB
[12:54:18] [PASSED] YCBCR422 -> YUV422
[12:54:18] [PASSED] YCBCR420 -> YUV420
[12:54:18] [PASSED] YCBCR444 -> YUV444
[12:54:18] [PASSED] RGB -> RGB
[12:54:18] ======== [PASSED] drm_test_check_hdmi_color_format =========
[12:54:18] ======== drm_test_check_hdmi_color_format_420_only ========
[12:54:18] [PASSED] RGB should fail
[12:54:18] [PASSED] YUV444 should fail
[12:54:18] [PASSED] YUV422 should fail
[12:54:18] [PASSED] YUV420 should work
[12:54:18] ==== [PASSED] drm_test_check_hdmi_color_format_420_only ====
[12:54:18] ===== [PASSED] drm_atomic_helper_connector_hdmi_check ======
[12:54:18] === drm_atomic_helper_connector_hdmi_reset (6 subtests) ====
[12:54:18] [PASSED] drm_test_check_broadcast_rgb_value
[12:54:18] [PASSED] drm_test_check_bpc_8_value
[12:54:18] [PASSED] drm_test_check_bpc_10_value
[12:54:18] [PASSED] drm_test_check_bpc_12_value
[12:54:18] [PASSED] drm_test_check_format_value
[12:54:18] [PASSED] drm_test_check_tmds_char_value
[12:54:18] ===== [PASSED] drm_atomic_helper_connector_hdmi_reset ======
[12:54:18] = drm_atomic_helper_connector_hdmi_mode_valid (7 subtests) =
[12:54:18] [PASSED] drm_test_check_mode_valid
[12:54:18] [PASSED] drm_test_check_mode_valid_reject
[12:54:18] [PASSED] drm_test_check_mode_valid_reject_rate
[12:54:18] [PASSED] drm_test_check_mode_valid_reject_max_clock
[12:54:18] [PASSED] drm_test_check_mode_valid_yuv420_only_max_clock
[12:54:18] [PASSED] drm_test_check_mode_valid_reject_yuv420_only_connector
[12:54:18] [PASSED] drm_test_check_mode_valid_accept_yuv420_also_connector_rgb
[12:54:18] === [PASSED] drm_atomic_helper_connector_hdmi_mode_valid ===
[12:54:18] = drm_atomic_helper_connector_hdmi_infoframes (5 subtests) =
[12:54:18] [PASSED] drm_test_check_infoframes
[12:54:18] [PASSED] drm_test_check_reject_avi_infoframe
[12:54:18] [PASSED] drm_test_check_reject_hdr_infoframe_bpc_8
[12:54:18] [PASSED] drm_test_check_reject_hdr_infoframe_bpc_10
[12:54:18] [PASSED] drm_test_check_reject_audio_infoframe
[12:54:18] === [PASSED] drm_atomic_helper_connector_hdmi_infoframes ===
[12:54:18] ================= drm_managed (2 subtests) =================
[12:54:18] [PASSED] drm_test_managed_release_action
[12:54:18] [PASSED] drm_test_managed_run_action
[12:54:18] =================== [PASSED] drm_managed ===================
[12:54:18] =================== drm_mm (6 subtests) ====================
[12:54:18] [PASSED] drm_test_mm_init
[12:54:18] [PASSED] drm_test_mm_debug
[12:54:18] [PASSED] drm_test_mm_align32
[12:54:18] [PASSED] drm_test_mm_align64
[12:54:18] [PASSED] drm_test_mm_lowest
[12:54:18] [PASSED] drm_test_mm_highest
[12:54:18] ===================== [PASSED] drm_mm ======================
[12:54:18] ============= drm_modes_analog_tv (5 subtests) =============
[12:54:18] [PASSED] drm_test_modes_analog_tv_mono_576i
[12:54:18] [PASSED] drm_test_modes_analog_tv_ntsc_480i
[12:54:18] [PASSED] drm_test_modes_analog_tv_ntsc_480i_inlined
[12:54:18] [PASSED] drm_test_modes_analog_tv_pal_576i
[12:54:18] [PASSED] drm_test_modes_analog_tv_pal_576i_inlined
[12:54:18] =============== [PASSED] drm_modes_analog_tv ===============
[12:54:18] ============== drm_panic_helper (3 subtests) ===============
[12:54:18] ============= drm_test_panic_screen_user_map ==============
[12:54:18] [PASSED] Panic screen user, mode: 1024 x 768 XR24 little-endian (0x34325258)
[12:54:18] [PASSED] Panic screen user, mode: 494 x 494 XR24 little-endian (0x34325258)
[12:54:18] [PASSED] Panic screen user, mode: 1920 x 1080 XR24 little-endian (0x34325258)
[12:54:18] [PASSED] Panic screen user, mode: 1024 x 768 RG16 little-endian (0x36314752)
[12:54:18] [PASSED] Panic screen user, mode: 1024 x 768 RG24 little-endian (0x34324752)
[12:54:18] [PASSED] Panic screen kmsg, mode: 1024 x 768 XR24 little-endian (0x34325258)
[12:54:18] [PASSED] Panic screen kmsg, mode: 494 x 494 XR24 little-endian (0x34325258)
[12:54:18] [PASSED] Panic screen kmsg, mode: 1920 x 1080 XR24 little-endian (0x34325258)
[12:54:18] [PASSED] Panic screen kmsg, mode: 1024 x 768 RG16 little-endian (0x36314752)
[12:54:18] [PASSED] Panic screen kmsg, mode: 1024 x 768 RG24 little-endian (0x34324752)
[12:54:18] ========= [PASSED] drm_test_panic_screen_user_map ==========
[12:54:18] ============= drm_test_panic_screen_user_page =============
[12:54:18] [PASSED] Panic screen user, mode: 1024 x 768 XR24 little-endian (0x34325258)
[12:54:18] [PASSED] Panic screen user, mode: 494 x 494 XR24 little-endian (0x34325258)
[12:54:18] [PASSED] Panic screen user, mode: 1920 x 1080 XR24 little-endian (0x34325258)
[12:54:18] [PASSED] Panic screen user, mode: 1024 x 768 RG16 little-endian (0x36314752)
[12:54:18] [PASSED] Panic screen user, mode: 1024 x 768 RG24 little-endian (0x34324752)
[12:54:18] [PASSED] Panic screen kmsg, mode: 1024 x 768 XR24 little-endian (0x34325258)
[12:54:18] [PASSED] Panic screen kmsg, mode: 494 x 494 XR24 little-endian (0x34325258)
[12:54:18] [PASSED] Panic screen kmsg, mode: 1920 x 1080 XR24 little-endian (0x34325258)
[12:54:18] [PASSED] Panic screen kmsg, mode: 1024 x 768 RG16 little-endian (0x36314752)
[12:54:18] [PASSED] Panic screen kmsg, mode: 1024 x 768 RG24 little-endian (0x34324752)
[12:54:18] ========= [PASSED] drm_test_panic_screen_user_page =========
[12:54:18] ========== drm_test_panic_screen_user_set_pixel ===========
[12:54:18] [PASSED] Panic screen user, mode: 1024 x 768 XR24 little-endian (0x34325258)
[12:54:18] [PASSED] Panic screen user, mode: 494 x 494 XR24 little-endian (0x34325258)
[12:54:18] [PASSED] Panic screen user, mode: 1920 x 1080 XR24 little-endian (0x34325258)
[12:54:18] [PASSED] Panic screen user, mode: 1024 x 768 RG16 little-endian (0x36314752)
[12:54:18] [PASSED] Panic screen user, mode: 1024 x 768 RG24 little-endian (0x34324752)
[12:54:18] [PASSED] Panic screen kmsg, mode: 1024 x 768 XR24 little-endian (0x34325258)
[12:54:18] [PASSED] Panic screen kmsg, mode: 494 x 494 XR24 little-endian (0x34325258)
[12:54:18] [PASSED] Panic screen kmsg, mode: 1920 x 1080 XR24 little-endian (0x34325258)
[12:54:18] [PASSED] Panic screen kmsg, mode: 1024 x 768 RG16 little-endian (0x36314752)
[12:54:18] [PASSED] Panic screen kmsg, mode: 1024 x 768 RG24 little-endian (0x34324752)
[12:54:18] ====== [PASSED] drm_test_panic_screen_user_set_pixel =======
[12:54:18] ================ [PASSED] drm_panic_helper =================
[12:54:18] ============== drm_plane_helper (2 subtests) ===============
[12:54:18] =============== drm_test_check_plane_state ================
[12:54:18] [PASSED] clipping_simple
[12:54:18] [PASSED] clipping_rotate_reflect
[12:54:18] [PASSED] positioning_simple
[12:54:18] [PASSED] upscaling
[12:54:18] [PASSED] downscaling
[12:54:18] [PASSED] rounding1
[12:54:18] [PASSED] rounding2
[12:54:18] [PASSED] rounding3
[12:54:18] [PASSED] rounding4
[12:54:18] =========== [PASSED] drm_test_check_plane_state ============
[12:54:18] =========== drm_test_check_invalid_plane_state ============
[12:54:18] [PASSED] positioning_invalid
[12:54:18] [PASSED] upscaling_invalid
[12:54:18] [PASSED] downscaling_invalid
[12:54:18] ======= [PASSED] drm_test_check_invalid_plane_state ========
[12:54:18] ================ [PASSED] drm_plane_helper =================
[12:54:18] ====== drm_connector_helper_tv_get_modes (1 subtest) =======
[12:54:18] ====== drm_test_connector_helper_tv_get_modes_check =======
[12:54:18] [PASSED] None
[12:54:18] [PASSED] PAL
[12:54:18] [PASSED] NTSC
[12:54:18] [PASSED] Both, NTSC Default
[12:54:18] [PASSED] Both, PAL Default
[12:54:18] [PASSED] Both, NTSC Default, with PAL on command-line
[12:54:18] [PASSED] Both, PAL Default, with NTSC on command-line
[12:54:18] == [PASSED] drm_test_connector_helper_tv_get_modes_check ===
[12:54:18] ======== [PASSED] drm_connector_helper_tv_get_modes ========
[12:54:18] ================== drm_rect (9 subtests) ===================
[12:54:18] [PASSED] drm_test_rect_clip_scaled_div_by_zero
[12:54:18] [PASSED] drm_test_rect_clip_scaled_not_clipped
[12:54:18] [PASSED] drm_test_rect_clip_scaled_clipped
[12:54:18] [PASSED] drm_test_rect_clip_scaled_signed_vs_unsigned
[12:54:18] ================= drm_test_rect_intersect =================
[12:54:18] [PASSED] top-left x bottom-right: 2x2+1+1 x 2x2+0+0
[12:54:18] [PASSED] top-right x bottom-left: 2x2+0+0 x 2x2+1-1
[12:54:18] [PASSED] bottom-left x top-right: 2x2+1-1 x 2x2+0+0
[12:54:18] [PASSED] bottom-right x top-left: 2x2+0+0 x 2x2+1+1
[12:54:18] [PASSED] right x left: 2x1+0+0 x 3x1+1+0
[12:54:18] [PASSED] left x right: 3x1+1+0 x 2x1+0+0
[12:54:18] [PASSED] up x bottom: 1x2+0+0 x 1x3+0-1
[12:54:18] [PASSED] bottom x up: 1x3+0-1 x 1x2+0+0
[12:54:18] [PASSED] touching corner: 1x1+0+0 x 2x2+1+1
[12:54:18] [PASSED] touching side: 1x1+0+0 x 1x1+1+0
[12:54:18] [PASSED] equal rects: 2x2+0+0 x 2x2+0+0
[12:54:18] [PASSED] inside another: 2x2+0+0 x 1x1+1+1
[12:54:18] [PASSED] far away: 1x1+0+0 x 1x1+3+6
[12:54:18] [PASSED] points intersecting: 0x0+5+10 x 0x0+5+10
[12:54:18] [PASSED] points not intersecting: 0x0+0+0 x 0x0+5+10
[12:54:18] ============= [PASSED] drm_test_rect_intersect =============
[12:54:18] ================ drm_test_rect_calc_hscale ================
[12:54:18] [PASSED] normal use
[12:54:18] [PASSED] out of max range
[12:54:18] [PASSED] out of min range
[12:54:18] [PASSED] zero dst
[12:54:18] [PASSED] negative src
[12:54:18] [PASSED] negative dst
[12:54:18] ============ [PASSED] drm_test_rect_calc_hscale ============
[12:54:18] ================ drm_test_rect_calc_vscale ================
[12:54:18] [PASSED] normal use
[12:54:18] [PASSED] out of max range
[12:54:18] [PASSED] out of min range
[12:54:18] [PASSED] zero dst
[12:54:18] [PASSED] negative src
[12:54:18] [PASSED] negative dst
[12:54:18] ============ [PASSED] drm_test_rect_calc_vscale ============
[12:54:18] ================== drm_test_rect_rotate ===================
[12:54:18] [PASSED] reflect-x
[12:54:18] [PASSED] reflect-y
[12:54:18] [PASSED] rotate-0
[12:54:18] [PASSED] rotate-90
[12:54:18] [PASSED] rotate-180
[12:54:18] [PASSED] rotate-270
[12:54:18] ============== [PASSED] drm_test_rect_rotate ===============
[12:54:18] ================ drm_test_rect_rotate_inv =================
[12:54:18] [PASSED] reflect-x
[12:54:18] [PASSED] reflect-y
[12:54:18] [PASSED] rotate-0
[12:54:18] [PASSED] rotate-90
[12:54:18] [PASSED] rotate-180
[12:54:18] [PASSED] rotate-270
[12:54:18] ============ [PASSED] drm_test_rect_rotate_inv =============
[12:54:18] ==================== [PASSED] drm_rect =====================
[12:54:18] ============ drm_sysfb_modeset_test (1 subtest) ============
[12:54:18] ============ drm_test_sysfb_build_fourcc_list =============
[12:54:18] [PASSED] no native formats
[12:54:18] [PASSED] XRGB8888 as native format
[12:54:18] [PASSED] remove duplicates
[12:54:18] [PASSED] convert alpha formats
[12:54:18] [PASSED] random formats
[12:54:18] ======== [PASSED] drm_test_sysfb_build_fourcc_list =========
[12:54:18] ============= [PASSED] drm_sysfb_modeset_test ==============
[12:54:18] ================== drm_fixp (2 subtests) ===================
[12:54:18] [PASSED] drm_test_int2fixp
[12:54:18] [PASSED] drm_test_sm2fixp
[12:54:18] ==================== [PASSED] drm_fixp =====================
[12:54:18] ============================================================
[12:54:18] Testing complete. Ran 671 tests: passed: 671
[12:54:19] Elapsed time: 27.559s total, 1.810s configuring, 25.177s building, 0.521s running
+ for kcfg in "${kunitconfigs[@]}"
+ [[ ! -f /kernel/drivers/gpu/drm/ttm/tests/.kunitconfig ]]
+ /kernel/tools/testing/kunit/kunit.py run --kunitconfig /kernel/drivers/gpu/drm/ttm/tests/.kunitconfig
[12:54:19] Configuring KUnit Kernel ...
Regenerating .config ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
[12:54:20] Building KUnit Kernel ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
Building with:
$ make all compile_commands.json scripts_gdb ARCH=um O=.kunit --jobs=48
[12:54:30] Starting KUnit Kernel (1/1)...
[12:54:30] ============================================================
Running tests with:
$ .kunit/linux kunit.enable=1 mem=1G console=tty kunit_shutdown=halt
[12:54:30] ============= refcount_interrupt (4 subtests) ==============
[12:54:30] [PASSED] test_single_irq_change
[12:54:30] [PASSED] test_nested_irq_change
[12:54:30] [PASSED] test_multiple_irq_change
[12:54:30] [PASSED] test_irq_save
[12:54:30] =============== [PASSED] refcount_interrupt ================
[12:54:30] ================= ttm_device (5 subtests) ==================
[12:54:30] [PASSED] ttm_device_init_basic
[12:54:30] [PASSED] ttm_device_init_multiple
[12:54:30] [PASSED] ttm_device_fini_basic
[12:54:30] [PASSED] ttm_device_init_no_vma_man
[12:54:30] ================== ttm_device_init_pools ==================
[12:54:30] [PASSED] No DMA allocations, no DMA32 required
[12:54:30] [PASSED] DMA allocations, DMA32 required
[12:54:30] [PASSED] No DMA allocations, DMA32 required
[12:54:30] [PASSED] DMA allocations, no DMA32 required
[12:54:30] ============== [PASSED] ttm_device_init_pools ==============
[12:54:30] =================== [PASSED] ttm_device ====================
[12:54:30] ================== ttm_pool (8 subtests) ===================
[12:54:30] ================== ttm_pool_alloc_basic ===================
[12:54:30] [PASSED] One page
[12:54:30] [PASSED] More than one page
[12:54:30] [PASSED] Above the allocation limit
[12:54:30] [PASSED] One page, with coherent DMA mappings enabled
[12:54:30] [PASSED] Above the allocation limit, with coherent DMA mappings enabled
[12:54:30] ============== [PASSED] ttm_pool_alloc_basic ===============
[12:54:30] ============== ttm_pool_alloc_basic_dma_addr ==============
[12:54:30] [PASSED] One page
[12:54:30] [PASSED] More than one page
[12:54:30] [PASSED] Above the allocation limit
[12:54:30] [PASSED] One page, with coherent DMA mappings enabled
[12:54:30] [PASSED] Above the allocation limit, with coherent DMA mappings enabled
[12:54:30] ========== [PASSED] ttm_pool_alloc_basic_dma_addr ==========
[12:54:30] [PASSED] ttm_pool_alloc_order_caching_match
[12:54:30] [PASSED] ttm_pool_alloc_caching_mismatch
[12:54:30] [PASSED] ttm_pool_alloc_order_mismatch
[12:54:30] [PASSED] ttm_pool_free_dma_alloc
[12:54:30] [PASSED] ttm_pool_free_no_dma_alloc
[12:54:30] [PASSED] ttm_pool_fini_basic
[12:54:30] ==================== [PASSED] ttm_pool =====================
[12:54:30] ================ ttm_resource (8 subtests) =================
[12:54:30] ================= ttm_resource_init_basic =================
[12:54:30] [PASSED] Init resource in TTM_PL_SYSTEM
[12:54:30] [PASSED] Init resource in TTM_PL_VRAM
[12:54:30] [PASSED] Init resource in a private placement
[12:54:30] [PASSED] Init resource in TTM_PL_SYSTEM, set placement flags
[12:54:30] ============= [PASSED] ttm_resource_init_basic =============
[12:54:30] [PASSED] ttm_resource_init_pinned
[12:54:30] [PASSED] ttm_resource_fini_basic
[12:54:30] [PASSED] ttm_resource_manager_init_basic
[12:54:30] [PASSED] ttm_resource_manager_usage_basic
[12:54:30] [PASSED] ttm_resource_manager_set_used_basic
[12:54:30] [PASSED] ttm_sys_man_alloc_basic
[12:54:30] [PASSED] ttm_sys_man_free_basic
[12:54:30] ================== [PASSED] ttm_resource ===================
[12:54:30] =================== ttm_tt (15 subtests) ===================
[12:54:30] ==================== ttm_tt_init_basic ====================
[12:54:30] [PASSED] Page-aligned size
[12:54:30] [PASSED] Extra pages requested
[12:54:30] ================ [PASSED] ttm_tt_init_basic ================
[12:54:30] [PASSED] ttm_tt_init_misaligned
[12:54:30] [PASSED] ttm_tt_fini_basic
[12:54:30] [PASSED] ttm_tt_fini_sg
[12:54:30] [PASSED] ttm_tt_fini_shmem
[12:54:30] [PASSED] ttm_tt_create_basic
[12:54:30] [PASSED] ttm_tt_create_invalid_bo_type
[12:54:30] [PASSED] ttm_tt_create_ttm_exists
[12:54:30] [PASSED] ttm_tt_create_failed
[12:54:30] [PASSED] ttm_tt_destroy_basic
[12:54:30] [PASSED] ttm_tt_populate_null_ttm
[12:54:30] [PASSED] ttm_tt_populate_populated_ttm
[12:54:30] [PASSED] ttm_tt_unpopulate_basic
[12:54:30] [PASSED] ttm_tt_unpopulate_empty_ttm
[12:54:30] [PASSED] ttm_tt_swapin_basic
[12:54:30] ===================== [PASSED] ttm_tt ======================
[12:54:30] =================== ttm_bo (14 subtests) ===================
[12:54:30] =========== ttm_bo_reserve_optimistic_no_ticket ===========
[12:54:30] [PASSED] Cannot be interrupted and sleeps
[12:54:30] [PASSED] Cannot be interrupted, locks straight away
[12:54:30] [PASSED] Can be interrupted, sleeps
[12:54:30] ======= [PASSED] ttm_bo_reserve_optimistic_no_ticket =======
[12:54:30] [PASSED] ttm_bo_reserve_locked_no_sleep
[12:54:30] [PASSED] ttm_bo_reserve_no_wait_ticket
[12:54:30] [PASSED] ttm_bo_reserve_double_resv
[12:54:30] [PASSED] ttm_bo_reserve_interrupted
[12:54:30] [PASSED] ttm_bo_reserve_deadlock
[12:54:30] [PASSED] ttm_bo_unreserve_basic
[12:54:30] [PASSED] ttm_bo_unreserve_pinned
[12:54:30] [PASSED] ttm_bo_unreserve_bulk
[12:54:30] [PASSED] ttm_bo_fini_basic
[12:54:30] [PASSED] ttm_bo_fini_shared_resv
[12:54:30] [PASSED] ttm_bo_pin_basic
[12:54:30] [PASSED] ttm_bo_pin_unpin_resource
[12:54:30] [PASSED] ttm_bo_multiple_pin_one_unpin
[12:54:30] ===================== [PASSED] ttm_bo ======================
[12:54:30] ============== ttm_bo_validate (22 subtests) ===============
[12:54:30] ============== ttm_bo_init_reserved_sys_man ===============
[12:54:30] [PASSED] Buffer object for userspace
[12:54:30] [PASSED] Kernel buffer object
[12:54:30] [PASSED] Shared buffer object
[12:54:30] ========== [PASSED] ttm_bo_init_reserved_sys_man ===========
[12:54:30] ============== ttm_bo_init_reserved_mock_man ==============
[12:54:30] [PASSED] Buffer object for userspace
[12:54:30] [PASSED] Kernel buffer object
[12:54:30] [PASSED] Shared buffer object
[12:54:30] ========== [PASSED] ttm_bo_init_reserved_mock_man ==========
[12:54:30] [PASSED] ttm_bo_init_reserved_resv
[12:54:30] ================== ttm_bo_validate_basic ==================
[12:54:30] [PASSED] Buffer object for userspace
[12:54:30] [PASSED] Kernel buffer object
[12:54:30] [PASSED] Shared buffer object
[12:54:30] ============== [PASSED] ttm_bo_validate_basic ==============
[12:54:30] [PASSED] ttm_bo_validate_invalid_placement
[12:54:30] ============= ttm_bo_validate_same_placement ==============
[12:54:30] [PASSED] System manager
[12:54:30] [PASSED] VRAM manager
[12:54:30] ========= [PASSED] ttm_bo_validate_same_placement ==========
[12:54:30] [PASSED] ttm_bo_validate_failed_alloc
[12:54:30] [PASSED] ttm_bo_validate_pinned
[12:54:30] [PASSED] ttm_bo_validate_busy_placement
[12:54:30] ================ ttm_bo_validate_multihop =================
[12:54:30] [PASSED] Buffer object for userspace
[12:54:30] [PASSED] Kernel buffer object
[12:54:30] [PASSED] Shared buffer object
[12:54:30] ============ [PASSED] ttm_bo_validate_multihop =============
[12:54:30] ========== ttm_bo_validate_no_placement_signaled ==========
[12:54:30] [PASSED] Buffer object in system domain, no page vector
[12:54:30] [PASSED] Buffer object in system domain with an existing page vector
[12:54:30] ====== [PASSED] ttm_bo_validate_no_placement_signaled ======
[12:54:30] ======== ttm_bo_validate_no_placement_not_signaled ========
[12:54:30] [PASSED] Buffer object for userspace
[12:54:30] [PASSED] Kernel buffer object
[12:54:30] [PASSED] Shared buffer object
[12:54:30] ==== [PASSED] ttm_bo_validate_no_placement_not_signaled ====
[12:54:30] [PASSED] ttm_bo_validate_move_fence_signaled
[12:54:30] ========= ttm_bo_validate_move_fence_not_signaled =========
[12:54:30] [PASSED] Waits for GPU
[12:54:30] [PASSED] Tries to lock straight away
[12:54:30] ===== [PASSED] ttm_bo_validate_move_fence_not_signaled =====
[12:54:30] [PASSED] ttm_bo_validate_swapout
[12:54:30] [PASSED] ttm_bo_validate_happy_evict
[12:54:30] [PASSED] ttm_bo_validate_all_pinned_evict
[12:54:30] [PASSED] ttm_bo_validate_allowed_only_evict
[12:54:30] [PASSED] ttm_bo_validate_deleted_evict
[12:54:30] [PASSED] ttm_bo_validate_busy_domain_evict
[12:54:30] [PASSED] ttm_bo_validate_evict_gutting
[12:54:30] [PASSED] ttm_bo_validate_recrusive_evict
[12:54:30] ================= [PASSED] ttm_bo_validate =================
[12:54:30] ============================================================
[12:54:30] Testing complete. Ran 106 tests: passed: 106
[12:54:31] Elapsed time: 11.872s total, 1.685s configuring, 9.922s building, 0.226s running
+ for kcfg in "${kunitconfigs[@]}"
+ [[ ! -f /kernel/drivers/dma-buf/.kunitconfig ]]
+ /kernel/tools/testing/kunit/kunit.py run --kunitconfig /kernel/drivers/dma-buf/.kunitconfig
[12:54:31] Configuring KUnit Kernel ...
Regenerating .config ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
[12:54:32] Building KUnit Kernel ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
Building with:
$ make all compile_commands.json scripts_gdb ARCH=um O=.kunit --jobs=48
[12:54:41] Starting KUnit Kernel (1/1)...
[12:54:41] ============================================================
Running tests with:
$ .kunit/linux kunit.enable=1 mem=1G console=tty kunit_shutdown=halt
[12:54:41] ============= refcount_interrupt (4 subtests) ==============
[12:54:41] [PASSED] test_single_irq_change
[12:54:41] [PASSED] test_nested_irq_change
[12:54:41] [PASSED] test_multiple_irq_change
[12:54:41] [PASSED] test_irq_save
[12:54:41] =============== [PASSED] refcount_interrupt ================
[12:54:41] =============== dma-buf-fence (12 subtests) ================
[12:54:41] [PASSED] test_sanitycheck
[12:54:41] [PASSED] test_signaling
[12:54:41] [PASSED] test_add_callback
[12:54:41] [PASSED] test_late_add_callback
[12:54:41] [PASSED] test_rm_callback
[12:54:41] [PASSED] test_late_rm_callback
[12:54:41] [PASSED] test_status
[12:54:41] [PASSED] test_error
[12:54:41] [PASSED] test_wait
[12:54:41] [PASSED] test_wait_timeout
[12:54:41] [PASSED] test_stub
[12:54:41] [SKIPPED] test_race_signal_callback (requires at least 2 CPUs)
[12:54:41] ================== [PASSED] dma-buf-fence ==================
[12:54:41] ============ dma-buf-fence-chain (11 subtests) =============
[12:54:41] [PASSED] test_sanitycheck
[12:54:41] [PASSED] test_find_seqno
[12:54:41] [PASSED] test_find_signaled
[12:54:41] [PASSED] test_find_out_of_order
[12:54:46] [PASSED] test_find_gap
[12:54:46] [PASSED] test_find_race
[12:54:46] [PASSED] test_signal_forward
[12:54:46] [PASSED] test_signal_backward
[12:54:46] [PASSED] test_wait_forward
[12:54:46] [PASSED] test_wait_backward
[12:54:46] [PASSED] test_wait_random
[12:54:46] =============== [PASSED] dma-buf-fence-chain ===============
[12:54:46] ============ dma-buf-fence-unwrap (10 subtests) ============
[12:54:46] [PASSED] test_sanitycheck
[12:54:46] [PASSED] test_unwrap_array
[12:54:46] [PASSED] test_unwrap_chain
[12:54:46] [PASSED] test_unwrap_chain_array
[12:54:46] [PASSED] test_unwrap_merge
[12:54:46] [PASSED] test_unwrap_merge_duplicate
[12:54:46] [PASSED] test_unwrap_merge_seqno
[12:54:46] [PASSED] test_unwrap_merge_order
[12:54:46] [PASSED] test_unwrap_merge_complex
[12:54:46] [PASSED] test_unwrap_merge_complex_seqno
[12:54:46] ============== [PASSED] dma-buf-fence-unwrap ===============
[12:54:46] ================ dma-buf-resv (5 subtests) =================
[12:54:46] [PASSED] test_sanitycheck
[12:54:46] ===================== test_signaling ======================
[12:54:46] [PASSED] kernel
[12:54:46] [PASSED] write
[12:54:46] [PASSED] read
[12:54:46] [PASSED] bookkeep
[12:54:46] ================= [PASSED] test_signaling ==================
[12:54:46] ====================== test_for_each ======================
[12:54:46] [PASSED] kernel
[12:54:46] [PASSED] write
[12:54:46] [PASSED] read
[12:54:46] [PASSED] bookkeep
[12:54:46] ================== [PASSED] test_for_each ==================
[12:54:46] ================= test_for_each_unlocked ==================
[12:54:46] [PASSED] kernel
[12:54:46] [PASSED] write
[12:54:46] [PASSED] read
[12:54:46] [PASSED] bookkeep
[12:54:46] ============= [PASSED] test_for_each_unlocked ==============
[12:54:46] ===================== test_get_fences =====================
[12:54:46] [PASSED] kernel
[12:54:46] [PASSED] write
[12:54:46] [PASSED] read
[12:54:46] [PASSED] bookkeep
[12:54:46] ================= [PASSED] test_get_fences =================
[12:54:46] ================== [PASSED] dma-buf-resv ===================
[12:54:46] ============================================================
[12:54:46] Testing complete. Ran 54 tests: passed: 53, skipped: 1
[12:54:46] Elapsed time: 15.700s total, 1.802s configuring, 8.577s building, 5.275s running
+ cleanup
++ stat -c %u:%g /kernel
+ chown -R 1003:1003 /kernel
^ permalink raw reply [flat|nested] 19+ messages in thread
* ✓ Xe.CI.BAT: success for drm/panic: Split into core and helpers (rev3)
2026-09-02 12:13 [PATCH v3 00/14] drm/panic: Split into core and helpers Thomas Zimmermann
` (15 preceding siblings ...)
2026-09-02 12:54 ` ✓ CI.KUnit: success " Patchwork
@ 2026-09-02 13:37 ` Patchwork
2026-09-03 0:02 ` ✓ Xe.CI.FULL: " Patchwork
17 siblings, 0 replies; 19+ messages in thread
From: Patchwork @ 2026-09-02 13:37 UTC (permalink / raw)
To: Thomas Zimmermann; +Cc: intel-xe
[-- Attachment #1: Type: text/plain, Size: 913 bytes --]
== Series Details ==
Series: drm/panic: Split into core and helpers (rev3)
URL : https://patchwork.freedesktop.org/series/172394/
State : success
== Summary ==
CI Bug Log - changes from xe-5673-69771454478b3dc773dee91f76cef9220ea1ce93_BAT -> xe-pw-172394v3_BAT
====================================================
Summary
-------
**SUCCESS**
No regressions found.
Participating hosts (12 -> 6)
------------------------------
Missing (6): bat-lnl-1 bat-ptl-1 bat-atsm-2 bat-bmg-2 bat-nvls-1 bat-adlp-7
Changes
-------
No changes found
Build changes
-------------
* Linux: xe-5673-69771454478b3dc773dee91f76cef9220ea1ce93 -> xe-pw-172394v3
IGT_9079: 9079
xe-5673-69771454478b3dc773dee91f76cef9220ea1ce93: 69771454478b3dc773dee91f76cef9220ea1ce93
xe-pw-172394v3: 172394v3
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/index.html
[-- Attachment #2: Type: text/html, Size: 1461 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* ✓ Xe.CI.FULL: success for drm/panic: Split into core and helpers (rev3)
2026-09-02 12:13 [PATCH v3 00/14] drm/panic: Split into core and helpers Thomas Zimmermann
` (16 preceding siblings ...)
2026-09-02 13:37 ` ✓ Xe.CI.BAT: " Patchwork
@ 2026-09-03 0:02 ` Patchwork
17 siblings, 0 replies; 19+ messages in thread
From: Patchwork @ 2026-09-03 0:02 UTC (permalink / raw)
To: Thomas Zimmermann; +Cc: intel-xe
[-- Attachment #1: Type: text/plain, Size: 12982 bytes --]
== Series Details ==
Series: drm/panic: Split into core and helpers (rev3)
URL : https://patchwork.freedesktop.org/series/172394/
State : success
== Summary ==
CI Bug Log - changes from xe-5673-69771454478b3dc773dee91f76cef9220ea1ce93_FULL -> xe-pw-172394v3_FULL
====================================================
Summary
-------
**SUCCESS**
No regressions found.
Participating hosts (2 -> 2)
------------------------------
No changes in participating hosts
Known issues
------------
Here are the changes found in xe-pw-172394v3_FULL that come from known issues:
### IGT changes ###
#### Issues hit ####
* igt@kms_big_fb@4-tiled-8bpp-rotate-270:
- shard-bmg: NOTRUN -> [SKIP][1] ([Intel XE#2327])
[1]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-bmg-5/igt@kms_big_fb@4-tiled-8bpp-rotate-270.html
* igt@kms_big_fb@linear-max-hw-stride-64bpp-rotate-0-hflip:
- shard-bmg: NOTRUN -> [SKIP][2] ([Intel XE#7059] / [Intel XE#7085])
[2]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-bmg-5/igt@kms_big_fb@linear-max-hw-stride-64bpp-rotate-0-hflip.html
* igt@kms_big_fb@y-tiled-32bpp-rotate-90:
- shard-bmg: NOTRUN -> [SKIP][3] ([Intel XE#1124])
[3]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-bmg-5/igt@kms_big_fb@y-tiled-32bpp-rotate-90.html
* igt@kms_ccs@bad-aux-stride-y-tiled-gen12-mc-ccs:
- shard-bmg: NOTRUN -> [SKIP][4] ([Intel XE#2887])
[4]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-bmg-5/igt@kms_ccs@bad-aux-stride-y-tiled-gen12-mc-ccs.html
* igt@kms_chamelium_edid@hdmi-edid-stress-resolution-non-4k:
- shard-bmg: NOTRUN -> [SKIP][5] ([Intel XE#2252])
[5]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-bmg-5/igt@kms_chamelium_edid@hdmi-edid-stress-resolution-non-4k.html
* igt@kms_cursor_legacy@flip-vs-cursor-legacy:
- shard-bmg: [PASS][6] -> [FAIL][7] ([Intel XE#7809])
[6]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-5673-69771454478b3dc773dee91f76cef9220ea1ce93/shard-bmg-7/igt@kms_cursor_legacy@flip-vs-cursor-legacy.html
[7]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-bmg-5/igt@kms_cursor_legacy@flip-vs-cursor-legacy.html
* igt@kms_flip@2x-flip-vs-absolute-wf_vblank@ab-dp2-hdmi-a3:
- shard-bmg: NOTRUN -> [FAIL][8] ([Intel XE#3098]) +1 other test fail
[8]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-bmg-5/igt@kms_flip@2x-flip-vs-absolute-wf_vblank@ab-dp2-hdmi-a3.html
* igt@kms_flip@flip-vs-expired-vblank-interruptible@b-edp1:
- shard-lnl: [PASS][9] -> [FAIL][10] ([Intel XE#301])
[9]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-5673-69771454478b3dc773dee91f76cef9220ea1ce93/shard-lnl-7/igt@kms_flip@flip-vs-expired-vblank-interruptible@b-edp1.html
[10]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-lnl-8/igt@kms_flip@flip-vs-expired-vblank-interruptible@b-edp1.html
* igt@kms_frontbuffer_tracking@fbc-1p-primscrn-cur-indfb-draw-blt:
- shard-bmg: NOTRUN -> [SKIP][11] ([Intel XE#4141]) +3 other tests skip
[11]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-bmg-5/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-cur-indfb-draw-blt.html
* igt@kms_frontbuffer_tracking@fbcdrrs-tiling-y:
- shard-bmg: NOTRUN -> [SKIP][12] ([Intel XE#2352] / [Intel XE#7399])
[12]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-bmg-5/igt@kms_frontbuffer_tracking@fbcdrrs-tiling-y.html
* igt@kms_frontbuffer_tracking@fbcdrrshdr-rgb565-draw-blt:
- shard-bmg: NOTRUN -> [SKIP][13] ([Intel XE#2311]) +5 other tests skip
[13]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-bmg-5/igt@kms_frontbuffer_tracking@fbcdrrshdr-rgb565-draw-blt.html
* igt@kms_frontbuffer_tracking@hdr-argb161616f-draw-blt:
- shard-bmg: NOTRUN -> [SKIP][14] ([Intel XE#7061]) +1 other test skip
[14]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-bmg-5/igt@kms_frontbuffer_tracking@hdr-argb161616f-draw-blt.html
* igt@kms_frontbuffer_tracking@psr-argb161616f-draw-blt:
- shard-bmg: NOTRUN -> [SKIP][15] ([Intel XE#7061] / [Intel XE#7356])
[15]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-bmg-5/igt@kms_frontbuffer_tracking@psr-argb161616f-draw-blt.html
* igt@kms_frontbuffer_tracking@psrhdr-1p-primscrn-spr-indfb-onoff:
- shard-bmg: NOTRUN -> [SKIP][16] ([Intel XE#2313]) +4 other tests skip
[16]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-bmg-5/igt@kms_frontbuffer_tracking@psrhdr-1p-primscrn-spr-indfb-onoff.html
* igt@kms_plane@pixel-format-y-tiled-gen12-rc-ccs-cc-modifier:
- shard-bmg: NOTRUN -> [SKIP][17] ([Intel XE#7283])
[17]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-bmg-5/igt@kms_plane@pixel-format-y-tiled-gen12-rc-ccs-cc-modifier.html
* igt@kms_pm_dc@dc3co-after-dc6:
- shard-bmg: NOTRUN -> [SKIP][18] ([Intel XE#8395] / [Intel XE#8396]) +1 other test skip
[18]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-bmg-5/igt@kms_pm_dc@dc3co-after-dc6.html
* igt@kms_pm_dc@dc3co-after-dc6@psr2-xrgb8888:
- shard-bmg: NOTRUN -> [SKIP][19] ([Intel XE#8396]) +1 other test skip
[19]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-bmg-5/igt@kms_pm_dc@dc3co-after-dc6@psr2-xrgb8888.html
* igt@kms_psr2_sf@fbc-pr-cursor-plane-move-continuous-exceed-fully-sf:
- shard-bmg: NOTRUN -> [SKIP][20] ([Intel XE#1489]) +1 other test skip
[20]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-bmg-5/igt@kms_psr2_sf@fbc-pr-cursor-plane-move-continuous-exceed-fully-sf.html
* igt@kms_psr@pr-sprite-render:
- shard-bmg: NOTRUN -> [SKIP][21] ([Intel XE#2234] / [Intel XE#2850]) +1 other test skip
[21]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-bmg-5/igt@kms_psr@pr-sprite-render.html
* igt@runner@aborted:
- shard-lnl: NOTRUN -> [FAIL][22] ([Intel XE#8990])
[22]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-lnl-3/igt@runner@aborted.html
* igt@xe_exec_basic@multigpu-no-exec-bindexecqueue-userptr-invalidate:
- shard-bmg: NOTRUN -> [SKIP][23] ([Intel XE#2322] / [Intel XE#7372])
[23]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-bmg-5/igt@xe_exec_basic@multigpu-no-exec-bindexecqueue-userptr-invalidate.html
* igt@xe_exec_fault_mode@many-multi-queue-rebind-imm:
- shard-bmg: NOTRUN -> [SKIP][24] ([Intel XE#8374])
[24]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-bmg-5/igt@xe_exec_fault_mode@many-multi-queue-rebind-imm.html
* igt@xe_exec_mix_modes@exec-multi-queue-spinner-interrupted-lr:
- shard-bmg: NOTRUN -> [SKIP][25] ([Intel XE#9003])
[25]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-bmg-5/igt@xe_exec_mix_modes@exec-multi-queue-spinner-interrupted-lr.html
* igt@xe_exec_multi_queue@one-queue-preempt-mode-fault-basic:
- shard-bmg: NOTRUN -> [SKIP][26] ([Intel XE#8364]) +1 other test skip
[26]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-bmg-5/igt@xe_exec_multi_queue@one-queue-preempt-mode-fault-basic.html
* igt@xe_exec_reset@multi-queue-cancel-on-secondary:
- shard-bmg: NOTRUN -> [SKIP][27] ([Intel XE#8369])
[27]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-bmg-5/igt@xe_exec_reset@multi-queue-cancel-on-secondary.html
* igt@xe_exec_threads@threads-hang-userptr-invalidate-race:
- shard-lnl: [PASS][28] -> [FAIL][29] ([Intel XE#9096])
[28]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-5673-69771454478b3dc773dee91f76cef9220ea1ce93/shard-lnl-4/igt@xe_exec_threads@threads-hang-userptr-invalidate-race.html
[29]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-lnl-7/igt@xe_exec_threads@threads-hang-userptr-invalidate-race.html
* igt@xe_exec_threads@threads-multi-queue-cm-fd-rebind:
- shard-bmg: NOTRUN -> [SKIP][30] ([Intel XE#8378]) +1 other test skip
[30]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-bmg-5/igt@xe_exec_threads@threads-multi-queue-cm-fd-rebind.html
* igt@xe_multigpu_svm@mgpu-atomic-op-conflict:
- shard-bmg: NOTRUN -> [SKIP][31] ([Intel XE#6964])
[31]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-bmg-5/igt@xe_multigpu_svm@mgpu-atomic-op-conflict.html
#### Warnings ####
* igt@kms_tiled_display@basic-test-pattern-with-chamelium:
- shard-bmg: [SKIP][32] ([Intel XE#2426] / [Intel XE#5848]) -> [SKIP][33] ([Intel XE#2509] / [Intel XE#7437])
[32]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-5673-69771454478b3dc773dee91f76cef9220ea1ce93/shard-bmg-2/igt@kms_tiled_display@basic-test-pattern-with-chamelium.html
[33]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-bmg-1/igt@kms_tiled_display@basic-test-pattern-with-chamelium.html
* igt@xe_fault_injection@exec-queue-create-fail-xe_pxp_exec_queue_add:
- shard-bmg: [ABORT][34] ([Intel XE#8007]) -> [SKIP][35] ([Intel XE#6281] / [Intel XE#7426])
[34]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-5673-69771454478b3dc773dee91f76cef9220ea1ce93/shard-bmg-7/igt@xe_fault_injection@exec-queue-create-fail-xe_pxp_exec_queue_add.html
[35]: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/shard-bmg-5/igt@xe_fault_injection@exec-queue-create-fail-xe_pxp_exec_queue_add.html
[Intel XE#1124]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1124
[Intel XE#1489]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/1489
[Intel XE#2234]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/2234
[Intel XE#2252]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/2252
[Intel XE#2311]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/2311
[Intel XE#2313]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/2313
[Intel XE#2322]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/2322
[Intel XE#2327]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/2327
[Intel XE#2352]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/2352
[Intel XE#2426]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/2426
[Intel XE#2509]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/2509
[Intel XE#2850]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/2850
[Intel XE#2887]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/2887
[Intel XE#301]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/301
[Intel XE#3098]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/3098
[Intel XE#4141]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/4141
[Intel XE#5848]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/5848
[Intel XE#6281]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/6281
[Intel XE#6964]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/6964
[Intel XE#7059]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7059
[Intel XE#7061]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7061
[Intel XE#7085]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7085
[Intel XE#7283]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7283
[Intel XE#7356]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7356
[Intel XE#7372]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7372
[Intel XE#7399]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7399
[Intel XE#7426]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7426
[Intel XE#7437]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7437
[Intel XE#7809]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/7809
[Intel XE#8007]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/8007
[Intel XE#8364]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/8364
[Intel XE#8369]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/8369
[Intel XE#8374]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/8374
[Intel XE#8378]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/8378
[Intel XE#8395]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/8395
[Intel XE#8396]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/8396
[Intel XE#8990]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/8990
[Intel XE#9003]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/9003
[Intel XE#9096]: https://gitlab.freedesktop.org/drm/xe/kernel/issues/9096
Build changes
-------------
* Linux: xe-5673-69771454478b3dc773dee91f76cef9220ea1ce93 -> xe-pw-172394v3
IGT_9079: 9079
xe-5673-69771454478b3dc773dee91f76cef9220ea1ce93: 69771454478b3dc773dee91f76cef9220ea1ce93
xe-pw-172394v3: 172394v3
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/intel-xe/xe-pw-172394v3/index.html
[-- Attachment #2: Type: text/html, Size: 14286 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2026-09-03 0:02 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-02 12:13 [PATCH v3 00/14] drm/panic: Split into core and helpers Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 01/14] drm/panic: Do not use un-escaped URL as format string Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 02/14] drm/panic: Test address from kmap op for NULL Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 03/14] drm/panic: Return -EINVAL if font is not available Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 04/14] drm/panic: Return errno codes if panic output fails Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 05/14] drm/panic: Pass colors to draw_panic_dispatch() Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 06/14] drm/panic: Pass global module parameters to drm_panic_dispatch() Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 07/14] drm/panic: Return from screen_user if display is too small Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 08/14] drm/panic: Retry in dispatch function if panic output fails Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 09/14] drm/panic: Split draw_panic_plane() Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 10/14] drm/panic: Restrict to primary planes Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 11/14] drm/panic: Display panic screen via per-plane callback Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 12/14] drm/panic: Internalize panic locking in DRM core and helpers Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 13/14] drm/panic: Move panic display code into helper library Thomas Zimmermann
2026-09-02 12:13 ` [PATCH v3 14/14] drm/panic: Compile KUnit tests as module Thomas Zimmermann
2026-09-02 12:52 ` ✗ CI.checkpatch: warning for drm/panic: Split into core and helpers (rev3) Patchwork
2026-09-02 12:54 ` ✓ CI.KUnit: success " Patchwork
2026-09-02 13:37 ` ✓ Xe.CI.BAT: " Patchwork
2026-09-03 0:02 ` ✓ Xe.CI.FULL: " Patchwork
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).