* [PATCH 1/1] nova-core: Update firmware bindings to use zerocopy traits
2026-06-29 2:52 [PATCH 0/1] nova-core: Convert bindings to use zerocopy Alistair Popple
@ 2026-06-29 2:52 ` Alistair Popple
2026-06-29 7:36 ` Alexandre Courbot
2026-06-29 5:55 ` [PATCH 0/1] nova-core: Convert bindings to use zerocopy SeungJong Ha
1 sibling, 1 reply; 9+ messages in thread
From: Alistair Popple @ 2026-06-29 2:52 UTC (permalink / raw)
To: acourbot
Cc: Alistair Popple, Danilo Krummrich, Alice Ryhl,
Nicolás Antinori, David Airlie, Shuah Khan, Simona Vetter,
Gary Guo, Onur Özkan, Tamir Duberstein, Trevor Gross,
Pedro Yudi Honda, SeungJong Ha, linux-kernel, dri-devel,
rust-for-linux, nova-gpu
Currently most of nova-core uses unsafe implementations of AsBytes and
FromBytes in order to read and write GSP commands using the generated
bindings. Whilst this is generally safe in practice there is nothing
that actually guarantees or checks this.
This is exactly what the zerocopy library was introduced to do - provide
compile-time checks ensuring From/AsBytes is safe. Make use of these
checks by converting all our generated bindings to derive the required
traits for the zerocopy checks, removing many unsafe implementations in
the process.
Note this does require the use of an unstable feature - trivial_bounds
- as some bindings end up needing to derive zerocopy::Unaligned.
A work-around is also required in the bindings to make some of the
__IncompleteArrayField<T> ZSTs monomorphic as the check macro can not
prove a generic type is aligned and thus forces T to derive
zerocopy::Unaligned, which is not satisfied by all types.
Signed-off-by: Alistair Popple <apopple@nvidia.com>
---
drivers/gpu/nova-core/Makefile | 4 +
drivers/gpu/nova-core/gsp/cmdq.rs | 21 +-
.../gpu/nova-core/gsp/cmdq/continuation.rs | 16 +-
drivers/gpu/nova-core/gsp/commands.rs | 19 +-
drivers/gpu/nova-core/gsp/fw.rs | 54 +----
drivers/gpu/nova-core/gsp/fw/commands.rs | 50 ++---
drivers/gpu/nova-core/gsp/fw/r570_144.rs | 41 ++++
.../gpu/nova-core/gsp/fw/r570_144/bindings.rs | 185 ++++++++++++------
drivers/gpu/nova-core/gsp/sequencer.rs | 5 +-
scripts/Makefile.build | 4 +-
10 files changed, 223 insertions(+), 176 deletions(-)
diff --git a/drivers/gpu/nova-core/Makefile b/drivers/gpu/nova-core/Makefile
index 4ae544f808f4..27a5752c4cf9 100644
--- a/drivers/gpu/nova-core/Makefile
+++ b/drivers/gpu/nova-core/Makefile
@@ -1,4 +1,8 @@
# SPDX-License-Identifier: GPL-2.0
+# The GSP firmware bindings derive zerocopy's `IntoBytes` on `#[repr(C)]`
+# unions, which is gated behind the `zerocopy_derive_union_into_bytes` cfg.
+rustflags-y += --cfg zerocopy_derive_union_into_bytes
+
obj-$(CONFIG_NOVA_CORE) += nova-core.o
nova-core-y := nova_core.o
diff --git a/drivers/gpu/nova-core/gsp/cmdq.rs b/drivers/gpu/nova-core/gsp/cmdq.rs
index 0671ee8a9960..6e79ec688983 100644
--- a/drivers/gpu/nova-core/gsp/cmdq.rs
+++ b/drivers/gpu/nova-core/gsp/cmdq.rs
@@ -29,6 +29,14 @@
},
};
+// TODO: Remove `as` once FromBytes is removed completely
+use zerocopy::{
+ FromBytes as ZCFromBytes,
+ Immutable,
+ IntoBytes,
+ KnownLayout, //
+};
+
use continuation::{
ContinuationRecord,
SplitState, //
@@ -76,7 +84,7 @@ pub(crate) trait CommandToGsp {
const FUNCTION: MsgFunction;
/// Type generated by [`CommandToGsp::init`], to be written into the command queue buffer.
- type Command: FromBytes + AsBytes;
+ type Command: ZCFromBytes + KnownLayout + Immutable + IntoBytes;
/// Type of the reply expected from the GSP, or [`NoReply`] for commands that don't
/// have a reply.
@@ -133,7 +141,7 @@ pub(crate) trait MessageFromGsp: Sized {
type InitError;
/// Type containing the raw message to be read from the message queue.
- type Message: FromBytes;
+ type Message: ZCFromBytes + KnownLayout + Immutable;
/// Method reading the message from the message queue and returning it.
///
@@ -383,7 +391,7 @@ fn allocate_command(&mut self, size: usize, timeout: Delta) -> Result<GspCommand
};
// Extract area for the `GspMsgElement`.
- let (header, slice_1) = GspMsgElement::from_bytes_mut_prefix(slice_1).ok_or(EIO)?;
+ let (header, slice_1) = GspMsgElement::mut_from_prefix(slice_1).map_err(|_| EIO)?;
// Create the contents area.
let (slice_1, slice_2) = if slice_1.len() > size {
@@ -639,7 +647,7 @@ fn send_single_command<M>(&mut self, bar: Bar0<'_>, command: M) -> Result
// Extract area for the command itself. The GSP message header and the command header
// together are guaranteed to fit entirely into a single page, so it's ok to only look
// at `dst.contents.0` here.
- let (cmd, payload_1) = M::Command::from_bytes_mut_prefix(dst.contents.0).ok_or(EIO)?;
+ let (cmd, payload_1) = M::Command::mut_from_prefix(dst.contents.0).map_err(|_| EIO)?;
// Fill the header and command in-place.
let msg_element = GspMsgElement::init(self.seq, size_in_bytes, M::FUNCTION);
@@ -744,7 +752,7 @@ fn wait_for_msg(&self, timeout: Delta) -> Result<GspMessage<'_>> {
.map(|(slice_1, slice_2)| (slice_1.as_flattened(), slice_2.as_flattened()))?;
// Extract the `GspMsgElement`.
- let (header, slice_1) = GspMsgElement::from_bytes_prefix(slice_1).ok_or(EIO)?;
+ let (header, slice_1) = GspMsgElement::ref_from_prefix(slice_1).map_err(|_| EIO)?;
dev_dbg!(
&self.dev,
@@ -822,7 +830,8 @@ fn receive_msg<M: MessageFromGsp>(&mut self, timeout: Delta) -> Result<M>
// Extract the message. Store the result as we want to advance the read pointer even in
// case of failure.
let result = if function == M::FUNCTION {
- let (cmd, contents_1) = M::Message::from_bytes_prefix(message.contents.0).ok_or(EIO)?;
+ let (cmd, contents_1) =
+ M::Message::ref_from_prefix(message.contents.0).map_err(|_| EIO)?;
let mut sbuffer = SBufferIter::new_reader([contents_1, message.contents.1]);
M::read(cmd, &mut sbuffer)
diff --git a/drivers/gpu/nova-core/gsp/cmdq/continuation.rs b/drivers/gpu/nova-core/gsp/cmdq/continuation.rs
index 05e904f18097..f0c69f0760a4 100644
--- a/drivers/gpu/nova-core/gsp/cmdq/continuation.rs
+++ b/drivers/gpu/nova-core/gsp/cmdq/continuation.rs
@@ -171,22 +171,18 @@ fn init_variable_payload(
mod tests {
use super::*;
- use kernel::transmute::{
- AsBytes,
- FromBytes, //
+ use zerocopy_derive::{
+ FromBytes,
+ Immutable,
+ IntoBytes,
+ KnownLayout, //
};
/// Non-zero-sized command header for testing.
#[repr(C)]
- #[derive(Clone, Copy, Zeroable)]
+ #[derive(Clone, Copy, FromBytes, Immutable, IntoBytes, KnownLayout, Zeroable)]
struct TestHeader([u8; 64]);
- // SAFETY: `TestHeader` is a plain array of bytes for which all bit patterns are valid.
- unsafe impl FromBytes for TestHeader {}
-
- // SAFETY: `TestHeader` is a plain array of bytes for which all bit patterns are valid.
- unsafe impl AsBytes for TestHeader {}
-
struct TestPayload {
data: KVVec<u8>,
}
diff --git a/drivers/gpu/nova-core/gsp/commands.rs b/drivers/gpu/nova-core/gsp/commands.rs
index 86a3747cd31c..f3c5806f9d19 100644
--- a/drivers/gpu/nova-core/gsp/commands.rs
+++ b/drivers/gpu/nova-core/gsp/commands.rs
@@ -12,11 +12,7 @@
use kernel::{
device,
pci,
- prelude::*,
- transmute::{
- AsBytes,
- FromBytes, //
- }, //
+ prelude::*, //
};
use crate::{
@@ -130,13 +126,12 @@ fn init_variable_payload(
let mut string_data = KVec::new();
for entry in self.entries.iter().take(Self::NUM_ENTRIES) {
- dst.write_all(
- fw::commands::PackedRegistryEntry::new(
+ dst.write_all(zerocopy::IntoBytes::as_bytes(
+ &fw::commands::PackedRegistryEntry::new(
(string_data_start_offset + string_data.len()) as u32,
entry.value,
- )
- .as_bytes(),
- )?;
+ ),
+ ))?;
let key_bytes = entry.key.as_bytes();
string_data.extend_from_slice(key_bytes, GFP_KERNEL)?;
@@ -150,10 +145,6 @@ fn init_variable_payload(
/// Message type for GSP initialization done notification.
struct GspInitDone;
-// SAFETY: `GspInitDone` is a zero-sized type with no bytes, therefore it
-// trivially has no uninitialized bytes.
-unsafe impl FromBytes for GspInitDone {}
-
impl MessageFromGsp for GspInitDone {
const FUNCTION: MsgFunction = MsgFunction::GspInitDone;
type InitError = Infallible;
diff --git a/drivers/gpu/nova-core/gsp/fw.rs b/drivers/gpu/nova-core/gsp/fw.rs
index 4db0cfa4dc4d..be2b4b046b19 100644
--- a/drivers/gpu/nova-core/gsp/fw.rs
+++ b/drivers/gpu/nova-core/gsp/fw.rs
@@ -27,6 +27,8 @@
},
};
+use zerocopy_derive::{Immutable, KnownLayout};
+
use crate::{
fb::FbLayout,
firmware::gsp::GspFirmware,
@@ -434,12 +436,6 @@ pub(crate) fn val(&self) -> u32 {
}
}
-// SAFETY: This struct only contains integer types for which all bit patterns are valid.
-unsafe impl FromBytes for RegWritePayload {}
-
-// SAFETY: Padding is explicit and will not contain uninitialized data.
-unsafe impl AsBytes for RegWritePayload {}
-
/// Wrapper for GSP sequencer register modify payload.
#[repr(transparent)]
#[derive(Copy, Clone, Debug)]
@@ -462,12 +458,6 @@ pub(crate) fn val(&self) -> u32 {
}
}
-// SAFETY: This struct only contains integer types for which all bit patterns are valid.
-unsafe impl FromBytes for RegModifyPayload {}
-
-// SAFETY: Padding is explicit and will not contain uninitialized data.
-unsafe impl AsBytes for RegModifyPayload {}
-
/// Wrapper for GSP sequencer register poll payload.
#[repr(transparent)]
#[derive(Copy, Clone, Debug)]
@@ -495,12 +485,6 @@ pub(crate) fn timeout(&self) -> u32 {
}
}
-// SAFETY: This struct only contains integer types for which all bit patterns are valid.
-unsafe impl FromBytes for RegPollPayload {}
-
-// SAFETY: Padding is explicit and will not contain uninitialized data.
-unsafe impl AsBytes for RegPollPayload {}
-
/// Wrapper for GSP sequencer delay payload.
#[repr(transparent)]
#[derive(Copy, Clone, Debug)]
@@ -513,12 +497,6 @@ pub(crate) fn val(&self) -> u32 {
}
}
-// SAFETY: This struct only contains integer types for which all bit patterns are valid.
-unsafe impl FromBytes for DelayUsPayload {}
-
-// SAFETY: Padding is explicit and will not contain uninitialized data.
-unsafe impl AsBytes for DelayUsPayload {}
-
/// Wrapper for GSP sequencer register store payload.
#[repr(transparent)]
#[derive(Copy, Clone, Debug)]
@@ -537,13 +515,8 @@ pub(crate) fn index(&self) -> u32 {
}
}
-// SAFETY: This struct only contains integer types for which all bit patterns are valid.
-unsafe impl FromBytes for RegStorePayload {}
-
-// SAFETY: Padding is explicit and will not contain uninitialized data.
-unsafe impl AsBytes for RegStorePayload {}
-
/// Wrapper for GSP sequencer buffer command.
+#[derive(FromBytes, Immutable, KnownLayout)]
#[repr(transparent)]
pub(crate) struct SequencerBufferCmd(bindings::GSP_SEQUENCER_BUFFER_CMD);
@@ -609,13 +582,8 @@ pub(crate) fn reg_store_payload(&self) -> Result<RegStorePayload> {
}
}
-// SAFETY: This struct only contains integer types for which all bit patterns are valid.
-unsafe impl FromBytes for SequencerBufferCmd {}
-
-// SAFETY: Padding is explicit and will not contain uninitialized data.
-unsafe impl AsBytes for SequencerBufferCmd {}
-
/// Wrapper for GSP run CPU sequencer RPC.
+#[derive(FromBytes, Immutable, KnownLayout)]
#[repr(transparent)]
pub(crate) struct RunCpuSequencer(bindings::rpc_run_cpu_sequencer_v17_00);
@@ -626,12 +594,6 @@ pub(crate) fn cmd_index(&self) -> u32 {
}
}
-// SAFETY: This struct only contains integer types for which all bit patterns are valid.
-unsafe impl FromBytes for RunCpuSequencer {}
-
-// SAFETY: Padding is explicit and will not contain uninitialized data.
-unsafe impl AsBytes for RunCpuSequencer {}
-
/// Struct containing the arguments required to pass a memory buffer to the GSP
/// for use during initialisation.
///
@@ -780,6 +742,7 @@ fn init(cmd_size: usize, function: MsgFunction) -> impl Init<Self, Error> {
/// GSP Message Element.
///
/// This is essentially a message header expected to be followed by the message data.
+#[derive(FromBytes, Immutable, IntoBytes, KnownLayout)]
#[repr(transparent)]
pub(crate) struct GspMsgElement {
inner: bindings::GSP_MSG_QUEUE_ELEMENT,
@@ -859,13 +822,6 @@ pub(crate) fn element_count(&self) -> u32 {
}
}
-// SAFETY: Padding is explicit and does not contain uninitialized data.
-unsafe impl AsBytes for GspMsgElement {}
-
-// SAFETY: This struct only contains integer types for which all bit patterns
-// are valid.
-unsafe impl FromBytes for GspMsgElement {}
-
/// Arguments for GSP startup.
#[repr(transparent)]
#[derive(Zeroable)]
diff --git a/drivers/gpu/nova-core/gsp/fw/commands.rs b/drivers/gpu/nova-core/gsp/fw/commands.rs
index ebdc12bcd4e3..18bb7ee2141a 100644
--- a/drivers/gpu/nova-core/gsp/fw/commands.rs
+++ b/drivers/gpu/nova-core/gsp/fw/commands.rs
@@ -6,11 +6,7 @@
use kernel::{
device,
pci,
- prelude::*,
- transmute::{
- AsBytes,
- FromBytes, //
- }, //
+ prelude::*, //
};
use crate::{
@@ -19,10 +15,16 @@
num::IntoSafeCast, //
};
+use zerocopy_derive::{
+ Immutable,
+ KnownLayout, //
+};
+
use super::bindings;
/// Payload of the `GspSetSystemInfo` command.
#[repr(transparent)]
+#[derive(FromBytes, Immutable, IntoBytes, KnownLayout)]
pub(crate) struct GspSetSystemInfo {
inner: bindings::GspSystemInfo,
}
@@ -64,15 +66,8 @@ pub(crate) fn init<'a>(
}
}
-// SAFETY: These structs don't meet the no-padding requirements of AsBytes but
-// that is not a problem because they are not used outside the kernel.
-unsafe impl AsBytes for GspSetSystemInfo {}
-
-// SAFETY: These structs don't meet the no-padding requirements of FromBytes but
-// that is not a problem because they are not used outside the kernel.
-unsafe impl FromBytes for GspSetSystemInfo {}
-
#[repr(transparent)]
+#[derive(FromBytes, Immutable, IntoBytes, KnownLayout)]
pub(crate) struct PackedRegistryEntry(bindings::PACKED_REGISTRY_ENTRY);
impl PackedRegistryEntry {
@@ -92,11 +87,9 @@ pub(crate) fn new(offset: u32, value: u32) -> Self {
}
}
-// SAFETY: Padding is explicit and will not contain uninitialized data.
-unsafe impl AsBytes for PackedRegistryEntry {}
-
/// Payload of the `SetRegistry` command.
#[repr(transparent)]
+#[derive(FromBytes, Immutable, IntoBytes, KnownLayout)]
pub(crate) struct PackedRegistryTable {
inner: bindings::PACKED_REGISTRY_TABLE,
}
@@ -115,16 +108,9 @@ pub(crate) fn init(num_entries: u32, size: u32) -> impl Init<Self> {
}
}
-// SAFETY: Padding is explicit and will not contain uninitialized data.
-unsafe impl AsBytes for PackedRegistryTable {}
-
-// SAFETY: This struct only contains integer types for which all bit patterns
-// are valid.
-unsafe impl FromBytes for PackedRegistryTable {}
-
/// Payload of the `GetGspStaticInfo` command and message.
#[repr(transparent)]
-#[derive(Zeroable)]
+#[derive(FromBytes, Immutable, IntoBytes, KnownLayout, Zeroable)]
pub(crate) struct GspStaticConfigInfo(bindings::GspStaticConfigInfo_t);
impl GspStaticConfigInfo {
@@ -169,13 +155,6 @@ pub(crate) fn usable_fb_regions(&self) -> impl Iterator<Item = Range<u64>> + '_
}
}
-// SAFETY: Padding is explicit and will not contain uninitialized data.
-unsafe impl AsBytes for GspStaticConfigInfo {}
-
-// SAFETY: This struct only contains integer types for which all bit patterns
-// are valid.
-unsafe impl FromBytes for GspStaticConfigInfo {}
-
/// Power level requested to the [`UnloadingGuestDriver`] command.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(u32)]
@@ -199,7 +178,7 @@ pub(crate) fn is_power_transition(self) -> bool {
/// Payload of the `UnloadingGuestDriver` command and message.
#[repr(transparent)]
-#[derive(Clone, Copy, Debug, Zeroable)]
+#[derive(Clone, Copy, Debug, FromBytes, Immutable, IntoBytes, KnownLayout, Zeroable)]
pub(crate) struct UnloadingGuestDriver(bindings::rpc_unloading_guest_driver_v1F_07);
impl UnloadingGuestDriver {
@@ -212,10 +191,3 @@ pub(crate) fn new(level: PowerStateLevel) -> Self {
})
}
}
-
-// SAFETY: Padding is explicit and will not contain uninitialized data.
-unsafe impl AsBytes for UnloadingGuestDriver {}
-
-// SAFETY: This struct only contains integer types for which all bit patterns
-// are valid.
-unsafe impl FromBytes for UnloadingGuestDriver {}
diff --git a/drivers/gpu/nova-core/gsp/fw/r570_144.rs b/drivers/gpu/nova-core/gsp/fw/r570_144.rs
index 2e6f0d298756..75f5e4a19596 100644
--- a/drivers/gpu/nova-core/gsp/fw/r570_144.rs
+++ b/drivers/gpu/nova-core/gsp/fw/r570_144.rs
@@ -23,9 +23,50 @@
)]
use kernel::ffi;
use pin_init::MaybeZeroable;
+use zerocopy_derive::{
+ FromBytes,
+ Immutable,
+ IntoBytes,
+ KnownLayout, //
+};
include!("r570_144/bindings.rs");
// SAFETY: This type has a size of zero, so its inclusion into another type should not affect their
// ability to implement `Zeroable`.
unsafe impl<T> kernel::prelude::Zeroable for __IncompleteArrayField<T> {}
+
+/// Monomorphic version of [`__IncompleteArrayField<PACKED_REGISTRY_ENTRY>`].
+///
+/// zerocopy's `IntoBytes` derive can only run its compile-time no-padding check
+/// on a concrete type; for the generic `__IncompleteArrayField<T>` it falls back
+/// to requiring every field be `Unaligned`, which `PACKED_REGISTRY_ENTRY`
+/// does not satisfy. Specializing to a concrete type lets the derive succeed.
+#[repr(C)]
+#[derive(Debug, Default, FromBytes, Immutable, IntoBytes, KnownLayout, MaybeZeroable)]
+pub struct __IncompletePackedRegistryEntry(
+ ::core::marker::PhantomData<PACKED_REGISTRY_ENTRY>,
+ [PACKED_REGISTRY_ENTRY; 0],
+);
+impl __IncompletePackedRegistryEntry {
+ #[inline]
+ pub const fn new() -> Self {
+ __IncompletePackedRegistryEntry(::core::marker::PhantomData, [])
+ }
+ #[inline]
+ pub fn as_ptr(&self) -> *const PACKED_REGISTRY_ENTRY {
+ self as *const _ as *const PACKED_REGISTRY_ENTRY
+ }
+ #[inline]
+ pub fn as_mut_ptr(&mut self) -> *mut PACKED_REGISTRY_ENTRY {
+ self as *mut _ as *mut PACKED_REGISTRY_ENTRY
+ }
+ #[inline]
+ pub unsafe fn as_slice(&self, len: usize) -> &[PACKED_REGISTRY_ENTRY] {
+ ::core::slice::from_raw_parts(self.as_ptr(), len)
+ }
+ #[inline]
+ pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [PACKED_REGISTRY_ENTRY] {
+ ::core::slice::from_raw_parts_mut(self.as_mut_ptr(), len)
+ }
+}
diff --git a/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs b/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
index ea350f9b2cc4..9c85c93f6eee 100644
--- a/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
+++ b/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
#[repr(C)]
-#[derive(Default)]
+#[derive(Default, FromBytes, IntoBytes, Immutable, KnownLayout)]
pub struct __IncompleteArrayField<T>(::core::marker::PhantomData<T>, [T; 0]);
impl<T> __IncompleteArrayField<T> {
#[inline]
@@ -325,7 +325,9 @@ fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
pub const NV_VGPU_MSG_EVENT_NUM_EVENTS: _bindgen_ty_3 = 4131;
pub type _bindgen_ty_3 = ffi::c_uint;
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct NV0080_CTRL_GPU_GET_SRIOV_CAPS_PARAMS {
pub totalVFs: u32_,
pub firstVfOffset: u32_,
@@ -349,7 +351,9 @@ pub struct NV0080_CTRL_GPU_GET_SRIOV_CAPS_PARAMS {
pub __bindgen_padding_1: [u8; 7usize],
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct NV2080_CTRL_BIOS_GET_SKU_INFO_PARAMS {
pub BoardID: u32_,
pub chipSKU: [ffi::c_char; 9usize],
@@ -365,7 +369,9 @@ pub struct NV2080_CTRL_BIOS_GET_SKU_INFO_PARAMS {
}
pub type NV2080_CTRL_CMD_FB_GET_FB_REGION_SURFACE_MEM_TYPE_FLAG = [u8_; 17usize];
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct NV2080_CTRL_CMD_FB_GET_FB_REGION_FB_REGION_INFO {
pub base: u64_,
pub limit: u64_,
@@ -377,14 +383,16 @@ pub struct NV2080_CTRL_CMD_FB_GET_FB_REGION_FB_REGION_INFO {
pub blackList: NV2080_CTRL_CMD_FB_GET_FB_REGION_SURFACE_MEM_TYPE_FLAG,
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_PARAMS {
pub numFBRegions: u32_,
pub __bindgen_padding_0: [u8; 4usize],
pub fbRegion: [NV2080_CTRL_CMD_FB_GET_FB_REGION_FB_REGION_INFO; 16usize],
}
#[repr(C)]
-#[derive(Debug, Copy, Clone, MaybeZeroable)]
+#[derive(Debug, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes)]
pub struct NV2080_CTRL_GPU_GET_GID_INFO_PARAMS {
pub index: u32_,
pub flags: u32_,
@@ -401,14 +409,18 @@ fn default() -> Self {
}
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct DOD_METHOD_DATA {
pub status: u32_,
pub acpiIdListLen: u32_,
pub acpiIdList: [u32_; 16usize],
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct JT_METHOD_DATA {
pub status: u32_,
pub jtCaps: u32_,
@@ -417,14 +429,18 @@ pub struct JT_METHOD_DATA {
pub __bindgen_padding_0: u8,
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct MUX_METHOD_DATA_ELEMENT {
pub acpiId: u32_,
pub mode: u32_,
pub status: u32_,
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct MUX_METHOD_DATA {
pub tableLen: u32_,
pub acpiIdMuxModeTable: [MUX_METHOD_DATA_ELEMENT; 16usize],
@@ -432,13 +448,17 @@ pub struct MUX_METHOD_DATA {
pub acpiIdMuxStateTable: [MUX_METHOD_DATA_ELEMENT; 16usize],
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct CAPS_METHOD_DATA {
pub status: u32_,
pub optimusCaps: u32_,
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct ACPI_METHOD_DATA {
pub bValid: u8_,
pub __bindgen_padding_0: [u8; 3usize],
@@ -447,21 +467,28 @@ pub struct ACPI_METHOD_DATA {
pub muxMethodData: MUX_METHOD_DATA,
pub capsMethodData: CAPS_METHOD_DATA,
}
+pub type GspStaticConfigInfo = GspStaticConfigInfo_t;
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct VIRTUAL_DISPLAY_GET_MAX_RESOLUTION_PARAMS {
pub headIndex: u32_,
pub maxHResolution: u32_,
pub maxVResolution: u32_,
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct VIRTUAL_DISPLAY_GET_NUM_HEADS_PARAMS {
pub numHeads: u32_,
pub maxNumHeads: u32_,
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct BUSINFO {
pub deviceID: u16_,
pub vendorID: u16_,
@@ -471,7 +498,9 @@ pub struct BUSINFO {
pub __bindgen_padding_0: u8,
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct GSP_VF_INFO {
pub totalVFs: u32_,
pub firstVFOffset: u32_,
@@ -484,25 +513,31 @@ pub struct GSP_VF_INFO {
pub __bindgen_padding_0: [u8; 5usize],
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct GSP_PCIE_CONFIG_REG {
pub linkCap: u32_,
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct EcidManufacturingInfo {
pub ecidLow: u32_,
pub ecidHigh: u32_,
pub ecidExtended: u32_,
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct FW_WPR_LAYOUT_OFFSET {
pub nonWprHeapOffset: u64_,
pub frtsOffset: u64_,
}
#[repr(C)]
-#[derive(Debug, Copy, Clone, MaybeZeroable)]
+#[derive(Debug, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes)]
pub struct GspStaticConfigInfo_t {
pub grCapsBits: [u8_; 23usize],
pub __bindgen_padding_0: u8,
@@ -575,7 +610,9 @@ fn default() -> Self {
}
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct GspSystemInfo {
pub gpuPhysAddr: u64_,
pub gpuPhysFbAddr: u64_,
@@ -632,7 +669,9 @@ pub struct GspSystemInfo {
pub hostPageSize: u64_,
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct MESSAGE_QUEUE_INIT_ARGUMENTS {
pub sharedMemPhysAddr: u64_,
pub pageTableEntryCount: u32_,
@@ -641,7 +680,9 @@ pub struct MESSAGE_QUEUE_INIT_ARGUMENTS {
pub statQueueOffset: u64_,
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct GSP_SR_INIT_ARGUMENTS {
pub oldLevel: u32_,
pub flags: u32_,
@@ -649,7 +690,9 @@ pub struct GSP_SR_INIT_ARGUMENTS {
pub __bindgen_padding_0: [u8; 3usize],
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct GSP_ARGUMENTS_CACHED {
pub messageQueueInitArguments: MESSAGE_QUEUE_INIT_ARGUMENTS,
pub srInitArguments: GSP_SR_INIT_ARGUMENTS,
@@ -659,13 +702,15 @@ pub struct GSP_ARGUMENTS_CACHED {
pub profilerArgs: GSP_ARGUMENTS_CACHED__bindgen_ty_1,
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct GSP_ARGUMENTS_CACHED__bindgen_ty_1 {
pub pa: u64_,
pub size: u64_,
}
#[repr(C)]
-#[derive(Copy, Clone, MaybeZeroable)]
+#[derive(Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes)]
pub union rpc_message_rpc_union_field_v03_00 {
pub spare: u32_,
pub cpuRmGfid: u32_,
@@ -681,7 +726,7 @@ fn default() -> Self {
}
pub type rpc_message_rpc_union_field_v = rpc_message_rpc_union_field_v03_00;
#[repr(C)]
-#[derive(MaybeZeroable)]
+#[derive(MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes)]
pub struct rpc_message_header_v03_00 {
pub header_version: u32_,
pub signature: u32_,
@@ -704,7 +749,7 @@ fn default() -> Self {
}
pub type rpc_message_header_v = rpc_message_header_v03_00;
#[repr(C)]
-#[derive(Copy, Clone, MaybeZeroable)]
+#[derive(Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes)]
pub struct GspFwWprMeta {
pub magic: u64_,
pub revision: u64_,
@@ -739,19 +784,23 @@ pub struct GspFwWprMeta {
pub verified: u64_,
}
#[repr(C)]
-#[derive(Copy, Clone, MaybeZeroable)]
+#[derive(Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes)]
pub union GspFwWprMeta__bindgen_ty_1 {
pub __bindgen_anon_1: GspFwWprMeta__bindgen_ty_1__bindgen_ty_1,
pub __bindgen_anon_2: GspFwWprMeta__bindgen_ty_1__bindgen_ty_2,
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct GspFwWprMeta__bindgen_ty_1__bindgen_ty_1 {
pub sysmemAddrOfSignature: u64_,
pub sizeOfSignature: u64_,
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct GspFwWprMeta__bindgen_ty_1__bindgen_ty_2 {
pub gspFwHeapFreeListWprOffset: u32_,
pub unused0: u32_,
@@ -767,13 +816,15 @@ fn default() -> Self {
}
}
#[repr(C)]
-#[derive(Copy, Clone, MaybeZeroable)]
+#[derive(Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes)]
pub union GspFwWprMeta__bindgen_ty_2 {
pub __bindgen_anon_1: GspFwWprMeta__bindgen_ty_2__bindgen_ty_1,
pub __bindgen_anon_2: GspFwWprMeta__bindgen_ty_2__bindgen_ty_2,
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct GspFwWprMeta__bindgen_ty_2__bindgen_ty_1 {
pub partitionRpcAddr: u64_,
pub partitionRpcRequestOffset: u16_,
@@ -785,7 +836,9 @@ pub struct GspFwWprMeta__bindgen_ty_2__bindgen_ty_1 {
pub lsUcodeVersion: u32_,
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct GspFwWprMeta__bindgen_ty_2__bindgen_ty_2 {
pub partitionRpcPadding: [u32_; 4usize],
pub sysmemAddrOfCrashReportQueue: u64_,
@@ -820,7 +873,9 @@ fn default() -> Self {
pub const LibosMemoryRegionLoc_LIBOS_MEMORY_REGION_LOC_FB: LibosMemoryRegionLoc = 2;
pub type LibosMemoryRegionLoc = ffi::c_uint;
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct LibosMemoryRegionInitArgument {
pub id8: LibosAddress,
pub pa: LibosAddress,
@@ -830,7 +885,9 @@ pub struct LibosMemoryRegionInitArgument {
pub __bindgen_padding_0: [u8; 6usize],
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct PACKED_REGISTRY_ENTRY {
pub nameOffset: u32_,
pub type_: u8_,
@@ -839,14 +896,16 @@ pub struct PACKED_REGISTRY_ENTRY {
pub length: u32_,
}
#[repr(C)]
-#[derive(Debug, Default, MaybeZeroable)]
+#[derive(Debug, Default, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes)]
pub struct PACKED_REGISTRY_TABLE {
pub size: u32_,
pub numEntries: u32_,
- pub entries: __IncompleteArrayField<PACKED_REGISTRY_ENTRY>,
+ pub entries: __IncompletePackedRegistryEntry,
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct msgqTxHeader {
pub version: u32_,
pub size: u32_,
@@ -858,13 +917,15 @@ pub struct msgqTxHeader {
pub entryOff: u32_,
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct msgqRxHeader {
pub readPtr: u32_,
}
#[repr(C)]
#[repr(align(8))]
-#[derive(MaybeZeroable)]
+#[derive(MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes)]
pub struct GSP_MSG_QUEUE_ELEMENT {
pub authTagBuffer: [u8_; 16usize],
pub aadBuffer: [u8_; 16usize],
@@ -889,12 +950,14 @@ fn default() -> Self {
pub const GSP_DMA_TARGET_GSP_DMA_TARGET_COUNT: GSP_DMA_TARGET = 3;
pub type GSP_DMA_TARGET = ffi::c_uint;
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct GSP_FMC_INIT_PARAMS {
pub regkeys: u32_,
}
#[repr(C)]
-#[derive(Debug, Copy, Clone, MaybeZeroable)]
+#[derive(Debug, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes)]
pub struct GSP_ACR_BOOT_GSP_RM_PARAMS {
pub target: GSP_DMA_TARGET,
pub gspRmDescSize: u32_,
@@ -914,7 +977,7 @@ fn default() -> Self {
}
}
#[repr(C)]
-#[derive(Debug, Copy, Clone, MaybeZeroable)]
+#[derive(Debug, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes)]
pub struct GSP_RM_PARAMS {
pub target: GSP_DMA_TARGET,
pub __bindgen_padding_0: [u8; 4usize],
@@ -930,7 +993,7 @@ fn default() -> Self {
}
}
#[repr(C)]
-#[derive(Debug, Copy, Clone, MaybeZeroable)]
+#[derive(Debug, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes)]
pub struct GSP_SPDM_PARAMS {
pub target: GSP_DMA_TARGET,
pub __bindgen_padding_0: [u8; 4usize],
@@ -948,7 +1011,7 @@ fn default() -> Self {
}
}
#[repr(C)]
-#[derive(Debug, Copy, Clone, MaybeZeroable)]
+#[derive(Debug, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes)]
pub struct GSP_FMC_BOOT_PARAMS {
pub initParams: GSP_FMC_INIT_PARAMS,
pub __bindgen_padding_0: [u8; 4usize],
@@ -966,7 +1029,9 @@ fn default() -> Self {
}
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct rpc_unloading_guest_driver_v1F_07 {
pub bInPMTransition: u8_,
pub bGc6Entering: u8_,
@@ -974,7 +1039,7 @@ pub struct rpc_unloading_guest_driver_v1F_07 {
pub newLevel: u32_,
}
#[repr(C)]
-#[derive(Debug, Default, MaybeZeroable)]
+#[derive(Debug, Default, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes)]
pub struct rpc_run_cpu_sequencer_v17_00 {
pub bufferSizeDWord: u32_,
pub cmdIndex: u32_,
@@ -992,20 +1057,26 @@ pub struct rpc_run_cpu_sequencer_v17_00 {
pub const GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_RESUME: GSP_SEQ_BUF_OPCODE = 8;
pub type GSP_SEQ_BUF_OPCODE = ffi::c_uint;
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct GSP_SEQ_BUF_PAYLOAD_REG_WRITE {
pub addr: u32_,
pub val: u32_,
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct GSP_SEQ_BUF_PAYLOAD_REG_MODIFY {
pub addr: u32_,
pub mask: u32_,
pub val: u32_,
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct GSP_SEQ_BUF_PAYLOAD_REG_POLL {
pub addr: u32_,
pub mask: u32_,
@@ -1014,24 +1085,28 @@ pub struct GSP_SEQ_BUF_PAYLOAD_REG_POLL {
pub error: u32_,
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct GSP_SEQ_BUF_PAYLOAD_DELAY_US {
pub val: u32_,
}
#[repr(C)]
-#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+#[derive(
+ Debug, Default, Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes,
+)]
pub struct GSP_SEQ_BUF_PAYLOAD_REG_STORE {
pub addr: u32_,
pub index: u32_,
}
#[repr(C)]
-#[derive(Copy, Clone, MaybeZeroable)]
+#[derive(Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes)]
pub struct GSP_SEQUENCER_BUFFER_CMD {
pub opCode: GSP_SEQ_BUF_OPCODE,
pub payload: GSP_SEQUENCER_BUFFER_CMD__bindgen_ty_1,
}
#[repr(C)]
-#[derive(Copy, Clone, MaybeZeroable)]
+#[derive(Copy, Clone, MaybeZeroable, FromBytes, Immutable, KnownLayout, IntoBytes)]
pub union GSP_SEQUENCER_BUFFER_CMD__bindgen_ty_1 {
pub regWrite: GSP_SEQ_BUF_PAYLOAD_REG_WRITE,
pub regModify: GSP_SEQ_BUF_PAYLOAD_REG_MODIFY,
diff --git a/drivers/gpu/nova-core/gsp/sequencer.rs b/drivers/gpu/nova-core/gsp/sequencer.rs
index e0850d21adca..99b05999c9b7 100644
--- a/drivers/gpu/nova-core/gsp/sequencer.rs
+++ b/drivers/gpu/nova-core/gsp/sequencer.rs
@@ -15,9 +15,10 @@
delay::fsleep,
Delta, //
},
- transmute::FromBytes, //
};
+use zerocopy::FromBytes;
+
use crate::{
driver::Bar0,
falcon::{
@@ -82,7 +83,7 @@ pub(crate) enum GspSeqCmd {
impl GspSeqCmd {
/// Creates a new `GspSeqCmd` from raw data returning the command and its size in bytes.
pub(crate) fn new(data: &[u8], dev: &device::Device) -> Result<(Self, usize)> {
- let fw_cmd = fw::SequencerBufferCmd::from_bytes(data).ok_or(EINVAL)?;
+ let fw_cmd = fw::SequencerBufferCmd::ref_from_bytes(data).map_err(|_| EINVAL)?;
let opcode_size = core::mem::size_of::<u32>();
let (cmd, size) = match fw_cmd.opcode()? {
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 911745743246..0d0f315e43d0 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -314,10 +314,12 @@ $(obj)/%.lst: $(obj)/%.c FORCE
# - Stable since Rust 1.89.0: `feature(generic_arg_infer)`.
# - Expected to become stable: `feature(arbitrary_self_types)`.
# - To be determined: `feature(used_with_arg)`.
+# - Required by nova-core's zerocopy firmware bindings, whose derives emit
+# trivial `where` bounds: `feature(trivial_bounds)`.
#
# Please see https://github.com/Rust-for-Linux/linux/issues/2 for details on
# the unstable features in use.
-rust_allowed_features := arbitrary_self_types,asm_goto,generic_arg_infer,used_with_arg
+rust_allowed_features := arbitrary_self_types,asm_goto,generic_arg_infer,used_with_arg,trivial_bounds
# `--out-dir` is required to avoid temporaries being created by `rustc` in the
# current working directory, which may be not accessible in the out-of-tree
--
2.54.0
^ permalink raw reply related [flat|nested] 9+ messages in thread