From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 63C2E109E530 for ; Thu, 26 Mar 2026 01:15:40 +0000 (UTC) Received: from kara.freedesktop.org (unknown [131.252.210.166]) by gabe.freedesktop.org (Postfix) with ESMTPS id 432FD10E1CC; Thu, 26 Mar 2026 01:15:40 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.b="CAOnZ1a0"; dkim-atps=neutral Received: from kara.freedesktop.org (localhost [127.0.0.1]) by kara.freedesktop.org (Postfix) with ESMTP id 62FEB45309; Thu, 26 Mar 2026 01:04:32 +0000 (UTC) ARC-Seal: i=1; cv=none; a=rsa-sha256; d=lists.freedesktop.org; s=20240201; t=1774487072; b=en/9pS+/f667LQhgFFsvLf2nX3Al1bH4TzwOIPTEy84EEYJ9vm8SPROyMd3aNCDya8hI1 LAajsGMn9FA6BIFaBYIz41NDyxFZCa5TbCYykpEarbJKHoDSBfOUG1TEpFgddrFUHmj2nSe pl3rcM+fwxzJ0CJgEMS0WoLaOGdCvxafahXOLah/qVk+7T3JV68Xj8qwxoPhzjC/qcPkr52 DTZRwUrvrY7EdS5BqoBsb7sygYt0WGUucB2Vi/gDijE0PAsYNsknW2ZRvB8xZH/7Wvhn7Lt xflKgpMUeRNPDYLoIltrZOBslh05PN7ns9DlVK+jlp+krxFXR1gI0PL9ZZWw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=lists.freedesktop.org; s=20240201; t=1774487072; h=from : sender : reply-to : subject : date : message-id : to : cc : mime-version : content-type : content-transfer-encoding : content-id : content-description : resent-date : resent-from : resent-sender : resent-to : resent-cc : resent-message-id : in-reply-to : references : list-id : list-help : list-unsubscribe : list-subscribe : list-post : list-owner : list-archive; bh=eGnZ+39o7yZSmcw2GUt8m8wccm5cFUrhBzb6UMF62nA=; b=s6N/iCQ+ql2/7AZIdOJH1qz1C5hB5jxoe0J/kqrBmzPDDA0PWgCXhYvzbvEYSJZcfoVIz 6xr7FZvKtXWvjQn9orddSF0hB5CDs87eFkZNicAqChKcCODrRSmZxjQVjn4pIaOW0Ab2Q6e lPR+RyXNoXfEK1XGkGULluZb/6e0JeYCx7Tf4xvXEoN3PtwbAT3uBCSi43icgXw8YPGHevv dOPtgNvgziS2NZcTTqPjoGhkibaEzPQBSiH5gXIwCeT2WTygsOGEfa+b801tjsQe94ygbJW xOCKq/DWyZAdnioeQOt/O/iAw9YLr+rmdrCCF1JlDaoRoRgEwcBa/qnltNUg== ARC-Authentication-Results: i=1; mail.freedesktop.org; dkim=pass header.d=kernel.org; arc=none (Message is not ARC signed); dmarc=pass (Used From Domain Record) header.from=kernel.org policy.dmarc=quarantine Authentication-Results: mail.freedesktop.org; dkim=pass header.d=kernel.org; arc=none (Message is not ARC signed); dmarc=pass (Used From Domain Record) header.from=kernel.org policy.dmarc=quarantine Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by kara.freedesktop.org (Postfix) with ESMTPS id 4ABFF44DDF for ; Thu, 26 Mar 2026 01:04:29 +0000 (UTC) Received: from tor.source.kernel.org (tor.source.kernel.org [172.105.4.254]) by gabe.freedesktop.org (Postfix) with ESMTPS id E14B010E1A5 for ; Thu, 26 Mar 2026 01:15:36 +0000 (UTC) Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by tor.source.kernel.org (Postfix) with ESMTP id D179D60123; Thu, 26 Mar 2026 01:15:35 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id D58FBC4CEF7; Thu, 26 Mar 2026 01:15:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1774487735; bh=ONoM3r8dhzn9gp/Rh8CpPc8mBuiVYIjyCbjkV7LKnK8=; h=Date:Subject:Cc:To:From:References:In-Reply-To:From; b=CAOnZ1a0q6D0c535RBzlK0A467wrlyMMTUCLhHaIahv4vb5pnwfhakQ8ugzQ/pcxH 1DedKNDxH7naDK5ncYMt0icIlFuGnqwzIh3VW4jg/hLePzADzliEE6gsgMxs/2Sl+N y0icYrEDe+aAYRlAuNd0geFdyDjJiCalG4V8nDKa2AZo3G7bS3BMEdcT10yUyp/sLE jq7tUi4BYuRMJNyy8DlU0CrzbYO8x3VD7AjqfRYF+5nQWgjdpn2+eZF9TDSZ1DW61A mO+hGffUVu56CdfQPmk6KeM0wFXV4YhcijwfmNGB0pJvti4ZD4Xrum1/9lXsFUglxS zEFg+2GKd5AxA== Mime-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=UTF-8 Date: Thu, 26 Mar 2026 02:15:28 +0100 Message-Id: Subject: Re: (subset) [PATCH v9 0/7] Rust bindings for gem shmem To: "Lyude Paul" , "Alice Ryhl" , "Miguel Ojeda" From: "Danilo Krummrich" References: <20260316211646.650074-1-lyude@redhat.com> In-Reply-To: <20260316211646.650074-1-lyude@redhat.com> Message-ID-Hash: PBN6M3QFVT3CAA24DMY4SRXIJJE3SK4H X-Message-ID-Hash: PBN6M3QFVT3CAA24DMY4SRXIJJE3SK4H X-MailFrom: dakr@kernel.org X-Mailman-Rule-Hits: nonmember-moderation X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation CC: nouveau@lists.freedesktop.org, Gary Guo , Daniel Almeida , rust-for-linux@vger.kernel.org, Matthew Maurer , FUJITA Tomonori , Lorenzo Stoakes , christian.koenig@amd.com, Asahi Lina , Miguel Ojeda , Andreas Hindborg , Simona Vetter , Alice Ryhl , Boqun Feng , Sumit Semwal , Krishna Ketan Rai , linux-media@vger.kernel.org, Shankari Anand , Benno Lossin , Viresh Kumar , linaro-mm-sig@lists.linaro.org, Asahi Lina , Greg Kroah-Hartman , kernel@vger.kernel.org, Deborah Brouwer X-Mailman-Version: 3.3.8 Precedence: list List-Id: Nouveau development list Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: On Mon Mar 16, 2026 at 10:16 PM CET, Lyude Paul wrote: > Lyude Paul (5): > rust: drm: Add gem::impl_aref_for_gem_obj! > rust: gem: Introduce DriverObject::Args Applied to drm-rust-next, thanks! > Asahi Lina (2): > rust: drm: gem: shmem: Add DRM shmem helper abstraction I was about to pick this one up as well, but did run into quite some build errors and warnings. I fixed them all up, but I consider this too excessive= to actually apply the patch. This is the changelog I came up with: [ * DRM_GEM_SHMEM_HELPER is a tristate; when a module driver selects it= , it becomes =3Dm. The Rust kernel crate and its C helpers are always built into vmlinux and can't reference symbols from a module, causing link errors. Thus, add RUST_DRM_GEM_SHMEM_HELPER bool Kconfig that selects DRM_GEM_SHMEM_HELPER, forcing it built-in when Rust drivers need it= ; use cfg(CONFIG_RUST_DRM_GEM_SHMEM_HELPER) for the shmem module. * Add cfg_attr(not(CONFIG_RUST_DRM_GEM_SHMEM_HELPER), expect(unused)) on pub(crate) use impl_aref_for_gem_obj and BaseObjectPrivate, so that unused warnings are suppressed when shmem is not enabled. * Enable const_refs_to_static (stabilized in 1.83) to prevent build errors with older compilers. * Use &raw const for bindings::drm_gem_shmem_vm_ops and add #[allow(unused_unsafe, reason =3D "Safe since Rust 1.82.0")]. * Fix incorrect C Header path and minor spelling and formatting issues. * Drop shmem::Object::sg_table() as the current implementation is unsound. - Danilo ] Please always consider [1] and [2]. [1] https://drm.pages.freedesktop.org/maintainer-tools/committer/committer-= drm-rust.html#submit-checklist [2] https://rust-for-linux.com/contributing#submit-checklist-addendum (@Deborah: I assume you were testing this with Tyr built-in?) @Lyude, Alice, Miguel: Please have a look at what I came up with below. commit 2dc69d77944dbd1494d2b10a4b134b7fead1c8e7 Author: Asahi Lina Date: Mon Mar 16 17:16:13 2026 -0400 rust: drm: gem: shmem: Add DRM shmem helper abstraction The DRM shmem helper includes common code useful for drivers which allocate GEM objects as anonymous shmem. Add a Rust abstraction for this. Drivers can choose the raw GEM implementation or the shmem layer, depending on their needs. Signed-off-by: Asahi Lina Signed-off-by: Daniel Almeida Reviewed-by: Daniel Almeida Signed-off-by: Lyude Paul Tested-by: Deborah Brouwer Link: https://patch.msgid.link/20260316211646.650074-6-lyude@redhat.com [ * DRM_GEM_SHMEM_HELPER is a tristate; when a module driver selects it= , it becomes =3Dm. The Rust kernel crate and its C helpers are always built into vmlinux and can't reference symbols from a module, causing link errors. Thus, add RUST_DRM_GEM_SHMEM_HELPER bool Kconfig that selects DRM_GEM_SHMEM_HELPER, forcing it built-in when Rust drivers need it= ; use cfg(CONFIG_RUST_DRM_GEM_SHMEM_HELPER) for the shmem module. * Add cfg_attr(not(CONFIG_RUST_DRM_GEM_SHMEM_HELPER), expect(unused)) on pub(crate) use impl_aref_for_gem_obj and BaseObjectPrivate, so that unused warnings are suppressed when shmem is not enabled. * Enable const_refs_to_static (stabilized in 1.83) to prevent build errors with older compilers. * Use &raw const for bindings::drm_gem_shmem_vm_ops and add #[allow(unused_unsafe, reason =3D "Safe since Rust 1.82.0")]. * Fix incorrect C Header path and minor spelling and formatting issues. * Drop shmem::Object::sg_table() as the current implementation is unsound. - Danilo ] Signed-off-by: Danilo Krummrich diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 0d0657dd1b41..0f68446c9122 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -258,6 +258,13 @@ config DRM_GEM_SHMEM_HELPER help Choose this if you need the GEM shmem helper functions +config RUST_DRM_GEM_SHMEM_HELPER + bool + depends on DRM && MMU + select DRM_GEM_SHMEM_HELPER + help + Choose this if you need the GEM shmem helper functions In Rust + config DRM_SUBALLOC_HELPER tristate depends on DRM diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helpe= r.h index 563863d96d38..eda8f50d3a3c 100644 --- a/rust/bindings/bindings_helper.h +++ b/rust/bindings/bindings_helper.h @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -63,6 +64,7 @@ #include #include #include +#include #include #include #include diff --git a/rust/helpers/drm.c b/rust/helpers/drm.c index fe226f7b53ef..65f3f22b0e1d 100644 --- a/rust/helpers/drm.c +++ b/rust/helpers/drm.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include #ifdef CONFIG_DRM @@ -21,4 +22,57 @@ rust_helper_drm_vma_node_offset_addr(struct drm_vma_offs= et_node *node) return drm_vma_node_offset_addr(node); } -#endif +#ifdef CONFIG_DRM_GEM_SHMEM_HELPER +__rust_helper void +rust_helper_drm_gem_shmem_object_free(struct drm_gem_object *obj) +{ + return drm_gem_shmem_object_free(obj); +} + +__rust_helper void +rust_helper_drm_gem_shmem_object_print_info(struct drm_printer *p, unsigne= d int indent, + const struct drm_gem_object *obj) +{ + drm_gem_shmem_object_print_info(p, indent, obj); +} + +__rust_helper int +rust_helper_drm_gem_shmem_object_pin(struct drm_gem_object *obj) +{ + return drm_gem_shmem_object_pin(obj); +} + +__rust_helper void +rust_helper_drm_gem_shmem_object_unpin(struct drm_gem_object *obj) +{ + drm_gem_shmem_object_unpin(obj); +} + +__rust_helper struct sg_table * +rust_helper_drm_gem_shmem_object_get_sg_table(struct drm_gem_object *obj) +{ + return drm_gem_shmem_object_get_sg_table(obj); +} + +__rust_helper int +rust_helper_drm_gem_shmem_object_vmap(struct drm_gem_object *obj, + struct iosys_map *map) +{ + return drm_gem_shmem_object_vmap(obj, map); +} + +__rust_helper void +rust_helper_drm_gem_shmem_object_vunmap(struct drm_gem_object *obj, + struct iosys_map *map) +{ + drm_gem_shmem_object_vunmap(obj, map); +} + +__rust_helper int +rust_helper_drm_gem_shmem_object_mmap(struct drm_gem_object *obj, struct v= m_area_struct *vma) +{ + return drm_gem_shmem_object_mmap(obj, vma); +} + +#endif /* CONFIG_DRM_GEM_SHMEM_HELPER */ +#endif /* CONFIG_DRM */ diff --git a/rust/kernel/drm/gem/mod.rs b/rust/kernel/drm/gem/mod.rs index 527d86f4ce92..58eb0a3d5686 100644 --- a/rust/kernel/drm/gem/mod.rs +++ b/rust/kernel/drm/gem/mod.rs @@ -26,6 +26,9 @@ ptr::NonNull, // }; +#[cfg(CONFIG_RUST_DRM_GEM_SHMEM_HELPER)] +pub mod shmem; + /// A macro for implementing [`AlwaysRefCounted`] for any GEM object type. /// /// Since all GEM objects use the same refcounting scheme. @@ -60,6 +63,8 @@ unsafe fn dec_ref(obj: core::ptr::NonNull) { } }; } +#[cfg_attr(not(CONFIG_RUST_DRM_GEM_SHMEM_HELPER), allow(unused))] +pub(crate) use impl_aref_for_gem_obj; /// A type alias for retrieving a [`Driver`]s [`DriverFile`] implementatio= n from its /// [`DriverObject`] implementation. @@ -216,7 +221,7 @@ fn create_mmap_offset(&self) -> Result { impl BaseObject for T {} /// Crate-private base operations shared by all GEM object classes. -#[expect(unused)] +#[cfg_attr(not(CONFIG_RUST_DRM_GEM_SHMEM_HELPER), expect(unused))] pub(crate) trait BaseObjectPrivate: IntoGEMObject { /// Return a pointer to this object's dma_resv. fn raw_dma_resv(&self) -> *mut bindings::dma_resv { diff --git a/rust/kernel/drm/gem/shmem.rs b/rust/kernel/drm/gem/shmem.rs new file mode 100644 index 000000000000..d025fb035195 --- /dev/null +++ b/rust/kernel/drm/gem/shmem.rs @@ -0,0 +1,228 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! DRM GEM shmem helper objects +//! +//! C header: [`include/linux/drm/drm_gem_shmem_helper.h`](srctree/include= /drm/drm_gem_shmem_helper.h) + +// TODO: +// - There are a number of spots here that manually acquire/release the DM= A reservation lock using +// dma_resv_(un)lock(). In the future we should add support for ww mutex= , expose a method to +// acquire a reference to the WwMutex, and then use that directly instea= d of the C functions here. + +use crate::{ + container_of, + drm::{ + device, + driver, + gem, + private::Sealed, // + }, + error::to_result, + prelude::*, + types::{ + ARef, + Opaque, // + }, // +}; +use core::{ + ops::{ + Deref, + DerefMut, // + }, + ptr::NonNull, +}; +use gem::{ + BaseObjectPrivate, + DriverObject, + IntoGEMObject, // +}; + +/// A struct for controlling the creation of shmem-backed GEM objects. +/// +/// This is used with [`Object::new()`] to control various properties that= can only be set when +/// initially creating a shmem-backed GEM object. +#[derive(Default)] +pub struct ObjectConfig<'a, T: DriverObject> { + /// Whether to set the write-combine map flag. + pub map_wc: bool, + + /// Reuse the DMA reservation from another GEM object. + /// + /// The newly created [`Object`] will hold an owned refcount to `paren= t_resv_obj` if specified. + pub parent_resv_obj: Option<&'a Object>, +} + +/// A shmem-backed GEM object. +/// +/// # Invariants +/// +/// `obj` contains a valid initialized `struct drm_gem_shmem_object` for t= he lifetime of this +/// object. +#[repr(C)] +#[pin_data] +pub struct Object { + #[pin] + obj: Opaque, + /// Parent object that owns this object's DMA reservation object. + parent_resv_obj: Option>>, + #[pin] + inner: T, +} + +super::impl_aref_for_gem_obj!(impl for Object where T: DriverObject)= ; + +// SAFETY: All GEM objects are thread-safe. +unsafe impl Send for Object {} + +// SAFETY: All GEM objects are thread-safe. +unsafe impl Sync for Object {} + +impl Object { + /// `drm_gem_object_funcs` vtable suitable for GEM shmem objects. + const VTABLE: bindings::drm_gem_object_funcs =3D bindings::drm_gem_obj= ect_funcs { + free: Some(Self::free_callback), + open: Some(super::open_callback::), + close: Some(super::close_callback::), + print_info: Some(bindings::drm_gem_shmem_object_print_info), + export: None, + pin: Some(bindings::drm_gem_shmem_object_pin), + unpin: Some(bindings::drm_gem_shmem_object_unpin), + get_sg_table: Some(bindings::drm_gem_shmem_object_get_sg_table), + vmap: Some(bindings::drm_gem_shmem_object_vmap), + vunmap: Some(bindings::drm_gem_shmem_object_vunmap), + mmap: Some(bindings::drm_gem_shmem_object_mmap), + status: None, + rss: None, + #[allow(unused_unsafe, reason =3D "Safe since Rust 1.82.0")] + // SAFETY: `drm_gem_shmem_vm_ops` is a valid, static const on the = C side. + vm_ops: unsafe { &raw const bindings::drm_gem_shmem_vm_ops }, + evict: None, + }; + + /// Return a raw pointer to the embedded drm_gem_shmem_object. + fn as_raw_shmem(&self) -> *mut bindings::drm_gem_shmem_object { + self.obj.get() + } + + /// Create a new shmem-backed DRM object of the given size. + /// + /// Additional config options can be specified using `config`. + pub fn new( + dev: &device::Device, + size: usize, + config: ObjectConfig<'_, T>, + args: T::Args, + ) -> Result> { + let new: Pin> =3D KBox::try_pin_init( + try_pin_init!(Self { + obj <- Opaque::init_zeroed(), + parent_resv_obj: config.parent_resv_obj.map(|p| p.into()), + inner <- T::new(dev, size, args), + }), + GFP_KERNEL, + )?; + + // SAFETY: `obj.as_raw()` is guaranteed to be valid by the initial= ization above. + unsafe { (*new.as_raw()).funcs =3D &Self::VTABLE }; + + // SAFETY: The arguments are all valid via the type invariants. + to_result(unsafe { bindings::drm_gem_shmem_init(dev.as_raw(), new.= as_raw_shmem(), size) })?; + + // SAFETY: We never move out of `self`. + let new =3D KBox::into_raw(unsafe { Pin::into_inner_unchecked(new)= }); + + // SAFETY: We're taking over the owned refcount from `drm_gem_shme= m_init`. + let obj =3D unsafe { ARef::from_raw(NonNull::new_unchecked(new)) }= ; + + // Start filling out values from `config` + if let Some(parent_resv) =3D config.parent_resv_obj { + // SAFETY: We have yet to expose the new gem object outside of= this function, so it is + // safe to modify this field. + unsafe { (*obj.obj.get()).base.resv =3D parent_resv.raw_dma_re= sv() }; + } + + // SAFETY: We have yet to expose this object outside of this funct= ion, so we're guaranteed + // to have exclusive access - thus making this safe to hold a muta= ble reference to. + let shmem =3D unsafe { &mut *obj.as_raw_shmem() }; + shmem.set_map_wc(config.map_wc); + + Ok(obj) + } + + /// Returns the `Device` that owns this GEM object. + pub fn dev(&self) -> &device::Device { + // SAFETY: `dev` will have been initialized in `Self::new()` by `d= rm_gem_shmem_init()`. + unsafe { device::Device::from_raw((*self.as_raw()).dev) } + } + + extern "C" fn free_callback(obj: *mut bindings::drm_gem_object) { + // SAFETY: + // - DRM always passes a valid gem object here + // - We used drm_gem_shmem_create() in our create_gem_object callb= ack, so we know that + // `obj` is contained within a drm_gem_shmem_object + let this =3D unsafe { container_of!(obj, bindings::drm_gem_shmem_o= bject, base) }; + + // SAFETY: + // - We're in free_callback - so this function is safe to call. + // - We won't be using the gem resources on `this` after this call= . + unsafe { bindings::drm_gem_shmem_release(this) }; + + // SAFETY: + // - We verified above that `obj` is valid, which makes `this` val= id + // - This function is set in AllocOps, so we know that `this` is c= ontained within a + // `Object` + let this =3D unsafe { container_of!(Opaque::cast_from(this), Self,= obj) }.cast_mut(); + + // SAFETY: We're recovering the Kbox<> we created in gem_create_ob= ject() + let _ =3D unsafe { KBox::from_raw(this) }; + } +} + +impl Deref for Object { + type Target =3D T; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl DerefMut for Object { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.inner + } +} + +impl Sealed for Object {} + +impl gem::IntoGEMObject for Object { + fn as_raw(&self) -> *mut bindings::drm_gem_object { + // SAFETY: + // - Our immutable reference is proof that this is safe to derefer= ence. + // - `obj` is always a valid drm_gem_shmem_object via our type inv= ariants. + unsafe { &raw mut (*self.obj.get()).base } + } + + unsafe fn from_raw<'a>(obj: *mut bindings::drm_gem_object) -> &'a Obje= ct { + // SAFETY: The safety contract of from_gem_obj() guarantees that `= obj` is contained within + // `Self` + unsafe { + let obj =3D Opaque::cast_from(container_of!(obj, bindings::drm= _gem_shmem_object, base)); + + &*container_of!(obj, Object, obj) + } + } +} + +impl driver::AllocImpl for Object { + type Driver =3D T::Driver; + + const ALLOC_OPS: driver::AllocOps =3D driver::AllocOps { + gem_create_object: None, + prime_handle_to_fd: None, + prime_fd_to_handle: None, + gem_prime_import: None, + gem_prime_import_sg_table: Some(bindings::drm_gem_shmem_prime_impo= rt_sg_table), + dumb_create: Some(bindings::drm_gem_shmem_dumb_create), + dumb_map_offset: None, + }; +} diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index e0837ffc91bf..40de00ce4f97 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -38,6 +38,7 @@ #![feature(const_option)] #![feature(const_ptr_write)] #![feature(const_refs_to_cell)] +#![feature(const_refs_to_static)] // // Stable since Rust 1.84.0. #![feature(strict_provenance)]