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

panic_qr: use new #[export] macro

This validates at compile time that the signatures match what is in the
header file. It highlights one annoyance with the compile-time check,
which is that it can only be used with functions marked unsafe.

If the function is not unsafe, then this error is emitted:

error[E0308]: `if` and `else` have incompatible types
--> <linux>/drivers/gpu/drm/drm_panic_qr.rs:987:19
|
986 | #[export]
| --------- expected because of this
987 | pub extern "C" fn drm_panic_qr_max_data_size(version: u8, url_len: usize) -> usize {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected unsafe fn, found safe fn
|
= note: expected fn item `unsafe extern "C" fn(_, _) -> _ {kernel::bindings::drm_panic_qr_max_data_size}`
found fn item `extern "C" fn(_, _) -> _ {drm_panic_qr_max_data_size}`

The signature declarations are moved to a header file so it can be
included in the Rust bindings helper, and the extern keyword is removed
as it is unnecessary.

Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Reviewed-by: Tamir Duberstein <tamird@gmail.com>
Acked-by: Simona Vetter <simona.vetter@ffwll.ch>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://lore.kernel.org/r/20250303-export-macro-v3-5-41fbad85a27f@google.com
[ Fixed `rustfmt`. Moved on top the unsafe requirement comment to follow
the usual style, and slightly reworded it for clarity. Formatted
bindings helper comment. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>

authored by

Alice Ryhl and committed by
Miguel Ojeda
fc2f191f 92d2873b

+21 -9
-5
drivers/gpu/drm/drm_panic.c
··· 486 486 stream.workspace = NULL; 487 487 } 488 488 489 - extern size_t drm_panic_qr_max_data_size(u8 version, size_t url_len); 490 - 491 - extern u8 drm_panic_qr_generate(const char *url, u8 *data, size_t data_len, size_t data_size, 492 - u8 *tmp, size_t tmp_size); 493 - 494 489 static int drm_panic_get_qr_code_url(u8 **qr_image) 495 490 { 496 491 struct kmsg_dump_iter iter;
+9 -4
drivers/gpu/drm/drm_panic_qr.rs
··· 27 27 //! * <https://github.com/bjguillot/qr> 28 28 29 29 use core::cmp; 30 - use kernel::str::CStr; 30 + use kernel::{prelude::*, str::CStr}; 31 31 32 32 #[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)] 33 33 struct Version(usize); ··· 929 929 /// * `tmp` must be valid for reading and writing for `tmp_size` bytes. 930 930 /// 931 931 /// They must remain valid for the duration of the function call. 932 - #[no_mangle] 932 + #[export] 933 933 pub unsafe extern "C" fn drm_panic_qr_generate( 934 934 url: *const kernel::ffi::c_char, 935 935 data: *mut u8, ··· 980 980 /// * If `url_len` > 0, remove the 2 segments header/length and also count the 981 981 /// conversion to numeric segments. 982 982 /// * If `url_len` = 0, only removes 3 bytes for 1 binary segment. 983 - #[no_mangle] 984 - pub extern "C" fn drm_panic_qr_max_data_size(version: u8, url_len: usize) -> usize { 983 + /// 984 + /// # Safety 985 + /// 986 + /// Always safe to call. 987 + // Required to be unsafe due to the `#[export]` annotation. 988 + #[export] 989 + pub unsafe extern "C" fn drm_panic_qr_max_data_size(version: u8, url_len: usize) -> usize { 985 990 #[expect(clippy::manual_range_contains)] 986 991 if version < 1 || version > 40 { 987 992 return 0;
+7
include/drm/drm_panic.h
··· 163 163 164 164 #endif 165 165 166 + #if defined(CONFIG_DRM_PANIC_SCREEN_QR_CODE) 167 + size_t drm_panic_qr_max_data_size(u8 version, size_t url_len); 168 + 169 + u8 drm_panic_qr_generate(const char *url, u8 *data, size_t data_len, size_t data_size, 170 + u8 *tmp, size_t tmp_size); 171 + #endif 172 + 166 173 #endif /* __DRM_PANIC_H__ */
+5
rust/bindings/bindings_helper.h
··· 37 37 #include <linux/workqueue.h> 38 38 #include <trace/events/rust_sample.h> 39 39 40 + #if defined(CONFIG_DRM_PANIC_SCREEN_QR_CODE) 41 + // Used by `#[export]` in `drivers/gpu/drm/drm_panic_qr.rs`. 42 + #include <drm/drm_panic.h> 43 + #endif 44 + 40 45 /* `bindgen` gets confused at certain things. */ 41 46 const size_t RUST_CONST_HELPER_ARCH_SLAB_MINALIGN = ARCH_SLAB_MINALIGN; 42 47 const size_t RUST_CONST_HELPER_PAGE_SIZE = PAGE_SIZE;