diff options
| author | Eliot Courtney <ecourtney@nvidia.com> | 2026-07-03 19:22:06 +0900 |
|---|---|---|
| committer | Alexandre Courbot <acourbot@nvidia.com> | 2026-07-23 11:33:03 +0900 |
| commit | ed33ea9390dd40eabb25069eaaed3d011143fe58 (patch) | |
| tree | 5a9f00a6756ab1ba620c129cdefc16fb7eb7e893 | |
| parent | 5f5237410773783c066c6c05bd502a34a95c6e8a (diff) | |
| download | linux-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.rs | 16 |
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), |
