Commit c4f2ae53 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-rust-fixes-2025-12-29' of...

Merge tag 'drm-rust-fixes-2025-12-29' of https://gitlab.freedesktop.org/drm/rust/kernel

 into drm-fixes

DRM Rust fixes for v6.19-rc4

MAINTAINERS:
  - Fix Nova GPU driver git links.
  - Fix typo in TYR driver entry preventing correct behavior of
    scripts/get_maintainer.pl.
  - Exclude TYR driver from DRM MISC.

Nova Core:
  - Correctly select RUST_FW_LOADER_ABSTRACTIONS to prevent build
    errors.
  - Regenerate nova-core bindgen bindings with '--explicit-padding' to
    avoid uninitialized bytes.
  - Fix length of received GSP messages, due to miscalculated message
    payload size.
  - Regenerate bindings to derive MaybeZeroable.
  - Use a bindings alias to derive the firmware version.

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: "Danilo Krummrich" <dakr@kernel.org>
Link: https://patch.msgid.link/DFATYVSQRQ4W.1R030NZ34XUZK@kernel.org
parents 9ace4753 97872fa2
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -2158,7 +2158,7 @@ M: Alice Ryhl <aliceryhl@google.com>
L:	dri-devel@lists.freedesktop.org
S:	Supported
W:	https://rust-for-linux.com/tyr-gpu-driver
W	https://drm.pages.freedesktop.org/maintainer-tools/drm-rust.html
W:	https://drm.pages.freedesktop.org/maintainer-tools/drm-rust.html
B:	https://gitlab.freedesktop.org/panfrost/linux/-/issues
T:	git https://gitlab.freedesktop.org/drm/rust/kernel.git
F:	Documentation/devicetree/bindings/gpu/arm,mali-valhall-csf.yaml
@@ -8067,7 +8067,7 @@ W: https://rust-for-linux.com/nova-gpu-driver
Q:	https://patchwork.freedesktop.org/project/nouveau/
B:	https://gitlab.freedesktop.org/drm/nova/-/issues
C:	irc://irc.oftc.net/nouveau
T:	git https://gitlab.freedesktop.org/drm/nova.git nova-next
T:	git https://gitlab.freedesktop.org/drm/rust/kernel.git drm-rust-next
F:	Documentation/gpu/nova/
F:	drivers/gpu/nova-core/
@@ -8079,7 +8079,7 @@ W: https://rust-for-linux.com/nova-gpu-driver
Q:	https://patchwork.freedesktop.org/project/nouveau/
B:	https://gitlab.freedesktop.org/drm/nova/-/issues
C:	irc://irc.oftc.net/nouveau
T:	git https://gitlab.freedesktop.org/drm/nova.git nova-next
T:	git https://gitlab.freedesktop.org/drm/rust/kernel.git drm-rust-next
F:	Documentation/gpu/nova/
F:	drivers/gpu/drm/nova/
F:	include/uapi/drm/nova_drm.h
@@ -8357,6 +8357,7 @@ X: drivers/gpu/drm/msm/
X:	drivers/gpu/drm/nova/
X:	drivers/gpu/drm/radeon/
X:	drivers/gpu/drm/tegra/
X:	drivers/gpu/drm/tyr/
X:	drivers/gpu/drm/xe/
DRM DRIVERS AND COMMON INFRASTRUCTURE [RUST]
+1 −1
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@ config NOVA_CORE
	depends on 64BIT
	depends on PCI
	depends on RUST
	depends on RUST_FW_LOADER_ABSTRACTIONS
	select RUST_FW_LOADER_ABSTRACTIONS
	select AUXILIARY_BUS
	default n
	help
