* [PATCH v4 0/6] gpu: drm: nova: enable calling into nova-core
@ 2026-06-05 8:31 Alexandre Courbot
2026-06-05 8:31 ` [PATCH v4 1/6] rust: inline some init methods Alexandre Courbot
` (6 more replies)
0 siblings, 7 replies; 12+ messages in thread
From: Alexandre Courbot @ 2026-06-05 8:31 UTC (permalink / raw)
To: Miguel Ojeda, Nicolas Schier, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard
Cc: John Hubbard, Alistair Popple, Timur Tabi, Zhi Wang,
Eliot Courtney, linux-kbuild, linux-kernel, rust-for-linux,
nova-gpu, dri-devel, Alexandre Courbot
`nova-drm` is scheduled to expose a user-space API to receive IOCTLs
from user-mode drivers, and to call into `nova-core` to perform the
actual work. We are about to reach the state where we need the ability
to call into `nova-core`, but the current Rust build system does not
support this, and the solution will likely take at least a couple of
cycles to be merged.
In the meantime, this series introduces a Nova-local workaround for
`nova-drm` to call into `nova-core`. It generates the `nova-core`
metadata that `nova-drm` can use to resolve references at build-time,
and also builds a list of exported symbols for symbol resolution when
modules are loaded.
Since Rust symbols are long, this work ran into the limits on symbol
sizes `modpost` can handle. Thus, the first patch instructs the compiler
to inline initializers for some Rust basic types to avoid those long
symbol names when symbols from `nova-core` are exported. Interestingly,
this also results in a smaller nova-core binary size [1].
The rest of the patches enable inter-module calls from nova-drm to
nova-core.
This series is based on `drm-rust-next`. The current revision includes
the feedback received on v3. In particular, moving everything to
`drivers/gpu/Makefile` simplifies things considerably, and I have tried
to align more with what is done in `rust/Makefile`.
[1] https://lore.kernel.org/all/DIN76NTFEU1N.1RT6G4IFD62RG@nvidia.com/
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
Changes in v4:
- Build nova-core and nova-drm from `drivers/gpu/Makefile`.
- Emit nova-core's crate metadata as a side-effect of its normal object
build.
- Align more closely with the rules of `rust/Makefile`.
- Add `.gitignore` entries for generated files.
- Inline a few more Rust methods per Sashiko's recommendation.
- Drop a few `Reviewed-by`s as the implementation has changed
significantly.
- Link to v3: https://patch.msgid.link/20260530-nova-exports-v3-0-1202aa339ef7@nvidia.com
Changes in v3:
- Drop the modpost overflow detection patch as it is to be merged
through the KBuild tree.
- Drop obsolete (and actually unnecessary) changes to `pin_init`.
- Do not inline methods returning `impl PinInit` as they cannot
contribute to the long symbol names problem.
- Use `#[inline]` instead of `#[inline(always)]` for methods that could
create excessively long symbols.
- Link to v2: https://patch.msgid.link/20260527-nova-exports-v2-0-06de4c556d55@nvidia.com
Changes in v2:
- Rebase on top of HRT v5.
- Inline some `pin_init` and Rust basic types methods to avoid long
symbol names and optimize code.
- Print truncating modpost symbols and abort upon meeting them.
- Drop increase of `buf_printf`'s buffer.
- Drop obsolete nova-core renaming patch.
- Link to v1: https://patch.msgid.link/20260430-nova-exports-v1-0-7ca31664e983@nvidia.com
---
Alexandre Courbot (6):
rust: inline some init methods
gpu: build nova-core and nova-drm from drivers/gpu/Makefile
gpu: nova-core: export Rust symbols for nova-drm
gpu: nova-core: emit Rust metadata for nova-drm
gpu: drm: nova: build after nova-core and use its symbols
[POC] gpu: drm: nova: demonstrate interaction with nova-core
drivers/gpu/Makefile | 36 ++++++++++++++++++-
drivers/gpu/drm/Makefile | 2 +-
drivers/gpu/drm/nova/Makefile | 4 +--
drivers/gpu/drm/nova/driver.rs | 9 ++++-
drivers/gpu/nova-core/.gitignore | 2 ++
drivers/gpu/nova-core/Makefile | 4 +--
drivers/gpu/nova-core/driver.rs | 59 +++++++++++++++++++++++--------
drivers/gpu/nova-core/gpu.rs | 9 +++--
drivers/gpu/nova-core/gsp/hal.rs | 2 +-
drivers/gpu/nova-core/nova_core.rs | 4 +--
drivers/gpu/nova-core/nova_core_exports.c | 15 ++++++++
rust/kernel/alloc/kbox.rs | 2 ++
rust/kernel/init.rs | 2 ++
rust/kernel/sync/arc.rs | 4 +++
14 files changed, 125 insertions(+), 29 deletions(-)
---
base-commit: fea3a2dd7d3fc1936211ced5f84420e610435730
change-id: 20260430-nova-exports-502f996c5aab
Best regards,
--
Alexandre Courbot <acourbot@nvidia.com>
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v4 1/6] rust: inline some init methods
2026-06-05 8:31 [PATCH v4 0/6] gpu: drm: nova: enable calling into nova-core Alexandre Courbot
@ 2026-06-05 8:31 ` Alexandre Courbot
2026-06-08 7:05 ` Miguel Ojeda
2026-06-05 8:31 ` [PATCH v4 2/6] gpu: build nova-core and nova-drm from drivers/gpu/Makefile Alexandre Courbot
` (5 subsequent siblings)
6 siblings, 1 reply; 12+ messages in thread
From: Alexandre Courbot @ 2026-06-05 8:31 UTC (permalink / raw)
To: Miguel Ojeda, Nicolas Schier, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard
Cc: John Hubbard, Alistair Popple, Timur Tabi, Zhi Wang,
Eliot Courtney, linux-kbuild, linux-kernel, rust-for-linux,
nova-gpu, dri-devel, Alexandre Courbot
These methods should be inlined for optimization reasons. Failure to do
so can also produce symbol names larger than what `modpost` or `objtool`
can handle.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
---
rust/kernel/alloc/kbox.rs | 2 ++
rust/kernel/init.rs | 2 ++
rust/kernel/sync/arc.rs | 4 ++++
3 files changed, 8 insertions(+)
diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs
index 2f8c16473c2c..1264a8118aca 100644
--- a/rust/kernel/alloc/kbox.rs
+++ b/rust/kernel/alloc/kbox.rs
@@ -433,6 +433,7 @@ impl<T, A> InPlaceWrite<T> for Box<MaybeUninit<T>, A>
{
type Initialized = Box<T, A>;
+ #[inline]
fn write_init<E>(mut self, init: impl Init<T, E>) -> Result<Self::Initialized, E> {
let slot = self.as_mut_ptr();
// SAFETY: When init errors/panics, slot will get deallocated but not dropped,
@@ -442,6 +443,7 @@ fn write_init<E>(mut self, init: impl Init<T, E>) -> Result<Self::Initialized, E
Ok(unsafe { Box::assume_init(self) })
}
+ #[inline]
fn write_pin_init<E>(mut self, init: impl PinInit<T, E>) -> Result<Pin<Self::Initialized>, E> {
let slot = self.as_mut_ptr();
// SAFETY: When init errors/panics, slot will get deallocated but not dropped,
diff --git a/rust/kernel/init.rs b/rust/kernel/init.rs
index 7a0d4559d7b5..05a12e869a57 100644
--- a/rust/kernel/init.rs
+++ b/rust/kernel/init.rs
@@ -151,6 +151,7 @@ fn try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Self::Pinne
/// type.
///
/// If `T: !Unpin` it will not be able to move afterwards.
+ #[inline]
fn pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> error::Result<Self::PinnedSelf>
where
Error: From<E>,
@@ -168,6 +169,7 @@ fn try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E>
E: From<AllocError>;
/// Use the given initializer to in-place initialize a `T`.
+ #[inline]
fn init<E>(init: impl Init<T, E>, flags: Flags) -> error::Result<Self>
where
Error: From<E>,
diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs
index 18d6c0d62ce0..feca07e8d13d 100644
--- a/rust/kernel/sync/arc.rs
+++ b/rust/kernel/sync/arc.rs
@@ -712,6 +712,7 @@ fn try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E>
impl<T> InPlaceWrite<T> for UniqueArc<MaybeUninit<T>> {
type Initialized = UniqueArc<T>;
+ #[inline]
fn write_init<E>(mut self, init: impl Init<T, E>) -> Result<Self::Initialized, E> {
let slot = self.as_mut_ptr();
// SAFETY: When init errors/panics, slot will get deallocated but not dropped,
@@ -721,6 +722,7 @@ fn write_init<E>(mut self, init: impl Init<T, E>) -> Result<Self::Initialized, E
Ok(unsafe { self.assume_init() })
}
+ #[inline]
fn write_pin_init<E>(mut self, init: impl PinInit<T, E>) -> Result<Pin<Self::Initialized>, E> {
let slot = self.as_mut_ptr();
// SAFETY: When init errors/panics, slot will get deallocated but not dropped,
@@ -782,6 +784,7 @@ pub unsafe fn assume_init(self) -> UniqueArc<T> {
}
/// Initialize `self` using the given initializer.
+ #[inline]
pub fn init_with<E>(mut self, init: impl Init<T, E>) -> core::result::Result<UniqueArc<T>, E> {
// SAFETY: The supplied pointer is valid for initialization.
match unsafe { init.__init(self.as_mut_ptr()) } {
@@ -792,6 +795,7 @@ pub fn init_with<E>(mut self, init: impl Init<T, E>) -> core::result::Result<Uni
}
/// Pin-initialize `self` using the given pin-initializer.
+ #[inline]
pub fn pin_init_with<E>(
mut self,
init: impl PinInit<T, E>,
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 2/6] gpu: build nova-core and nova-drm from drivers/gpu/Makefile
2026-06-05 8:31 [PATCH v4 0/6] gpu: drm: nova: enable calling into nova-core Alexandre Courbot
2026-06-05 8:31 ` [PATCH v4 1/6] rust: inline some init methods Alexandre Courbot
@ 2026-06-05 8:31 ` Alexandre Courbot
2026-06-05 8:31 ` [PATCH v4 3/6] gpu: nova-core: export Rust symbols for nova-drm Alexandre Courbot
` (4 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Alexandre Courbot @ 2026-06-05 8:31 UTC (permalink / raw)
To: Miguel Ojeda, Nicolas Schier, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard
Cc: John Hubbard, Alistair Popple, Timur Tabi, Zhi Wang,
Eliot Courtney, linux-kbuild, linux-kernel, rust-for-linux,
nova-gpu, dri-devel, Alexandre Courbot
A dependency between nova-core and nova-drm is about to be introduced,
which requires nova-core to be built first. As this is not easily doable
from separate directories, move both build targets to the first common
parent, `drivers/gpu/Makefile`.
Suggested-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
drivers/gpu/Makefile | 12 +++++++++++-
drivers/gpu/drm/Makefile | 2 +-
drivers/gpu/drm/nova/Makefile | 4 +---
drivers/gpu/nova-core/Makefile | 4 +---
4 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile
index b4e5e338efa2..45e0941324fb 100644
--- a/drivers/gpu/Makefile
+++ b/drivers/gpu/Makefile
@@ -7,4 +7,14 @@ obj-$(CONFIG_GPU_BUDDY) += buddy.o
obj-y += host1x/ drm/ vga/ tests/
obj-$(CONFIG_IMX_IPUV3_CORE) += ipu-v3/
obj-$(CONFIG_TRACE_GPU_MEM) += trace/
-obj-$(CONFIG_NOVA_CORE) += nova-core/
+
+# nova-core and nova-drm are built from this Makefile so nova-drm's dependency
+# on nova-core can be expressed as a plain Make prerequisite rather than a
+# recursive sub-make. This is a temporary workaround until the Rust build
+# system supports cross-crate dependencies natively.
+
+obj-$(CONFIG_NOVA_CORE) += nova-core.o
+nova-core-y := nova-core/nova_core.o
+
+obj-$(CONFIG_DRM_NOVA) += nova-drm.o
+nova-drm-y := drm/nova/nova.o
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index e97faabcd783..e635fcffd379 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -186,7 +186,7 @@ obj-$(CONFIG_DRM_VMWGFX)+= vmwgfx/
obj-$(CONFIG_DRM_VGEM) += vgem/
obj-$(CONFIG_DRM_VKMS) += vkms/
obj-$(CONFIG_DRM_NOUVEAU) +=nouveau/
-obj-$(CONFIG_DRM_NOVA) += nova/
+# nova-drm is built from drivers/gpu/Makefile together with nova-core.
obj-$(CONFIG_DRM_EXYNOS) +=exynos/
obj-$(CONFIG_DRM_ROCKCHIP) +=rockchip/
obj-$(CONFIG_DRM_GMA500) += gma500/
diff --git a/drivers/gpu/drm/nova/Makefile b/drivers/gpu/drm/nova/Makefile
index f8527b2b7b4a..b9fad3956358 100644
--- a/drivers/gpu/drm/nova/Makefile
+++ b/drivers/gpu/drm/nova/Makefile
@@ -1,4 +1,2 @@
# SPDX-License-Identifier: GPL-2.0
-
-obj-$(CONFIG_DRM_NOVA) += nova-drm.o
-nova-drm-y := nova.o
+# nova-drm is built from drivers/gpu/Makefile.
diff --git a/drivers/gpu/nova-core/Makefile b/drivers/gpu/nova-core/Makefile
index 4ae544f808f4..4c15729704a1 100644
--- a/drivers/gpu/nova-core/Makefile
+++ b/drivers/gpu/nova-core/Makefile
@@ -1,4 +1,2 @@
# SPDX-License-Identifier: GPL-2.0
-
-obj-$(CONFIG_NOVA_CORE) += nova-core.o
-nova-core-y := nova_core.o
+# nova-core is built from drivers/gpu/Makefile.
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 3/6] gpu: nova-core: export Rust symbols for nova-drm
2026-06-05 8:31 [PATCH v4 0/6] gpu: drm: nova: enable calling into nova-core Alexandre Courbot
2026-06-05 8:31 ` [PATCH v4 1/6] rust: inline some init methods Alexandre Courbot
2026-06-05 8:31 ` [PATCH v4 2/6] gpu: build nova-core and nova-drm from drivers/gpu/Makefile Alexandre Courbot
@ 2026-06-05 8:31 ` Alexandre Courbot
2026-06-05 8:45 ` sashiko-bot
2026-06-05 8:31 ` [PATCH v4 4/6] gpu: nova-core: emit Rust metadata " Alexandre Courbot
` (3 subsequent siblings)
6 siblings, 1 reply; 12+ messages in thread
From: Alexandre Courbot @ 2026-06-05 8:31 UTC (permalink / raw)
To: Miguel Ojeda, Nicolas Schier, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard
Cc: John Hubbard, Alistair Popple, Timur Tabi, Zhi Wang,
Eliot Courtney, linux-kbuild, linux-kernel, rust-for-linux,
nova-gpu, dri-devel, Alexandre Courbot
Export nova-core's Rust symbols so nova-drm can resolve references to it
when loaded as a module.
This is done by generating declarations and EXPORT_SYMBOL_RUST_GPL()
calls for Rust global symbols using nm and compiling them into the
module as nova_core_exports.o.
This is intended to be a workaround until the build system supports Rust
cross-crate dependencies natively.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
drivers/gpu/Makefile | 18 +++++++++++++++++-
drivers/gpu/nova-core/.gitignore | 1 +
drivers/gpu/nova-core/nova_core_exports.c | 15 +++++++++++++++
3 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile
index 45e0941324fb..2f9c6101e21c 100644
--- a/drivers/gpu/Makefile
+++ b/drivers/gpu/Makefile
@@ -14,7 +14,23 @@ obj-$(CONFIG_TRACE_GPU_MEM) += trace/
# system supports cross-crate dependencies natively.
obj-$(CONFIG_NOVA_CORE) += nova-core.o
-nova-core-y := nova-core/nova_core.o
+nova-core-y := nova-core/nova_core.o nova-core/nova_core_exports.o
obj-$(CONFIG_DRM_NOVA) += nova-drm.o
nova-drm-y := drm/nova/nova.o
+
+# Slightly adapted from rust/Makefile's rust_exports, restricted to Rust v0
+# mangled symbols.
+rust_exports = $(NM) -p --defined-only $(1) | awk '$$2~/(T|R|D|B)/ && $$3~/^_R/ && $$3!~/_(init|cleanup)_module$$/ && $$3!~/__(pfx|cfi|odr_asan)/ { printf $(2),$$3 }'
+
+quiet_cmd_exports = EXPORTS $@
+ cmd_exports = \
+ $(call rust_exports,$<,"EXPORT_SYMBOL_RUST_GPL(%s);\n") > $@
+
+$(obj)/nova-core/exports_nova_core_generated.h: $(obj)/nova-core/nova_core.o FORCE
+ $(call if_changed,exports)
+
+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
diff --git a/drivers/gpu/nova-core/.gitignore b/drivers/gpu/nova-core/.gitignore
new file mode 100644
index 000000000000..7cc8318c76b1
--- /dev/null
+++ b/drivers/gpu/nova-core/.gitignore
@@ -0,0 +1 @@
+exports_nova_core_generated.h
diff --git a/drivers/gpu/nova-core/nova_core_exports.c b/drivers/gpu/nova-core/nova_core_exports.c
new file mode 100644
index 000000000000..6e80ca9792ee
--- /dev/null
+++ b/drivers/gpu/nova-core/nova_core_exports.c
@@ -0,0 +1,15 @@
+// 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
+ * dependencies natively.
+ */
+
+#include <linux/export.h>
+
+#define EXPORT_SYMBOL_RUST_GPL(sym) extern int sym; EXPORT_SYMBOL_GPL(sym)
+
+#include "exports_nova_core_generated.h"
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 4/6] gpu: nova-core: emit Rust metadata for nova-drm
2026-06-05 8:31 [PATCH v4 0/6] gpu: drm: nova: enable calling into nova-core Alexandre Courbot
` (2 preceding siblings ...)
2026-06-05 8:31 ` [PATCH v4 3/6] gpu: nova-core: export Rust symbols for nova-drm Alexandre Courbot
@ 2026-06-05 8:31 ` Alexandre Courbot
2026-06-05 8:36 ` Miguel Ojeda
2026-06-05 8:31 ` [PATCH v4 5/6] gpu: drm: nova: build after nova-core and use its symbols Alexandre Courbot
` (2 subsequent siblings)
6 siblings, 1 reply; 12+ messages in thread
From: Alexandre Courbot @ 2026-06-05 8:31 UTC (permalink / raw)
To: Miguel Ojeda, Nicolas Schier, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard
Cc: John Hubbard, Alistair Popple, Timur Tabi, Zhi Wang,
Eliot Courtney, linux-kbuild, linux-kernel, rust-for-linux,
nova-gpu, dri-devel, Alexandre Courbot
Emit nova-core's crate metadata (libnova_core.rmeta) so that nova-drm
can import nova-core's types and functions at compile time.
This is intended to be a workaround until the build system supports Rust
cross-crate dependencies natively.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
drivers/gpu/Makefile | 4 ++++
drivers/gpu/nova-core/.gitignore | 1 +
2 files changed, 5 insertions(+)
diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile
index 2f9c6101e21c..164e704bc741 100644
--- a/drivers/gpu/Makefile
+++ b/drivers/gpu/Makefile
@@ -34,3 +34,7 @@ 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
+
+# Output nova-core's crate metadata for use by nova-drm at compile time.
+RUSTFLAGS_nova-core/nova_core.o += \
+ --emit=metadata=$(objtree)/$(obj)/nova-core/libnova_core.rmeta
diff --git a/drivers/gpu/nova-core/.gitignore b/drivers/gpu/nova-core/.gitignore
index 7cc8318c76b1..bac774beba3b 100644
--- a/drivers/gpu/nova-core/.gitignore
+++ b/drivers/gpu/nova-core/.gitignore
@@ -1 +1,2 @@
exports_nova_core_generated.h
+libnova_core.rmeta
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 5/6] gpu: drm: nova: build after nova-core and use its symbols
2026-06-05 8:31 [PATCH v4 0/6] gpu: drm: nova: enable calling into nova-core Alexandre Courbot
` (3 preceding siblings ...)
2026-06-05 8:31 ` [PATCH v4 4/6] gpu: nova-core: emit Rust metadata " Alexandre Courbot
@ 2026-06-05 8:31 ` Alexandre Courbot
2026-06-05 8:31 ` [PATCH POC v4 6/6] gpu: drm: nova: demonstrate interaction with nova-core Alexandre Courbot
2026-06-05 8:48 ` [PATCH v4 0/6] gpu: drm: nova: enable calling into nova-core Miguel Ojeda
6 siblings, 0 replies; 12+ messages in thread
From: Alexandre Courbot @ 2026-06-05 8:31 UTC (permalink / raw)
To: Miguel Ojeda, Nicolas Schier, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard
Cc: John Hubbard, Alistair Popple, Timur Tabi, Zhi Wang,
Eliot Courtney, linux-kbuild, linux-kernel, rust-for-linux,
nova-gpu, dri-devel, Alexandre Courbot
Make nova-core a build dependency of nova-drm, so its crate metadata is
available and up-to-date when the latter is built.
This is intended to be a workaround until the build system supports Rust
cross-crate dependencies natively.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
drivers/gpu/Makefile | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile
index 164e704bc741..a996047be69a 100644
--- a/drivers/gpu/Makefile
+++ b/drivers/gpu/Makefile
@@ -38,3 +38,7 @@ CFLAGS_nova-core/nova_core_exports.o := -I $(objtree)/$(obj)/nova-core
# Output nova-core's crate metadata for use by nova-drm at compile time.
RUSTFLAGS_nova-core/nova_core.o += \
--emit=metadata=$(objtree)/$(obj)/nova-core/libnova_core.rmeta
+
+# Allow nova-drm to import nova-core's types.
+$(obj)/drm/nova/nova.o: $(obj)/nova-core/nova_core.o
+RUSTFLAGS_drm/nova/nova.o := -L $(objtree)/$(obj)/nova-core --extern nova_core
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH POC v4 6/6] gpu: drm: nova: demonstrate interaction with nova-core
2026-06-05 8:31 [PATCH v4 0/6] gpu: drm: nova: enable calling into nova-core Alexandre Courbot
` (4 preceding siblings ...)
2026-06-05 8:31 ` [PATCH v4 5/6] gpu: drm: nova: build after nova-core and use its symbols Alexandre Courbot
@ 2026-06-05 8:31 ` Alexandre Courbot
2026-06-05 8:45 ` sashiko-bot
2026-06-05 8:48 ` [PATCH v4 0/6] gpu: drm: nova: enable calling into nova-core Miguel Ojeda
6 siblings, 1 reply; 12+ messages in thread
From: Alexandre Courbot @ 2026-06-05 8:31 UTC (permalink / raw)
To: Miguel Ojeda, Nicolas Schier, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard
Cc: John Hubbard, Alistair Popple, Timur Tabi, Zhi Wang,
Eliot Courtney, linux-kbuild, linux-kernel, rust-for-linux,
nova-gpu, dri-devel, Alexandre Courbot
Export a few items from nova-core and use them from nova-drm in order to
print the chipset of the GPU being probed.
Some documentation items are added to make Clippy happy.
This is only meant for demonstration purposes, and won't be merged.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
drivers/gpu/drm/nova/driver.rs | 9 +++++-
drivers/gpu/nova-core/driver.rs | 59 +++++++++++++++++++++++++++++---------
drivers/gpu/nova-core/gpu.rs | 9 ++++--
drivers/gpu/nova-core/gsp/hal.rs | 2 +-
drivers/gpu/nova-core/nova_core.rs | 4 +--
5 files changed, 62 insertions(+), 21 deletions(-)
diff --git a/drivers/gpu/drm/nova/driver.rs b/drivers/gpu/drm/nova/driver.rs
index 48933d86ddda..de1ad7032b6c 100644
--- a/drivers/gpu/drm/nova/driver.rs
+++ b/drivers/gpu/drm/nova/driver.rs
@@ -9,12 +9,15 @@
ioctl, //
},
prelude::*,
- sync::aref::ARef, //
+ sync::aref::ARef,
+ types::ForLt, //
};
use crate::file::File;
use crate::gem::NovaObject;
+use nova_core::driver::AuxData;
+
pub(crate) struct NovaDriver;
pub(crate) struct Nova {
@@ -60,6 +63,10 @@ fn probe<'bound>(
adev: &'bound auxiliary::Device<Core<'_>>,
_info: &'bound Self::IdInfo,
) -> impl PinInit<Self::Data<'bound>, Error> + 'bound {
+ let aux_data = adev.registration_data::<ForLt!(AuxData<'_>)>()?;
+
+ pr_info!("Chipset from nova-core: {}\n", aux_data.chipset());
+
let data = try_pin_init!(NovaData { adev: adev.into() });
let drm = drm::UnregisteredDevice::<Self>::new(adev.as_ref(), data)?;
diff --git a/drivers/gpu/nova-core/driver.rs b/drivers/gpu/nova-core/driver.rs
index 5738d4ac521b..a214860f20de 100644
--- a/drivers/gpu/nova-core/driver.rs
+++ b/drivers/gpu/nova-core/driver.rs
@@ -1,5 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
+//! Main driver module.
+
use kernel::{
auxiliary,
device::Core,
@@ -18,18 +20,36 @@
types::ForLt,
};
-use crate::gpu::Gpu;
+use crate::gpu::{
+ Chipset,
+ Gpu, //
+};
/// Counter for generating unique auxiliary device IDs.
static AUXILIARY_ID_COUNTER: Atomic<u32> = Atomic::new(0);
+/// Data passed to the auxiliary device registration, for the sibling driver to use.
+pub struct AuxData<'bound> {
+ gpu: &'bound Gpu<'bound>,
+}
+
+impl AuxData<'_> {
+ /// Returns the chipset of this GPU.
+ pub fn chipset(&self) -> Chipset {
+ self.gpu.spec.chipset
+ }
+}
+
+/// Driver-associated data.
#[pin_data]
-pub(crate) struct NovaCore<'bound> {
+pub struct NovaCore<'bound> {
+ // Fields are dropped in declaration order: unregister the auxiliary device before dropping
+ // `gpu`, and drop `gpu` before `bar` because `AuxData` borrows `gpu` and `Gpu` borrows `bar`.
+ #[allow(clippy::type_complexity)]
+ _reg: auxiliary::Registration<'bound, ForLt!(AuxData<'_>)>,
#[pin]
pub(crate) gpu: Gpu<'bound>,
bar: pci::Bar<'bound, BAR0_SIZE>,
- #[allow(clippy::type_complexity)]
- _reg: auxiliary::Registration<'bound, ForLt!(())>,
}
pub(crate) struct NovaCoreDriver;
@@ -78,7 +98,7 @@ fn probe<'bound>(
pdev.enable_device_mem()?;
pdev.set_master();
- Ok(try_pin_init!(NovaCore {
+ Ok(try_pin_init!(&this in NovaCore {
bar: pdev.iomap_region_sized::<BAR0_SIZE>(0, c"nova-core/bar0")?,
// TODO: Use `&bar` self-referential pin-init syntax once available.
//
@@ -86,15 +106,26 @@ fn probe<'bound>(
// (`try_pin_init!()` initializes fields in declaration order), lives at a pinned
// stable address, and is dropped after `gpu` (struct field drop order).
gpu <- Gpu::new(pdev, unsafe { &*core::ptr::from_ref(bar) }),
- _reg: auxiliary::Registration::new(
- pdev.as_ref(),
- c"nova-drm",
- // TODO[XARR]: Use XArray or perhaps IDA for proper ID allocation/recycling. For
- // now, use a simple atomic counter that never recycles IDs.
- AUXILIARY_ID_COUNTER.fetch_add(1, Relaxed),
- crate::MODULE_NAME,
- (),
- )?,
+ // SAFETY: `NovaCore` is dropped when the device is unbound; i.e. `mem::forget()` is
+ // never called on it.
+ _reg: unsafe {
+ auxiliary::Registration::new_with_lt(
+ pdev.as_ref(),
+ c"nova-drm",
+ // TODO[XARR]: Use XArray or perhaps IDA for proper ID allocation/recycling.
+ // For now, use a simple atomic counter that never recycles IDs.
+ AUXILIARY_ID_COUNTER.fetch_add(1, Relaxed),
+ crate::MODULE_NAME,
+ AuxData {
+ // TODO: Use `&gpu` self-referential pin-init syntax once available.
+ //
+ // SAFETY: `this.gpu` is initialized before this expression is
+ // evaluated, lives at a pinned stable address, and is dropped after
+ // `_reg` (struct field drop order).
+ gpu: &(*this.as_ptr()).gpu,
+ },
+ )?
+ },
}))
})
}
diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
index b3c91731db45..bceed4652508 100644
--- a/drivers/gpu/nova-core/gpu.rs
+++ b/drivers/gpu/nova-core/gpu.rs
@@ -1,5 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
+//! Core types for the driver.
+
use core::ops::Range;
use kernel::{
@@ -35,7 +37,8 @@ macro_rules! define_chipset {
{
/// Enum representation of the GPU chipset.
#[derive(fmt::Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq)]
- pub(crate) enum Chipset {
+ #[allow(missing_docs)]
+ pub enum Chipset {
$($variant = $value),*,
}
@@ -203,7 +206,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
/// Structure holding a basic description of the GPU: `Chipset` and `Revision`.
#[derive(Clone, Copy)]
pub(crate) struct Spec {
- chipset: Chipset,
+ pub(crate) chipset: Chipset,
revision: Revision,
}
@@ -267,7 +270,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
pub(crate) struct Gpu<'gpu> {
/// Device owning the GPU.
device: &'gpu device::Device<device::Bound>,
- spec: Spec,
+ pub(crate) spec: Spec,
/// MMIO mapping of PCI BAR 0.
bar: Bar0<'gpu>,
/// System memory page required for flushing all pending GPU-side memory writes done through
diff --git a/drivers/gpu/nova-core/gsp/hal.rs b/drivers/gpu/nova-core/gsp/hal.rs
index 04f004856c60..5f2d4a0c25cc 100644
--- a/drivers/gpu/nova-core/gsp/hal.rs
+++ b/drivers/gpu/nova-core/gsp/hal.rs
@@ -36,7 +36,7 @@
/// The GSP unload code might run in a situation where we cannot load firmware dynamically (e.g.
/// because we are in shutdown and the file system is not accessible anymore). Thus, the firmware
/// required for unloading is prepared at load time, and stored here until it needs to be run.
-pub(super) trait UnloadBundle: Send {
+pub(super) trait UnloadBundle: Send + Sync {
/// Performs the steps required to properly reset the GSP after it has been stopped.
fn run(
&self,
diff --git a/drivers/gpu/nova-core/nova_core.rs b/drivers/gpu/nova-core/nova_core.rs
index 9f0199f7b38c..77f647b8862a 100644
--- a/drivers/gpu/nova-core/nova_core.rs
+++ b/drivers/gpu/nova-core/nova_core.rs
@@ -13,12 +13,12 @@
#[macro_use]
mod bitfield;
-mod driver;
+pub mod driver;
mod falcon;
mod fb;
mod firmware;
mod fsp;
-mod gpu;
+pub mod gpu;
mod gsp;
mod mctp;
#[macro_use]
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v4 4/6] gpu: nova-core: emit Rust metadata for nova-drm
2026-06-05 8:31 ` [PATCH v4 4/6] gpu: nova-core: emit Rust metadata " Alexandre Courbot
@ 2026-06-05 8:36 ` Miguel Ojeda
0 siblings, 0 replies; 12+ messages in thread
From: Miguel Ojeda @ 2026-06-05 8:36 UTC (permalink / raw)
To: Alexandre Courbot
Cc: Miguel Ojeda, Nicolas Schier, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, John Hubbard, Alistair Popple,
Timur Tabi, Zhi Wang, Eliot Courtney, linux-kbuild, linux-kernel,
rust-for-linux, nova-gpu, dri-devel
On Fri, Jun 5, 2026 at 10:32 AM Alexandre Courbot <acourbot@nvidia.com> wrote:
>
> +libnova_core.rmeta
This should be already covered by our global `.gitignore`, unless I am
missing something subtle here.
Cheers,
Miguel
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 3/6] gpu: nova-core: export Rust symbols for nova-drm
2026-06-05 8:31 ` [PATCH v4 3/6] gpu: nova-core: export Rust symbols for nova-drm Alexandre Courbot
@ 2026-06-05 8:45 ` sashiko-bot
0 siblings, 0 replies; 12+ messages in thread
From: sashiko-bot @ 2026-06-05 8:45 UTC (permalink / raw)
To: Alexandre Courbot; +Cc: ojeda, dri-devel, Danilo Krummrich
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Exporting Rust symbols via `nova_core_exports.c` silently assigns identical `int`-based CRCs to all exported Rust symbols, defeating kernel module versioning (CONFIG_MODVERSIONS).
--
commit 7d9ae3e551194f16dfdfeaf200ba6d4a6e3969c0
Author: Alexandre Courbot <acourbot@nvidia.com>
gpu: nova-core: export Rust symbols for nova-drm
This commit exports nova-core's Rust symbols so nova-drm can resolve references
to it when loaded as a module. It generates declarations and
EXPORT_SYMBOL_RUST_GPL() calls for Rust global symbols using nm and compiles
them into the module as nova_core_exports.o.
> diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile
> index 45e0941324fbf..2f9c6101e21c7 100644
> --- a/drivers/gpu/Makefile
> +++ b/drivers/gpu/Makefile
[ ... ]
> +$(obj)/nova-core/exports_nova_core_generated.h: $(obj)/nova-core/nova_core.o FORCE
> + $(call if_changed,exports)
> +
> +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
[Severity: High]
Does this rule need to skip gendwarfksyms?
When CONFIG_MODVERSIONS and CONFIG_GENDWARFKSYMS are enabled, Kbuild computes
symbol CRCs based on their DWARF type information. Since gendwarfksyms runs on
nova_core_exports.o without skipping, it will generate CRCs based on the types
defined in the generated C file rather than the actual Rust types.
To fix this, should nova_core_exports.o skip gendwarfksyms
($(obj)/nova-core/nova_core_exports.o: private skip_gendwarfksyms = 1) and
Kbuild support be added to run gendwarfksyms directly on the nova_core.o
Rust object, similar to how it is handled in rust/Makefile?
> diff --git a/drivers/gpu/nova-core/nova_core_exports.c b/drivers/gpu/nova-core/nova_core_exports.c
> new file mode 100644
> index 0000000000000..6e80ca9792ee5
> --- /dev/null
> +++ b/drivers/gpu/nova-core/nova_core_exports.c
[ ... ]
> +#include <linux/export.h>
> +
> +#define EXPORT_SYMBOL_RUST_GPL(sym) extern int sym; EXPORT_SYMBOL_GPL(sym)
[Severity: High]
Will this macro assign identical, unchanging CRCs to all exported Rust
symbols?
Because EXPORT_SYMBOL_RUST_GPL types all exported Rust symbols as extern int
sym, the resulting DWARF type for the symbols in the C object is simply int.
Consequently, gendwarfksyms calculates the CRC for the C int type and assigns
it to all exported Rust symbols. Any subsequent ABI changes in the Rust
structs or functions that do not alter the mangled symbol name will not be
reflected in the CRC.
Could this silently allow incompatible, out-of-date dependent modules like
nova-drm to load and cause memory corruption?
> +
> +#include "exports_nova_core_generated.h"
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260605-nova-exports-v4-0-e948c287407c@nvidia.com?part=3
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH POC v4 6/6] gpu: drm: nova: demonstrate interaction with nova-core
2026-06-05 8:31 ` [PATCH POC v4 6/6] gpu: drm: nova: demonstrate interaction with nova-core Alexandre Courbot
@ 2026-06-05 8:45 ` sashiko-bot
0 siblings, 0 replies; 12+ messages in thread
From: sashiko-bot @ 2026-06-05 8:45 UTC (permalink / raw)
To: Alexandre Courbot; +Cc: dri-devel, Danilo Krummrich, ojeda
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The external crate import `nova_core::driver::AuxData` is placed after local `crate::` imports.
--
commit 11d167edf5ebf94c9cb9d05943e976e68fe80753
Author: Alexandre Courbot <acourbot@nvidia.com>
gpu: drm: nova: demonstrate interaction with nova-core
This commit exports a few items from nova-core and uses them from nova-drm
to print the chipset of the GPU being probed. It also adds some documentation
items to satisfy Clippy.
> diff --git a/drivers/gpu/drm/nova/driver.rs b/drivers/gpu/drm/nova/driver.rs
> index 48933d86ddda9..de1ad7032b6c3 100644
> --- a/drivers/gpu/drm/nova/driver.rs
> +++ b/drivers/gpu/drm/nova/driver.rs
> @@ -9,12 +9,15 @@
> ioctl, //
> },
> prelude::*,
> - sync::aref::ARef, //
> + sync::aref::ARef,
> + types::ForLt, //
> };
>
> use crate::file::File;
> use crate::gem::NovaObject;
>
> +use nova_core::driver::AuxData;
[Severity: Low]
This isn't a bug, but should the external crate import be placed before the
local crate imports to follow the kernel vertical import style? The Rust
subsystem coding guidelines mention grouping external crate imports above local
ones.
> +
> pub(crate) struct NovaDriver;
>
> pub(crate) struct Nova {
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260605-nova-exports-v4-0-e948c287407c@nvidia.com?part=6
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 0/6] gpu: drm: nova: enable calling into nova-core
2026-06-05 8:31 [PATCH v4 0/6] gpu: drm: nova: enable calling into nova-core Alexandre Courbot
` (5 preceding siblings ...)
2026-06-05 8:31 ` [PATCH POC v4 6/6] gpu: drm: nova: demonstrate interaction with nova-core Alexandre Courbot
@ 2026-06-05 8:48 ` Miguel Ojeda
6 siblings, 0 replies; 12+ messages in thread
From: Miguel Ojeda @ 2026-06-05 8:48 UTC (permalink / raw)
To: Alexandre Courbot
Cc: Miguel Ojeda, Nicolas Schier, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, John Hubbard, Alistair Popple,
Timur Tabi, Zhi Wang, Eliot Courtney, linux-kbuild, linux-kernel,
rust-for-linux, nova-gpu, dri-devel
On Fri, Jun 5, 2026 at 10:32 AM Alexandre Courbot <acourbot@nvidia.com> wrote:
>
> This series is based on `drm-rust-next`. The current revision includes
> the feedback received on v3. In particular, moving everything to
> `drivers/gpu/Makefile` simplifies things considerably, and I have tried
> to align more with what is done in `rust/Makefile`.
Thanks for reworking it!
It looks indeed way simpler, and is pretty much what tried when we
discussed this a few months ago (well, speaking from memory), so I am
glad it works for you.
And now that it is also closer to `rust/Makefile`, it will be easier to replace.
So thanks again :)
Cheers,
Miguel
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 1/6] rust: inline some init methods
2026-06-05 8:31 ` [PATCH v4 1/6] rust: inline some init methods Alexandre Courbot
@ 2026-06-08 7:05 ` Miguel Ojeda
0 siblings, 0 replies; 12+ messages in thread
From: Miguel Ojeda @ 2026-06-08 7:05 UTC (permalink / raw)
To: Alexandre Courbot
Cc: Miguel Ojeda, Nicolas Schier, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, John Hubbard, Alistair Popple,
Timur Tabi, Zhi Wang, Eliot Courtney, linux-kbuild, linux-kernel,
rust-for-linux, nova-gpu, dri-devel
On Fri, Jun 5, 2026 at 10:32 AM Alexandre Courbot <acourbot@nvidia.com> wrote:
>
> These methods should be inlined for optimization reasons. Failure to do
> so can also produce symbol names larger than what `modpost` or `objtool`
> can handle.
>
> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
> Reviewed-by: Gary Guo <gary@garyguo.net>
Applied to `rust-next` (just this one) -- thanks everyone!
Cheers,
Miguel
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-06-08 7:05 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-05 8:31 [PATCH v4 0/6] gpu: drm: nova: enable calling into nova-core Alexandre Courbot
2026-06-05 8:31 ` [PATCH v4 1/6] rust: inline some init methods Alexandre Courbot
2026-06-08 7:05 ` Miguel Ojeda
2026-06-05 8:31 ` [PATCH v4 2/6] gpu: build nova-core and nova-drm from drivers/gpu/Makefile Alexandre Courbot
2026-06-05 8:31 ` [PATCH v4 3/6] gpu: nova-core: export Rust symbols for nova-drm Alexandre Courbot
2026-06-05 8:45 ` sashiko-bot
2026-06-05 8:31 ` [PATCH v4 4/6] gpu: nova-core: emit Rust metadata " Alexandre Courbot
2026-06-05 8:36 ` Miguel Ojeda
2026-06-05 8:31 ` [PATCH v4 5/6] gpu: drm: nova: build after nova-core and use its symbols Alexandre Courbot
2026-06-05 8:31 ` [PATCH POC v4 6/6] gpu: drm: nova: demonstrate interaction with nova-core Alexandre Courbot
2026-06-05 8:45 ` sashiko-bot
2026-06-05 8:48 ` [PATCH v4 0/6] gpu: drm: nova: enable calling into nova-core Miguel Ojeda
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox