[PATCH v2 02/10] gpu: nova-core: fsp: catch bogus queue pointer issues

Eliot Courtney <[email protected]>
Newsgroups dev.linux.lists.nova-gpu,org.freedesktop.lists.dri-devel,org.kernel.vger.linux-kernel,org.kernel.vger.rust-for-linux
Message-ID <[email protected]>
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.

Reviewed-by: Alistair Popple <[email protected]>
Signed-off-by: Eliot Courtney <[email protected]>
---
 drivers/gpu/nova-core/falcon/fsp.rs | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/nova-core/falcon/fsp.rs b/drivers/gpu/nova-core/falcon/fsp.rs
index 7cd9604d1f4d..3752448df431 100644
--- a/drivers/gpu/nova-core/falcon/fsp.rs
+++ b/drivers/gpu/nova-core/falcon/fsp.rs
@@ -109,19 +109,22 @@ fn read_emem(&mut self, data: &mut [u8]) -> Result {
     /// Poll FSP for incoming data.
     ///
     /// Returns the size of available data in bytes, or 0 if no data is available.
+    /// Returns an error 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.
@@ -155,7 +158,7 @@ pub(crate) fn send_msg(&mut self, packet: &[u8]) -> Result {
     /// 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),

-- 
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.