+8 −6
Original line number Diff line number Diff line
@@ -588,21 +588,23 @@ fn wait_for_msg(&self, timeout: Delta) -> Result<GspMessage<'_>> {
            header.length(),
        );

        let payload_length = header.payload_length();

        // Check that the driver read area is large enough for the message.
        if slice_1.len() + slice_2.len() < header.length() {
        if slice_1.len() + slice_2.len() < payload_length {
            return Err(EIO);
        }

        // Cut the message slices down to the actual length of the message.
        let (slice_1, slice_2) = if slice_1.len() > header.length() {
            // PANIC: we checked above that `slice_1` is at least as long as `msg_header.length()`.
            (slice_1.split_at(header.length()).0, &slice_2[0..0])
        let (slice_1, slice_2) = if slice_1.len() > payload_length {
            // PANIC: we checked above that `slice_1` is at least as long as `payload_length`.
            (slice_1.split_at(payload_length).0, &slice_2[0..0])
        } else {
            (
                slice_1,
                // PANIC: we checked above that `slice_1.len() + slice_2.len()` is at least as
                // large as `msg_header.length()`.
                slice_2.split_at(header.length() - slice_1.len()).0,
                // large as `payload_length`.
                slice_2.split_at(payload_length - slice_1.len()).0,
            )
        };

+38 −40
Original line number Diff line number Diff line
@@ -141,8 +141,8 @@ unsafe impl AsBytes for GspFwWprMeta {}
// are valid.
unsafe impl FromBytes for GspFwWprMeta {}

type GspFwWprMetaBootResumeInfo = r570_144::GspFwWprMeta__bindgen_ty_1;
type GspFwWprMetaBootInfo = r570_144::GspFwWprMeta__bindgen_ty_1__bindgen_ty_1;
type GspFwWprMetaBootResumeInfo = bindings::GspFwWprMeta__bindgen_ty_1;
type GspFwWprMetaBootInfo = bindings::GspFwWprMeta__bindgen_ty_1__bindgen_ty_1;

impl GspFwWprMeta {
    /// Fill in and return a `GspFwWprMeta` suitable for booting `gsp_firmware` using the
@@ -150,8 +150,8 @@ impl GspFwWprMeta {
    pub(crate) fn new(gsp_firmware: &GspFirmware, fb_layout: &FbLayout) -> Self {
        Self(bindings::GspFwWprMeta {
            // CAST: we want to store the bits of `GSP_FW_WPR_META_MAGIC` unmodified.
            magic: r570_144::GSP_FW_WPR_META_MAGIC as u64,
            revision: u64::from(r570_144::GSP_FW_WPR_META_REVISION),
            magic: bindings::GSP_FW_WPR_META_MAGIC as u64,
            revision: u64::from(bindings::GSP_FW_WPR_META_REVISION),
            sysmemAddrOfRadix3Elf: gsp_firmware.radix3_dma_handle(),
            sizeOfRadix3Elf: u64::from_safe_cast(gsp_firmware.size),
            sysmemAddrOfBootloader: gsp_firmware.bootloader.ucode.dma_handle(),
@@ -315,19 +315,19 @@ fn from(value: MsgFunction) -> Self {
#[repr(u32)]
pub(crate) enum SeqBufOpcode {
    // Core operation opcodes
    CoreReset = r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_RESET,
    CoreResume = r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_RESUME,
    CoreStart = r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_START,
    CoreWaitForHalt = r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_WAIT_FOR_HALT,
    CoreReset = bindings::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_RESET,
    CoreResume = bindings::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_RESUME,
    CoreStart = bindings::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_START,
    CoreWaitForHalt = bindings::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_WAIT_FOR_HALT,

    // Delay opcode
    DelayUs = r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_DELAY_US,
    DelayUs = bindings::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_DELAY_US,

    // Register operation opcodes
    RegModify = r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_REG_MODIFY,
    RegPoll = r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_REG_POLL,
    RegStore = r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_REG_STORE,
    RegWrite = r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_REG_WRITE,
    RegModify = bindings::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_REG_MODIFY,
    RegPoll = bindings::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_REG_POLL,
    RegStore = bindings::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_REG_STORE,
    RegWrite = bindings::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_REG_WRITE,
}

impl fmt::Display for SeqBufOpcode {
@@ -351,25 +351,25 @@ impl TryFrom<u32> for SeqBufOpcode {

    fn try_from(value: u32) -> Result<SeqBufOpcode> {
        match value {
            r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_RESET => {
            bindings::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_RESET => {
                Ok(SeqBufOpcode::CoreReset)
            }
            r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_RESUME => {
            bindings::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_RESUME => {
                Ok(SeqBufOpcode::CoreResume)
            }
            r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_START => {
            bindings::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_START => {
                Ok(SeqBufOpcode::CoreStart)
            }
            r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_WAIT_FOR_HALT => {
            bindings::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_CORE_WAIT_FOR_HALT => {
                Ok(SeqBufOpcode::CoreWaitForHalt)
            }
            r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_DELAY_US => Ok(SeqBufOpcode::DelayUs),
            r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_REG_MODIFY => {
            bindings::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_DELAY_US => Ok(SeqBufOpcode::DelayUs),
            bindings::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_REG_MODIFY => {
                Ok(SeqBufOpcode::RegModify)
            }
            r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_REG_POLL => Ok(SeqBufOpcode::RegPoll),
            r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_REG_STORE => Ok(SeqBufOpcode::RegStore),
            r570_144::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_REG_WRITE => Ok(SeqBufOpcode::RegWrite),
            bindings::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_REG_POLL => Ok(SeqBufOpcode::RegPoll),
            bindings::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_REG_STORE => Ok(SeqBufOpcode::RegStore),
            bindings::GSP_SEQ_BUF_OPCODE_GSP_SEQ_BUF_OPCODE_REG_WRITE => Ok(SeqBufOpcode::RegWrite),
            _ => Err(EINVAL),
        }
    }
@@ -385,7 +385,7 @@ fn from(value: SeqBufOpcode) -> Self {
/// Wrapper for GSP sequencer register write payload.
#[repr(transparent)]
#[derive(Copy, Clone)]
pub(crate) struct RegWritePayload(r570_144::GSP_SEQ_BUF_PAYLOAD_REG_WRITE);
pub(crate) struct RegWritePayload(bindings::GSP_SEQ_BUF_PAYLOAD_REG_WRITE);

impl RegWritePayload {
    /// Returns the register address.
@@ -408,7 +408,7 @@ unsafe impl AsBytes for RegWritePayload {}
/// Wrapper for GSP sequencer register modify payload.
#[repr(transparent)]
#[derive(Copy, Clone)]
pub(crate) struct RegModifyPayload(r570_144::GSP_SEQ_BUF_PAYLOAD_REG_MODIFY);
pub(crate) struct RegModifyPayload(bindings::GSP_SEQ_BUF_PAYLOAD_REG_MODIFY);

impl RegModifyPayload {
    /// Returns the register address.
@@ -436,7 +436,7 @@ unsafe impl AsBytes for RegModifyPayload {}
/// Wrapper for GSP sequencer register poll payload.
#[repr(transparent)]
#[derive(Copy, Clone)]
pub(crate) struct RegPollPayload(r570_144::GSP_SEQ_BUF_PAYLOAD_REG_POLL);
pub(crate) struct RegPollPayload(bindings::GSP_SEQ_BUF_PAYLOAD_REG_POLL);

impl RegPollPayload {
    /// Returns the register address.
@@ -469,7 +469,7 @@ unsafe impl AsBytes for RegPollPayload {}
/// Wrapper for GSP sequencer delay payload.
#[repr(transparent)]
#[derive(Copy, Clone)]
pub(crate) struct DelayUsPayload(r570_144::GSP_SEQ_BUF_PAYLOAD_DELAY_US);
pub(crate) struct DelayUsPayload(bindings::GSP_SEQ_BUF_PAYLOAD_DELAY_US);

impl DelayUsPayload {
    /// Returns the delay value in microseconds.
@@ -487,7 +487,7 @@ unsafe impl AsBytes for DelayUsPayload {}
/// Wrapper for GSP sequencer register store payload.
#[repr(transparent)]
#[derive(Copy, Clone)]
pub(crate) struct RegStorePayload(r570_144::GSP_SEQ_BUF_PAYLOAD_REG_STORE);
pub(crate) struct RegStorePayload(bindings::GSP_SEQ_BUF_PAYLOAD_REG_STORE);

impl RegStorePayload {
    /// Returns the register address.
@@ -510,7 +510,7 @@ unsafe impl AsBytes for RegStorePayload {}

/// Wrapper for GSP sequencer buffer command.
#[repr(transparent)]
pub(crate) struct SequencerBufferCmd(r570_144::GSP_SEQUENCER_BUFFER_CMD);
pub(crate) struct SequencerBufferCmd(bindings::GSP_SEQUENCER_BUFFER_CMD);

impl SequencerBufferCmd {
    /// Returns the opcode as a `SeqBufOpcode` enum, or error if invalid.
@@ -612,7 +612,7 @@ unsafe impl AsBytes for SequencerBufferCmd {}

/// Wrapper for GSP run CPU sequencer RPC.
#[repr(transparent)]
pub(crate) struct RunCpuSequencer(r570_144::rpc_run_cpu_sequencer_v17_00);
pub(crate) struct RunCpuSequencer(bindings::rpc_run_cpu_sequencer_v17_00);

impl RunCpuSequencer {
    /// Returns the command index.
@@ -797,13 +797,6 @@ fn init(cmd_size: usize, function: MsgFunction) -> impl Init<Self, Error> {
    }
}

// SAFETY: We can't derive the Zeroable trait for this binding because the
// procedural macro doesn't support the syntax used by bindgen to create the
// __IncompleteArrayField types. So instead we implement it here, which is safe
// because these are explicitly padded structures only containing types for
// which any bit pattern, including all zeros, is valid.
unsafe impl Zeroable for bindings::rpc_message_header_v {}

/// GSP Message Element.
///
/// This is essentially a message header expected to be followed by the message data.
@@ -853,11 +846,16 @@ pub(crate) fn set_checksum(&mut self, checksum: u32) {
        self.inner.checkSum = checksum;
    }

    /// Returns the total length of the message.
    /// Returns the length of the message's payload.
    pub(crate) fn payload_length(&self) -> usize {
        // `rpc.length` includes the length of the RPC message header.
        num::u32_as_usize(self.inner.rpc.length)
            .saturating_sub(size_of::<bindings::rpc_message_header_v>())
    }

    /// Returns the total length of the message, message and RPC headers included.
    pub(crate) fn length(&self) -> usize {
        // `rpc.length` includes the length of the GspRpcHeader but not the message header.
        size_of::<Self>() - size_of::<bindings::rpc_message_header_v>()
            + num::u32_as_usize(self.inner.rpc.length)
        size_of::<Self>() + self.payload_length()
    }

    // Returns the sequence number of the message.
+7 −4
Original line number Diff line number Diff line
@@ -24,8 +24,11 @@
    unreachable_pub,
    unsafe_op_in_unsafe_fn
)]
use kernel::{
    ffi,
    prelude::Zeroable, //
};
use kernel::ffi;
use pin_init::MaybeZeroable;

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> {}
Loading