summaryrefslogtreecommitdiff
path: root/rust
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2026-01-28 13:35:17 +1000
committerDave Airlie <airlied@redhat.com>2026-01-28 13:35:23 +1000
commit15392f76405ecb953216b437bed76ffa49cefb7b (patch)
tree475b2e745389418a67ccc3066e8bf9354fc536c2 /rust
parent205bd15619322a1429c1bf53831a284a12b25e2a (diff)
parentcea7b66a80412e2a5b74627b89ae25f1d0110a4b (diff)
Merge tag 'drm-rust-next-2026-01-26' of https://gitlab.freedesktop.org/drm/rust/kernel into drm-next
DRM Rust changes for v7.0-rc1 DRM: - Fix documentation for Registration constructors. - Use pin_init::zeroed() for fops initialization. - Annotate DRM helpers with __rust_helper. - Improve safety documentation for gem::Object::new(). - Update AlwaysRefCounted imports. MM: - Prevent integer overflow in page_align(). Nova (Core): - Prepare for Turing support. This includes parsing and handling Turing-specific firmware headers and sections as well as a Turing Falcon HAL implementation. - Get rid of the Result<impl PinInit<T, E>> anti-pattern. - Relocate initializer-specific code into the appropriate initializer. - Use CStr::from_bytes_until_nul() to remove custom helpers. - Improve handling of unexpected firmware values. - Clean up redundant debug prints. - Replace c_str!() with native Rust C-string literals. - Update nova-core task list. Nova (DRM): - Align GEM object size to system page size. Tyr: - Use generated uAPI bindings for GpuInfo. - Replace manual sleeps with read_poll_timeout(). - Replace c_str!() with native Rust C-string literals. - Suppress warnings for unread fields. - Fix incorrect register name in print statement. Signed-off-by: Dave Airlie <airlied@redhat.com> From: "Danilo Krummrich" <dakr@kernel.org> Link: https://patch.msgid.link/DFYW1WV6DUCG.3K8V2DAVD1Q4A@kernel.org
Diffstat (limited to 'rust')
-rw-r--r--rust/helpers/drm.c7
-rw-r--r--rust/kernel/drm/driver.rs6
-rw-r--r--rust/kernel/drm/gem/mod.rs8
-rw-r--r--rust/kernel/page.rs36
4 files changed, 39 insertions, 18 deletions
diff --git a/rust/helpers/drm.c b/rust/helpers/drm.c
index 450b406c6f27..fe226f7b53ef 100644
--- a/rust/helpers/drm.c
+++ b/rust/helpers/drm.c
@@ -5,17 +5,18 @@
#ifdef CONFIG_DRM
-void rust_helper_drm_gem_object_get(struct drm_gem_object *obj)
+__rust_helper void rust_helper_drm_gem_object_get(struct drm_gem_object *obj)
{
drm_gem_object_get(obj);
}
-void rust_helper_drm_gem_object_put(struct drm_gem_object *obj)
+__rust_helper void rust_helper_drm_gem_object_put(struct drm_gem_object *obj)
{
drm_gem_object_put(obj);
}
-__u64 rust_helper_drm_vma_node_offset_addr(struct drm_vma_offset_node *node)
+__rust_helper __u64
+rust_helper_drm_vma_node_offset_addr(struct drm_vma_offset_node *node)
{
return drm_vma_node_offset_addr(node);
}
diff --git a/rust/kernel/drm/driver.rs b/rust/kernel/drm/driver.rs
index f30ee4c6245c..e09f977b5b51 100644
--- a/rust/kernel/drm/driver.rs
+++ b/rust/kernel/drm/driver.rs
@@ -121,7 +121,6 @@ pub trait Driver {
pub struct Registration<T: Driver>(ARef<drm::Device<T>>);
impl<T: Driver> Registration<T> {
- /// Creates a new [`Registration`] and registers it.
fn new(drm: &drm::Device<T>, flags: usize) -> Result<Self> {
// SAFETY: `drm.as_raw()` is valid by the invariants of `drm::Device`.
to_result(unsafe { bindings::drm_dev_register(drm.as_raw(), flags) })?;
@@ -129,8 +128,9 @@ impl<T: Driver> Registration<T> {
Ok(Self(drm.into()))
}
- /// Same as [`Registration::new`}, but transfers ownership of the [`Registration`] to
- /// [`devres::register`].
+ /// Registers a new [`Device`](drm::Device) with userspace.
+ ///
+ /// Ownership of the [`Registration`] object is passed to [`devres::register`].
pub fn new_foreign_owned(
drm: &drm::Device<T>,
dev: &device::Device<device::Bound>,
diff --git a/rust/kernel/drm/gem/mod.rs b/rust/kernel/drm/gem/mod.rs
index a7f682e95c01..d49a9ba02635 100644
--- a/rust/kernel/drm/gem/mod.rs
+++ b/rust/kernel/drm/gem/mod.rs
@@ -210,7 +210,7 @@ impl<T: DriverObject> Object<T> {
// SAFETY: The arguments are all valid per the type invariants.
to_result(unsafe { bindings::drm_gem_object_init(dev.as_raw(), obj.obj.get(), size) })?;
- // SAFETY: We never move out of `Self`.
+ // SAFETY: We will never move out of `Self` as `ARef<Self>` is always treated as pinned.
let ptr = KBox::into_raw(unsafe { Pin::into_inner_unchecked(obj) });
// SAFETY: `ptr` comes from `KBox::into_raw` and hence can't be NULL.
@@ -253,7 +253,7 @@ impl<T: DriverObject> Object<T> {
}
// SAFETY: Instances of `Object<T>` are always reference-counted.
-unsafe impl<T: DriverObject> crate::types::AlwaysRefCounted for Object<T> {
+unsafe impl<T: DriverObject> crate::sync::aref::AlwaysRefCounted for Object<T> {
fn inc_ref(&self) {
// SAFETY: The existence of a shared reference guarantees that the refcount is non-zero.
unsafe { bindings::drm_gem_object_get(self.as_raw()) };
@@ -293,9 +293,7 @@ impl<T: DriverObject> AllocImpl for Object<T> {
}
pub(super) const fn create_fops() -> bindings::file_operations {
- // SAFETY: As by the type invariant, it is safe to initialize `bindings::file_operations`
- // zeroed.
- let mut fops: bindings::file_operations = unsafe { core::mem::zeroed() };
+ let mut fops: bindings::file_operations = pin_init::zeroed();
fops.owner = core::ptr::null_mut();
fops.open = Some(bindings::drm_open);
diff --git a/rust/kernel/page.rs b/rust/kernel/page.rs
index 432fc0297d4a..adecb200c654 100644
--- a/rust/kernel/page.rs
+++ b/rust/kernel/page.rs
@@ -25,14 +25,36 @@ pub const PAGE_SIZE: usize = bindings::PAGE_SIZE;
/// A bitmask that gives the page containing a given address.
pub const PAGE_MASK: usize = !(PAGE_SIZE - 1);
-/// Round up the given number to the next multiple of [`PAGE_SIZE`].
+/// Rounds up to the next multiple of [`PAGE_SIZE`].
///
-/// It is incorrect to pass an address where the next multiple of [`PAGE_SIZE`] doesn't fit in a
-/// [`usize`].
-pub const fn page_align(addr: usize) -> usize {
- // Parentheses around `PAGE_SIZE - 1` to avoid triggering overflow sanitizers in the wrong
- // cases.
- (addr + (PAGE_SIZE - 1)) & PAGE_MASK
+/// Returns [`None`] on integer overflow.
+///
+/// # Examples
+///
+/// ```
+/// use kernel::page::{
+/// page_align,
+/// PAGE_SIZE,
+/// };
+///
+/// // Requested address is already aligned.
+/// assert_eq!(page_align(0x0), Some(0x0));
+/// assert_eq!(page_align(PAGE_SIZE), Some(PAGE_SIZE));
+///
+/// // Requested address needs alignment up.
+/// assert_eq!(page_align(0x1), Some(PAGE_SIZE));
+/// assert_eq!(page_align(PAGE_SIZE + 1), Some(2 * PAGE_SIZE));
+///
+/// // Requested address causes overflow (returns `None`).
+/// let overflow_addr = usize::MAX - (PAGE_SIZE / 2);
+/// assert_eq!(page_align(overflow_addr), None);
+/// ```
+#[inline(always)]
+pub const fn page_align(addr: usize) -> Option<usize> {
+ let Some(sum) = addr.checked_add(PAGE_SIZE - 1) else {
+ return None;
+ };
+ Some(sum & PAGE_MASK)
}
/// Representation of a non-owning reference to a [`Page`].