Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/panic: Report invalid or unsupported panic modes

Currently the user can write anything into the drm.panic_screen modparam,
either at runtime via sysfs, or as a kernel boot time argument. Invalid
strings will be silently accepted and ignored at use time by defaulting to
the 'user' panic mode.

Let instead add some validation in order to have immediate feedback when
something has been mistyped, or not compiled in.

For example during kernel boot:

Booting kernel: `bsod' invalid for parameter `drm.panic_screen'

Or at runtime:

# echo -n bsod > /sys/module/drm/parameters/panic_screen
-bash: echo: write error: Invalid argument

Change of behavior is that when invalid mode is attempted to be
configured, currently the code will default to the 'user' mode, while with
this change the code will ignore it, and default to the mode set at kernel
build time via CONFIG_DRM_PANIC_SCREEN.

While at it lets also fix the module parameter description to include all
compiled in modes.

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
Cc: Jocelyn Falempe <jfalempe@redhat.com>
Cc: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net>
Link: https://lore.kernel.org/r/20251127090349.92717-1-tvrtko.ursulin@igalia.com

authored by

Tvrtko Ursulin and committed by
Tvrtko Ursulin
e85e9ccf 36c5dff4

+63 -14
+63 -14
drivers/gpu/drm/drm_panic.c
··· 39 39 MODULE_DESCRIPTION("DRM panic handler"); 40 40 MODULE_LICENSE("GPL"); 41 41 42 - static char drm_panic_screen[16] = CONFIG_DRM_PANIC_SCREEN; 43 - module_param_string(panic_screen, drm_panic_screen, sizeof(drm_panic_screen), 0644); 44 - MODULE_PARM_DESC(panic_screen, 45 - "Choose what will be displayed by drm_panic, 'user' or 'kmsg' [default=" 46 - CONFIG_DRM_PANIC_SCREEN "]"); 47 - 48 42 /** 49 43 * DOC: overview 50 44 * ··· 759 765 draw_panic_static_user(sb); 760 766 } 761 767 #else 762 - static void draw_panic_static_qr_code(struct drm_scanout_buffer *sb) 763 - { 764 - draw_panic_static_user(sb); 765 - } 766 - 767 768 static void drm_panic_qr_init(void) {}; 768 769 static void drm_panic_qr_exit(void) {}; 769 770 #endif 771 + 772 + enum drm_panic_type { 773 + DRM_PANIC_TYPE_KMSG, 774 + DRM_PANIC_TYPE_USER, 775 + DRM_PANIC_TYPE_QR, 776 + }; 777 + 778 + static enum drm_panic_type drm_panic_type = -1; 779 + 780 + static const char *drm_panic_type_map[] = { 781 + [DRM_PANIC_TYPE_KMSG] = "kmsg", 782 + [DRM_PANIC_TYPE_USER] = "user", 783 + #if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE) 784 + [DRM_PANIC_TYPE_QR] = "qr", 785 + #endif 786 + }; 787 + 788 + static int drm_panic_type_set(const char *val, const struct kernel_param *kp) 789 + { 790 + unsigned int i; 791 + 792 + for (i = 0; i < ARRAY_SIZE(drm_panic_type_map); i++) { 793 + if (!strcmp(val, drm_panic_type_map[i])) { 794 + drm_panic_type = i; 795 + return 0; 796 + } 797 + } 798 + 799 + return -EINVAL; 800 + } 801 + 802 + static int drm_panic_type_get(char *buffer, const struct kernel_param *kp) 803 + { 804 + return scnprintf(buffer, PAGE_SIZE, "%s\n", 805 + drm_panic_type_map[drm_panic_type]); 806 + } 807 + 808 + static const struct kernel_param_ops drm_panic_ops = { 809 + .set = drm_panic_type_set, 810 + .get = drm_panic_type_get, 811 + }; 812 + 813 + module_param_cb(panic_screen, &drm_panic_ops, NULL, 0644); 814 + MODULE_PARM_DESC(panic_screen, 815 + #if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE) 816 + "Choose what will be displayed by drm_panic, 'user', 'kmsg' or 'qr' [default=" 817 + #else 818 + "Choose what will be displayed by drm_panic, 'user' or 'kmsg' [default=" 819 + #endif 820 + CONFIG_DRM_PANIC_SCREEN "]"); 770 821 771 822 /* 772 823 * drm_panic_is_format_supported() ··· 829 790 830 791 static void draw_panic_dispatch(struct drm_scanout_buffer *sb) 831 792 { 832 - if (!strcmp(drm_panic_screen, "kmsg")) { 793 + switch (drm_panic_type) { 794 + case DRM_PANIC_TYPE_KMSG: 833 795 draw_panic_static_kmsg(sb); 834 - } else if (!strcmp(drm_panic_screen, "qr_code")) { 796 + break; 797 + 798 + #if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE) 799 + case DRM_PANIC_TYPE_QR: 835 800 draw_panic_static_qr_code(sb); 836 - } else { 801 + break; 802 + #endif 803 + 804 + case DRM_PANIC_TYPE_USER: 805 + default: 837 806 draw_panic_static_user(sb); 838 807 } 839 808 } ··· 1024 977 */ 1025 978 void __init drm_panic_init(void) 1026 979 { 980 + if (drm_panic_type == -1) 981 + drm_panic_type_set(CONFIG_DRM_PANIC_SCREEN, NULL); 1027 982 drm_panic_qr_init(); 1028 983 } 1029 984