Re: [PATCH v2 10/15] gpu: nova-core: recover the GSP receive path from corrupt framing

From: Alexandre Courbot

Date: Mon Aug 31 2026 - 01:36:10 EST


On Sat Aug 29, 2026 at 10:33 AM JST, John Hubbard wrote:
<...>
> @@ -748,11 +756,13 @@ fn send_command<M>(&mut self, bar: Bar0<'_>, command: M) -> Result<u32>
> /// # Errors
> ///
> /// - `ETIMEDOUT` if `timeout` has elapsed before any message becomes available.
> - /// - `EIO` if there was some inconsistency (e.g. message shorter than advertised) on the
> - /// message queue.
> - ///
> - /// Error codes returned by the message constructor are propagated as-is.
> + /// - `EIO` if the framing or the checksum is invalid, or the queue was already poisoned by an
> + /// earlier such failure. Either failure poisons the queue, so recovery requires a reset.
> fn wait_for_msg(&self, timeout: Delta) -> Result<GspMessage<'_>> {
> + if self.poisoned.get() {
> + return Err(EIO);
> + }
> +
> // Wait for a message to arrive from the GSP.
> let (slice_1, slice_2) = read_poll_timeout(
> || Ok(self.gsp_mem.driver_read_area()),
> @@ -763,7 +773,10 @@ fn wait_for_msg(&self, timeout: Delta) -> Result<GspMessage<'_>> {
> .map(|(slice_1, slice_2)| (slice_1.as_flattened(), slice_2.as_flattened()))?;
>
> // Extract the `GspMsgElement`.
> - let (header, slice_1) = GspMsgElement::from_bytes_prefix(slice_1).ok_or(EIO)?;
> + let Some((header, slice_1)) = GspMsgElement::from_bytes_prefix(slice_1) else {
> + self.poisoned.set(true);

We probably want to `dev_err` some error here, or the queue will just
stop working without explanation.

> + return Err(EIO);
> + };
>
> dev_dbg!(
> &self.dev,
> @@ -777,6 +790,7 @@ fn wait_for_msg(&self, timeout: Delta) -> Result<GspMessage<'_>> {
>
> // Check that the driver read area is large enough for the message.
> if slice_1.len() + slice_2.len() < payload_length {
> + self.poisoned.set(true);

Same here. Maybe we can have a `fn poison(&self, reason:
fmt::Arguments<'_>) -> Error` that performs the log and returns `EIO`
for convenience?