`wait_for_msg` mixes two layers: the transport layer which polls the queue, extracts the element header and validates the checksum, and the RPC layer which reads the RPC header and trims the payload slices to the length advertised by the RPC header.
Move the transport layer into `wait_for_element`, and make `wait_for_msg` call it before validating the RPC layer. This sets things up for moving the RPC code into its own module, leaving the transport agnostic of the message type. No functional change intended. Signed-off-by: Alexandre Courbot <[email protected]> --- drivers/gpu/nova-core/gsp/cmdq.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/nova-core/gsp/cmdq.rs b/drivers/gpu/nova-core/gsp/cmdq.rs index 2d22ae45e990..d50a2a594f82 100644 --- a/drivers/gpu/nova-core/gsp/cmdq.rs +++ b/drivers/gpu/nova-core/gsp/cmdq.rs @@ -584,7 +584,7 @@ fn send_command_element( /// message queue. /// /// Error codes returned by the message constructor are propagated as-is. - fn wait_for_msg(&self, timeout: Delta) -> Result<GspMessage<'_>> { + fn wait_for_element(&self, timeout: Delta) -> Result<GspMessage<'_>> { // Wait for a message to arrive from the GSP. let (slice_1, slice_2) = read_poll_timeout( || Ok(self.gsp_mem.driver_read_area()), @@ -608,6 +608,18 @@ fn wait_for_msg(&self, timeout: Delta) -> Result<GspMessage<'_>> { return Err(EIO); } + Ok(GspMessage { + header, + contents: (slice_1, slice_2), + }) + } + + fn wait_for_msg(&self, timeout: Delta) -> Result<GspMessage<'_>> { + let GspMessage { + header, + contents: (slice_1, slice_2), + } = self.wait_for_element(timeout)?; + let rpc_header = header.rpc_header(); let payload_length = rpc_header.length(); @@ -619,6 +631,8 @@ fn wait_for_msg(&self, timeout: Delta) -> Result<GspMessage<'_>> { payload_length, ); + // Validate the RPC layer before returning the message. + // Check that the driver read area is large enough for the message. if slice_1.len() + slice_2.len() < payload_length { return Err(EIO); -- 2.55.0
