* [PATCH v5 1/4] kbuild: respect skip_gendwarfksyms in cmd_gensymtypes_S
2026-11-12 12:15 [PATCH v5 0/4] clean up EXPORT_SYMBOL_RUST_GPL Giuliano Procida
@ 2026-11-12 12:15 ` Giuliano Procida
2026-11-12 12:15 ` [PATCH v5 2/4] rust: convert exports.c to assembly Giuliano Procida
` (3 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Giuliano Procida @ 2026-11-12 12:15 UTC (permalink / raw)
To: Miguel Ojeda
Cc: Miguel Ojeda, rust-for-linux, Alice Ryhl, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Alexandre Courbot, Onur Özkan, linux-modules,
Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
Aaron Tomlin, Giuliano Procida
Commit 9c3681f9b9fd ("kbuild: Add gendwarfksyms as an alternative to
genksyms") added `skip_gendwarfksyms` handling to `cmd_gensymtypes_c` so
that `rust/exports.o` could skip symbol version generation, as CRCs are
computed directly from the defining Rust and helper object files.
`cmd_gensymtypes_S` is meant to mirror `cmd_gensymtypes_c`, as noted in
the comments above both definitions, but omitted the
`skip_gendwarfksyms` check. Respect `skip_gendwarfksyms` in
`cmd_gensymtypes_S` as well so that `rust/exports.c` can be converted to
assembly without `getasmexports` attempting to compile undeclared Rust
and helper symbols against `<asm/asm-prototypes.h>` when
`CONFIG_MODVERSIONS` is enabled.
Signed-off-by: Giuliano Procida <gprocida@google.com>
---
scripts/Makefile.build | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 6127feb970c6..873a9ed62a18 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -428,11 +428,11 @@ getasmexports = \
$(call getexportsymbols,EXPORT_SYMBOL(\1);) ; }
ifdef CONFIG_GENDWARFKSYMS
-cmd_gensymtypes_S = \
+cmd_gensymtypes_S = $(if $(skip_gendwarfksyms),, \
$(getasmexports) | \
$(CC) $(c_flags) -c -o $(@:.o=.gendwarfksyms.o) -xc -; \
$(call getexportsymbols,\1) | \
- $(gendwarfksyms) $(@:.o=.gendwarfksyms.o)
+ $(gendwarfksyms) $(@:.o=.gendwarfksyms.o))
else
cmd_gensymtypes_S = \
$(getasmexports) | \
--
2.56.0.567.gdb80ae8cd5-goog
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v5 2/4] rust: convert exports.c to assembly
2026-11-12 12:15 [PATCH v5 0/4] clean up EXPORT_SYMBOL_RUST_GPL Giuliano Procida
2026-11-12 12:15 ` [PATCH v5 1/4] kbuild: respect skip_gendwarfksyms in cmd_gensymtypes_S Giuliano Procida
@ 2026-11-12 12:15 ` Giuliano Procida
2026-11-12 14:20 ` Miguel Ojeda
2026-11-12 12:15 ` [PATCH v5 3/4] gpu: nova-core: convert nova_core_exports.c " Giuliano Procida
` (2 subsequent siblings)
4 siblings, 1 reply; 7+ messages in thread
From: Giuliano Procida @ 2026-11-12 12:15 UTC (permalink / raw)
To: Miguel Ojeda
Cc: Miguel Ojeda, rust-for-linux, Alice Ryhl, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Alexandre Courbot, Onur Özkan, linux-modules,
Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
Aaron Tomlin, Giuliano Procida
Previously, `rust/exports.c` defined `EXPORT_SYMBOL_RUST_GPL(sym)` with
`extern int sym;` so that it could invoke the C `EXPORT_SYMBOL_GPL(sym)`
macro, which requires `sym` to be a declared C identifier in scope for
`typeof(sym)`, `__ADDRESSABLE(sym)` and `__GENDWARFKSYMS_EXPORT(sym)`.
This caused the C compiler to emit DWARF debug information in
`rust/exports.o` describing every exported Rust and helper symbol,
functions and data alike, as a C `int` variable. Those bogus `int` DWARF
entries ended up in `vmlinux`, conflicting with the true DWARF types
emitted by `rustc` and confusing debuggers and ABI analysis tools.
Convert `rust/exports.c` to `rust/exports.S` and emit
`EXPORT_SYMBOL_GPL(sym)` directly. Under `__ASSEMBLY__`,
`<linux/export.h>` expands `EXPORT_SYMBOL_GPL(sym)` straight to
`___EXPORT_SYMBOL(sym, "GPL", ...)` without requiring symbol
declarations or emitting bogus DWARF entries, while also avoiding a C
compilation step.
Signed-off-by: Giuliano Procida <gprocida@google.com>
---
rust/Makefile | 2 +-
rust/{exports.c => exports.S} | 12 +++++-------
2 files changed, 6 insertions(+), 8 deletions(-)
rename rust/{exports.c => exports.S} (72%)
diff --git a/rust/Makefile b/rust/Makefile
index 0ac9ab28cc2b..2e5f5a84bb24 100644
--- a/rust/Makefile
+++ b/rust/Makefile
@@ -564,7 +564,7 @@ rust_exports = $(NM) -p --defined-only $(1) | awk '$$2~/(T|R|D|B)/ && $$3!~/__(p
quiet_cmd_exports = EXPORTS $@
cmd_exports = \
- $(call rust_exports,$<,"EXPORT_SYMBOL_RUST_GPL(%s);\n") > $@
+ $(call rust_exports,$<,"EXPORT_SYMBOL_GPL(%s)\n") > $@
$(obj)/exports_core_generated.h: $(obj)/core.o FORCE
$(call if_changed,exports)
diff --git a/rust/exports.c b/rust/exports.S
similarity index 72%
rename from rust/exports.c
rename to rust/exports.S
index 1b52460b0f4e..e1a6923081fa 100644
--- a/rust/exports.c
+++ b/rust/exports.S
@@ -1,11 +1,11 @@
-// SPDX-License-Identifier: GPL-2.0
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* A hack to export Rust symbols for loadable modules without having to redo
* the entire `include/linux/export.h` logic in Rust.
*
* This requires Rust's new/future `v0` mangling scheme because the default one
- * ("legacy") uses invalid characters for C identifiers (thus we cannot use the
- * `EXPORT_SYMBOL_*` macros).
+ * ("legacy") uses invalid characters for C identifiers (thus we could not use
+ * the `EXPORT_SYMBOL_*` macros).
*
* All symbols are exported as GPL-only to guarantee no GPL-only feature is
* accidentally exposed.
@@ -13,8 +13,6 @@
#include <linux/export.h>
-#define EXPORT_SYMBOL_RUST_GPL(sym) extern int sym; EXPORT_SYMBOL_GPL(sym)
-
#include "exports_core_generated.h"
#include "exports_bindings_generated.h"
#include "exports_kernel_generated.h"
@@ -23,7 +21,7 @@
#include "exports_helpers_generated.h"
#endif
-// For modules using `rust/build_error.rs`.
+/* For modules using `rust/build_error.rs`. */
#ifdef CONFIG_RUST_BUILD_ASSERT_ALLOW
-EXPORT_SYMBOL_RUST_GPL(rust_build_error);
+EXPORT_SYMBOL_GPL(rust_build_error)
#endif
--
2.56.0.567.gdb80ae8cd5-goog
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH v5 2/4] rust: convert exports.c to assembly
2026-11-12 12:15 ` [PATCH v5 2/4] rust: convert exports.c to assembly Giuliano Procida
@ 2026-11-12 14:20 ` Miguel Ojeda
0 siblings, 0 replies; 7+ messages in thread
From: Miguel Ojeda @ 2026-11-12 14:20 UTC (permalink / raw)
To: Giuliano Procida, Gary Guo
Cc: Miguel Ojeda, rust-for-linux, Alice Ryhl, Boqun Feng,
Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Alexandre Courbot, Onur Özkan, linux-modules,
Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
Aaron Tomlin
On Thu, Nov 12, 2026 at 1:15 PM Giuliano Procida <gprocida@google.com> wrote:
>
> Previously, `rust/exports.c` defined `EXPORT_SYMBOL_RUST_GPL(sym)` with
> `extern int sym;` so that it could invoke the C `EXPORT_SYMBOL_GPL(sym)`
> macro, which requires `sym` to be a declared C identifier in scope for
> `typeof(sym)`, `__ADDRESSABLE(sym)` and `__GENDWARFKSYMS_EXPORT(sym)`.
>
> This caused the C compiler to emit DWARF debug information in
> `rust/exports.o` describing every exported Rust and helper symbol,
> functions and data alike, as a C `int` variable. Those bogus `int` DWARF
> entries ended up in `vmlinux`, conflicting with the true DWARF types
> emitted by `rustc` and confusing debuggers and ABI analysis tools.
>
> Convert `rust/exports.c` to `rust/exports.S` and emit
> `EXPORT_SYMBOL_GPL(sym)` directly. Under `__ASSEMBLY__`,
> `<linux/export.h>` expands `EXPORT_SYMBOL_GPL(sym)` straight to
> `___EXPORT_SYMBOL(sym, "GPL", ...)` without requiring symbol
> declarations or emitting bogus DWARF entries, while also avoiding a C
> compilation step.
>
> Signed-off-by: Giuliano Procida <gprocida@google.com>
I guess Suggested-by: Gary?
Cheers,
Miguel
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v5 3/4] gpu: nova-core: convert nova_core_exports.c to assembly
2026-11-12 12:15 [PATCH v5 0/4] clean up EXPORT_SYMBOL_RUST_GPL Giuliano Procida
2026-11-12 12:15 ` [PATCH v5 1/4] kbuild: respect skip_gendwarfksyms in cmd_gensymtypes_S Giuliano Procida
2026-11-12 12:15 ` [PATCH v5 2/4] rust: convert exports.c to assembly Giuliano Procida
@ 2026-11-12 12:15 ` Giuliano Procida
2026-11-12 12:15 ` [PATCH v5 4/4] scripts/sbom: update rust export macro in nm parser test Giuliano Procida
2026-11-12 12:21 ` [PATCH v5 0/4] clean up EXPORT_SYMBOL_RUST_GPL Giuliano Procida
4 siblings, 0 replies; 7+ messages in thread
From: Giuliano Procida @ 2026-11-12 12:15 UTC (permalink / raw)
To: Miguel Ojeda
Cc: Miguel Ojeda, rust-for-linux, Alice Ryhl, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Alexandre Courbot, Onur Özkan, linux-modules,
Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
Aaron Tomlin, Giuliano Procida
Like `rust/exports.c` before it, `nova_core_exports.c` defined
`EXPORT_SYMBOL_RUST_GPL(sym)` with `extern int sym;` so that it could
invoke the C `EXPORT_SYMBOL_GPL(sym)` macro. This emitted bogus `int`
DWARF debug information in `nova_core_exports.o` and `nova-core.ko` for
every exported Rust symbol, conflicting with the DWARF types emitted by
`rustc`.
Convert `nova_core_exports.c` to `nova_core_exports.S`, emit
`EXPORT_SYMBOL_GPL(sym)` directly in `exports_nova_core_generated.h`
and switch the include path and `MODVERSIONS` symbol-versioning hook in
`drivers/gpu/Makefile` from the `.c` rules (`CFLAGS_*` /
`cmd_gensymtypes_c`) to the `.S` rules (`AFLAGS_*` /
`cmd_gensymtypes_S`).
Also set `private cmd_gen_symversions_S = $(call gen_symversions,S)`
under `CONFIG_MODVERSIONS`. Kbuild normally defines
`cmd_gen_symversions_S` only under `CONFIG_ASM_MODVERSIONS` (which
requires `<asm/asm-prototypes.h>` and is not selected on 32-bit `arm`),
whereas `nova_core_exports.o` generates CRCs directly from `nova_core.o`
via `gendwarfksyms` without needing `<asm/asm-prototypes.h>`. Although
`NOVA_CORE` currently depends on `64BIT`, keeping the `MODVERSIONS`
override self-contained avoids an implicit `CONFIG_ASM_MODVERSIONS`
dependency if `64BIT` is ever relaxed or the pattern is reused by
another Rust module.
This removes the last definition and use of `EXPORT_SYMBOL_RUST_GPL`.
Signed-off-by: Giuliano Procida <gprocida@google.com>
---
drivers/gpu/Makefile | 11 ++++++-----
.../{nova_core_exports.c => nova_core_exports.S} | 8 +++-----
2 files changed, 9 insertions(+), 10 deletions(-)
rename drivers/gpu/nova-core/{nova_core_exports.c => nova_core_exports.S} (62%)
diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile
index e372fc02139f..49205525d2a5 100644
--- a/drivers/gpu/Makefile
+++ b/drivers/gpu/Makefile
@@ -36,7 +36,7 @@ rust_needed_exports = \
quiet_cmd_exports = EXPORTS $@
cmd_exports = \
- $(call rust_needed_exports,$<,$(nova-core-export-deps),EXPORT_SYMBOL_RUST_GPL(%s);\n) > $@
+ $(call rust_needed_exports,$<,$(nova-core-export-deps),EXPORT_SYMBOL_GPL(%s)\n) > $@
$(obj)/nova-core/exports_nova_core_generated.h: $(obj)/nova-core/nova_core.o $(nova-core-export-deps) FORCE
$(call if_changed,exports)
@@ -44,12 +44,13 @@ $(obj)/nova-core/exports_nova_core_generated.h: $(obj)/nova-core/nova_core.o $(n
targets += nova-core/exports_nova_core_generated.h
$(obj)/nova-core/nova_core_exports.o: $(obj)/nova-core/exports_nova_core_generated.h
-CFLAGS_nova-core/nova_core_exports.o := -I $(objtree)/$(obj)/nova-core
+AFLAGS_nova-core/nova_core_exports.o := -I $(objtree)/$(obj)/nova-core
ifdef CONFIG_MODVERSIONS
-# The C export shim declares Rust symbols as `extern int`, so reuse its export
-# list but generate symbol CRCs from the Rust object instead of the shim's DWARF.
-$(obj)/nova-core/nova_core_exports.o: private cmd_gensymtypes_c = \
+# The assembly export shim has no DWARF type info for Rust symbols, so reuse
+# its export list but generate symbol CRCs from the Rust object.
+$(obj)/nova-core/nova_core_exports.o: private cmd_gen_symversions_S = $(call gen_symversions,S)
+$(obj)/nova-core/nova_core_exports.o: private cmd_gensymtypes_S = \
$(call getexportsymbols,\1) | \
$(objtree)/scripts/gendwarfksyms/gendwarfksyms \
$(if $(KBUILD_GENDWARFKSYMS_STABLE), --stable) \
diff --git a/drivers/gpu/nova-core/nova_core_exports.c b/drivers/gpu/nova-core/nova_core_exports.S
similarity index 62%
rename from drivers/gpu/nova-core/nova_core_exports.c
rename to drivers/gpu/nova-core/nova_core_exports.S
index 6e80ca9792ee..90a9f709ed38 100644
--- a/drivers/gpu/nova-core/nova_core_exports.c
+++ b/drivers/gpu/nova-core/nova_core_exports.S
@@ -1,7 +1,7 @@
-// SPDX-License-Identifier: GPL-2.0
-// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
-
+/* SPDX-License-Identifier: GPL-2.0 */
/*
+ * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+ *
* Exports Rust symbols from the `nova_core` crate for use by dependent modules.
*
* This is a workaround until the build system supports Rust cross-module
@@ -10,6 +10,4 @@
#include <linux/export.h>
-#define EXPORT_SYMBOL_RUST_GPL(sym) extern int sym; EXPORT_SYMBOL_GPL(sym)
-
#include "exports_nova_core_generated.h"
--
2.56.0.567.gdb80ae8cd5-goog
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v5 4/4] scripts/sbom: update rust export macro in nm parser test
2026-11-12 12:15 [PATCH v5 0/4] clean up EXPORT_SYMBOL_RUST_GPL Giuliano Procida
` (2 preceding siblings ...)
2026-11-12 12:15 ` [PATCH v5 3/4] gpu: nova-core: convert nova_core_exports.c " Giuliano Procida
@ 2026-11-12 12:15 ` Giuliano Procida
2026-11-12 12:21 ` [PATCH v5 0/4] clean up EXPORT_SYMBOL_RUST_GPL Giuliano Procida
4 siblings, 0 replies; 7+ messages in thread
From: Giuliano Procida @ 2026-11-12 12:15 UTC (permalink / raw)
To: Miguel Ojeda
Cc: Miguel Ojeda, rust-for-linux, Alice Ryhl, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Alexandre Courbot, Onur Özkan, linux-modules,
Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
Aaron Tomlin, Giuliano Procida
Update the sample `rust/Makefile` export generation command in `test_nm`
to match the conversion from `EXPORT_SYMBOL_RUST_GPL(%s);` to
`EXPORT_SYMBOL_GPL(%s)`.
Signed-off-by: Giuliano Procida <gprocida@google.com>
---
scripts/sbom/tests/cmd_graph/test_savedcmd_parser.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/sbom/tests/cmd_graph/test_savedcmd_parser.py b/scripts/sbom/tests/cmd_graph/test_savedcmd_parser.py
index 93787a1cd156..4f7ee1142cd8 100644
--- a/scripts/sbom/tests/cmd_graph/test_savedcmd_parser.py
+++ b/scripts/sbom/tests/cmd_graph/test_savedcmd_parser.py
@@ -214,7 +214,7 @@ class TestSavedCmdParser(unittest.TestCase):
# nm command tests
def test_nm(self):
- cmd = """llvm-nm -p --defined-only rust/core.o | awk '$$2~/(T|R|D|B)/ && $$3!~/__(pfx|cfi|odr_asan)/ { printf "EXPORT_SYMBOL_RUST_GPL(%s);\n",$$3 }' > rust/exports_core_generated.h"""
+ cmd = """llvm-nm -p --defined-only rust/core.o | awk '$$2~/(T|R|D|B)/ && $$3!~/__(pfx|cfi|odr_asan)/ { printf "EXPORT_SYMBOL_GPL(%s)\n",$$3 }' > rust/exports_core_generated.h"""
expected = "rust/core.o"
self._assert_parsing(cmd, expected)
--
2.56.0.567.gdb80ae8cd5-goog
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH v5 0/4] clean up EXPORT_SYMBOL_RUST_GPL
2026-11-12 12:15 [PATCH v5 0/4] clean up EXPORT_SYMBOL_RUST_GPL Giuliano Procida
` (3 preceding siblings ...)
2026-11-12 12:15 ` [PATCH v5 4/4] scripts/sbom: update rust export macro in nm parser test Giuliano Procida
@ 2026-11-12 12:21 ` Giuliano Procida
4 siblings, 0 replies; 7+ messages in thread
From: Giuliano Procida @ 2026-11-12 12:21 UTC (permalink / raw)
To: Miguel Ojeda
Cc: Miguel Ojeda, rust-for-linux, Alice Ryhl, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
Alexandre Courbot, Onur Özkan, linux-modules,
Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
Aaron Tomlin
Oops.
On Thu, 12 Nov 2026 at 12:15, Giuliano Procida <gprocida@google.com> wrote:
>
> This is a complete rework of the previous series to switch to assembly
> as suggested by Gary Guo <gary@garyguo.net> in a review comment.
>
> The first change in this series is a miniscule safety fix that will be
> obsoleted once the Nova driver Rust symbol handling is itself cleaned
> up.
Sorry, that's a lie. This is the prep work for the next two changes.
The tiny safety fix relating to `arm` is in the nova-core change itself.
> The second and third changes switch symbol export to assembly.
>
> The fourth change tweaks a related test file.
>
> Giuliano Procida (4):
> kbuild: respect skip_gendwarfksyms in cmd_gensymtypes_S
> rust: convert exports.c to assembly
> gpu: nova-core: convert nova_core_exports.c to assembly
> scripts/sbom: update rust export macro in nm parser test
>
> drivers/gpu/Makefile | 11 ++++++-----
> .../{nova_core_exports.c => nova_core_exports.S} | 8 +++-----
> rust/Makefile | 2 +-
> rust/{exports.c => exports.S} | 12 +++++-------
> scripts/Makefile.build | 4 ++--
> scripts/sbom/tests/cmd_graph/test_savedcmd_parser.py | 2 +-
> 6 files changed, 18 insertions(+), 21 deletions(-)
> rename drivers/gpu/nova-core/{nova_core_exports.c => nova_core_exports.S} (62%)
> rename rust/{exports.c => exports.S} (72%)
>
> --
> 2.56.0.567.gdb80ae8cd5-goog
>
^ permalink raw reply [flat|nested] 7+ messages in thread