* [PATCH v2 3/5] drm/nova: use `zerocopy` in fwsec.rs
2026-07-01 17:40 [PATCH " Pedro Yudi Honda
@ 2026-07-01 17:40 ` Pedro Yudi Honda
2026-07-01 17:48 ` sashiko-bot
0 siblings, 1 reply; 14+ messages in thread
From: Pedro Yudi Honda @ 2026-07-01 17:40 UTC (permalink / raw)
To: dakr, acourbot, apopple
Cc: nico.antinori.7, aliceryhl, airlied, simona, dri-devel, ojeda,
rust-for-linux, Pedro Yudi Honda
From: Pedro Yudi Honda <niyudi.honda@usp.br>
In firmware/fwsec.rs, replace the following `transmute` traits with
their `zerocopy` equivalents:
- `transmute::FromBytes` -> `zerocopy::FromBytes`
- `transmute::AsBytes` -> `zerocopy::IntoBytes`
- add `zerocopy::KnownLayout` where necessary
Update call sites accordingly.
Signed-off-by: Pedro Yudi Honda <niyudi.honda@usp.br>
---
drivers/gpu/nova-core/firmware/fwsec.rs | 49 ++++++-------------------
1 file changed, 12 insertions(+), 37 deletions(-)
diff --git a/drivers/gpu/nova-core/firmware/fwsec.rs b/drivers/gpu/nova-core/firmware/fwsec.rs
index 95e0dd77746b..1b75cdc02256 100644
--- a/drivers/gpu/nova-core/firmware/fwsec.rs
+++ b/drivers/gpu/nova-core/firmware/fwsec.rs
@@ -19,11 +19,7 @@
self,
Device, //
},
- prelude::*,
- transmute::{
- AsBytes,
- FromBytes, //
- },
+ prelude::*, //
};
use crate::{
@@ -49,26 +45,22 @@
const NVFW_FALCON_APPIF_ID_DMEMMAPPER: u32 = 0x4;
#[repr(C)]
-#[derive(Debug)]
+#[derive(Debug, FromBytes)]
struct FalconAppifHdrV1 {
version: u8,
header_size: u8,
entry_size: u8,
entry_count: u8,
}
-// SAFETY: Any byte sequence is valid for this struct.
-unsafe impl FromBytes for FalconAppifHdrV1 {}
#[repr(C, packed)]
-#[derive(Debug)]
+#[derive(Debug, FromBytes)]
struct FalconAppifV1 {
id: u32,
dmem_base: u32,
}
-// SAFETY: Any byte sequence is valid for this struct.
-unsafe impl FromBytes for FalconAppifV1 {}
-#[derive(Debug)]
+#[derive(Debug, FromBytes, IntoBytes, zerocopy_derive::KnownLayout)]
#[repr(C, packed)]
struct FalconAppifDmemmapperV3 {
signature: u32,
@@ -89,12 +81,8 @@ struct FalconAppifDmemmapperV3 {
ucode_cmd_mask1: u32,
multi_tgt_tbl: u32,
}
-// SAFETY: Any byte sequence is valid for this struct.
-unsafe impl FromBytes for FalconAppifDmemmapperV3 {}
-// SAFETY: This struct doesn't contain uninitialized bytes and doesn't have interior mutability.
-unsafe impl AsBytes for FalconAppifDmemmapperV3 {}
-#[derive(Debug)]
+#[derive(Debug, FromBytes, IntoBytes, zerocopy_derive::KnownLayout)]
#[repr(C, packed)]
struct ReadVbios {
ver: u32,
@@ -103,12 +91,8 @@ struct ReadVbios {
size: u32,
flags: u32,
}
-// SAFETY: Any byte sequence is valid for this struct.
-unsafe impl FromBytes for ReadVbios {}
-// SAFETY: This struct doesn't contain uninitialized bytes and doesn't have interior mutability.
-unsafe impl AsBytes for ReadVbios {}
-#[derive(Debug)]
+#[derive(Debug, FromBytes, IntoBytes, zerocopy_derive::KnownLayout)]
#[repr(C, packed)]
struct FrtsRegion {
ver: u32,
@@ -117,22 +101,15 @@ struct FrtsRegion {
size: u32,
ftype: u32,
}
-// SAFETY: Any byte sequence is valid for this struct.
-unsafe impl FromBytes for FrtsRegion {}
-// SAFETY: This struct doesn't contain uninitialized bytes and doesn't have interior mutability.
-unsafe impl AsBytes for FrtsRegion {}
const NVFW_FRTS_CMD_REGION_TYPE_FB: u32 = 2;
#[repr(C, packed)]
+#[derive(FromBytes, IntoBytes, zerocopy_derive::KnownLayout)]
struct FrtsCmd {
read_vbios: ReadVbios,
frts_region: FrtsRegion,
}
-// SAFETY: Any byte sequence is valid for this struct.
-unsafe impl FromBytes for FrtsCmd {}
-// SAFETY: This struct doesn't contain uninitialized bytes and doesn't have interior mutability.
-unsafe impl AsBytes for FrtsCmd {}
const NVFW_FALCON_APPIF_DMEMMAPPER_CMD_FRTS: u32 = 0x15;
const NVFW_FALCON_APPIF_DMEMMAPPER_CMD_SB: u32 = 0x19;
@@ -151,11 +128,9 @@ pub(crate) enum FwsecCommand {
/// A single signature that can be patched into a FWSEC image.
#[repr(transparent)]
+#[derive(FromBytes)]
pub(crate) struct Bcrt30Rsa3kSignature([u8; BCRT30_RSA3K_SIG_SIZE]);
-/// SAFETY: A signature is just an array of bytes.
-unsafe impl FromBytes for Bcrt30Rsa3kSignature {}
-
impl From<[u8; BCRT30_RSA3K_SIG_SIZE]> for Bcrt30Rsa3kSignature {
fn from(sig: [u8; BCRT30_RSA3K_SIG_SIZE]) -> Self {
Self(sig)
@@ -228,7 +203,7 @@ fn new_fwsec(bios: &Vbios, cmd: FwsecCommand) -> Result<Self> {
let hdr = ucode
.get(hdr_offset..)
- .and_then(FalconAppifHdrV1::from_bytes_prefix)
+ .and_then(|b| FalconAppifHdrV1::read_from_prefix(b).ok())
.ok_or(EINVAL)?
.0;
@@ -246,7 +221,7 @@ fn new_fwsec(bios: &Vbios, cmd: FwsecCommand) -> Result<Self> {
let app = ucode
.get(entry_offset..)
- .and_then(FalconAppifV1::from_bytes_prefix)
+ .and_then(|b| FalconAppifV1::read_from_prefix(b).ok())
.ok_or(EINVAL)?
.0;
@@ -263,7 +238,7 @@ fn new_fwsec(bios: &Vbios, cmd: FwsecCommand) -> Result<Self> {
let dmem_mapper = ucode
.get_mut(dmem_mapper_offset..)
- .and_then(FalconAppifDmemmapperV3::from_bytes_mut_prefix)
+ .and_then(|b| FalconAppifDmemmapperV3::mut_from_prefix(b).ok())
.ok_or(EINVAL)?
.0;
@@ -281,7 +256,7 @@ fn new_fwsec(bios: &Vbios, cmd: FwsecCommand) -> Result<Self> {
let frts_cmd = ucode
.get_mut(frts_cmd_offset..)
- .and_then(FrtsCmd::from_bytes_mut_prefix)
+ .and_then(|b| FrtsCmd::mut_from_prefix(b).ok())
.ok_or(EINVAL)?
.0;
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH v2 3/5] drm/nova: use `zerocopy` in fwsec.rs
2026-07-01 17:40 ` [PATCH v2 3/5] drm/nova: use `zerocopy` in fwsec.rs Pedro Yudi Honda
@ 2026-07-01 17:48 ` sashiko-bot
0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-07-01 17:48 UTC (permalink / raw)
To: Pedro Yudi Honda; +Cc: dri-devel, ojeda
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Firmware structures use native integer types (e.g., `u32`, `u64`, `u16`) instead of explicit little-endian types, which causes data corruption when parsing firmware metadata on big-endian architectures.
--
commit 5588d64059dd57b42b45063f16c1c4ba8ddc35f4
Author: Pedro Yudi Honda <niyudi.honda@usp.br>
drm/nova: use zerocopy in fwsec.rs
In firmware/fwsec.rs, replace the following transmute traits with
their zerocopy equivalents:
- transmute::FromBytes -> zerocopy::FromBytes
- transmute::AsBytes -> zerocopy::IntoBytes
- add zerocopy::KnownLayout where necessary
Update call sites accordingly.
> diff --git a/drivers/gpu/nova-core/firmware/fwsec.rs b/drivers/gpu/nova-core/firmware/fwsec.rs
> index 95e0dd77746b0..1b75cdc02256c 100644
> --- a/drivers/gpu/nova-core/firmware/fwsec.rs
> +++ b/drivers/gpu/nova-core/firmware/fwsec.rs
[ ... ]
> #[repr(C, packed)]
> -#[derive(Debug)]
> +#[derive(Debug, FromBytes)]
> struct FalconAppifV1 {
> id: u32,
> dmem_base: u32,
> }
[Severity: High]
This is a pre-existing issue, but will this struct misinterpret the firmware
data on big-endian architectures?
The firmware is little-endian, but these fields use native u32 types. When
read_from_prefix() parses the little-endian bytes directly into native types
on a big-endian host, it will corrupt dmem_base and id.
This causes out-of-bounds calculations when using dmem_base as an offset,
leading to an EINVAL failure during driver initialization.
Since this patch migrates the code to use zerocopy, would it make sense to
update these structures to use zerocopy's endian-aware types (such as
zerocopy::byteorder::little_endian::U32) instead of native integers?
[ ... ]
> -#[derive(Debug)]
> +#[derive(Debug, FromBytes, IntoBytes, zerocopy_derive::KnownLayout)]
> #[repr(C, packed)]
> struct FalconAppifDmemmapperV3 {
> signature: u32,
> os_code_offset: u32,
> os_code_size: u32,
[Severity: High]
This is a pre-existing issue, but does this struct also need endian-aware
types for its u32 fields to prevent data corruption during parsing on
big-endian hosts?
[ ... ]
> -#[derive(Debug)]
> +#[derive(Debug, FromBytes, IntoBytes, zerocopy_derive::KnownLayout)]
> #[repr(C, packed)]
> struct ReadVbios {
> ver: u32,
> hdr: u32,
> addr: u64,
[Severity: High]
This is a pre-existing issue, but does this struct also need endian-aware
types for its native u32 and u64 fields?
[ ... ]
> -#[derive(Debug)]
> +#[derive(Debug, FromBytes, IntoBytes, zerocopy_derive::KnownLayout)]
> #[repr(C, packed)]
> struct FrtsRegion {
> ver: u32,
> hdr: u32,
> addr: u32,
[Severity: High]
This is a pre-existing issue, but will this command structure send corrupted
coordinates to the firmware if written from a big-endian architecture?
It appears to use native u32 types instead of little-endian types.
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260701174056.12604-1-niyudi.honda@gmail.com?part=3
^ permalink raw reply [flat|nested] 14+ messages in thread
* [RESEND PATCH v2 0/5] drm/nova: replace `transmute` with `zerocopy`
@ 2026-07-02 12:03 Pedro Yudi Honda
2026-07-02 12:03 ` [PATCH v2 1/5] drm/nova: use `zerocopy` in firmware.rs Pedro Yudi Honda
` (5 more replies)
0 siblings, 6 replies; 14+ messages in thread
From: Pedro Yudi Honda @ 2026-07-02 12:03 UTC (permalink / raw)
To: dakr, acourbot, apopple
Cc: nico.antinori.7, aliceryhl, airlied, simona, dri-devel, ojeda,
rust-for-linux, nova-gpu, Pedro Yudi Honda
From: Pedro Yudi Honda <niyudi.honda@usp.br>
This series follows the introduction of `zerocopy` to rust-next and
replaces `transmute` traits with `zerocopy` traits. These changes are
mechanical and don't alter functionality.
This series is built upon Nicolás' recent patch, and does not touch
gsp bindings.
Specifically, the trait `transmute::FromBytes` is replaced by
`zerocopy::FromBytes` and the trait `transmute::AsBytes` is replaced
by `zerocopy::IntoBytes`. Additional traits such as
`zerocopy::Immutable` and `zerocopy::KnownLayout` are implemented as
necessary.
Resent because of wrong target list and wrong email in "From:".
Pedro Yudi Honda (5):
drm/nova: use `zerocopy` in firmware.rs
drm/nova: use `zerocopy` in booter.rs
drm/nova: use `zerocopy` in fwsec.rs
drm/nova: use `zerocopy` in bootloader.rs
drm/nova: use `zerocopy` in riscv.rs
drivers/gpu/nova-core/firmware.rs | 10 ++--
drivers/gpu/nova-core/firmware/booter.rs | 26 +++-------
drivers/gpu/nova-core/firmware/fwsec.rs | 49 +++++--------------
.../nova-core/firmware/fwsec/bootloader.rs | 18 ++-----
drivers/gpu/nova-core/firmware/riscv.rs | 10 ++--
5 files changed, 30 insertions(+), 83 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v2 1/5] drm/nova: use `zerocopy` in firmware.rs
2026-07-02 12:03 [RESEND PATCH v2 0/5] drm/nova: replace `transmute` with `zerocopy` Pedro Yudi Honda
@ 2026-07-02 12:03 ` Pedro Yudi Honda
2026-07-06 7:15 ` Alistair Popple
2026-07-02 12:03 ` [PATCH v2 2/5] drm/nova: use `zerocopy` in booter.rs Pedro Yudi Honda
` (4 subsequent siblings)
5 siblings, 1 reply; 14+ messages in thread
From: Pedro Yudi Honda @ 2026-07-02 12:03 UTC (permalink / raw)
To: dakr, acourbot, apopple
Cc: nico.antinori.7, aliceryhl, airlied, simona, dri-devel, ojeda,
rust-for-linux, nova-gpu, Pedro Yudi Honda
From: Pedro Yudi Honda <niyudi.honda@usp.br>
In firmware.rs, replace the following `transmute` traits with their
`zerocopy` equivalents:
- `transmute::FromBytes` -> `zerocopy::FromBytes`
Update call sites accordingly.
Note that the module `elf` is untouched, as the bindings generated by
bindgen do not implement `FromBytes` for the structs.
Signed-off-by: Pedro Yudi Honda <niyudi.honda@usp.br>
---
drivers/gpu/nova-core/firmware.rs | 10 +++-------
drivers/gpu/nova-core/firmware/fwsec/bootloader.rs | 4 +++-
2 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/nova-core/firmware.rs b/drivers/gpu/nova-core/firmware.rs
index a94820a3b335..80ce0df244a8 100644
--- a/drivers/gpu/nova-core/firmware.rs
+++ b/drivers/gpu/nova-core/firmware.rs
@@ -11,8 +11,7 @@
device,
firmware,
prelude::*,
- str::CString,
- transmute::FromBytes, //
+ str::CString, //
};
use crate::{
@@ -347,7 +346,7 @@ fn no_patch_signature(self) -> FirmwareObject<F, Signed> {
/// Header common to most firmware files.
#[repr(C)]
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, FromBytes)]
struct BinHdr {
/// Magic number, must be `0x10de`.
bin_magic: u32,
@@ -363,9 +362,6 @@ struct BinHdr {
data_size: u32,
}
-// SAFETY: all bit patterns are valid for this type, and it doesn't use interior mutability.
-unsafe impl FromBytes for BinHdr {}
-
// A firmware blob starting with a `BinHdr`.
struct BinFirmware<'a> {
hdr: BinHdr,
@@ -381,7 +377,7 @@ fn new(fw: &'a firmware::Firmware) -> Result<Self> {
fw.get(0..size_of::<BinHdr>())
// Extract header.
- .and_then(BinHdr::from_bytes_copy)
+ .and_then(|b| BinHdr::read_from_bytes(b).ok())
// Validate header.
.filter(|hdr| hdr.bin_magic == BIN_MAGIC)
.map(|hdr| Self { hdr, fw })
diff --git a/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs b/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs
index d9fafd2eea5b..66b9f4d1b41c 100644
--- a/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs
+++ b/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs
@@ -25,6 +25,8 @@
},
};
+use zerocopy::FromBytes as _;
+
use crate::{
driver::Bar0,
falcon::{
@@ -150,7 +152,7 @@ pub(crate) fn new(
let hdr = fw
.data()
.get(0..size_of::<BinHdr>())
- .and_then(BinHdr::from_bytes_copy)
+ .and_then(|b| BinHdr::read_from_bytes(b).ok())
.ok_or(EINVAL)?;
let desc = {
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v2 2/5] drm/nova: use `zerocopy` in booter.rs
2026-07-02 12:03 [RESEND PATCH v2 0/5] drm/nova: replace `transmute` with `zerocopy` Pedro Yudi Honda
2026-07-02 12:03 ` [PATCH v2 1/5] drm/nova: use `zerocopy` in firmware.rs Pedro Yudi Honda
@ 2026-07-02 12:03 ` Pedro Yudi Honda
2026-07-06 11:39 ` Alistair Popple
2026-07-02 12:03 ` [PATCH v2 3/5] drm/nova: use `zerocopy` in fwsec.rs Pedro Yudi Honda
` (3 subsequent siblings)
5 siblings, 1 reply; 14+ messages in thread
From: Pedro Yudi Honda @ 2026-07-02 12:03 UTC (permalink / raw)
To: dakr, acourbot, apopple
Cc: nico.antinori.7, aliceryhl, airlied, simona, dri-devel, ojeda,
rust-for-linux, nova-gpu, Pedro Yudi Honda
From: Pedro Yudi Honda <niyudi.honda@usp.br>
In firmware/booter.rs, replace the following `transmute` traits with
their `zerocopy` equivalents:
- `transmute::FromBytes` -> `zerocopy::FromBytes`
Update call sites accordingly.
Signed-off-by: Pedro Yudi Honda <niyudi.honda@usp.br>
---
drivers/gpu/nova-core/firmware/booter.rs | 26 +++++++-----------------
1 file changed, 7 insertions(+), 19 deletions(-)
diff --git a/drivers/gpu/nova-core/firmware/booter.rs b/drivers/gpu/nova-core/firmware/booter.rs
index acb7f4d8a532..fe9389b84b90 100644
--- a/drivers/gpu/nova-core/firmware/booter.rs
+++ b/drivers/gpu/nova-core/firmware/booter.rs
@@ -10,8 +10,7 @@
use kernel::{
device,
dma::Coherent,
- prelude::*,
- transmute::FromBytes, //
+ prelude::*, //
};
use crate::{
@@ -43,7 +42,7 @@ fn frombytes_at<S: FromBytes + Sized>(slice: &[u8], offset: usize) -> Result<S>
let end = offset.checked_add(size_of::<S>()).ok_or(EINVAL)?;
slice
.get(offset..end)
- .and_then(S::from_bytes_copy)
+ .and_then(|b| S::read_from_bytes(b).ok())
.ok_or(EINVAL)
}
@@ -52,7 +51,7 @@ fn frombytes_at<S: FromBytes + Sized>(slice: &[u8], offset: usize) -> Result<S>
/// Such firmwares have an application-specific payload that needs to be patched with a given
/// signature.
#[repr(C)]
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, FromBytes)]
struct HsHeaderV2 {
/// Offset to the start of the signatures.
sig_prod_offset: u32,
@@ -75,9 +74,6 @@ struct HsHeaderV2 {
header_size: u32,
}
-// SAFETY: all bit patterns are valid for this type, and it doesn't use interior mutability.
-unsafe impl FromBytes for HsHeaderV2 {}
-
/// Heavy-Secured Firmware image container.
///
/// This provides convenient access to the fields of [`HsHeaderV2`] that are actually indices to
@@ -144,6 +140,7 @@ fn signatures_iter(&'a self) -> Result<impl Iterator<Item = BooterSignature<'a>>
/// Signature parameters, as defined in the firmware.
#[repr(C)]
+#[derive(FromBytes)]
struct HsSignatureParams {
/// Fuse version to use.
fuse_ver: u32,
@@ -153,9 +150,6 @@ struct HsSignatureParams {
ucode_id: u32,
}
-// SAFETY: all bit patterns are valid for this type, and it doesn't use interior mutability.
-unsafe impl FromBytes for HsSignatureParams {}
-
impl HsSignatureParams {
/// Returns the signature parameters contained in `hs_fw`.
///
@@ -170,14 +164,14 @@ fn new(hs_fw: &HsFirmwareV2<'_>) -> Result<Self> {
hs_fw
.fw
.get(start..end)
- .and_then(Self::from_bytes_copy)
+ .and_then(|b| Self::read_from_bytes(b).ok())
.ok_or(EINVAL)
}
}
/// Header for code and data load offsets.
#[repr(C)]
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, FromBytes)]
struct HsLoadHeaderV2 {
// Offset at which the code starts.
os_code_offset: u32,
@@ -191,9 +185,6 @@ struct HsLoadHeaderV2 {
num_apps: u32,
}
-// SAFETY: all bit patterns are valid for this type, and it doesn't use interior mutability.
-unsafe impl FromBytes for HsLoadHeaderV2 {}
-
impl HsLoadHeaderV2 {
/// Returns the load header contained in `hs_fw`.
///
@@ -205,7 +196,7 @@ fn new(hs_fw: &HsFirmwareV2<'_>) -> Result<Self> {
/// Header for app code loader.
#[repr(C)]
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, FromBytes)]
struct HsLoadHeaderV2App {
/// Offset at which to load the app code.
offset: u32,
@@ -213,9 +204,6 @@ struct HsLoadHeaderV2App {
len: u32,
}
-// SAFETY: all bit patterns are valid for this type, and it doesn't use interior mutability.
-unsafe impl FromBytes for HsLoadHeaderV2App {}
-
impl HsLoadHeaderV2App {
/// Returns the [`HsLoadHeaderV2App`] for app `idx` of `hs_fw`.
///
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v2 3/5] drm/nova: use `zerocopy` in fwsec.rs
2026-07-02 12:03 [RESEND PATCH v2 0/5] drm/nova: replace `transmute` with `zerocopy` Pedro Yudi Honda
2026-07-02 12:03 ` [PATCH v2 1/5] drm/nova: use `zerocopy` in firmware.rs Pedro Yudi Honda
2026-07-02 12:03 ` [PATCH v2 2/5] drm/nova: use `zerocopy` in booter.rs Pedro Yudi Honda
@ 2026-07-02 12:03 ` Pedro Yudi Honda
2026-07-06 11:43 ` Alistair Popple
2026-07-02 12:03 ` [PATCH v2 4/5] drm/nova: use `zerocopy` in bootloader.rs Pedro Yudi Honda
` (2 subsequent siblings)
5 siblings, 1 reply; 14+ messages in thread
From: Pedro Yudi Honda @ 2026-07-02 12:03 UTC (permalink / raw)
To: dakr, acourbot, apopple
Cc: nico.antinori.7, aliceryhl, airlied, simona, dri-devel, ojeda,
rust-for-linux, nova-gpu, Pedro Yudi Honda
From: Pedro Yudi Honda <niyudi.honda@usp.br>
In firmware/fwsec.rs, replace the following `transmute` traits with
their `zerocopy` equivalents:
- `transmute::FromBytes` -> `zerocopy::FromBytes`
- `transmute::AsBytes` -> `zerocopy::IntoBytes`
- add `zerocopy::KnownLayout` where necessary
Update call sites accordingly.
Signed-off-by: Pedro Yudi Honda <niyudi.honda@usp.br>
---
drivers/gpu/nova-core/firmware/fwsec.rs | 49 ++++++-------------------
1 file changed, 12 insertions(+), 37 deletions(-)
diff --git a/drivers/gpu/nova-core/firmware/fwsec.rs b/drivers/gpu/nova-core/firmware/fwsec.rs
index 95e0dd77746b..1b75cdc02256 100644
--- a/drivers/gpu/nova-core/firmware/fwsec.rs
+++ b/drivers/gpu/nova-core/firmware/fwsec.rs
@@ -19,11 +19,7 @@
self,
Device, //
},
- prelude::*,
- transmute::{
- AsBytes,
- FromBytes, //
- },
+ prelude::*, //
};
use crate::{
@@ -49,26 +45,22 @@
const NVFW_FALCON_APPIF_ID_DMEMMAPPER: u32 = 0x4;
#[repr(C)]
-#[derive(Debug)]
+#[derive(Debug, FromBytes)]
struct FalconAppifHdrV1 {
version: u8,
header_size: u8,
entry_size: u8,
entry_count: u8,
}
-// SAFETY: Any byte sequence is valid for this struct.
-unsafe impl FromBytes for FalconAppifHdrV1 {}
#[repr(C, packed)]
-#[derive(Debug)]
+#[derive(Debug, FromBytes)]
struct FalconAppifV1 {
id: u32,
dmem_base: u32,
}
-// SAFETY: Any byte sequence is valid for this struct.
-unsafe impl FromBytes for FalconAppifV1 {}
-#[derive(Debug)]
+#[derive(Debug, FromBytes, IntoBytes, zerocopy_derive::KnownLayout)]
#[repr(C, packed)]
struct FalconAppifDmemmapperV3 {
signature: u32,
@@ -89,12 +81,8 @@ struct FalconAppifDmemmapperV3 {
ucode_cmd_mask1: u32,
multi_tgt_tbl: u32,
}
-// SAFETY: Any byte sequence is valid for this struct.
-unsafe impl FromBytes for FalconAppifDmemmapperV3 {}
-// SAFETY: This struct doesn't contain uninitialized bytes and doesn't have interior mutability.
-unsafe impl AsBytes for FalconAppifDmemmapperV3 {}
-#[derive(Debug)]
+#[derive(Debug, FromBytes, IntoBytes, zerocopy_derive::KnownLayout)]
#[repr(C, packed)]
struct ReadVbios {
ver: u32,
@@ -103,12 +91,8 @@ struct ReadVbios {
size: u32,
flags: u32,
}
-// SAFETY: Any byte sequence is valid for this struct.
-unsafe impl FromBytes for ReadVbios {}
-// SAFETY: This struct doesn't contain uninitialized bytes and doesn't have interior mutability.
-unsafe impl AsBytes for ReadVbios {}
-#[derive(Debug)]
+#[derive(Debug, FromBytes, IntoBytes, zerocopy_derive::KnownLayout)]
#[repr(C, packed)]
struct FrtsRegion {
ver: u32,
@@ -117,22 +101,15 @@ struct FrtsRegion {
size: u32,
ftype: u32,
}
-// SAFETY: Any byte sequence is valid for this struct.
-unsafe impl FromBytes for FrtsRegion {}
-// SAFETY: This struct doesn't contain uninitialized bytes and doesn't have interior mutability.
-unsafe impl AsBytes for FrtsRegion {}
const NVFW_FRTS_CMD_REGION_TYPE_FB: u32 = 2;
#[repr(C, packed)]
+#[derive(FromBytes, IntoBytes, zerocopy_derive::KnownLayout)]
struct FrtsCmd {
read_vbios: ReadVbios,
frts_region: FrtsRegion,
}
-// SAFETY: Any byte sequence is valid for this struct.
-unsafe impl FromBytes for FrtsCmd {}
-// SAFETY: This struct doesn't contain uninitialized bytes and doesn't have interior mutability.
-unsafe impl AsBytes for FrtsCmd {}
const NVFW_FALCON_APPIF_DMEMMAPPER_CMD_FRTS: u32 = 0x15;
const NVFW_FALCON_APPIF_DMEMMAPPER_CMD_SB: u32 = 0x19;
@@ -151,11 +128,9 @@ pub(crate) enum FwsecCommand {
/// A single signature that can be patched into a FWSEC image.
#[repr(transparent)]
+#[derive(FromBytes)]
pub(crate) struct Bcrt30Rsa3kSignature([u8; BCRT30_RSA3K_SIG_SIZE]);
-/// SAFETY: A signature is just an array of bytes.
-unsafe impl FromBytes for Bcrt30Rsa3kSignature {}
-
impl From<[u8; BCRT30_RSA3K_SIG_SIZE]> for Bcrt30Rsa3kSignature {
fn from(sig: [u8; BCRT30_RSA3K_SIG_SIZE]) -> Self {
Self(sig)
@@ -228,7 +203,7 @@ fn new_fwsec(bios: &Vbios, cmd: FwsecCommand) -> Result<Self> {
let hdr = ucode
.get(hdr_offset..)
- .and_then(FalconAppifHdrV1::from_bytes_prefix)
+ .and_then(|b| FalconAppifHdrV1::read_from_prefix(b).ok())
.ok_or(EINVAL)?
.0;
@@ -246,7 +221,7 @@ fn new_fwsec(bios: &Vbios, cmd: FwsecCommand) -> Result<Self> {
let app = ucode
.get(entry_offset..)
- .and_then(FalconAppifV1::from_bytes_prefix)
+ .and_then(|b| FalconAppifV1::read_from_prefix(b).ok())
.ok_or(EINVAL)?
.0;
@@ -263,7 +238,7 @@ fn new_fwsec(bios: &Vbios, cmd: FwsecCommand) -> Result<Self> {
let dmem_mapper = ucode
.get_mut(dmem_mapper_offset..)
- .and_then(FalconAppifDmemmapperV3::from_bytes_mut_prefix)
+ .and_then(|b| FalconAppifDmemmapperV3::mut_from_prefix(b).ok())
.ok_or(EINVAL)?
.0;
@@ -281,7 +256,7 @@ fn new_fwsec(bios: &Vbios, cmd: FwsecCommand) -> Result<Self> {
let frts_cmd = ucode
.get_mut(frts_cmd_offset..)
- .and_then(FrtsCmd::from_bytes_mut_prefix)
+ .and_then(|b| FrtsCmd::mut_from_prefix(b).ok())
.ok_or(EINVAL)?
.0;
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v2 4/5] drm/nova: use `zerocopy` in bootloader.rs
2026-07-02 12:03 [RESEND PATCH v2 0/5] drm/nova: replace `transmute` with `zerocopy` Pedro Yudi Honda
` (2 preceding siblings ...)
2026-07-02 12:03 ` [PATCH v2 3/5] drm/nova: use `zerocopy` in fwsec.rs Pedro Yudi Honda
@ 2026-07-02 12:03 ` Pedro Yudi Honda
2026-07-06 11:44 ` Alistair Popple
2026-07-02 12:03 ` [PATCH v2 5/5] drm/nova: use `zerocopy` in riscv.rs Pedro Yudi Honda
2026-07-04 13:00 ` [RESEND PATCH v2 0/5] drm/nova: replace `transmute` with `zerocopy` Miguel Ojeda
5 siblings, 1 reply; 14+ messages in thread
From: Pedro Yudi Honda @ 2026-07-02 12:03 UTC (permalink / raw)
To: dakr, acourbot, apopple
Cc: nico.antinori.7, aliceryhl, airlied, simona, dri-devel, ojeda,
rust-for-linux, nova-gpu, Pedro Yudi Honda
From: Pedro Yudi Honda <niyudi.honda@usp.br>
In firmware/fwsec/bootloader.rs, replace the following `transmute`
traits with their `zerocopy` equivalents:
- `transmute::FromBytes` -> `zerocopy::FromBytes`
- `transmute::AsBytes` -> `zerocopy::IntoBytes`
- add `zerocopy::Immutable` where necessary
Update call sites accordingly.
Signed-off-by: Pedro Yudi Honda <niyudi.honda@usp.br>
---
.../gpu/nova-core/firmware/fwsec/bootloader.rs | 18 ++++--------------
1 file changed, 4 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs b/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs
index 66b9f4d1b41c..03d3090bd9ef 100644
--- a/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs
+++ b/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs
@@ -18,15 +18,9 @@
Alignable,
Alignment, //
},
- sizes,
- transmute::{
- AsBytes,
- FromBytes, //
- },
+ sizes, //
};
-use zerocopy::FromBytes as _;
-
use crate::{
driver::Bar0,
falcon::{
@@ -57,7 +51,7 @@
///
/// Most of its fields appear to be legacy and carry incorrect values, so they are left unused.
#[repr(C)]
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, FromBytes)]
struct BootloaderDesc {
/// Starting tag of bootloader.
start_tag: u32,
@@ -73,15 +67,13 @@ struct BootloaderDesc {
/// Size of data section in the image. Unused as we build the data section ourselves.
_data_size: u32,
}
-// SAFETY: any byte sequence is valid for this struct.
-unsafe impl FromBytes for BootloaderDesc {}
/// Structure used by the boot-loader to load the rest of the code.
///
/// This has to be filled by the GPU driver and copied into DMEM at offset
/// [`BootloaderDesc.dmem_load_off`].
#[repr(C, packed)]
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, IntoBytes, zerocopy_derive::Immutable)]
struct BootloaderDmemDescV2 {
/// Reserved, should always be first element.
reserved: [u32; 4],
@@ -120,8 +112,6 @@ struct BootloaderDmemDescV2 {
/// Arguments to be passed to the target firmware being loaded.
argv: u32,
}
-// SAFETY: This struct doesn't contain uninitialized bytes and doesn't have interior mutability.
-unsafe impl AsBytes for BootloaderDmemDescV2 {}
/// Wrapper for [`FwsecFirmware`] that includes the bootloader performing the actual load
/// operation.
@@ -160,7 +150,7 @@ pub(crate) fn new(
fw.data()
.get(desc_offset..)
- .and_then(BootloaderDesc::from_bytes_copy_prefix)
+ .and_then(|b| BootloaderDesc::read_from_prefix(b).ok())
.ok_or(EINVAL)?
.0
};
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v2 5/5] drm/nova: use `zerocopy` in riscv.rs
2026-07-02 12:03 [RESEND PATCH v2 0/5] drm/nova: replace `transmute` with `zerocopy` Pedro Yudi Honda
` (3 preceding siblings ...)
2026-07-02 12:03 ` [PATCH v2 4/5] drm/nova: use `zerocopy` in bootloader.rs Pedro Yudi Honda
@ 2026-07-02 12:03 ` Pedro Yudi Honda
2026-07-06 11:44 ` Alistair Popple
2026-07-04 13:00 ` [RESEND PATCH v2 0/5] drm/nova: replace `transmute` with `zerocopy` Miguel Ojeda
5 siblings, 1 reply; 14+ messages in thread
From: Pedro Yudi Honda @ 2026-07-02 12:03 UTC (permalink / raw)
To: dakr, acourbot, apopple
Cc: nico.antinori.7, aliceryhl, airlied, simona, dri-devel, ojeda,
rust-for-linux, nova-gpu, Pedro Yudi Honda
From: Pedro Yudi Honda <niyudi.honda@usp.br>
In riscv.rs, replave the following `transmute` traits with their
`zerocopy` equivalents:
- `transmute::FromBytes` -> `zerocopy::FromBytes`
Update call sites accordingly.
Signed-off-by: Pedro Yudi Honda <niyudi.honda@usp.br>
---
drivers/gpu/nova-core/firmware/riscv.rs | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/nova-core/firmware/riscv.rs b/drivers/gpu/nova-core/firmware/riscv.rs
index 2afa7f36404e..ba56bc7d4188 100644
--- a/drivers/gpu/nova-core/firmware/riscv.rs
+++ b/drivers/gpu/nova-core/firmware/riscv.rs
@@ -7,8 +7,7 @@
device,
dma::Coherent,
firmware::Firmware,
- prelude::*,
- transmute::FromBytes, //
+ prelude::*, //
};
use crate::{
@@ -18,7 +17,7 @@
/// Descriptor for microcode running on a RISC-V core.
#[repr(C)]
-#[derive(Debug)]
+#[derive(Debug, FromBytes)]
struct RmRiscvUCodeDesc {
version: u32,
bootloader_offset: u32,
@@ -36,9 +35,6 @@ struct RmRiscvUCodeDesc {
monitor_code_size: u32,
}
-// SAFETY: all bit patterns are valid for this type, and it doesn't use interior mutability.
-unsafe impl FromBytes for RmRiscvUCodeDesc {}
-
impl RmRiscvUCodeDesc {
/// Interprets the header of `bin_fw` as a [`RmRiscvUCodeDesc`] and returns it.
///
@@ -50,7 +46,7 @@ fn new(bin_fw: &BinFirmware<'_>) -> Result<Self> {
bin_fw
.fw
.get(offset..end)
- .and_then(Self::from_bytes_copy)
+ .and_then(|b| Self::read_from_bytes(b).ok())
.ok_or(EINVAL)
}
}
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [RESEND PATCH v2 0/5] drm/nova: replace `transmute` with `zerocopy`
2026-07-02 12:03 [RESEND PATCH v2 0/5] drm/nova: replace `transmute` with `zerocopy` Pedro Yudi Honda
` (4 preceding siblings ...)
2026-07-02 12:03 ` [PATCH v2 5/5] drm/nova: use `zerocopy` in riscv.rs Pedro Yudi Honda
@ 2026-07-04 13:00 ` Miguel Ojeda
5 siblings, 0 replies; 14+ messages in thread
From: Miguel Ojeda @ 2026-07-04 13:00 UTC (permalink / raw)
To: Pedro Yudi Honda
Cc: dakr, acourbot, apopple, nico.antinori.7, aliceryhl, airlied,
simona, dri-devel, ojeda, rust-for-linux, nova-gpu
On Thu, Jul 2, 2026 at 2:05 PM Pedro Yudi Honda <niyudi.honda@usp.br> wrote:
>
> Resent because of wrong target list and wrong email in "From:".
It is good that you mention this, thanks!
For future series, please also include a changelog between versions,
i.e. so that reviewers know what changed :)
Cheers,
Miguel
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 1/5] drm/nova: use `zerocopy` in firmware.rs
2026-07-02 12:03 ` [PATCH v2 1/5] drm/nova: use `zerocopy` in firmware.rs Pedro Yudi Honda
@ 2026-07-06 7:15 ` Alistair Popple
0 siblings, 0 replies; 14+ messages in thread
From: Alistair Popple @ 2026-07-06 7:15 UTC (permalink / raw)
To: Pedro Yudi Honda
Cc: dakr, acourbot, nico.antinori.7, aliceryhl, airlied, simona,
dri-devel, ojeda, rust-for-linux, nova-gpu
On 2026-07-02 at 22:03 +1000, Pedro Yudi Honda <niyudi.honda@usp.br> wrote...
> From: Pedro Yudi Honda <niyudi.honda@usp.br>
>
> In firmware.rs, replace the following `transmute` traits with their
> `zerocopy` equivalents:
>
> - `transmute::FromBytes` -> `zerocopy::FromBytes`
>
> Update call sites accordingly.
>
> Note that the module `elf` is untouched, as the bindings generated by
> bindgen do not implement `FromBytes` for the structs.
Also I believe this module is pretty temporary and going to go away.
Everything here is pretty mechanical though, and looks good to me so:
Reviewed-by: Alistair Popple <apopple@nvidia.com>
> Signed-off-by: Pedro Yudi Honda <niyudi.honda@usp.br>
> ---
> drivers/gpu/nova-core/firmware.rs | 10 +++-------
> drivers/gpu/nova-core/firmware/fwsec/bootloader.rs | 4 +++-
> 2 files changed, 6 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/nova-core/firmware.rs b/drivers/gpu/nova-core/firmware.rs
> index a94820a3b335..80ce0df244a8 100644
> --- a/drivers/gpu/nova-core/firmware.rs
> +++ b/drivers/gpu/nova-core/firmware.rs
> @@ -11,8 +11,7 @@
> device,
> firmware,
> prelude::*,
> - str::CString,
> - transmute::FromBytes, //
> + str::CString, //
> };
>
> use crate::{
> @@ -347,7 +346,7 @@ fn no_patch_signature(self) -> FirmwareObject<F, Signed> {
>
> /// Header common to most firmware files.
> #[repr(C)]
> -#[derive(Debug, Clone)]
> +#[derive(Debug, Clone, FromBytes)]
> struct BinHdr {
> /// Magic number, must be `0x10de`.
> bin_magic: u32,
> @@ -363,9 +362,6 @@ struct BinHdr {
> data_size: u32,
> }
>
> -// SAFETY: all bit patterns are valid for this type, and it doesn't use interior mutability.
> -unsafe impl FromBytes for BinHdr {}
> -
> // A firmware blob starting with a `BinHdr`.
> struct BinFirmware<'a> {
> hdr: BinHdr,
> @@ -381,7 +377,7 @@ fn new(fw: &'a firmware::Firmware) -> Result<Self> {
>
> fw.get(0..size_of::<BinHdr>())
> // Extract header.
> - .and_then(BinHdr::from_bytes_copy)
> + .and_then(|b| BinHdr::read_from_bytes(b).ok())
> // Validate header.
> .filter(|hdr| hdr.bin_magic == BIN_MAGIC)
> .map(|hdr| Self { hdr, fw })
> diff --git a/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs b/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs
> index d9fafd2eea5b..66b9f4d1b41c 100644
> --- a/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs
> +++ b/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs
> @@ -25,6 +25,8 @@
> },
> };
>
> +use zerocopy::FromBytes as _;
> +
> use crate::{
> driver::Bar0,
> falcon::{
> @@ -150,7 +152,7 @@ pub(crate) fn new(
> let hdr = fw
> .data()
> .get(0..size_of::<BinHdr>())
> - .and_then(BinHdr::from_bytes_copy)
> + .and_then(|b| BinHdr::read_from_bytes(b).ok())
> .ok_or(EINVAL)?;
>
> let desc = {
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 2/5] drm/nova: use `zerocopy` in booter.rs
2026-07-02 12:03 ` [PATCH v2 2/5] drm/nova: use `zerocopy` in booter.rs Pedro Yudi Honda
@ 2026-07-06 11:39 ` Alistair Popple
0 siblings, 0 replies; 14+ messages in thread
From: Alistair Popple @ 2026-07-06 11:39 UTC (permalink / raw)
To: Pedro Yudi Honda
Cc: dakr, acourbot, nico.antinori.7, aliceryhl, airlied, simona,
dri-devel, ojeda, rust-for-linux, nova-gpu
On 2026-07-02 at 22:03 +1000, Pedro Yudi Honda <niyudi.honda@usp.br> wrote...
> From: Pedro Yudi Honda <niyudi.honda@usp.br>
>
> In firmware/booter.rs, replace the following `transmute` traits with
> their `zerocopy` equivalents:
>
> - `transmute::FromBytes` -> `zerocopy::FromBytes`
Having a single item list reads a bit strange to me. I'd just say "replace
`transmute::FromBytes` with `zerocopy::FromBytes`" and if you want to list the
types it's replaced for you could. But that's a bit superfluous as it's clear
from the patch anyway.
But that's a small nit really, everything looks ok to me so feel free to add:
Reviewed-by: Alistair Popple <apopple@nvidia.com>
> Update call sites accordingly.
>
> Signed-off-by: Pedro Yudi Honda <niyudi.honda@usp.br>
> ---
> drivers/gpu/nova-core/firmware/booter.rs | 26 +++++++-----------------
> 1 file changed, 7 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/gpu/nova-core/firmware/booter.rs b/drivers/gpu/nova-core/firmware/booter.rs
> index acb7f4d8a532..fe9389b84b90 100644
> --- a/drivers/gpu/nova-core/firmware/booter.rs
> +++ b/drivers/gpu/nova-core/firmware/booter.rs
> @@ -10,8 +10,7 @@
> use kernel::{
> device,
> dma::Coherent,
> - prelude::*,
> - transmute::FromBytes, //
> + prelude::*, //
> };
>
> use crate::{
> @@ -43,7 +42,7 @@ fn frombytes_at<S: FromBytes + Sized>(slice: &[u8], offset: usize) -> Result<S>
> let end = offset.checked_add(size_of::<S>()).ok_or(EINVAL)?;
> slice
> .get(offset..end)
> - .and_then(S::from_bytes_copy)
> + .and_then(|b| S::read_from_bytes(b).ok())
> .ok_or(EINVAL)
> }
>
> @@ -52,7 +51,7 @@ fn frombytes_at<S: FromBytes + Sized>(slice: &[u8], offset: usize) -> Result<S>
> /// Such firmwares have an application-specific payload that needs to be patched with a given
> /// signature.
> #[repr(C)]
> -#[derive(Debug, Clone)]
> +#[derive(Debug, Clone, FromBytes)]
> struct HsHeaderV2 {
> /// Offset to the start of the signatures.
> sig_prod_offset: u32,
> @@ -75,9 +74,6 @@ struct HsHeaderV2 {
> header_size: u32,
> }
>
> -// SAFETY: all bit patterns are valid for this type, and it doesn't use interior mutability.
> -unsafe impl FromBytes for HsHeaderV2 {}
> -
> /// Heavy-Secured Firmware image container.
> ///
> /// This provides convenient access to the fields of [`HsHeaderV2`] that are actually indices to
> @@ -144,6 +140,7 @@ fn signatures_iter(&'a self) -> Result<impl Iterator<Item = BooterSignature<'a>>
>
> /// Signature parameters, as defined in the firmware.
> #[repr(C)]
> +#[derive(FromBytes)]
> struct HsSignatureParams {
> /// Fuse version to use.
> fuse_ver: u32,
> @@ -153,9 +150,6 @@ struct HsSignatureParams {
> ucode_id: u32,
> }
>
> -// SAFETY: all bit patterns are valid for this type, and it doesn't use interior mutability.
> -unsafe impl FromBytes for HsSignatureParams {}
> -
> impl HsSignatureParams {
> /// Returns the signature parameters contained in `hs_fw`.
> ///
> @@ -170,14 +164,14 @@ fn new(hs_fw: &HsFirmwareV2<'_>) -> Result<Self> {
> hs_fw
> .fw
> .get(start..end)
> - .and_then(Self::from_bytes_copy)
> + .and_then(|b| Self::read_from_bytes(b).ok())
> .ok_or(EINVAL)
> }
> }
>
> /// Header for code and data load offsets.
> #[repr(C)]
> -#[derive(Debug, Clone)]
> +#[derive(Debug, Clone, FromBytes)]
> struct HsLoadHeaderV2 {
> // Offset at which the code starts.
> os_code_offset: u32,
> @@ -191,9 +185,6 @@ struct HsLoadHeaderV2 {
> num_apps: u32,
> }
>
> -// SAFETY: all bit patterns are valid for this type, and it doesn't use interior mutability.
> -unsafe impl FromBytes for HsLoadHeaderV2 {}
> -
> impl HsLoadHeaderV2 {
> /// Returns the load header contained in `hs_fw`.
> ///
> @@ -205,7 +196,7 @@ fn new(hs_fw: &HsFirmwareV2<'_>) -> Result<Self> {
>
> /// Header for app code loader.
> #[repr(C)]
> -#[derive(Debug, Clone)]
> +#[derive(Debug, Clone, FromBytes)]
> struct HsLoadHeaderV2App {
> /// Offset at which to load the app code.
> offset: u32,
> @@ -213,9 +204,6 @@ struct HsLoadHeaderV2App {
> len: u32,
> }
>
> -// SAFETY: all bit patterns are valid for this type, and it doesn't use interior mutability.
> -unsafe impl FromBytes for HsLoadHeaderV2App {}
> -
> impl HsLoadHeaderV2App {
> /// Returns the [`HsLoadHeaderV2App`] for app `idx` of `hs_fw`.
> ///
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 3/5] drm/nova: use `zerocopy` in fwsec.rs
2026-07-02 12:03 ` [PATCH v2 3/5] drm/nova: use `zerocopy` in fwsec.rs Pedro Yudi Honda
@ 2026-07-06 11:43 ` Alistair Popple
0 siblings, 0 replies; 14+ messages in thread
From: Alistair Popple @ 2026-07-06 11:43 UTC (permalink / raw)
To: Pedro Yudi Honda
Cc: dakr, acourbot, nico.antinori.7, aliceryhl, airlied, simona,
dri-devel, ojeda, rust-for-linux, nova-gpu
On 2026-07-02 at 22:03 +1000, Pedro Yudi Honda <niyudi.honda@usp.br> wrote...
> From: Pedro Yudi Honda <niyudi.honda@usp.br>
>
> In firmware/fwsec.rs, replace the following `transmute` traits with
> their `zerocopy` equivalents:
>
> - `transmute::FromBytes` -> `zerocopy::FromBytes`
> - `transmute::AsBytes` -> `zerocopy::IntoBytes`
> - add `zerocopy::KnownLayout` where necessary
Argh, ok. It makes more sense when there are more things in the list :-) That
said I'd also be ok without, but either is fine.
Reviewed-by: Alistair Popple <apopple@nvidia.com>
> Update call sites accordingly.
>
> Signed-off-by: Pedro Yudi Honda <niyudi.honda@usp.br>
> ---
> drivers/gpu/nova-core/firmware/fwsec.rs | 49 ++++++-------------------
> 1 file changed, 12 insertions(+), 37 deletions(-)
>
> diff --git a/drivers/gpu/nova-core/firmware/fwsec.rs b/drivers/gpu/nova-core/firmware/fwsec.rs
> index 95e0dd77746b..1b75cdc02256 100644
> --- a/drivers/gpu/nova-core/firmware/fwsec.rs
> +++ b/drivers/gpu/nova-core/firmware/fwsec.rs
> @@ -19,11 +19,7 @@
> self,
> Device, //
> },
> - prelude::*,
> - transmute::{
> - AsBytes,
> - FromBytes, //
> - },
> + prelude::*, //
> };
>
> use crate::{
> @@ -49,26 +45,22 @@
> const NVFW_FALCON_APPIF_ID_DMEMMAPPER: u32 = 0x4;
>
> #[repr(C)]
> -#[derive(Debug)]
> +#[derive(Debug, FromBytes)]
> struct FalconAppifHdrV1 {
> version: u8,
> header_size: u8,
> entry_size: u8,
> entry_count: u8,
> }
> -// SAFETY: Any byte sequence is valid for this struct.
> -unsafe impl FromBytes for FalconAppifHdrV1 {}
>
> #[repr(C, packed)]
> -#[derive(Debug)]
> +#[derive(Debug, FromBytes)]
> struct FalconAppifV1 {
> id: u32,
> dmem_base: u32,
> }
> -// SAFETY: Any byte sequence is valid for this struct.
> -unsafe impl FromBytes for FalconAppifV1 {}
>
> -#[derive(Debug)]
> +#[derive(Debug, FromBytes, IntoBytes, zerocopy_derive::KnownLayout)]
> #[repr(C, packed)]
> struct FalconAppifDmemmapperV3 {
> signature: u32,
> @@ -89,12 +81,8 @@ struct FalconAppifDmemmapperV3 {
> ucode_cmd_mask1: u32,
> multi_tgt_tbl: u32,
> }
> -// SAFETY: Any byte sequence is valid for this struct.
> -unsafe impl FromBytes for FalconAppifDmemmapperV3 {}
> -// SAFETY: This struct doesn't contain uninitialized bytes and doesn't have interior mutability.
> -unsafe impl AsBytes for FalconAppifDmemmapperV3 {}
>
> -#[derive(Debug)]
> +#[derive(Debug, FromBytes, IntoBytes, zerocopy_derive::KnownLayout)]
> #[repr(C, packed)]
> struct ReadVbios {
> ver: u32,
> @@ -103,12 +91,8 @@ struct ReadVbios {
> size: u32,
> flags: u32,
> }
> -// SAFETY: Any byte sequence is valid for this struct.
> -unsafe impl FromBytes for ReadVbios {}
> -// SAFETY: This struct doesn't contain uninitialized bytes and doesn't have interior mutability.
> -unsafe impl AsBytes for ReadVbios {}
>
> -#[derive(Debug)]
> +#[derive(Debug, FromBytes, IntoBytes, zerocopy_derive::KnownLayout)]
> #[repr(C, packed)]
> struct FrtsRegion {
> ver: u32,
> @@ -117,22 +101,15 @@ struct FrtsRegion {
> size: u32,
> ftype: u32,
> }
> -// SAFETY: Any byte sequence is valid for this struct.
> -unsafe impl FromBytes for FrtsRegion {}
> -// SAFETY: This struct doesn't contain uninitialized bytes and doesn't have interior mutability.
> -unsafe impl AsBytes for FrtsRegion {}
>
> const NVFW_FRTS_CMD_REGION_TYPE_FB: u32 = 2;
>
> #[repr(C, packed)]
> +#[derive(FromBytes, IntoBytes, zerocopy_derive::KnownLayout)]
> struct FrtsCmd {
> read_vbios: ReadVbios,
> frts_region: FrtsRegion,
> }
> -// SAFETY: Any byte sequence is valid for this struct.
> -unsafe impl FromBytes for FrtsCmd {}
> -// SAFETY: This struct doesn't contain uninitialized bytes and doesn't have interior mutability.
> -unsafe impl AsBytes for FrtsCmd {}
>
> const NVFW_FALCON_APPIF_DMEMMAPPER_CMD_FRTS: u32 = 0x15;
> const NVFW_FALCON_APPIF_DMEMMAPPER_CMD_SB: u32 = 0x19;
> @@ -151,11 +128,9 @@ pub(crate) enum FwsecCommand {
>
> /// A single signature that can be patched into a FWSEC image.
> #[repr(transparent)]
> +#[derive(FromBytes)]
> pub(crate) struct Bcrt30Rsa3kSignature([u8; BCRT30_RSA3K_SIG_SIZE]);
>
> -/// SAFETY: A signature is just an array of bytes.
> -unsafe impl FromBytes for Bcrt30Rsa3kSignature {}
> -
> impl From<[u8; BCRT30_RSA3K_SIG_SIZE]> for Bcrt30Rsa3kSignature {
> fn from(sig: [u8; BCRT30_RSA3K_SIG_SIZE]) -> Self {
> Self(sig)
> @@ -228,7 +203,7 @@ fn new_fwsec(bios: &Vbios, cmd: FwsecCommand) -> Result<Self> {
>
> let hdr = ucode
> .get(hdr_offset..)
> - .and_then(FalconAppifHdrV1::from_bytes_prefix)
> + .and_then(|b| FalconAppifHdrV1::read_from_prefix(b).ok())
> .ok_or(EINVAL)?
> .0;
>
> @@ -246,7 +221,7 @@ fn new_fwsec(bios: &Vbios, cmd: FwsecCommand) -> Result<Self> {
>
> let app = ucode
> .get(entry_offset..)
> - .and_then(FalconAppifV1::from_bytes_prefix)
> + .and_then(|b| FalconAppifV1::read_from_prefix(b).ok())
> .ok_or(EINVAL)?
> .0;
>
> @@ -263,7 +238,7 @@ fn new_fwsec(bios: &Vbios, cmd: FwsecCommand) -> Result<Self> {
>
> let dmem_mapper = ucode
> .get_mut(dmem_mapper_offset..)
> - .and_then(FalconAppifDmemmapperV3::from_bytes_mut_prefix)
> + .and_then(|b| FalconAppifDmemmapperV3::mut_from_prefix(b).ok())
> .ok_or(EINVAL)?
> .0;
>
> @@ -281,7 +256,7 @@ fn new_fwsec(bios: &Vbios, cmd: FwsecCommand) -> Result<Self> {
>
> let frts_cmd = ucode
> .get_mut(frts_cmd_offset..)
> - .and_then(FrtsCmd::from_bytes_mut_prefix)
> + .and_then(|b| FrtsCmd::mut_from_prefix(b).ok())
> .ok_or(EINVAL)?
> .0;
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 4/5] drm/nova: use `zerocopy` in bootloader.rs
2026-07-02 12:03 ` [PATCH v2 4/5] drm/nova: use `zerocopy` in bootloader.rs Pedro Yudi Honda
@ 2026-07-06 11:44 ` Alistair Popple
0 siblings, 0 replies; 14+ messages in thread
From: Alistair Popple @ 2026-07-06 11:44 UTC (permalink / raw)
To: Pedro Yudi Honda
Cc: dakr, acourbot, nico.antinori.7, aliceryhl, airlied, simona,
dri-devel, ojeda, rust-for-linux, nova-gpu
On 2026-07-02 at 22:03 +1000, Pedro Yudi Honda <niyudi.honda@usp.br> wrote...
> From: Pedro Yudi Honda <niyudi.honda@usp.br>
>
> In firmware/fwsec/bootloader.rs, replace the following `transmute`
> traits with their `zerocopy` equivalents:
>
> - `transmute::FromBytes` -> `zerocopy::FromBytes`
> - `transmute::AsBytes` -> `zerocopy::IntoBytes`
> - add `zerocopy::Immutable` where necessary
>
> Update call sites accordingly.
Reviewed-by: Alistair Popple <apopple@nvidia.com>
>
> Signed-off-by: Pedro Yudi Honda <niyudi.honda@usp.br>
> ---
> .../gpu/nova-core/firmware/fwsec/bootloader.rs | 18 ++++--------------
> 1 file changed, 4 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs b/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs
> index 66b9f4d1b41c..03d3090bd9ef 100644
> --- a/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs
> +++ b/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs
> @@ -18,15 +18,9 @@
> Alignable,
> Alignment, //
> },
> - sizes,
> - transmute::{
> - AsBytes,
> - FromBytes, //
> - },
> + sizes, //
> };
>
> -use zerocopy::FromBytes as _;
> -
> use crate::{
> driver::Bar0,
> falcon::{
> @@ -57,7 +51,7 @@
> ///
> /// Most of its fields appear to be legacy and carry incorrect values, so they are left unused.
> #[repr(C)]
> -#[derive(Debug, Clone)]
> +#[derive(Debug, Clone, FromBytes)]
> struct BootloaderDesc {
> /// Starting tag of bootloader.
> start_tag: u32,
> @@ -73,15 +67,13 @@ struct BootloaderDesc {
> /// Size of data section in the image. Unused as we build the data section ourselves.
> _data_size: u32,
> }
> -// SAFETY: any byte sequence is valid for this struct.
> -unsafe impl FromBytes for BootloaderDesc {}
>
> /// Structure used by the boot-loader to load the rest of the code.
> ///
> /// This has to be filled by the GPU driver and copied into DMEM at offset
> /// [`BootloaderDesc.dmem_load_off`].
> #[repr(C, packed)]
> -#[derive(Debug, Clone)]
> +#[derive(Debug, Clone, IntoBytes, zerocopy_derive::Immutable)]
> struct BootloaderDmemDescV2 {
> /// Reserved, should always be first element.
> reserved: [u32; 4],
> @@ -120,8 +112,6 @@ struct BootloaderDmemDescV2 {
> /// Arguments to be passed to the target firmware being loaded.
> argv: u32,
> }
> -// SAFETY: This struct doesn't contain uninitialized bytes and doesn't have interior mutability.
> -unsafe impl AsBytes for BootloaderDmemDescV2 {}
>
> /// Wrapper for [`FwsecFirmware`] that includes the bootloader performing the actual load
> /// operation.
> @@ -160,7 +150,7 @@ pub(crate) fn new(
>
> fw.data()
> .get(desc_offset..)
> - .and_then(BootloaderDesc::from_bytes_copy_prefix)
> + .and_then(|b| BootloaderDesc::read_from_prefix(b).ok())
> .ok_or(EINVAL)?
> .0
> };
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 5/5] drm/nova: use `zerocopy` in riscv.rs
2026-07-02 12:03 ` [PATCH v2 5/5] drm/nova: use `zerocopy` in riscv.rs Pedro Yudi Honda
@ 2026-07-06 11:44 ` Alistair Popple
0 siblings, 0 replies; 14+ messages in thread
From: Alistair Popple @ 2026-07-06 11:44 UTC (permalink / raw)
To: Pedro Yudi Honda
Cc: dakr, acourbot, nico.antinori.7, aliceryhl, airlied, simona,
dri-devel, ojeda, rust-for-linux, nova-gpu
On 2026-07-02 at 22:03 +1000, Pedro Yudi Honda <niyudi.honda@usp.br> wrote...
> From: Pedro Yudi Honda <niyudi.honda@usp.br>
>
> In riscv.rs, replave the following `transmute` traits with their
> `zerocopy` equivalents:
>
> - `transmute::FromBytes` -> `zerocopy::FromBytes`
>
> Update call sites accordingly.
Thanks for the clean-ups.
Reviewed-by: Alistair Popple <apopple@nvidia.com>
> Signed-off-by: Pedro Yudi Honda <niyudi.honda@usp.br>
> ---
> drivers/gpu/nova-core/firmware/riscv.rs | 10 +++-------
> 1 file changed, 3 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/nova-core/firmware/riscv.rs b/drivers/gpu/nova-core/firmware/riscv.rs
> index 2afa7f36404e..ba56bc7d4188 100644
> --- a/drivers/gpu/nova-core/firmware/riscv.rs
> +++ b/drivers/gpu/nova-core/firmware/riscv.rs
> @@ -7,8 +7,7 @@
> device,
> dma::Coherent,
> firmware::Firmware,
> - prelude::*,
> - transmute::FromBytes, //
> + prelude::*, //
> };
>
> use crate::{
> @@ -18,7 +17,7 @@
>
> /// Descriptor for microcode running on a RISC-V core.
> #[repr(C)]
> -#[derive(Debug)]
> +#[derive(Debug, FromBytes)]
> struct RmRiscvUCodeDesc {
> version: u32,
> bootloader_offset: u32,
> @@ -36,9 +35,6 @@ struct RmRiscvUCodeDesc {
> monitor_code_size: u32,
> }
>
> -// SAFETY: all bit patterns are valid for this type, and it doesn't use interior mutability.
> -unsafe impl FromBytes for RmRiscvUCodeDesc {}
> -
> impl RmRiscvUCodeDesc {
> /// Interprets the header of `bin_fw` as a [`RmRiscvUCodeDesc`] and returns it.
> ///
> @@ -50,7 +46,7 @@ fn new(bin_fw: &BinFirmware<'_>) -> Result<Self> {
> bin_fw
> .fw
> .get(offset..end)
> - .and_then(Self::from_bytes_copy)
> + .and_then(|b| Self::read_from_bytes(b).ok())
> .ok_or(EINVAL)
> }
> }
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2026-07-06 11:44 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-02 12:03 [RESEND PATCH v2 0/5] drm/nova: replace `transmute` with `zerocopy` Pedro Yudi Honda
2026-07-02 12:03 ` [PATCH v2 1/5] drm/nova: use `zerocopy` in firmware.rs Pedro Yudi Honda
2026-07-06 7:15 ` Alistair Popple
2026-07-02 12:03 ` [PATCH v2 2/5] drm/nova: use `zerocopy` in booter.rs Pedro Yudi Honda
2026-07-06 11:39 ` Alistair Popple
2026-07-02 12:03 ` [PATCH v2 3/5] drm/nova: use `zerocopy` in fwsec.rs Pedro Yudi Honda
2026-07-06 11:43 ` Alistair Popple
2026-07-02 12:03 ` [PATCH v2 4/5] drm/nova: use `zerocopy` in bootloader.rs Pedro Yudi Honda
2026-07-06 11:44 ` Alistair Popple
2026-07-02 12:03 ` [PATCH v2 5/5] drm/nova: use `zerocopy` in riscv.rs Pedro Yudi Honda
2026-07-06 11:44 ` Alistair Popple
2026-07-04 13:00 ` [RESEND PATCH v2 0/5] drm/nova: replace `transmute` with `zerocopy` Miguel Ojeda
-- strict thread matches above, loose matches on Subject: below --
2026-07-01 17:40 [PATCH " Pedro Yudi Honda
2026-07-01 17:40 ` [PATCH v2 3/5] drm/nova: use `zerocopy` in fwsec.rs Pedro Yudi Honda
2026-07-01 17:48 ` sashiko-bot
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.