summaryrefslogtreecommitdiff
path: root/drivers/gpu/nova-core
diff options
context:
space:
mode:
authorAlexandre Courbot <acourbot@nvidia.com>2025-12-16 11:57:08 +0900
committerAlexandre Courbot <acourbot@nvidia.com>2025-12-16 22:03:48 +0900
commit9d250ab0cf80deb11148efe862d1184ebf5115f6 (patch)
tree142193759a08556d548b6c6479013f0c5d448a83 /drivers/gpu/nova-core
parentb6c76518233e876a0f26e66b83643891c0f341db (diff)
gpu: nova-core: gsp: fix length of received messages
The size of messages' payload is miscalculated, leading to extra data passed to the message handler. While this is not a problem with our current set of commands, others with a variable-length payload may misbehave. Fix this by introducing a method returning the payload size and using it. Fixes: 75f6b1de8133 ("gpu: nova-core: gsp: Add GSP command queue bindings and handling") Reviewed-by: Lyude Paul <lyude@redhat.com> Reviewed-by: Joel Fernandes <joelagnelf@nvidia.com> Reviewed-by: Alistair Popple <apopple@nvidia.com> Acked-by: Danilo Krummrich <dakr@kernel.org> Link: https://patch.msgid.link/20251216-nova-fixes-v3-2-c7469a71f7c4@nvidia.com [acourbot@nvidia.com: update `PANIC:` comments as pointed out by Joel.] Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Diffstat (limited to 'drivers/gpu/nova-core')
-rw-r--r--drivers/gpu/nova-core/gsp/cmdq.rs14
-rw-r--r--drivers/gpu/nova-core/gsp/fw.rs13
2 files changed, 17 insertions, 10 deletions
diff --git a/drivers/gpu/nova-core/gsp/cmdq.rs b/drivers/gpu/nova-core/gsp/cmdq.rs
index 6f946d14868a..3991ccc0c10f 100644
--- a/drivers/gpu/nova-core/gsp/cmdq.rs
+++ b/drivers/gpu/nova-core/gsp/cmdq.rs
@@ -588,21 +588,23 @@ impl Cmdq {
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,
)
};
diff --git a/drivers/gpu/nova-core/gsp/fw.rs b/drivers/gpu/nova-core/gsp/fw.rs
index abffd6beec65..7b8e710b33e7 100644
--- a/drivers/gpu/nova-core/gsp/fw.rs
+++ b/drivers/gpu/nova-core/gsp/fw.rs
@@ -853,11 +853,16 @@ impl GspMsgElement {
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.