summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEliot Courtney <ecourtney@nvidia.com>2026-07-03 19:22:06 +0900
committerAlexandre Courbot <acourbot@nvidia.com>2026-07-23 11:33:03 +0900
commited33ea9390dd40eabb25069eaaed3d011143fe58 (patch)
tree5a9f00a6756ab1ba620c129cdefc16fb7eb7e893
parent5f5237410773783c066c6c05bd502a34a95c6e8a (diff)
downloadlinux-ed33ea9390dd40eabb25069eaaed3d011143fe58.tar.gz
linux-ed33ea9390dd40eabb25069eaaed3d011143fe58.zip
gpu: nova-core: fsp: catch bogus queue pointer issues
Currently, `poll_msgq` will report a message of size 4 if the queue pointers are broken. It's easy to catch this if it occurs, so have `poll_msgq` return an error in this case. Signed-off-by: Eliot Courtney <ecourtney@nvidia.com> Reviewed-by: Alistair Popple <apopple@nvidia.com> Link: https://patch.msgid.link/20260703-blackwell-fixes-v2-2-8e3d8bc32bb9@nvidia.com [acourbot: explicitly mention the error, add paragraph separator.] Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
-rw-r--r--drivers/gpu/nova-core/falcon/fsp.rs16
1 files changed, 10 insertions, 6 deletions
diff --git a/drivers/gpu/nova-core/falcon/fsp.rs b/drivers/gpu/nova-core/falcon/fsp.rs
index 9d7322de1ce4..0437180b8829 100644
--- a/drivers/gpu/nova-core/falcon/fsp.rs
+++ b/drivers/gpu/nova-core/falcon/fsp.rs
@@ -111,18 +111,22 @@ impl<'a> Falcon<'a, Fsp> {
///
/// Returns the size of available data in bytes, or 0 if no data is available.
///
+ /// Returns [`EIO`] if the queue pointers are bogus (`tail < head`).
+ ///
/// The FSP message queue is not circular. Pointers are reset to 0 after each
/// message exchange, so `tail >= head` is always true when data is present.
- fn poll_msgq(&self) -> u32 {
+ fn poll_msgq(&self) -> Result<u32> {
let head = self.bar.read(regs::NV_PFSP_MSGQ_HEAD::at(0)).val();
let tail = self.bar.read(regs::NV_PFSP_MSGQ_TAIL::at(0)).val();
if head == tail {
- return 0;
+ Ok(0)
+ } else {
+ // TAIL points at the last DWORD written, so the size is `tail - head + 4`.
+ tail.checked_sub(head)
+ .and_then(|delta| delta.checked_add(4))
+ .ok_or(EIO)
}
-
- // TAIL points at last DWORD written, so add 4 to get total size.
- tail.saturating_sub(head).saturating_add(4)
}
/// Writes `packet` to FSP EMEM and updates the queue pointers to notify FSP.
@@ -156,7 +160,7 @@ impl<'a> Falcon<'a, Fsp> {
/// memory allocation error occurred.
pub(crate) fn recv_msg(&mut self) -> Result<KVec<u8>> {
let msg_size = read_poll_timeout(
- || Ok(self.poll_msgq()),
+ || self.poll_msgq(),
|&size| size > 0,
Delta::from_millis(10),
Delta::from_millis(FSP_MSG_TIMEOUT_MS),