* [PATCH v3 0/5] nouveau/gsp: Clean up IS_ERR vs IS_ERR_OR_NULL usage
@ 2026-06-22 2:12 Hongling Zeng
2026-06-22 2:12 ` Hongling Zeng
` (9 more replies)
0 siblings, 10 replies; 23+ messages in thread
From: Hongling Zeng @ 2026-06-22 2:12 UTC (permalink / raw)
To: lyude, dakr, maarten.lankhorst, mripard, tzimmermann, airlied,
simona, airlied, ttabi, bskeggs, dri-devel
Cc: nouveau, linux-kernel, zhongling0719, Hongling Zeng
This series addresses feedback from Danilo Krummrich and Timur Tabi
regarding the use of IS_ERR() vs IS_ERR_OR_NULL() in the nouveau
GSP RPC code.
The key insight is that we should align error checking with the actual
return value contracts of each function:
- Functions that never return NULL should use IS_ERR()
- Functions that can return NULL should use IS_ERR_OR_NULL()
This version adds documentation to clarify the return value contracts,
making it easier for maintainers to validate future changes.
Return Value Analysis
After thorough code analysis, the RPC functions are categorized as:
Never return NULL (use IS_ERR):**
- r535_gsp_msgq_peek()
- r535_gsp_msgq_recv_one_elem()
- r535_gsp_rpc_get()
CAN return NULL (use IS_ERR_OR_NULL):**
- r535_gsp_msgq_recv() - returns NULL when RPC length is invalid
- r535_gsp_msg_recv() - returns NULL when queue drained
- r535_gsp_rpc_handle_reply() - returns NULL for NOWAIT/NOSEQ policies
- r535_gsp_rpc_send() - can return NULL via handle_reply
- r535_gsp_rpc_push() - can return NULL via handle_reply
Changes in v2
- Added kernel-doc comments documenting return value contracts for all
RPC functions
- Cleaned up incorrect IS_ERR_OR_NULL() usage for functions that never
return NULL
- Kept IS_ERR_OR_NULL() in places where NULL is actually possible
- Added Fixes tags to all patches
Testing
This fixes the NULL pointer dereference oops that occurs during
nouveau initialization on some systems.
Patches
Hongling Zeng (5):
nouveau/gsp/rpc: Document RPC function return value contracts
nouveau/gsp/rpc: Cleanup incorrect IS_ERR_OR_NULL in rpc.c
nouveau/gsp/rm/alloc: Cleanup IS_ERR_OR_NULL usage
nouveau/gsp/rm/bar: Cleanup IS_ERR_OR_NULL usage
nouveau/gsp: Cleanup IS_ERR_OR_NULL in nvkm_gsp_rpc_rd()
drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h | 2 +-
.../gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/alloc.c | 2 +-
.../gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c | 2 +-
.../gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c | 81 ++++++++++++++++++-
4 files changed, 81 insertions(+), 6 deletions(-)
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v3 1/5] nouveau/gsp/rpc: Document RPC function return value contracts
2026-06-22 2:12 [PATCH v3 0/5] nouveau/gsp: Clean up IS_ERR vs IS_ERR_OR_NULL usage Hongling Zeng
@ 2026-06-22 2:12 ` Hongling Zeng
2026-06-22 2:12 ` Hongling Zeng
` (8 subsequent siblings)
9 siblings, 0 replies; 23+ messages in thread
From: Hongling Zeng @ 2026-06-22 2:12 UTC (permalink / raw)
To: lyude, dakr, maarten.lankhorst, mripard, tzimmermann, airlied,
simona, airlied, ttabi, bskeggs, dri-devel
Cc: nouveau, linux-kernel, zhongling0719, Hongling Zeng
Add kernel-doc comments to document the return value semantics of
RPC functions in r535/rpc.c. This clarifies which functions can return
NULL, error pointers, or both, helping maintainers validate future
changes.
Return value analysis:
- r535_gsp_msgq_peek(): Never returns NULL
- r535_gsp_msgq_recv_one_elem(): Never returns NULL
- r535_gsp_msgq_recv(): CAN return NULL (when RPC length invalid)
- r535_gsp_msg_recv(): CAN return NULL (queue drained/no matching message)
- r535_gsp_rpc_get(): Never returns NULL
- r535_gsp_rpc_handle_reply(): CAN return NULL (NOWAIT/NOSEQ policies)
- r535_gsp_rpc_send(): CAN return NULL (via handle_reply)
- r535_gsp_rpc_push(): CAN return NULL (via handle_reply)
Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
---
Change in v3:
-Fix documentation accuracy for r535_gsp_msg_recv() to clarify.
-Fix documentation accuracy for r535_gsp_rpc_handle_reply() to clarify.
---
.../drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c | 85 +++++++++++++++++++
1 file changed, 85 insertions(+)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
index 3ca3de8f4340..1b125dcb279a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
@@ -204,6 +204,15 @@ r535_gsp_msgq_get_entry(struct nvkm_gsp *gsp)
* The user is responsible for freeing the memory allocated for the GSP
* message pages after they have been processed.
*/
+/**
+ * r535_gsp_msgq_peek - Peek at next message in GSP command queue
+ * @gsp: GSP device
+ * @gsp_rpc_len: Expected RPC length
+ * @retries: Retry counter
+ *
+ * Return: Pointer to RPC message on success, or ERR_PTR() on error.
+ * Never returns NULL.
+ */
static void *
r535_gsp_msgq_peek(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries)
{
@@ -229,6 +238,14 @@ struct r535_gsp_msg_info {
static void
r535_gsp_msg_dump(struct nvkm_gsp *gsp, struct nvfw_gsp_rpc *msg, int lvl);
+/**
+ * r535_gsp_msgq_recv_one_elem - Receive one message element from GSP queue
+ * @gsp: GSP device
+ * @info: Message queue information
+ *
+ * Return: Pointer to received buffer on success, or ERR_PTR() on error.
+ * Never returns NULL.
+ */
static void *
r535_gsp_msgq_recv_one_elem(struct nvkm_gsp *gsp,
struct r535_gsp_msg_info *info)
@@ -283,6 +300,15 @@ r535_gsp_msgq_recv_one_elem(struct nvkm_gsp *gsp,
return buf;
}
+/**
+ * r535_gsp_msgq_recv - Receive RPC message(s) from GSP queue
+ * @gsp: GSP device
+ * @gsp_rpc_len: Expected RPC length
+ * @retries: Retry counter
+ *
+ * Return: Pointer to received buffer on success, ERR_PTR() on error,
+ * or NULL if RPC length is invalid.
+ */
static void *
r535_gsp_msgq_recv(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries)
{
@@ -450,6 +476,20 @@ r535_gsp_msg_dump(struct nvkm_gsp *gsp, struct nvfw_gsp_rpc *msg, int lvl)
}
}
+/**
+ * r535_gsp_msg_recv - Receive RPC message from GSP message queue
+ * @gsp: GSP device
+ * @fn: Expected RPC function number (0 to accept any)
+ * @gsp_rpc_len: Expected RPC length (0 for POLL mode)
+ *
+ * Return: Pointer to RPC message on success, ERR_PTR() on error.
+ * When fn!=0: retries until timeout, returns ERR_PTR(-ETIMEDOUT)
+ * if no match found (never returns NULL for timeout).
+ * When fn!=0 and gsp_rpc_len==0 (POLL mode): returns
+ * NULL on successful message processing.
+ * When fn==0: returns NULL if queue is drained or no matching
+ * message found without retrying.
+ */
struct nvfw_gsp_rpc *
r535_gsp_msg_recv(struct nvkm_gsp *gsp, int fn, u32 gsp_rpc_len)
{
@@ -547,6 +587,17 @@ r535_gsp_rpc_poll(struct nvkm_gsp *gsp, u32 fn)
return 0;
}
+/**
+ * r535_gsp_rpc_handle_reply - Handle RPC reply based on policy
+ * @gsp: GSP device
+ * @fn: RPC function number
+ * @policy: Reply policy (NOWAIT, NOSEQ, RECV, or POLL)
+ * @gsp_rpc_len: Expected RPC length
+ *
+ * Return: NULL when policy is NOWAIT or NOSEQ (no reply expected),
+ * pointer to reply data on success, ERR_PTR() on error.
+ * When policy is POLL: NULL on successful message processing.
+ */
static void *
r535_gsp_rpc_handle_reply(struct nvkm_gsp *gsp, u32 fn,
enum nvkm_gsp_rpc_reply_policy policy,
@@ -574,6 +625,16 @@ r535_gsp_rpc_handle_reply(struct nvkm_gsp *gsp, u32 fn,
return repv;
}
+/**
+ * r535_gsp_rpc_send - Send RPC message and handle reply
+ * @gsp: GSP device
+ * @payload: RPC payload to send
+ * @policy: Reply policy (NOWAIT, NOSEQ, RECV, or POLL)
+ * @gsp_rpc_len: Expected RPC length for reply
+ *
+ * Return: NULL if policy is NOWAIT/NOSEQ (no reply expected),
+ * pointer to reply data on success, or ERR_PTR() on error.
+ */
static void *
r535_gsp_rpc_send(struct nvkm_gsp *gsp, void *payload,
enum nvkm_gsp_rpc_reply_policy policy, u32 gsp_rpc_len)
@@ -601,6 +662,11 @@ r535_gsp_rpc_send(struct nvkm_gsp *gsp, void *payload,
return r535_gsp_rpc_handle_reply(gsp, fn, policy, gsp_rpc_len);
}
+/**
+ * r535_gsp_rpc_done - Free an RPC message
+ * @gsp: GSP device
+ * @repv: Pointer to RPC payload data returned by r535_gsp_rpc_get()
+ */
static void
r535_gsp_rpc_done(struct nvkm_gsp *gsp, void *repv)
{
@@ -609,6 +675,15 @@ r535_gsp_rpc_done(struct nvkm_gsp *gsp, void *repv)
r535_gsp_msg_done(gsp, rpc);
}
+/**
+ * r535_gsp_rpc_get - Allocate and initialize an RPC message
+ * @gsp: GSP device
+ * @fn: RPC function number
+ * @payload_size: Size of the payload
+ *
+ * Return: Pointer to RPC payload data on success, or ERR_PTR() on error.
+ * Never returns NULL.
+ */
static void *
r535_gsp_rpc_get(struct nvkm_gsp *gsp, u32 fn, u32 payload_size)
{
@@ -628,6 +703,16 @@ r535_gsp_rpc_get(struct nvkm_gsp *gsp, u32 fn, u32 payload_size)
return rpc->data;
}
+/**
+ * r535_gsp_rpc_push - Push RPC message to GSP and wait for reply
+ * @gsp: GSP device
+ * @payload: RPC payload to send
+ * @policy: Reply policy (NOWAIT, NOSEQ, RECV, or POLL)
+ * @gsp_rpc_len: Expected RPC length in the reply
+ *
+ * Return: NULL when policy is NOWAIT/NOSEQ (no reply expected),
+ * pointer to reply data on success, or ERR_PTR() on error.
+ */
static void *
r535_gsp_rpc_push(struct nvkm_gsp *gsp, void *payload,
enum nvkm_gsp_rpc_reply_policy policy, u32 gsp_rpc_len)
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v3 1/5] nouveau/gsp/rpc: Document RPC function return value contracts
@ 2026-06-22 2:12 ` Hongling Zeng
0 siblings, 0 replies; 23+ messages in thread
From: Hongling Zeng @ 2026-06-22 2:12 UTC (permalink / raw)
To: lyude, dakr, maarten.lankhorst, mripard, tzimmermann, airlied,
simona, airlied, ttabi, bskeggs, dri-devel
Cc: nouveau, linux-kernel, zhongling0719, Hongling Zeng
Add kernel-doc comments to document the return value semantics of
RPC functions in r535/rpc.c. This clarifies which functions can return
NULL, error pointers, or both, helping maintainers validate future
changes.
Return value analysis:
- r535_gsp_msgq_peek(): Never returns NULL
- r535_gsp_msgq_recv_one_elem(): Never returns NULL
- r535_gsp_msgq_recv(): CAN return NULL (when RPC length invalid)
- r535_gsp_msg_recv(): CAN return NULL (queue drained/no matching message)
- r535_gsp_rpc_get(): Never returns NULL
- r535_gsp_rpc_handle_reply(): CAN return NULL (NOWAIT/NOSEQ policies)
- r535_gsp_rpc_send(): CAN return NULL (via handle_reply)
- r535_gsp_rpc_push(): CAN return NULL (via handle_reply)
Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
---
Change in v3:
-Fix documentation accuracy for r535_gsp_msg_recv() to clarify.
-Fix documentation accuracy for r535_gsp_rpc_handle_reply() to clarify.
---
.../drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c | 85 +++++++++++++++++++
1 file changed, 85 insertions(+)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
index 3ca3de8f4340..1b125dcb279a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
@@ -204,6 +204,15 @@ r535_gsp_msgq_get_entry(struct nvkm_gsp *gsp)
* The user is responsible for freeing the memory allocated for the GSP
* message pages after they have been processed.
*/
+/**
+ * r535_gsp_msgq_peek - Peek at next message in GSP command queue
+ * @gsp: GSP device
+ * @gsp_rpc_len: Expected RPC length
+ * @retries: Retry counter
+ *
+ * Return: Pointer to RPC message on success, or ERR_PTR() on error.
+ * Never returns NULL.
+ */
static void *
r535_gsp_msgq_peek(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries)
{
@@ -229,6 +238,14 @@ struct r535_gsp_msg_info {
static void
r535_gsp_msg_dump(struct nvkm_gsp *gsp, struct nvfw_gsp_rpc *msg, int lvl);
+/**
+ * r535_gsp_msgq_recv_one_elem - Receive one message element from GSP queue
+ * @gsp: GSP device
+ * @info: Message queue information
+ *
+ * Return: Pointer to received buffer on success, or ERR_PTR() on error.
+ * Never returns NULL.
+ */
static void *
r535_gsp_msgq_recv_one_elem(struct nvkm_gsp *gsp,
struct r535_gsp_msg_info *info)
@@ -283,6 +300,15 @@ r535_gsp_msgq_recv_one_elem(struct nvkm_gsp *gsp,
return buf;
}
+/**
+ * r535_gsp_msgq_recv - Receive RPC message(s) from GSP queue
+ * @gsp: GSP device
+ * @gsp_rpc_len: Expected RPC length
+ * @retries: Retry counter
+ *
+ * Return: Pointer to received buffer on success, ERR_PTR() on error,
+ * or NULL if RPC length is invalid.
+ */
static void *
r535_gsp_msgq_recv(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries)
{
@@ -450,6 +476,20 @@ r535_gsp_msg_dump(struct nvkm_gsp *gsp, struct nvfw_gsp_rpc *msg, int lvl)
}
}
+/**
+ * r535_gsp_msg_recv - Receive RPC message from GSP message queue
+ * @gsp: GSP device
+ * @fn: Expected RPC function number (0 to accept any)
+ * @gsp_rpc_len: Expected RPC length (0 for POLL mode)
+ *
+ * Return: Pointer to RPC message on success, ERR_PTR() on error.
+ * When fn!=0: retries until timeout, returns ERR_PTR(-ETIMEDOUT)
+ * if no match found (never returns NULL for timeout).
+ * When fn!=0 and gsp_rpc_len==0 (POLL mode): returns
+ * NULL on successful message processing.
+ * When fn==0: returns NULL if queue is drained or no matching
+ * message found without retrying.
+ */
struct nvfw_gsp_rpc *
r535_gsp_msg_recv(struct nvkm_gsp *gsp, int fn, u32 gsp_rpc_len)
{
@@ -547,6 +587,17 @@ r535_gsp_rpc_poll(struct nvkm_gsp *gsp, u32 fn)
return 0;
}
+/**
+ * r535_gsp_rpc_handle_reply - Handle RPC reply based on policy
+ * @gsp: GSP device
+ * @fn: RPC function number
+ * @policy: Reply policy (NOWAIT, NOSEQ, RECV, or POLL)
+ * @gsp_rpc_len: Expected RPC length
+ *
+ * Return: NULL when policy is NOWAIT or NOSEQ (no reply expected),
+ * pointer to reply data on success, ERR_PTR() on error.
+ * When policy is POLL: NULL on successful message processing.
+ */
static void *
r535_gsp_rpc_handle_reply(struct nvkm_gsp *gsp, u32 fn,
enum nvkm_gsp_rpc_reply_policy policy,
@@ -574,6 +625,16 @@ r535_gsp_rpc_handle_reply(struct nvkm_gsp *gsp, u32 fn,
return repv;
}
+/**
+ * r535_gsp_rpc_send - Send RPC message and handle reply
+ * @gsp: GSP device
+ * @payload: RPC payload to send
+ * @policy: Reply policy (NOWAIT, NOSEQ, RECV, or POLL)
+ * @gsp_rpc_len: Expected RPC length for reply
+ *
+ * Return: NULL if policy is NOWAIT/NOSEQ (no reply expected),
+ * pointer to reply data on success, or ERR_PTR() on error.
+ */
static void *
r535_gsp_rpc_send(struct nvkm_gsp *gsp, void *payload,
enum nvkm_gsp_rpc_reply_policy policy, u32 gsp_rpc_len)
@@ -601,6 +662,11 @@ r535_gsp_rpc_send(struct nvkm_gsp *gsp, void *payload,
return r535_gsp_rpc_handle_reply(gsp, fn, policy, gsp_rpc_len);
}
+/**
+ * r535_gsp_rpc_done - Free an RPC message
+ * @gsp: GSP device
+ * @repv: Pointer to RPC payload data returned by r535_gsp_rpc_get()
+ */
static void
r535_gsp_rpc_done(struct nvkm_gsp *gsp, void *repv)
{
@@ -609,6 +675,15 @@ r535_gsp_rpc_done(struct nvkm_gsp *gsp, void *repv)
r535_gsp_msg_done(gsp, rpc);
}
+/**
+ * r535_gsp_rpc_get - Allocate and initialize an RPC message
+ * @gsp: GSP device
+ * @fn: RPC function number
+ * @payload_size: Size of the payload
+ *
+ * Return: Pointer to RPC payload data on success, or ERR_PTR() on error.
+ * Never returns NULL.
+ */
static void *
r535_gsp_rpc_get(struct nvkm_gsp *gsp, u32 fn, u32 payload_size)
{
@@ -628,6 +703,16 @@ r535_gsp_rpc_get(struct nvkm_gsp *gsp, u32 fn, u32 payload_size)
return rpc->data;
}
+/**
+ * r535_gsp_rpc_push - Push RPC message to GSP and wait for reply
+ * @gsp: GSP device
+ * @payload: RPC payload to send
+ * @policy: Reply policy (NOWAIT, NOSEQ, RECV, or POLL)
+ * @gsp_rpc_len: Expected RPC length in the reply
+ *
+ * Return: NULL when policy is NOWAIT/NOSEQ (no reply expected),
+ * pointer to reply data on success, or ERR_PTR() on error.
+ */
static void *
r535_gsp_rpc_push(struct nvkm_gsp *gsp, void *payload,
enum nvkm_gsp_rpc_reply_policy policy, u32 gsp_rpc_len)
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v3 1/5] nouveau/gsp/rpc: Document RPC function return value contracts
2026-06-22 2:12 [PATCH v3 0/5] nouveau/gsp: Clean up IS_ERR vs IS_ERR_OR_NULL usage Hongling Zeng
2026-06-22 2:12 ` Hongling Zeng
@ 2026-06-22 2:12 ` Hongling Zeng
2026-06-22 9:20 ` sashiko-bot
2026-06-22 2:12 ` Hongling Zeng
` (7 subsequent siblings)
9 siblings, 1 reply; 23+ messages in thread
From: Hongling Zeng @ 2026-06-22 2:12 UTC (permalink / raw)
To: lyude, dakr, maarten.lankhorst, mripard, tzimmermann, airlied,
simona, airlied, ttabi, bskeggs, dri-devel
Cc: nouveau, linux-kernel, zhongling0719, Hongling Zeng
Add kernel-doc comments to document the return value semantics of
RPC functions in r535/rpc.c. This clarifies which functions can return
NULL, error pointers, or both, helping maintainers validate future
changes.
Return value analysis:
- r535_gsp_msgq_peek(): Never returns NULL
- r535_gsp_msgq_recv_one_elem(): Never returns NULL
- r535_gsp_msgq_recv(): CAN return NULL (when RPC length invalid)
- r535_gsp_msg_recv(): CAN return NULL (queue drained/no matching message)
- r535_gsp_rpc_get(): Never returns NULL
- r535_gsp_rpc_handle_reply(): CAN return NULL (NOWAIT/NOSEQ policies)
- r535_gsp_rpc_send(): CAN return NULL (via handle_reply)
- r535_gsp_rpc_push(): CAN return NULL (via handle_reply)
Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
---
Change in v3:
-Fix documentation accuracy for r535_gsp_msg_recv() to clarify.
-Fix documentation accuracy for r535_gsp_rpc_handle_reply() to clarify.
---
.../drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c | 85 +++++++++++++++++++
1 file changed, 85 insertions(+)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
index 3ca3de8f4340..1b125dcb279a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
@@ -204,6 +204,15 @@ r535_gsp_msgq_get_entry(struct nvkm_gsp *gsp)
* The user is responsible for freeing the memory allocated for the GSP
* message pages after they have been processed.
*/
+/**
+ * r535_gsp_msgq_peek - Peek at next message in GSP command queue
+ * @gsp: GSP device
+ * @gsp_rpc_len: Expected RPC length
+ * @retries: Retry counter
+ *
+ * Return: Pointer to RPC message on success, or ERR_PTR() on error.
+ * Never returns NULL.
+ */
static void *
r535_gsp_msgq_peek(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries)
{
@@ -229,6 +238,14 @@ struct r535_gsp_msg_info {
static void
r535_gsp_msg_dump(struct nvkm_gsp *gsp, struct nvfw_gsp_rpc *msg, int lvl);
+/**
+ * r535_gsp_msgq_recv_one_elem - Receive one message element from GSP queue
+ * @gsp: GSP device
+ * @info: Message queue information
+ *
+ * Return: Pointer to received buffer on success, or ERR_PTR() on error.
+ * Never returns NULL.
+ */
static void *
r535_gsp_msgq_recv_one_elem(struct nvkm_gsp *gsp,
struct r535_gsp_msg_info *info)
@@ -283,6 +300,15 @@ r535_gsp_msgq_recv_one_elem(struct nvkm_gsp *gsp,
return buf;
}
+/**
+ * r535_gsp_msgq_recv - Receive RPC message(s) from GSP queue
+ * @gsp: GSP device
+ * @gsp_rpc_len: Expected RPC length
+ * @retries: Retry counter
+ *
+ * Return: Pointer to received buffer on success, ERR_PTR() on error,
+ * or NULL if RPC length is invalid.
+ */
static void *
r535_gsp_msgq_recv(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries)
{
@@ -450,6 +476,20 @@ r535_gsp_msg_dump(struct nvkm_gsp *gsp, struct nvfw_gsp_rpc *msg, int lvl)
}
}
+/**
+ * r535_gsp_msg_recv - Receive RPC message from GSP message queue
+ * @gsp: GSP device
+ * @fn: Expected RPC function number (0 to accept any)
+ * @gsp_rpc_len: Expected RPC length (0 for POLL mode)
+ *
+ * Return: Pointer to RPC message on success, ERR_PTR() on error.
+ * When fn!=0: retries until timeout, returns ERR_PTR(-ETIMEDOUT)
+ * if no match found (never returns NULL for timeout).
+ * When fn!=0 and gsp_rpc_len==0 (POLL mode): returns
+ * NULL on successful message processing.
+ * When fn==0: returns NULL if queue is drained or no matching
+ * message found without retrying.
+ */
struct nvfw_gsp_rpc *
r535_gsp_msg_recv(struct nvkm_gsp *gsp, int fn, u32 gsp_rpc_len)
{
@@ -547,6 +587,17 @@ r535_gsp_rpc_poll(struct nvkm_gsp *gsp, u32 fn)
return 0;
}
+/**
+ * r535_gsp_rpc_handle_reply - Handle RPC reply based on policy
+ * @gsp: GSP device
+ * @fn: RPC function number
+ * @policy: Reply policy (NOWAIT, NOSEQ, RECV, or POLL)
+ * @gsp_rpc_len: Expected RPC length
+ *
+ * Return: NULL when policy is NOWAIT or NOSEQ (no reply expected),
+ * pointer to reply data on success, ERR_PTR() on error.
+ * When policy is POLL: NULL on successful message processing.
+ */
static void *
r535_gsp_rpc_handle_reply(struct nvkm_gsp *gsp, u32 fn,
enum nvkm_gsp_rpc_reply_policy policy,
@@ -574,6 +625,16 @@ r535_gsp_rpc_handle_reply(struct nvkm_gsp *gsp, u32 fn,
return repv;
}
+/**
+ * r535_gsp_rpc_send - Send RPC message and handle reply
+ * @gsp: GSP device
+ * @payload: RPC payload to send
+ * @policy: Reply policy (NOWAIT, NOSEQ, RECV, or POLL)
+ * @gsp_rpc_len: Expected RPC length for reply
+ *
+ * Return: NULL if policy is NOWAIT/NOSEQ (no reply expected),
+ * pointer to reply data on success, or ERR_PTR() on error.
+ */
static void *
r535_gsp_rpc_send(struct nvkm_gsp *gsp, void *payload,
enum nvkm_gsp_rpc_reply_policy policy, u32 gsp_rpc_len)
@@ -601,6 +662,11 @@ r535_gsp_rpc_send(struct nvkm_gsp *gsp, void *payload,
return r535_gsp_rpc_handle_reply(gsp, fn, policy, gsp_rpc_len);
}
+/**
+ * r535_gsp_rpc_done - Free an RPC message
+ * @gsp: GSP device
+ * @repv: Pointer to RPC payload data returned by r535_gsp_rpc_get()
+ */
static void
r535_gsp_rpc_done(struct nvkm_gsp *gsp, void *repv)
{
@@ -609,6 +675,15 @@ r535_gsp_rpc_done(struct nvkm_gsp *gsp, void *repv)
r535_gsp_msg_done(gsp, rpc);
}
+/**
+ * r535_gsp_rpc_get - Allocate and initialize an RPC message
+ * @gsp: GSP device
+ * @fn: RPC function number
+ * @payload_size: Size of the payload
+ *
+ * Return: Pointer to RPC payload data on success, or ERR_PTR() on error.
+ * Never returns NULL.
+ */
static void *
r535_gsp_rpc_get(struct nvkm_gsp *gsp, u32 fn, u32 payload_size)
{
@@ -628,6 +703,16 @@ r535_gsp_rpc_get(struct nvkm_gsp *gsp, u32 fn, u32 payload_size)
return rpc->data;
}
+/**
+ * r535_gsp_rpc_push - Push RPC message to GSP and wait for reply
+ * @gsp: GSP device
+ * @payload: RPC payload to send
+ * @policy: Reply policy (NOWAIT, NOSEQ, RECV, or POLL)
+ * @gsp_rpc_len: Expected RPC length in the reply
+ *
+ * Return: NULL when policy is NOWAIT/NOSEQ (no reply expected),
+ * pointer to reply data on success, or ERR_PTR() on error.
+ */
static void *
r535_gsp_rpc_push(struct nvkm_gsp *gsp, void *payload,
enum nvkm_gsp_rpc_reply_policy policy, u32 gsp_rpc_len)
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v3 2/5] nouveau/gsp/rpc: Cleanup incorrect IS_ERR_OR_NULL in rpc.c
2026-06-22 2:12 [PATCH v3 0/5] nouveau/gsp: Clean up IS_ERR vs IS_ERR_OR_NULL usage Hongling Zeng
@ 2026-06-22 2:12 ` Hongling Zeng
2026-06-22 2:12 ` Hongling Zeng
` (8 subsequent siblings)
9 siblings, 0 replies; 23+ messages in thread
From: Hongling Zeng @ 2026-06-22 2:12 UTC (permalink / raw)
To: lyude, dakr, maarten.lankhorst, mripard, tzimmermann, airlied,
simona, airlied, ttabi, bskeggs, dri-devel
Cc: nouveau, linux-kernel, zhongling0719, Hongling Zeng
Clean up incorrect IS_ERR_OR_NULL() usage for functions that never
return NULL:
- r535_gsp_msgq_peek() never returns NULL
- r535_gsp_msgq_recv_one_elem() never returns NULL
These functions should be checked with IS_ERR() instead.
Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
---
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
index 1b125dcb279a..f6d54c4c939d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
@@ -350,7 +350,7 @@ r535_gsp_msgq_recv(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries)
u32 size;
rpc = r535_gsp_msgq_peek(gsp, sizeof(*rpc), info.retries);
- if (IS_ERR_OR_NULL(rpc)) {
+ if (IS_ERR(rpc)) {
kvfree(buf);
return rpc;
}
@@ -359,7 +359,7 @@ r535_gsp_msgq_recv(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries)
info.continuation = true;
rpc = r535_gsp_msgq_recv_one_elem(gsp, &info);
- if (IS_ERR_OR_NULL(rpc)) {
+ if (IS_ERR(rpc)) {
kvfree(buf);
return rpc;
}
@@ -499,7 +499,7 @@ r535_gsp_msg_recv(struct nvkm_gsp *gsp, int fn, u32 gsp_rpc_len)
retry:
rpc = r535_gsp_msgq_peek(gsp, sizeof(*rpc), &retries);
- if (IS_ERR_OR_NULL(rpc))
+ if (IS_ERR(rpc))
return rpc;
rpc = r535_gsp_msgq_recv(gsp, gsp_rpc_len, &retries);
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v3 2/5] nouveau/gsp/rpc: Cleanup incorrect IS_ERR_OR_NULL in rpc.c
@ 2026-06-22 2:12 ` Hongling Zeng
0 siblings, 0 replies; 23+ messages in thread
From: Hongling Zeng @ 2026-06-22 2:12 UTC (permalink / raw)
To: lyude, dakr, maarten.lankhorst, mripard, tzimmermann, airlied,
simona, airlied, ttabi, bskeggs, dri-devel
Cc: nouveau, linux-kernel, zhongling0719, Hongling Zeng
Clean up incorrect IS_ERR_OR_NULL() usage for functions that never
return NULL:
- r535_gsp_msgq_peek() never returns NULL
- r535_gsp_msgq_recv_one_elem() never returns NULL
These functions should be checked with IS_ERR() instead.
Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
---
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
index 1b125dcb279a..f6d54c4c939d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
@@ -350,7 +350,7 @@ r535_gsp_msgq_recv(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries)
u32 size;
rpc = r535_gsp_msgq_peek(gsp, sizeof(*rpc), info.retries);
- if (IS_ERR_OR_NULL(rpc)) {
+ if (IS_ERR(rpc)) {
kvfree(buf);
return rpc;
}
@@ -359,7 +359,7 @@ r535_gsp_msgq_recv(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries)
info.continuation = true;
rpc = r535_gsp_msgq_recv_one_elem(gsp, &info);
- if (IS_ERR_OR_NULL(rpc)) {
+ if (IS_ERR(rpc)) {
kvfree(buf);
return rpc;
}
@@ -499,7 +499,7 @@ r535_gsp_msg_recv(struct nvkm_gsp *gsp, int fn, u32 gsp_rpc_len)
retry:
rpc = r535_gsp_msgq_peek(gsp, sizeof(*rpc), &retries);
- if (IS_ERR_OR_NULL(rpc))
+ if (IS_ERR(rpc))
return rpc;
rpc = r535_gsp_msgq_recv(gsp, gsp_rpc_len, &retries);
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v3 2/5] nouveau/gsp/rpc: Cleanup incorrect IS_ERR_OR_NULL in rpc.c
2026-06-22 2:12 [PATCH v3 0/5] nouveau/gsp: Clean up IS_ERR vs IS_ERR_OR_NULL usage Hongling Zeng
` (2 preceding siblings ...)
2026-06-22 2:12 ` Hongling Zeng
@ 2026-06-22 2:12 ` Hongling Zeng
2026-06-22 9:33 ` sashiko-bot
2026-06-22 2:12 ` [PATCH v3 3/5] nouveau/gsp/rm/alloc: Cleanup IS_ERR_OR_NULL usage Hongling Zeng
` (5 subsequent siblings)
9 siblings, 1 reply; 23+ messages in thread
From: Hongling Zeng @ 2026-06-22 2:12 UTC (permalink / raw)
To: lyude, dakr, maarten.lankhorst, mripard, tzimmermann, airlied,
simona, airlied, ttabi, bskeggs, dri-devel
Cc: nouveau, linux-kernel, zhongling0719, Hongling Zeng
Clean up incorrect IS_ERR_OR_NULL() usage for functions that never
return NULL:
- r535_gsp_msgq_peek() never returns NULL
- r535_gsp_msgq_recv_one_elem() never returns NULL
These functions should be checked with IS_ERR() instead.
Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
---
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
index 1b125dcb279a..f6d54c4c939d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
@@ -350,7 +350,7 @@ r535_gsp_msgq_recv(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries)
u32 size;
rpc = r535_gsp_msgq_peek(gsp, sizeof(*rpc), info.retries);
- if (IS_ERR_OR_NULL(rpc)) {
+ if (IS_ERR(rpc)) {
kvfree(buf);
return rpc;
}
@@ -359,7 +359,7 @@ r535_gsp_msgq_recv(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries)
info.continuation = true;
rpc = r535_gsp_msgq_recv_one_elem(gsp, &info);
- if (IS_ERR_OR_NULL(rpc)) {
+ if (IS_ERR(rpc)) {
kvfree(buf);
return rpc;
}
@@ -499,7 +499,7 @@ r535_gsp_msg_recv(struct nvkm_gsp *gsp, int fn, u32 gsp_rpc_len)
retry:
rpc = r535_gsp_msgq_peek(gsp, sizeof(*rpc), &retries);
- if (IS_ERR_OR_NULL(rpc))
+ if (IS_ERR(rpc))
return rpc;
rpc = r535_gsp_msgq_recv(gsp, gsp_rpc_len, &retries);
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v3 3/5] nouveau/gsp/rm/alloc: Cleanup IS_ERR_OR_NULL usage
2026-06-22 2:12 [PATCH v3 0/5] nouveau/gsp: Clean up IS_ERR vs IS_ERR_OR_NULL usage Hongling Zeng
` (4 preceding siblings ...)
2026-06-22 2:12 ` [PATCH v3 3/5] nouveau/gsp/rm/alloc: Cleanup IS_ERR_OR_NULL usage Hongling Zeng
@ 2026-06-22 2:12 ` Hongling Zeng
2026-06-22 4:28 ` sashiko-bot
2026-06-22 2:12 ` [PATCH v3 4/5] nouveau/gsp/rm/bar: " Hongling Zeng
` (3 subsequent siblings)
9 siblings, 1 reply; 23+ messages in thread
From: Hongling Zeng @ 2026-06-22 2:12 UTC (permalink / raw)
To: lyude, dakr, maarten.lankhorst, mripard, tzimmermann, airlied,
simona, airlied, ttabi, bskeggs, dri-devel
Cc: nouveau, linux-kernel, zhongling0719, Hongling Zeng
r535_gsp_rpc_rm_free() calls nvkm_gsp_rpc_get() which never returns
NULL, only valid pointers or error pointers. Clean up by using IS_ERR()
instead, matching the actual return value contract.
Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
---
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/alloc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/alloc.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/alloc.c
index 46e3a29f2ad7..c9f86c0e9b25 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/alloc.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/alloc.c
@@ -35,7 +35,7 @@ r535_gsp_rpc_rm_free(struct nvkm_gsp_object *object)
client->object.handle, object->handle);
rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_FREE, sizeof(*rpc));
- if (WARN_ON(IS_ERR_OR_NULL(rpc)))
+ if (WARN_ON(IS_ERR(rpc)))
return -EIO;
rpc->params.hRoot = client->object.handle;
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v3 3/5] nouveau/gsp/rm/alloc: Cleanup IS_ERR_OR_NULL usage
2026-06-22 2:12 [PATCH v3 0/5] nouveau/gsp: Clean up IS_ERR vs IS_ERR_OR_NULL usage Hongling Zeng
` (3 preceding siblings ...)
2026-06-22 2:12 ` Hongling Zeng
@ 2026-06-22 2:12 ` Hongling Zeng
2026-06-22 9:47 ` sashiko-bot
2026-06-22 2:12 ` Hongling Zeng
` (4 subsequent siblings)
9 siblings, 1 reply; 23+ messages in thread
From: Hongling Zeng @ 2026-06-22 2:12 UTC (permalink / raw)
To: lyude, dakr, maarten.lankhorst, mripard, tzimmermann, airlied,
simona, airlied, ttabi, bskeggs, dri-devel
Cc: nouveau, linux-kernel, zhongling0719, Hongling Zeng
r535_gsp_rpc_rm_free() calls nvkm_gsp_rpc_get() which never returns
NULL, only valid pointers or error pointers. Clean up by using IS_ERR()
instead, matching the actual return value contract.
Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
---
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/alloc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/alloc.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/alloc.c
index 46e3a29f2ad7..c9f86c0e9b25 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/alloc.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/alloc.c
@@ -35,7 +35,7 @@ r535_gsp_rpc_rm_free(struct nvkm_gsp_object *object)
client->object.handle, object->handle);
rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_FREE, sizeof(*rpc));
- if (WARN_ON(IS_ERR_OR_NULL(rpc)))
+ if (WARN_ON(IS_ERR(rpc)))
return -EIO;
rpc->params.hRoot = client->object.handle;
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v3 4/5] nouveau/gsp/rm/bar: Cleanup IS_ERR_OR_NULL usage
2026-06-22 2:12 [PATCH v3 0/5] nouveau/gsp: Clean up IS_ERR vs IS_ERR_OR_NULL usage Hongling Zeng
` (5 preceding siblings ...)
2026-06-22 2:12 ` Hongling Zeng
@ 2026-06-22 2:12 ` Hongling Zeng
2026-06-22 2:27 ` sashiko-bot
2026-06-22 2:12 ` Hongling Zeng
` (2 subsequent siblings)
9 siblings, 1 reply; 23+ messages in thread
From: Hongling Zeng @ 2026-06-22 2:12 UTC (permalink / raw)
To: lyude, dakr, maarten.lankhorst, mripard, tzimmermann, airlied,
simona, airlied, ttabi, bskeggs, dri-devel
Cc: nouveau, linux-kernel, zhongling0719, Hongling Zeng
r535_bar_bar2_update_pde() calls nvkm_gsp_rpc_get() which never
returns NULL, only valid pointers or error pointers. Clean up by
using IS_ERR() instead, matching the actual return value contract.
Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
---
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c
index fae08ac3b18c..9cd68f8622d3 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c
@@ -55,7 +55,7 @@ r535_bar_bar2_update_pde(struct nvkm_gsp *gsp, u8 page_shift, u64 pdbe)
rpc_update_bar_pde_v15_00 *rpc;
rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_UPDATE_BAR_PDE, sizeof(*rpc));
- if (WARN_ON(IS_ERR_OR_NULL(rpc)))
+ if (WARN_ON(IS_ERR(rpc)))
return -EIO;
rpc->info.barType = NV_RPC_UPDATE_PDE_BAR_2;
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v3 4/5] nouveau/gsp/rm/bar: Cleanup IS_ERR_OR_NULL usage
2026-06-22 2:12 [PATCH v3 0/5] nouveau/gsp: Clean up IS_ERR vs IS_ERR_OR_NULL usage Hongling Zeng
` (6 preceding siblings ...)
2026-06-22 2:12 ` [PATCH v3 4/5] nouveau/gsp/rm/bar: " Hongling Zeng
@ 2026-06-22 2:12 ` Hongling Zeng
2026-06-22 2:12 ` Hongling Zeng
2026-06-22 2:12 ` Hongling Zeng
9 siblings, 0 replies; 23+ messages in thread
From: Hongling Zeng @ 2026-06-22 2:12 UTC (permalink / raw)
To: lyude, dakr, maarten.lankhorst, mripard, tzimmermann, airlied,
simona, airlied, ttabi, bskeggs, dri-devel
Cc: nouveau, linux-kernel, zhongling0719, Hongling Zeng
r535_bar_bar2_update_pde() calls nvkm_gsp_rpc_get() which never
returns NULL, only valid pointers or error pointers. Clean up by
using IS_ERR() instead, matching the actual return value contract.
Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
---
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c
index fae08ac3b18c..9cd68f8622d3 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c
@@ -55,7 +55,7 @@ r535_bar_bar2_update_pde(struct nvkm_gsp *gsp, u8 page_shift, u64 pdbe)
rpc_update_bar_pde_v15_00 *rpc;
rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_UPDATE_BAR_PDE, sizeof(*rpc));
- if (WARN_ON(IS_ERR_OR_NULL(rpc)))
+ if (WARN_ON(IS_ERR(rpc)))
return -EIO;
rpc->info.barType = NV_RPC_UPDATE_PDE_BAR_2;
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v3 5/5] nouveau/gsp: Cleanup IS_ERR_OR_NULL in nvkm_gsp_rpc_rd()
2026-06-22 2:12 [PATCH v3 0/5] nouveau/gsp: Clean up IS_ERR vs IS_ERR_OR_NULL usage Hongling Zeng
@ 2026-06-22 2:12 ` Hongling Zeng
2026-06-22 2:12 ` Hongling Zeng
` (8 subsequent siblings)
9 siblings, 0 replies; 23+ messages in thread
From: Hongling Zeng @ 2026-06-22 2:12 UTC (permalink / raw)
To: lyude, dakr, maarten.lankhorst, mripard, tzimmermann, airlied,
simona, airlied, ttabi, bskeggs, dri-devel
Cc: nouveau, linux-kernel, zhongling0719, Hongling Zeng
nvkm_gsp_rpc_rd() calls nvkm_gsp_rpc_get() which never returns NULL,
only valid pointers or error pointers. Clean up by using IS_ERR()
instead, matching the actual return value contract.
Note: nvkm_gsp_rpc_push() can return NULL when policy is NOWAIT or
NOSEQ, but nvkm_gsp_rpc_rd() uses RECV policy which expects a reply.
If the RPC fails to get a reply, it should return an error pointer,
not NULL.
Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
---
drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
index 64fed208e4cf..a061779e0107 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
@@ -293,7 +293,7 @@ nvkm_gsp_rpc_rd(struct nvkm_gsp *gsp, u32 fn, u32 argc)
{
void *argv = nvkm_gsp_rpc_get(gsp, fn, argc);
- if (IS_ERR_OR_NULL(argv))
+ if (IS_ERR(argv))
return argv;
return nvkm_gsp_rpc_push(gsp, argv, NVKM_GSP_RPC_REPLY_RECV, argc);
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v3 5/5] nouveau/gsp: Cleanup IS_ERR_OR_NULL in nvkm_gsp_rpc_rd()
@ 2026-06-22 2:12 ` Hongling Zeng
0 siblings, 0 replies; 23+ messages in thread
From: Hongling Zeng @ 2026-06-22 2:12 UTC (permalink / raw)
To: lyude, dakr, maarten.lankhorst, mripard, tzimmermann, airlied,
simona, airlied, ttabi, bskeggs, dri-devel
Cc: nouveau, linux-kernel, zhongling0719, Hongling Zeng
nvkm_gsp_rpc_rd() calls nvkm_gsp_rpc_get() which never returns NULL,
only valid pointers or error pointers. Clean up by using IS_ERR()
instead, matching the actual return value contract.
Note: nvkm_gsp_rpc_push() can return NULL when policy is NOWAIT or
NOSEQ, but nvkm_gsp_rpc_rd() uses RECV policy which expects a reply.
If the RPC fails to get a reply, it should return an error pointer,
not NULL.
Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
---
drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
index 64fed208e4cf..a061779e0107 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
@@ -293,7 +293,7 @@ nvkm_gsp_rpc_rd(struct nvkm_gsp *gsp, u32 fn, u32 argc)
{
void *argv = nvkm_gsp_rpc_get(gsp, fn, argc);
- if (IS_ERR_OR_NULL(argv))
+ if (IS_ERR(argv))
return argv;
return nvkm_gsp_rpc_push(gsp, argv, NVKM_GSP_RPC_REPLY_RECV, argc);
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v3 5/5] nouveau/gsp: Cleanup IS_ERR_OR_NULL in nvkm_gsp_rpc_rd()
2026-06-22 2:12 [PATCH v3 0/5] nouveau/gsp: Clean up IS_ERR vs IS_ERR_OR_NULL usage Hongling Zeng
` (8 preceding siblings ...)
2026-06-22 2:12 ` Hongling Zeng
@ 2026-06-22 2:12 ` Hongling Zeng
2026-06-22 12:09 ` sashiko-bot
9 siblings, 1 reply; 23+ messages in thread
From: Hongling Zeng @ 2026-06-22 2:12 UTC (permalink / raw)
To: lyude, dakr, maarten.lankhorst, mripard, tzimmermann, airlied,
simona, airlied, ttabi, bskeggs, dri-devel
Cc: nouveau, linux-kernel, zhongling0719, Hongling Zeng
nvkm_gsp_rpc_rd() calls nvkm_gsp_rpc_get() which never returns NULL,
only valid pointers or error pointers. Clean up by using IS_ERR()
instead, matching the actual return value contract.
Note: nvkm_gsp_rpc_push() can return NULL when policy is NOWAIT or
NOSEQ, but nvkm_gsp_rpc_rd() uses RECV policy which expects a reply.
If the RPC fails to get a reply, it should return an error pointer,
not NULL.
Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
---
drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
index 64fed208e4cf..a061779e0107 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
@@ -293,7 +293,7 @@ nvkm_gsp_rpc_rd(struct nvkm_gsp *gsp, u32 fn, u32 argc)
{
void *argv = nvkm_gsp_rpc_get(gsp, fn, argc);
- if (IS_ERR_OR_NULL(argv))
+ if (IS_ERR(argv))
return argv;
return nvkm_gsp_rpc_push(gsp, argv, NVKM_GSP_RPC_REPLY_RECV, argc);
--
2.25.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH v3 1/5] nouveau/gsp/rpc: Document RPC function return value contracts
2026-06-22 2:12 ` Hongling Zeng
(?)
@ 2026-06-22 2:26 ` sashiko-bot
-1 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-06-22 2:26 UTC (permalink / raw)
To: Hongling Zeng; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
New issues:
- [Low] The newly added kernel-doc comments for `r535_gsp_rpc_send` and `r535_gsp_rpc_push` incorrectly document their return values regarding the POLL policy.
Pre-existing issues:
- [High] r535_gsp_msgq_recv() returns NULL instead of an error pointer on invalid RPC length, leading to unchecked propagation and widespread NULL pointer dereferences.
--
commit 0752081ac429b7a0554a2c49b5c123044b8bdc1f
Author: Hongling Zeng <zenghongling@kylinos.cn>
nouveau/gsp/rpc: Document RPC function return value contracts
Add kernel-doc comments to document the return value semantics of
RPC functions in r535/rpc.c. This clarifies which functions can return
NULL, error pointers, or both, helping maintainers validate future
changes.
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
> index 3ca3de8f43408..35272c1538699 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
[ ... ]
> @@ -283,6 +300,15 @@ r535_gsp_msgq_recv_one_elem(struct nvkm_gsp *gsp,
> return buf;
> }
>
> +/**
> + * r535_gsp_msgq_recv - Receive RPC message(s) from GSP queue
> + * @gsp: GSP device
> + * @gsp_rpc_len: Expected RPC length
> + * @retries: Retry counter
> + *
> + * Return: Pointer to received buffer on success, ERR_PTR() on error,
> + * or NULL if RPC length is invalid.
> + */
> static void *
> r535_gsp_msgq_recv(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries)
[Severity: High]
This is a pre-existing issue, but returning NULL here on an invalid
RPC length seems to cause widespread NULL pointer dereferences later on.
If r535_gsp_msgq_recv() returns NULL, it propagates to callers like
r535_gsp_rpc_rm_ctrl_push(), which handles the error like this:
if (IS_ERR_OR_NULL(rpc)) {
*params = NULL;
return PTR_ERR(rpc);
}
Because PTR_ERR(NULL) evaluates to 0, this gets passed up the stack as a
success condition. Wrapper functions like nvkm_gsp_rm_ctrl_rd() receive
the 0 return code and pass the NULL argv pointer back to their callers.
When a downstream caller like r535_disp_get_supported() checks the result:
ctrl = nvkm_gsp_rm_ctrl_rd(&disp->rm.objcom,
NV0073_CTRL_CMD_SYSTEM_GET_SUPPORTED,
sizeof(*ctrl));
if (IS_ERR(ctrl))
return PTR_ERR(ctrl);
*pmask = ctrl->displayMask;
The IS_ERR(NULL) check evaluates to false, causing a kernel panic when
the NULL pointer is dereferenced on the very next line.
Could we change r535_gsp_msgq_recv() to return an error pointer like
ERR_PTR(-EINVAL) instead of NULL when the message length is invalid?
[ ... ]
> @@ -574,6 +625,16 @@ r535_gsp_rpc_handle_reply(struct nvkm_gsp *gsp, u32 fn,
> return repv;
> }
>
> +/**
> + * r535_gsp_rpc_send - Send RPC message and handle reply
> + * @gsp: GSP device
> + * @payload: RPC payload to send
> + * @policy: Reply policy (NOWAIT, NOSEQ, RECV, or POLL)
> + * @gsp_rpc_len: Expected RPC length for reply
> + *
> + * Return: NULL if policy is NOWAIT/NOSEQ (no reply expected),
> + * pointer to reply data on success, or ERR_PTR() on error.
> + */
> static void *
> r535_gsp_rpc_send(struct nvkm_gsp *gsp, void *payload,
[Severity: Low]
Does this documentation miss the POLL policy's NULL return behavior?
The documentation for r535_gsp_rpc_handle_reply() correctly notes that
when the policy is POLL, it returns NULL on successful message processing.
Since r535_gsp_rpc_send() returns the result of r535_gsp_rpc_handle_reply(),
should POLL be included in the list of policies that return NULL here?
[ ... ]
> @@ -628,6 +703,16 @@ r535_gsp_rpc_get(struct nvkm_gsp *gsp, u32 fn, u32 payload_size)
> return rpc->data;
> }
>
> +/**
> + * r535_gsp_rpc_push - Push RPC message to GSP and wait for reply
> + * @gsp: GSP device
> + * @payload: RPC payload to send
> + * @policy: Reply policy (NOWAIT, NOSEQ, RECV, or POLL)
> + * @gsp_rpc_len: Expected RPC length in the reply
> + *
> + * Return: NULL when policy is NOWAIT/NOSEQ (no reply expected),
> + * pointer to reply data on success, or ERR_PTR() on error.
> + */
> static void *
> r535_gsp_rpc_push(struct nvkm_gsp *gsp, void *payload,
[Severity: Low]
Similar to r535_gsp_rpc_send() above, should this also document that the
POLL policy can return NULL on success?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260622021207.14764-1-zenghongling@kylinos.cn?part=1
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v3 4/5] nouveau/gsp/rm/bar: Cleanup IS_ERR_OR_NULL usage
2026-06-22 2:12 ` [PATCH v3 4/5] nouveau/gsp/rm/bar: " Hongling Zeng
@ 2026-06-22 2:27 ` sashiko-bot
0 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-06-22 2:27 UTC (permalink / raw)
To: Hongling Zeng; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [Medium] The original GSP message wrapper (`msg`) is leaked on error paths when pushing large RPC payloads.
--
commit 983901af13a13a0d204f00f3cb9a175b176bf22f
Author: Hongling Zeng <zenghongling@kylinos.cn>
nouveau/gsp/rm/bar: Cleanup IS_ERR_OR_NULL usage
r535_bar_bar2_update_pde() calls nvkm_gsp_rpc_get() which never
returns NULL, only valid pointers or error pointers. Clean up by
using IS_ERR() instead, matching the actual return value contract.
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c
> index fae08ac3b18c7..9cd68f8622d36 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c
> @@ -55,7 +55,7 @@ r535_bar_bar2_update_pde(struct nvkm_gsp *gsp, u8 page_shift, u64 pdbe)
> rpc_update_bar_pde_v15_00 *rpc;
>
> rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_UPDATE_BAR_PDE, sizeof(*rpc));
> - if (WARN_ON(IS_ERR_OR_NULL(rpc)))
> + if (WARN_ON(IS_ERR(rpc)))
> return -EIO;
>
> rpc->info.barType = NV_RPC_UPDATE_PDE_BAR_2;
[Severity: Medium]
This isn't a bug introduced by this patch, but does the GSP message wrapper
leak on error paths when pushing large RPC payloads?
In drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c:r535_gsp_rpc_push():
if (payload_size > max_payload_size) {
...
/* Send initial RPC. */
next = r535_gsp_rpc_get(gsp, fn, max_payload_size);
if (IS_ERR(next)) {
repv = next;
goto done;
}
...
repv = r535_gsp_rpc_send(gsp, next, NVKM_GSP_RPC_REPLY_NOWAIT, 0);
if (IS_ERR(repv))
goto done;
...
/* Wait for reply. */
repv = r535_gsp_rpc_handle_reply(gsp, fn, policy, payload_size +
sizeof(*rpc));
if (!IS_ERR(repv))
kvfree(msg);
} else {
If a payload exceeds max_payload_size, the original msg wrapper is retained
while the payload is sent in chunks using new messages. The chunks are
properly freed by the inner r535_gsp_cmdq_push(), but the original msg is
only freed at the end if no error occurred.
If an error occurs at any point (e.g., r535_gsp_rpc_get() fails,
r535_gsp_rpc_send() fails, or the final reply is an error pointer), the
function exits without freeing msg.
Callers such as r535_gsp_rpc_rm_ctrl_push() clear their pointers on error:
if (IS_ERR_OR_NULL(rpc)) {
*params = NULL;
return PTR_ERR(rpc);
}
so they cannot free the message either, which appears to result in a memory
leak on these error paths.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260622021207.14764-1-zenghongling@kylinos.cn?part=4
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v3 2/5] nouveau/gsp/rpc: Cleanup incorrect IS_ERR_OR_NULL in rpc.c
2026-06-22 2:12 ` Hongling Zeng
(?)
@ 2026-06-22 2:27 ` sashiko-bot
-1 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-06-22 2:27 UTC (permalink / raw)
To: Hongling Zeng; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
Pre-existing issues:
- [Critical] Missing lower and relative bounds validation for GSP RPC message lengths leads to multiple severe memory corruption vulnerabilities, including out-of-bounds reads, massive integer/buffer underflows, and kernel heap overflows.
- [Critical] Incorrect destination offset calculation when receiving a wrap-around continuation element leaves a 32-byte gap in the payload and causes a 32-byte heap buffer overflow.
- [High] Returning `NULL` instead of an `ERR_PTR` on abnormally large `rpc->length` causes silent failure propagation, leading to NULL pointer dereferences in caller functions and queue deadlocks.
- [Medium] Large payload requests are leaked on error paths in `r535_gsp_rpc_push()`.
--
commit 849e62a17ca943158f16f67ef2b39000a10c58b6
Author: Hongling Zeng <zenghongling@kylinos.cn>
nouveau/gsp/rpc: Cleanup incorrect IS_ERR_OR_NULL in rpc.c
Clean up incorrect IS_ERR_OR_NULL() usage for functions that never
return NULL:
- r535_gsp_msgq_peek() never returns NULL
- r535_gsp_msgq_recv_one_elem() never returns NULL
These functions should be checked with IS_ERR() instead.
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
> index 35272c1538699..25d3adbc13550 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
> @@ -350,7 +350,7 @@ r535_gsp_msgq_recv(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries)
> u32 size;
>
> rpc = r535_gsp_msgq_peek(gsp, sizeof(*rpc), info.retries);
> - if (IS_ERR_OR_NULL(rpc)) {
> + if (IS_ERR(rpc)) {
[Severity: High]
This is a pre-existing issue, but does r535_gsp_msgq_recv() correctly handle
returning NULL?
Earlier in r535_gsp_msgq_recv(), if the length exceeds the maximum, it returns
NULL:
if (WARN_ON(rpc->length > max_rpc_size))
return NULL;
When this NULL is propagated to callers like r535_gsp_rpc_rm_ctrl_push(), it
can translate to a 0 (success) return code because PTR_ERR(NULL) is 0. This
can lead to silent failure propagation and queue deadlocks. Would it be better
to return an ERR_PTR() instead?
[Severity: Critical]
This is also a pre-existing issue, but does rpc->length need a lower bounds
check?
In r535_gsp_msgq_recv(), the code verifies rpc->length <= max_rpc_size, but
doesn't verify if it is smaller than sizeof(struct nvfw_gsp_rpc).
If the length is smaller than the struct size, calculations like
len - sizeof(struct nvfw_gsp_rpc) in r535_gsp_msgq_recv_one_elem() can
underflow. Could this lead to an out-of-bounds read and massive buffer
underflows during memcpy?
> kvfree(buf);
> return rpc;
> }
> @@ -359,7 +359,7 @@ r535_gsp_msgq_recv(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries)
> info.continuation = true;
>
> rpc = r535_gsp_msgq_recv_one_elem(gsp, &info);
> - if (IS_ERR_OR_NULL(rpc)) {
> + if (IS_ERR(rpc)) {
[Severity: Critical]
This isn't a bug introduced by this patch, but does
r535_gsp_msgq_recv_one_elem() calculate the destination offset correctly for
continuation elements?
When info.continuation is true and the message wraps around the ring buffer,
the second memcpy() writes to buf + len:
r535_gsp_msgq_recv_one_elem() {
...
if (expected) {
mqe = (void *)((u8 *)gsp->shm.msgq.ptr + 0x1000 + 0 * 0x1000);
memcpy(buf + len, mqe, expected);
}
...
}
Since len isn't adjusted for the sizeof(struct nvfw_gsp_rpc) that was skipped
in the first memcpy, does this leave an uninitialized gap and cause a heap
buffer overflow by writing past the end of the kvmalloc-allocated buffer?
> kvfree(buf);
> return rpc;
> }
[ ... ]
> @@ -499,7 +499,7 @@ r535_gsp_msg_recv(struct nvkm_gsp *gsp, int fn, u32 gsp_rpc_len)
>
> retry:
> rpc = r535_gsp_msgq_peek(gsp, sizeof(*rpc), &retries);
> - if (IS_ERR_OR_NULL(rpc))
> + if (IS_ERR(rpc))
> return rpc;
>
> rpc = r535_gsp_msgq_recv(gsp, gsp_rpc_len, &retries);
[Severity: Medium]
While reviewing these changes, I noticed another pre-existing issue. Does
r535_gsp_rpc_push() leak the msg buffer on error paths?
In r535_gsp_rpc_push(), msg is explicitly freed on success:
r535_gsp_rpc_push() {
...
if (!IS_ERR(repv))
kvfree(msg);
...
}
However, if any intermediate chunk fails to send or if handling the reply
fails, the code jumps to the done: label and returns an error without freeing
msg. Should msg be freed on these error paths as well?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260622021207.14764-1-zenghongling@kylinos.cn?part=2
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v3 5/5] nouveau/gsp: Cleanup IS_ERR_OR_NULL in nvkm_gsp_rpc_rd()
2026-06-22 2:12 ` Hongling Zeng
(?)
@ 2026-06-22 2:28 ` sashiko-bot
-1 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-06-22 2:28 UTC (permalink / raw)
To: Hongling Zeng; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] A malformed GSP message size causes r535_gsp_msgq_recv() to return NULL, which propagates through nvkm_gsp_rpc_rd() and leads to a NULL pointer dereference in its callers.
--
commit 604de241374540fdccd3d8af5fec3fe8ff826d71
Author: Hongling Zeng <zenghongling@kylinos.cn>
nouveau/gsp: Cleanup IS_ERR_OR_NULL in nvkm_gsp_rpc_rd()
This commit cleans up nvkm_gsp_rpc_rd() by replacing IS_ERR_OR_NULL()
with IS_ERR(). The commit message notes that nvkm_gsp_rpc_push() expects
a reply under the RECV policy and should return an error pointer rather
than NULL if the RPC fails.
> diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
> index 64fed208e4cf8..a061779e0107b 100644
> --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
> +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
> @@ -293,7 +293,7 @@ nvkm_gsp_rpc_rd(struct nvkm_gsp *gsp, u32 fn, u32 argc)
> {
> void *argv = nvkm_gsp_rpc_get(gsp, fn, argc);
>
> - if (IS_ERR_OR_NULL(argv))
> + if (IS_ERR(argv))
> return argv;
>
> return nvkm_gsp_rpc_push(gsp, argv, NVKM_GSP_RPC_REPLY_RECV, argc);
[Severity: High]
This is a pre-existing issue, but does nvkm_gsp_rpc_push() strictly return
an error pointer instead of NULL on failure under the RECV policy?
If the GSP firmware returns an RPC message with an invalid length,
r535_gsp_msgq_recv() triggers a WARN_ON and returns NULL:
r535_gsp_msgq_recv() in drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c:
...
if (WARN_ON(rpc->length > max_rpc_size))
return NULL;
...
This NULL propagates up through r535_gsp_msg_recv() and
r535_gsp_rpc_handle_reply() to nvkm_gsp_rpc_push(), which is then returned
directly by nvkm_gsp_rpc_rd() here.
Since callers like r535_gsp_get_static_info() only check IS_ERR(), could this
lead to a NULL pointer dereference?
r535_gsp_get_static_info() in drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c:
...
rpc = nvkm_gsp_rpc_rd(gsp, NV_VGPU_MSG_FUNCTION_GET_GSP_STATIC_INFO, sizeof(*rpc));
if (IS_ERR(rpc))
return PTR_ERR(rpc);
gsp->internal.client.object.client = &gsp->internal.client;
gsp->internal.client.object.parent = NULL;
gsp->internal.client.object.handle = rpc->hInternalClient;
...
Similarly, does r535_gsp_rpc_rm_ctrl_push() mishandle this NULL?
r535_gsp_rpc_rm_ctrl_push() in drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/ctrl.c:
...
repv = nvkm_gsp_rpc_push(gsp, rpc, repc ? NVKM_GSP_RPC_REPLY_RECV :
NVKM_GSP_RPC_REPLY_NOWAIT, repc);
if (IS_ERR_OR_NULL(repv)) {
*params = NULL;
return PTR_ERR(repv);
}
...
If nvkm_gsp_rpc_push() returns NULL, PTR_ERR(repv) evaluates to 0 (success),
which causes it to return success while passing a NULL pointer back to callers
like r535_gsp_intr_get_table().
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260622021207.14764-1-zenghongling@kylinos.cn?part=5
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v3 3/5] nouveau/gsp/rm/alloc: Cleanup IS_ERR_OR_NULL usage
2026-06-22 2:12 ` Hongling Zeng
@ 2026-06-22 4:28 ` sashiko-bot
0 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-06-22 4:28 UTC (permalink / raw)
To: Hongling Zeng; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Silently dropping oversized GSP RPC messages and reporting false success.
--
commit c03df51ffa049e6fe56eec7d75137d404fe0855b
Author: Hongling Zeng <zenghongling@kylinos.cn>
nouveau/gsp/rm/alloc: Cleanup IS_ERR_OR_NULL usage
This commit cleans up error checking by using IS_ERR() instead of
WARN_ON(IS_ERR_OR_NULL()) after nvkm_gsp_rpc_get() calls, matching
the actual return value contract.
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/alloc.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/alloc.c
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/alloc.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/alloc.c
> @@ -35,7 +35,7 @@ r535_gsp_rpc_rm_free(struct nvkm_gsp_object *object)
> client->object.handle, object->handle);
>
> rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_FREE, sizeof(*rpc));
> - if (WARN_ON(IS_ERR_OR_NULL(rpc)))
> + if (WARN_ON(IS_ERR(rpc)))
> return -EIO;
>
> rpc->params.hRoot = client->object.handle;
> rpc->params.hObjectParent = 0;
> rpc->params.hObjectOld = object->handle;
> return nvkm_gsp_rpc_wr(gsp, rpc, NVKM_GSP_RPC_REPLY_RECV);
[Severity: High]
This isn't a bug introduced by this patch, but since this commit is
cleaning up error handling around GSP RPC interactions, does
nvkm_gsp_rpc_wr() also have an error handling issue that hides critical
failures?
Looking at drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c, if the
GSP sends an RPC message where rpc->length > max_rpc_size,
r535_gsp_msgq_recv() returns NULL without advancing the message queue read
pointer:
r535_gsp_msgq_recv()
...
if (WARN_ON(rpc->length > max_rpc_size))
return NULL;
This NULL propagates to nvkm_gsp_rpc_wr() in
drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h, which translates it into
a false success:
nvkm_gsp_rpc_wr()
...
if (IS_ERR(repv))
return PTR_ERR(repv);
return 0;
Since repv is NULL, IS_ERR(repv) evaluates to false, causing the function
to silently return 0.
Could this cause the caller to proceed assuming the RPC succeeded,
potentially leading to an invalid state or use-after-free, while the
unadvanced read pointer permanently wedges the message queue for all
subsequent reads?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260622021207.14764-1-zenghongling@kylinos.cn?part=3
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v3 1/5] nouveau/gsp/rpc: Document RPC function return value contracts
2026-06-22 2:12 ` Hongling Zeng
@ 2026-06-22 9:20 ` sashiko-bot
0 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-06-22 9:20 UTC (permalink / raw)
To: Hongling Zeng; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
New issues:
- [Medium] The newly added kernel-doc claims that several high-level RPC functions only return ERR_PTR on error, but they can actually propagate NULL.
Pre-existing issues:
- [High] Returning NULL on an invalid RPC message length causes a queue deadlock and subsequent NULL pointer dereferences in downstream callers that only check IS_ERR().
--
commit db05356d173cc7558f718a62efd7f0f223cf7152
Author: Hongling Zeng <zenghongling@kylinos.cn>
nouveau/gsp/rpc: Document RPC function return value contracts
This commit adds kernel-doc comments to document the return value semantics
of RPC functions in the nouveau GSP code to clarify which functions can
return error pointers or NULL.
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
> index 3ca3de8f43408..35272c1538699 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
[ ... ]
> @@ -283,6 +300,15 @@ r535_gsp_msgq_recv_one_elem(struct nvkm_gsp *gsp,
> return buf;
> }
>
> +/**
> + * r535_gsp_msgq_recv - Receive RPC message(s) from GSP queue
> + * @gsp: GSP device
> + * @gsp_rpc_len: Expected RPC length
> + * @retries: Retry counter
> + *
> + * Return: Pointer to received buffer on success, ERR_PTR() on error,
> + * or NULL if RPC length is invalid.
> + */
> static void *
> r535_gsp_msgq_recv(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries)
[Severity: High]
This is a pre-existing issue, but does returning NULL here on an invalid RPC
message length cause issues for callers?
When r535_gsp_msgq_recv() encounters an invalid length, it returns NULL
without advancing the queue read pointer:
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c:r535_gsp_msgq_recv() {
if (WARN_ON(rpc->length > max_rpc_size))
return NULL;
...
}
This NULL return propagates up to API wrappers like nvkm_gsp_rpc_rd() and
nvkm_gsp_rpc_wr(). Downstream callers such as r535_gsp_get_static_info()
check for errors using IS_ERR(). Since IS_ERR(NULL) is false, the error check
is bypassed. This leads to silent successes (like PTR_ERR(NULL) == 0) or
immediate NULL pointer dereferences when the payload is accessed.
Also, since the queue read pointer is not advanced, wouldn't subsequent reads
process the same invalid message and deadlock the queue?
[ ... ]
> @@ -450,6 +476,20 @@ r535_gsp_msg_dump(struct nvkm_gsp *gsp, struct nvfw_gsp_rpc *msg, int lvl)
> }
> }
>
> +/**
> + * r535_gsp_msg_recv - Receive RPC message from GSP message queue
> + * @gsp: GSP device
> + * @fn: Expected RPC function number (0 to accept any)
> + * @gsp_rpc_len: Expected RPC length (0 for POLL mode)
> + *
> + * Return: Pointer to RPC message on success, ERR_PTR() on error.
> + * When fn!=0: retries until timeout, returns ERR_PTR(-ETIMEDOUT)
> + * if no match found (never returns NULL for timeout).
[Severity: Medium]
Is this documentation accurate regarding error returns?
The kernel-doc states this function returns ERR_PTR() on error, but it
can actually propagate the NULL returned by r535_gsp_msgq_recv() when an
invalid RPC length is encountered:
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c:r535_gsp_msg_recv() {
...
rpc = r535_gsp_msgq_recv(gsp, gsp_rpc_len, &retries);
if (IS_ERR_OR_NULL(rpc))
return rpc;
...
}
Could this mislead developers into incorrectly replacing IS_ERR_OR_NULL()
checks with IS_ERR() in the callers?
[ ... ]
> @@ -628,6 +703,16 @@ r535_gsp_rpc_get(struct nvkm_gsp *gsp, u32 fn, u32 payload_size)
> return rpc->data;
> }
>
> +/**
> + * r535_gsp_rpc_push - Push RPC message to GSP and wait for reply
> + * @gsp: GSP device
> + * @payload: RPC payload to send
> + * @policy: Reply policy (NOWAIT, NOSEQ, RECV, or POLL)
> + * @gsp_rpc_len: Expected RPC length in the reply
> + *
> + * Return: NULL when policy is NOWAIT/NOSEQ (no reply expected),
> + * pointer to reply data on success, or ERR_PTR() on error.
> + */
> static void *
> r535_gsp_rpc_push(struct nvkm_gsp *gsp, void *payload,
[Severity: Medium]
Does this documentation also hide a potential NULL return on error?
Similar to r535_gsp_msg_recv() above, this function can return NULL on error
if an invalid RPC length propagates up from the reply handler. Should the
documentation reflect that NULL can be returned as an error state?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260622021207.14764-1-zenghongling@kylinos.cn?part=1
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v3 2/5] nouveau/gsp/rpc: Cleanup incorrect IS_ERR_OR_NULL in rpc.c
2026-06-22 2:12 ` Hongling Zeng
@ 2026-06-22 9:33 ` sashiko-bot
0 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-06-22 9:33 UTC (permalink / raw)
To: Hongling Zeng; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
Pre-existing issues:
- [Critical] Missing validation of `rpc->length` from untrusted GSP firmware leads to integer underflows and massive out-of-bounds memory accesses.
- [High] Incorrect destination offset when a continuation message wraps around the ring buffer leads to payload corruption and an out-of-bounds write.
- [High] `r535_gsp_msgq_recv()` returns `NULL` on oversized RPC messages, leading to NULL pointer dereferences in callers.
--
commit c55dadd139cb2f5047a2ad1948afcbd89e5133ab
Author: Hongling Zeng <zenghongling@kylinos.cn>
nouveau/gsp/rpc: Cleanup incorrect IS_ERR_OR_NULL in rpc.c
Clean up incorrect IS_ERR_OR_NULL() usage for functions that never
return NULL:
- r535_gsp_msgq_peek() never returns NULL
- r535_gsp_msgq_recv_one_elem() never returns NULL
These functions should be checked with IS_ERR() instead.
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
> index 35272c1538699..25d3adbc13550 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c
[ ... ]
> @@ -359,7 +359,7 @@ r535_gsp_msgq_recv(struct nvkm_gsp *gsp, u32 gsp_rpc_len, int *retries)
> info.continuation = true;
>
> rpc = r535_gsp_msgq_recv_one_elem(gsp, &info);
> - if (IS_ERR_OR_NULL(rpc)) {
> + if (IS_ERR(rpc)) {
> kvfree(buf);
> return rpc;
> }
[Severity: Critical]
This is a pre-existing issue, but does r535_gsp_msgq_recv() validate the
size of rpc->length coming from the untrusted GSP firmware?
If a compromised GSP sends an rpc->length less than sizeof(*rpc) (32 bytes),
wouldn't the size calculation immediately following this block underflow:
size = info.gsp_rpc_len - sizeof(*rpc);
expected -= size;
info.gsp_rpc_buf += size;
Could this result in info.gsp_rpc_buf pointing to massively out-of-bounds
addresses and cause arbitrary memory corruption?
[Severity: High]
This isn't a bug introduced by this patch, but is there an out-of-bounds
write inside r535_gsp_msgq_recv_one_elem() when handling wrapped
continuation messages?
For continuation messages, the first part of the copy skips the 32-byte
header, but the destination offset for the second part appears to be
incorrect:
if (info->continuation)
memcpy(buf, mqe->data + sizeof(struct nvfw_gsp_rpc),
len - sizeof(struct nvfw_gsp_rpc));
else
memcpy(buf, mqe->data, len);
expected -= len;
if (expected) {
mqe = (void *)((u8 *)gsp->shm.msgq.ptr + ...);
memcpy(buf + len, mqe, expected);
Since len isn't reduced by sizeof(struct nvfw_gsp_rpc) for the offset,
won't buf + len leave a 32-byte uninitialized hole and push the remainder
copy 32 bytes past the end of the allocated buffer?
> @@ -499,7 +499,7 @@ r535_gsp_msg_recv(struct nvkm_gsp *gsp, int fn, u32 gsp_rpc_len)
>
> retry:
> rpc = r535_gsp_msgq_peek(gsp, sizeof(*rpc), &retries);
> - if (IS_ERR_OR_NULL(rpc))
> + if (IS_ERR(rpc))
> return rpc;
>
> rpc = r535_gsp_msgq_recv(gsp, gsp_rpc_len, &retries);
[Severity: High]
This is a pre-existing issue, but could r535_gsp_msgq_recv() return NULL
on oversized RPC messages?
Looking at r535_gsp_msgq_recv(), it returns NULL instead of an error
pointer when the WARN_ON triggers:
if (WARN_ON(rpc->length > max_rpc_size))
return NULL;
Many callers expect either a valid pointer or an ERR_PTR, and only check
for errors using IS_ERR(). For example, in r535_gsp_get_static_info():
rpc = nvkm_gsp_rpc_rd(gsp, NV_VGPU_MSG_FUNCTION_GET_GSP_STATIC_INFO, ...);
if (IS_ERR(rpc))
return PTR_ERR(rpc);
gsp->internal.client.object.client = &gsp->internal.client;
gsp->internal.client.object.parent = NULL;
gsp->internal.client.object.handle = rpc->hInternalClient;
Since IS_ERR(NULL) is false, won't this result in a NULL pointer
dereference? Should r535_gsp_msgq_recv() return ERR_PTR(-E2BIG) instead?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260622021207.14764-1-zenghongling@kylinos.cn?part=2
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v3 3/5] nouveau/gsp/rm/alloc: Cleanup IS_ERR_OR_NULL usage
2026-06-22 2:12 ` [PATCH v3 3/5] nouveau/gsp/rm/alloc: Cleanup IS_ERR_OR_NULL usage Hongling Zeng
@ 2026-06-22 9:47 ` sashiko-bot
0 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-06-22 9:47 UTC (permalink / raw)
To: Hongling Zeng; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
Pre-existing issues:
- [Critical] Double fetch of `rpc->length` from untrusted GSP shared memory allows bypassing size validation and causing a heap buffer overflow.
- [Critical] Integer underflow in `r535_gsp_msgq_recv_one_elem()` when copying continuation records with a small length.
- [Critical] Missing validation of continuation chunk sizes in `r535_gsp_msgq_recv()` leads to heap buffer overflow and integer underflow.
- [High] Silent failure when GSP firmware sends a corrupted RPC reply for an allocation request.
- [High] Memory leak of the RPC reply payload when `nvkm_gsp_rpc_wr()` is used with `NVKM_GSP_RPC_REPLY_RECV`.
- [High] Large RPC message buffer leak on error paths in `r535_gsp_rpc_push()`.
--
commit 80c014f86c2f1ac065ff1b0e24d2eb0c508a2e4a
Author: Hongling Zeng <zenghongling@kylinos.cn>
nouveau/gsp/rm/alloc: Cleanup IS_ERR_OR_NULL usage
This commit cleans up the usage of IS_ERR_OR_NULL in r535_gsp_rpc_rm_free().
It updates the check for nvkm_gsp_rpc_get() to only use IS_ERR(), matching
its actual return value contract.
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/alloc.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/alloc.c
> index 46e3a29f2ad7f..c9f86c0e9b255 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/alloc.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/alloc.c
> @@ -35,7 +35,7 @@ r535_gsp_rpc_rm_free(struct nvkm_gsp_object *object)
> client->object.handle, object->handle);
>
> rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_FREE, sizeof(*rpc));
> - if (WARN_ON(IS_ERR_OR_NULL(rpc)))
> + if (WARN_ON(IS_ERR(rpc)))
> return -EIO;
>
> rpc->params.hRoot = client->object.handle;
> rpc->params.hObjectParent = 0;
> rpc->params.hObjectOld = object->handle;
> return nvkm_gsp_rpc_wr(gsp, rpc, NVKM_GSP_RPC_REPLY_RECV);
[Severity: High]
This is a pre-existing issue, but I noticed nvkm_gsp_rpc_wr() returns 0 on
success and drops the reply buffer allocated by nvkm_gsp_rpc_push().
When nvkm_gsp_rpc_wr() is called with NVKM_GSP_RPC_REPLY_RECV, the reply
is returned via:
drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h:nvkm_gsp_rpc_wr() {
...
void *repv = nvkm_gsp_rpc_push(gsp, argv, policy, 0);
if (IS_ERR(repv))
return PTR_ERR(repv);
return 0;
}
Since the caller here doesn't receive the reply buffer, and nvkm_gsp_rpc_wr()
doesn't free it, does this leak memory every time r535_gsp_rpc_rm_free()
is called?
[Severity: High]
This isn't a bug introduced by this patch, but looking at the error
handling for RPCs, I see that r535_gsp_rpc_rm_alloc_push() can return NULL:
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/alloc.c:r535_gsp_rpc_rm_alloc_push() {
...
if (IS_ERR_OR_NULL(rpc))
return rpc;
...
}
However, nvkm_gsp_rm_alloc_wr() only checks for IS_ERR(repv) and then
returns 0 (success) if it is not an error:
drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h:nvkm_gsp_rm_alloc_wr() {
...
if (IS_ERR(repv))
return PTR_ERR(repv);
return 0;
}
Since IS_ERR() evaluates to false for NULL, does this incorrectly mask
failures and treat them as successful allocations?
[Severity: High]
This is a pre-existing issue, but in r535_gsp_rpc_push(), if the final
reply yields an error, the code skips kvfree(msg):
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c:r535_gsp_rpc_push() {
...
repv = r535_gsp_rpc_handle_reply(gsp, fn, policy, payload_size +
sizeof(*rpc));
if (!IS_ERR(repv))
kvfree(msg);
...
}
If an error occurs or the code branches to the done label, does this leak
the large RPC message buffer?
[Severity: Critical]
This isn't a bug introduced by this patch, but looking at
r535_gsp_msgq_recv(), the length is read from shared memory directly:
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c:r535_gsp_msgq_recv() {
...
if (WARN_ON(rpc->length > max_rpc_size))
return NULL;
buf = kvmalloc(max_t(u32, rpc->length, expected), GFP_KERNEL);
...
info.gsp_rpc_len = rpc->length;
}
Since the length is read again after kvmalloc(), which acts as a compiler
barrier, can the GSP firmware change rpc->length between the validation
and the second fetch, bypassing the size check?
[Severity: Critical]
This is a pre-existing issue, but in r535_gsp_msgq_recv_one_elem(), there
is a size calculation without validation:
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c:r535_gsp_msgq_recv_one_elem() {
...
if (info->continuation)
memcpy(buf, mqe->data + sizeof(struct nvfw_gsp_rpc),
len - sizeof(struct nvfw_gsp_rpc));
}
If the provided length is smaller than sizeof(struct nvfw_gsp_rpc), will
this underflow and copy an excessive amount of data out-of-bounds?
[Severity: Critical]
This isn't a bug introduced by this patch, but when processing multi-part
messages in r535_gsp_msgq_recv(), the code subtracts chunk size from expected
without validation:
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c:r535_gsp_msgq_recv() {
...
size = info.gsp_rpc_len - sizeof(*rpc);
expected -= size;
info.gsp_rpc_buf += size;
}
If size is larger than the remaining expected amount, does expected underflow
and cause the buffer pointer to advance out of bounds on subsequent chunks?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260622021207.14764-1-zenghongling@kylinos.cn?part=3
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v3 5/5] nouveau/gsp: Cleanup IS_ERR_OR_NULL in nvkm_gsp_rpc_rd()
2026-06-22 2:12 ` Hongling Zeng
@ 2026-06-22 12:09 ` sashiko-bot
0 siblings, 0 replies; 23+ messages in thread
From: sashiko-bot @ 2026-06-22 12:09 UTC (permalink / raw)
To: Hongling Zeng; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [High] The commit message explains that `nvkm_gsp_rpc_push()` should not return `NULL` for RECV policies, but this assumption is incorrect, leaving callers vulnerable to NULL pointer dereferences.
- [Medium] Memory leak of large RPC payloads in `r535_gsp_rpc_push()` on error paths.
--
commit 1659548cc5b32b66b3c5a9f4367151960bb1562d
Author: Hongling Zeng <zenghongling@kylinos.cn>
nouveau/gsp: Cleanup IS_ERR_OR_NULL in nvkm_gsp_rpc_rd()
nvkm_gsp_rpc_rd() calls nvkm_gsp_rpc_get() which never returns NULL,
only valid pointers or error pointers. Clean up by using IS_ERR()
instead, matching the actual return value contract.
> Note: nvkm_gsp_rpc_push() can return NULL when policy is NOWAIT or
> NOSEQ, but nvkm_gsp_rpc_rd() uses RECV policy which expects a reply.
> If the RPC fails to get a reply, it should return an error pointer,
> not NULL.
[Severity: High]
This isn't a bug introduced by this patch, but is this description accurate?
If the RPC reply has an invalid length, r535_gsp_msgq_recv() returns NULL:
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c:r535_gsp_msgq_recv() {
...
if (WARN_ON(rpc->length > max_rpc_size))
return NULL;
...
}
This NULL propagates up through r535_gsp_msg_recv() and
r535_gsp_rpc_handle_reply(), causing nvkm_gsp_rpc_push() to return NULL even
with the RECV policy.
Since callers like r535_gsp_get_static_info() only check IS_ERR(), won't they
dereference the NULL pointer?
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c:r535_gsp_get_static_info() {
...
rpc = nvkm_gsp_rpc_rd(gsp, NV_VGPU_MSG_FUNCTION_GET_STATIC_INFO, 0);
if (IS_ERR(rpc))
return PTR_ERR(rpc);
gsp->internal.client.object.client = &gsp->internal.client;
gsp->internal.client.object.parent = NULL;
gsp->internal.client.object.handle = rpc->hInternalClient;
...
}
> diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
> index 64fed208e4cf8..a061779e0107b 100644
> --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
> +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
> @@ -293,7 +293,7 @@ nvkm_gsp_rpc_rd(struct nvkm_gsp *gsp, u32 fn, u32 argc)
> {
> void *argv = nvkm_gsp_rpc_get(gsp, fn, argc);
>
> - if (IS_ERR_OR_NULL(argv))
> + if (IS_ERR(argv))
> return argv;
>
> return nvkm_gsp_rpc_push(gsp, argv, NVKM_GSP_RPC_REPLY_RECV, argc);
[Severity: Medium]
This is a pre-existing issue, but does r535_gsp_rpc_push() leak memory on
error paths for large payloads?
If a large RPC payload fails to send, the kvfree(msg) call is skipped:
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rpc.c:r535_gsp_rpc_push() {
...
/* Wait for reply. */
repv = r535_gsp_rpc_handle_reply(gsp, fn, policy, payload_size +
sizeof(*rpc));
if (!IS_ERR(repv))
kvfree(msg);
} else {
repv = r535_gsp_rpc_send(gsp, payload, policy, gsp_rpc_len);
}
...
}
Since small RPCs unconditionally free msg via r535_gsp_cmdq_push(), callers
assume the RPC layer consumes the buffer. Will this leak the large staging
buffer if r535_gsp_rpc_get(), r535_gsp_rpc_send(), or
r535_gsp_rpc_handle_reply() fails and returns an error pointer?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260622021207.14764-1-zenghongling@kylinos.cn?part=5
^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2026-06-22 12:09 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-22 2:12 [PATCH v3 0/5] nouveau/gsp: Clean up IS_ERR vs IS_ERR_OR_NULL usage Hongling Zeng
2026-06-22 2:12 ` [PATCH v3 1/5] nouveau/gsp/rpc: Document RPC function return value contracts Hongling Zeng
2026-06-22 2:12 ` Hongling Zeng
2026-06-22 2:26 ` sashiko-bot
2026-06-22 2:12 ` Hongling Zeng
2026-06-22 9:20 ` sashiko-bot
2026-06-22 2:12 ` [PATCH v3 2/5] nouveau/gsp/rpc: Cleanup incorrect IS_ERR_OR_NULL in rpc.c Hongling Zeng
2026-06-22 2:12 ` Hongling Zeng
2026-06-22 2:27 ` sashiko-bot
2026-06-22 2:12 ` Hongling Zeng
2026-06-22 9:33 ` sashiko-bot
2026-06-22 2:12 ` [PATCH v3 3/5] nouveau/gsp/rm/alloc: Cleanup IS_ERR_OR_NULL usage Hongling Zeng
2026-06-22 9:47 ` sashiko-bot
2026-06-22 2:12 ` Hongling Zeng
2026-06-22 4:28 ` sashiko-bot
2026-06-22 2:12 ` [PATCH v3 4/5] nouveau/gsp/rm/bar: " Hongling Zeng
2026-06-22 2:27 ` sashiko-bot
2026-06-22 2:12 ` Hongling Zeng
2026-06-22 2:12 ` [PATCH v3 5/5] nouveau/gsp: Cleanup IS_ERR_OR_NULL in nvkm_gsp_rpc_rd() Hongling Zeng
2026-06-22 2:12 ` Hongling Zeng
2026-06-22 2:28 ` sashiko-bot
2026-06-22 2:12 ` Hongling Zeng
2026-06-22 12:09 ` sashiko-bot
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.