From: Danilo Krummrich <dakr@kernel.org>
To: dakr@kernel.org, acourbot@nvidia.com, aliceryhl@google.com,
abdiel.janulgue@gmail.com, daniel.almeida@collabora.com,
robin.murphy@arm.com, a.hindborg@kernel.org, ojeda@kernel.org,
boqun@kernel.org, gary@garyguo.net, bjorn3_gh@protonmail.com,
lossin@kernel.org, tmgross@umich.edu, tamird@kernel.org,
work@onurozkan.dev
Cc: driver-core@lists.linux.dev, nova-gpu@lists.linux.dev,
dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
rust-for-linux@vger.kernel.org
Subject: [PATCH 2/2] gpu: nova-core: remove unnecessary firmware pin-init
Date: Sun, 15 Nov 2026 00:42:54 +0100 [thread overview]
Message-ID: <20261114234324.82387-2-dakr@kernel.org> (raw)
In-Reply-To: <20261114234324.82387-1-dakr@kernel.org>
Now that SGTable no longer requires pinning, remove the pin-init
machinery from Radix3 and GspFirmware.
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
drivers/gpu/nova-core/firmware/gsp.rs | 43 +++++--------
drivers/gpu/nova-core/firmware/radix3.rs | 82 +++++++++++-------------
drivers/gpu/nova-core/gsp/boot.rs | 2 +-
3 files changed, 56 insertions(+), 71 deletions(-)
diff --git a/drivers/gpu/nova-core/firmware/gsp.rs b/drivers/gpu/nova-core/firmware/gsp.rs
index 341a8b19aa38..ff92a12b2994 100644
--- a/drivers/gpu/nova-core/firmware/gsp.rs
+++ b/drivers/gpu/nova-core/firmware/gsp.rs
@@ -25,10 +25,8 @@
};
/// The GSP firmware image, its signatures, and the GSP bootloader.
-#[pin_data]
pub(crate) struct GspFirmware<'a> {
/// The firmware image and the radix3 table that maps it.
- #[pin]
radix3: Radix3<'a>,
/// Device-mapped GSP signatures matching the GPU's [`Chipset`].
pub(crate) signatures: Coherent<'a, [u8]>,
@@ -39,34 +37,27 @@ pub(crate) struct GspFirmware<'a> {
impl<'a> GspFirmware<'a> {
/// Loads the GSP firmware binaries, map them into `dev`'s address-space, and creates the page
/// tables expected by the GSP bootloader to load it.
- pub(crate) fn new(
- dev: &'a device::Device<device::Bound>,
- chipset: Chipset,
- ) -> impl PinInit<Self, Error> + 'a {
- pin_init::pin_init_scope(move || {
- let firmware = request_tlv(dev, chipset, "gsp")?;
- let tlv = Tlv::new(firmware.data())?;
- dev_dbg!(dev, "loaded gsp firmware v{}\n", tlv.get_string(b"VERS")?);
+ pub(crate) fn new(dev: &'a device::Device<device::Bound>, chipset: Chipset) -> Result<Self> {
+ let firmware = request_tlv(dev, chipset, "gsp")?;
+ let tlv = Tlv::new(firmware.data())?;
+ dev_dbg!(dev, "loaded gsp firmware v{}\n", tlv.get_string(b"VERS")?);
- let size = usize::from_safe_cast(tlv.get_u32(b"SIZE")?);
- let mut fw_vvec = VVec::zeroed(size, GFP_KERNEL).map_err(|_| ENOMEM)?;
+ let size = usize::from_safe_cast(tlv.get_u32(b"SIZE")?);
+ let mut fw_vvec = VVec::zeroed(size, GFP_KERNEL).map_err(|_| ENOMEM)?;
- let chip_name = chipset.name();
- let file = tlv.get_string(b"FILE")?;
- let filename = CString::try_from_fmt(fmt!("nvidia/{chip_name}/gsp/{file}"))?;
- firmware::request_into_buf(&filename, dev, fw_vvec.as_mut_slice())?;
+ let chip_name = chipset.name();
+ let file = tlv.get_string(b"FILE")?;
+ let filename = CString::try_from_fmt(fmt!("nvidia/{chip_name}/gsp/{file}"))?;
+ firmware::request_into_buf(&filename, dev, fw_vvec.as_mut_slice())?;
- let signatures = Coherent::from_slice(dev, tlv.get_bytes(b"SIGN")?, GFP_KERNEL)?;
+ Ok(Self {
+ radix3: Radix3::new(dev, fw_vvec)?,
+ signatures: Coherent::from_slice(dev, tlv.get_bytes(b"SIGN")?, GFP_KERNEL)?,
+ bootloader: {
+ let bl = request_tlv(dev, chipset, "gsp_bootloader")?;
- Ok(try_pin_init!(Self {
- radix3 <- Radix3::new(dev, fw_vvec),
- signatures,
- bootloader: {
- let bl = request_tlv(dev, chipset, "gsp_bootloader")?;
-
- RiscvFirmware::new(dev, &bl)?
- },
- }))
+ RiscvFirmware::new(dev, &bl)?
+ },
})
}
diff --git a/drivers/gpu/nova-core/firmware/radix3.rs b/drivers/gpu/nova-core/firmware/radix3.rs
index a3e43fc8ec86..2c8787d5930d 100644
--- a/drivers/gpu/nova-core/firmware/radix3.rs
+++ b/drivers/gpu/nova-core/firmware/radix3.rs
@@ -32,60 +32,54 @@
};
/// A radix3 page table and the data it maps.
-#[pin_data]
pub(crate) struct Radix3<'a> {
/// The mapped data.
- data: SGTable<Owned<'a, VVec<u8>>>,
- /// Level 2: one entry per page of `data`.
- level2: SGTable<Owned<'a, VVec<u8>>>,
- /// Level 1: one entry per page of `level2`.
- level1: SGTable<Owned<'a, VVec<u8>>>,
- /// Level 0: one page, whose single entry is the DMA address of the first `level1` page.
+ _data: SGTable<Owned<'a, VVec<u8>>>,
+ /// Level 2: one entry per page of `_data`.
+ _level2: SGTable<Owned<'a, VVec<u8>>>,
+ /// Level 1: one entry per page of `_level2`.
+ _level1: SGTable<Owned<'a, VVec<u8>>>,
+ /// Level 0: one page, whose single entry is the DMA address of the first `_level1` page.
level0: Coherent<'a, [u64]>,
- /// Length of `data`, in bytes.
+ /// Length of `_data`, in bytes.
size: usize,
}
impl<'a> Radix3<'a> {
/// Builds a radix3 page table over `data`, mapped for `dev` to read. May sleep.
- pub(crate) fn new(
- dev: &'a device::Device<device::Bound>,
- data: VVec<u8>,
- ) -> impl PinInit<Self, Error> + 'a {
+ pub(crate) fn new(dev: &'a device::Device<device::Bound>, data: VVec<u8>) -> Result<Self> {
let size = data.len();
- pin_init::pin_init_scope(move || {
- Ok(try_pin_init!(Self {
- data: SGTable::new(dev, data, DataDirection::ToDevice, GFP_KERNEL)?,
- level2: {
- let l2 = build_lvl(data)?;
- SGTable::new(dev, l2, DataDirection::ToDevice, GFP_KERNEL)?
- },
- level1: {
- let l1 = build_lvl(level2)?;
- SGTable::new(dev, l1, DataDirection::ToDevice, GFP_KERNEL)?
- },
- level0: {
- // Allocate the level 0 page table as a device-visible DMA object, and map the
- // level 1 page table onto it.
-
- // Fill level 1 page entry.
- let level1_entry = level1.iter().next().ok_or(EINVAL)?;
- let level1_entry_addr = level1_entry.dma_address();
-
- // Create level 0 page table data and fill its first entry with the level 1
- // table.
- let mut level0 = CoherentBox::<'_, [u64]>::zeroed_slice(
- dev,
- GSP_PAGE_SIZE / size_of::<u64>(),
- GFP_KERNEL,
- )?;
- level0[0] = level1_entry_addr.to_le();
-
- level0.into()
- },
- size,
- }))
+ let data = SGTable::new(dev, data, DataDirection::ToDevice, GFP_KERNEL)?;
+
+ let l2 = build_lvl(&data)?;
+ let level2 = SGTable::new(dev, l2, DataDirection::ToDevice, GFP_KERNEL)?;
+
+ let l1 = build_lvl(&level2)?;
+ let level1 = SGTable::new(dev, l1, DataDirection::ToDevice, GFP_KERNEL)?;
+
+ // Allocate the level 0 page table as a device-visible DMA object, and map the
+ // level 1 page table onto it.
+
+ // Fill level 1 page entry.
+ let level1_entry = level1.iter().next().ok_or(EINVAL)?;
+ let level1_entry_addr = level1_entry.dma_address();
+
+ // Create level 0 page table data and fill its first entry with the level 1
+ // table.
+ let mut level0 = CoherentBox::<'_, [u64]>::zeroed_slice(
+ dev,
+ GSP_PAGE_SIZE / size_of::<u64>(),
+ GFP_KERNEL,
+ )?;
+ level0[0] = level1_entry_addr.to_le();
+
+ Ok(Self {
+ _data: data,
+ _level2: level2,
+ _level1: level1,
+ level0: level0.into(),
+ size,
})
}
diff --git a/drivers/gpu/nova-core/gsp/boot.rs b/drivers/gpu/nova-core/gsp/boot.rs
index 4fb1b69ac9d5..ac09b40832aa 100644
--- a/drivers/gpu/nova-core/gsp/boot.rs
+++ b/drivers/gpu/nova-core/gsp/boot.rs
@@ -40,7 +40,7 @@ pub(crate) fn boot(
let dev = pdev.as_ref();
let hal = super::hal::gsp_hal(chipset);
- let gsp_fw = KBox::pin_init(GspFirmware::new(dev, chipset), GFP_KERNEL)?;
+ let gsp_fw = GspFirmware::new(dev, chipset)?;
self.cmdq
.send_command_no_wait(commands::SetSystemInfo::new(pdev, chipset))?;
--
2.56.1
prev parent reply other threads:[~2026-11-14 23:43 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-14 23:42 [PATCH 1/2] rust: scatterlist: tie owned tables to the device's bound lifetime Danilo Krummrich
2026-11-14 23:42 ` Danilo Krummrich [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261114234324.82387-2-dakr@kernel.org \
--to=dakr@kernel.org \
--cc=a.hindborg@kernel.org \
--cc=abdiel.janulgue@gmail.com \
--cc=acourbot@nvidia.com \
--cc=aliceryhl@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun@kernel.org \
--cc=daniel.almeida@collabora.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=driver-core@lists.linux.dev \
--cc=gary@garyguo.net \
--cc=linux-kernel@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=nova-gpu@lists.linux.dev \
--cc=ojeda@kernel.org \
--cc=robin.murphy@arm.com \
--cc=rust-for-linux@vger.kernel.org \
--cc=tamird@kernel.org \
--cc=tmgross@umich.edu \
--cc=work@onurozkan.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.