Assisted-by: LLM
Signed-off-by: 纳西妲 · Nahida <[email protected]>
---
v2:
- Grow the formatted URL buffer to accommodate the maximum 255-byte
runtime base URL.
- Reject unexpectedly truncated formatted URLs.
- Test the maximum-length runtime URL.
v1: https://lore.kernel.org/r/[email protected]
Tested on x86_64:
- Full modular build with DRM=m and DRM_KMS_HELPER=m.
- QEMU/virtio-gpu runtime override with a non-empty Kconfig default URL.
- QEMU/virtio-gpu runtime fallback to the Kconfig default URL.
- QEMU/virtio-gpu runtime override with an empty Kconfig default URL.
- QEMU/virtio-gpu raw kmsg QR fallback with no configured URL.
- QEMU/virtio-gpu runtime override with a 255-byte base URL.
drivers/gpu/drm/Kconfig | 9 +++++----
drivers/gpu/drm/drm_panic.c | 9 +++++++++
drivers/gpu/drm/drm_panic_helper.c | 17 +++++++++++------
drivers/gpu/drm/drm_panic_internal.h | 4 ++++
4 files changed, 29 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 61111d50b..3d9d421f0 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -111,10 +111,11 @@ config DRM_PANIC_SCREEN_QR_CODE_URL
string "Base URL of the QR code in the panic screen"
depends on DRM_PANIC_SCREEN_QR_CODE
help
- This option sets the base URL to report the kernel panic. If it's set
- the QR code will contain the URL and the kmsg compressed with zlib as
- a URL parameter. If it's empty, the QR code will contain the kmsg as
- uncompressed text only.
+ This option sets the default base URL to report the kernel panic. If
+ it's set the QR code will contain the URL and the kmsg compressed with
+ zlib as a URL parameter. If it's empty, the QR code will contain the
+ kmsg as uncompressed text only. It can be overridden with the
+ drm.panic_qr_url=<url> kernel parameter.
There is a demo code in javascript, to decode and uncompress the kmsg
data from the URL parameter at https://github.com/kdj0c/panic_report
diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
index 9fe97c4ed..463544f71 100644
--- a/drivers/gpu/drm/drm_panic.c
+++ b/drivers/gpu/drm/drm_panic.c
@@ -49,6 +49,15 @@ MODULE_LICENSE("GPL");
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");
+static char panic_qr_url[256] = CONFIG_DRM_PANIC_SCREEN_QR_CODE_URL;
+module_param_string(panic_qr_url, panic_qr_url, sizeof(panic_qr_url), 0444);
+MODULE_PARM_DESC(panic_qr_url, "base URL of the QR code in the panic screen");
+
+const char *drm_panic_get_qr_url(void)
+{
+ return panic_qr_url;
+}
+EXPORT_SYMBOL_GPL(drm_panic_get_qr_url);
#endif
static enum drm_panic_type drm_panic_type = -1;
diff --git a/drivers/gpu/drm/drm_panic_helper.c
b/drivers/gpu/drm/drm_panic_helper.c
index 8913c3d22..b0ea0b4e8 100644
--- a/drivers/gpu/drm/drm_panic_helper.c
+++ b/drivers/gpu/drm/drm_panic_helper.c
@@ -609,17 +609,20 @@ static void drm_panic_helper_qr_exit(void)
stream.workspace = NULL;
}
-static int drm_panic_helper_get_qr_code_url(u8 **qr_image, unsigned int
qr_version)
+static int drm_panic_helper_get_qr_code_url(u8 **qr_image, unsigned int
qr_version,
+ const char *qr_url)
{
struct kmsg_dump_iter iter;
- char url[256];
+ char url[512];
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);
+ qr_url, utsname()->machine, utsname()->release);
+
+ if (url_len >= (int)sizeof(url))
+ return -E2BIG;
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);
@@ -686,8 +689,10 @@ static int drm_panic_helper_get_qr_code_raw(u8 **qr_image,
unsigned int qr_versi
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);
+ const char *qr_url = drm_panic_get_qr_url();
+
+ if (qr_url[0])
+ return drm_panic_helper_get_qr_code_url(qr_image, qr_version,
qr_url);
else
return drm_panic_helper_get_qr_code_raw(qr_image, qr_version);
}
diff --git a/drivers/gpu/drm/drm_panic_internal.h
b/drivers/gpu/drm/drm_panic_internal.h
index fe6d514a0..f33552265 100644
--- a/drivers/gpu/drm/drm_panic_internal.h
+++ b/drivers/gpu/drm/drm_panic_internal.h
@@ -14,6 +14,10 @@ struct drm_device;
#ifdef CONFIG_DRM_PANIC
+#if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
+const char *drm_panic_get_qr_url(void);
+#endif
+
/**
* drm_panic_lock - protect panic printing relevant state
* @dev: struct drm_device
base-commit: 54e61ea6c492d69a1717018826d8340810c812eb