summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLizhi Hou <lizhi.hou@amd.com>2026-07-07 13:15:56 -0700
committerLizhi Hou <lizhi.hou@amd.com>2026-07-07 20:49:28 -0700
commitc69dbbf0212734e22219dfc31c0922bd7c9ffbb0 (patch)
tree4bfbbbe6d0260f8f5bf765c963d57825e7cd990c /drivers
parent44d8fddf1c87d6bb6b65983041a0ce6c2af66bb9 (diff)
accel/amdxdna: Fix potential NULL pointer dereference of abo->client
Closing a BO handle clears abo->client, while the underlying GEM object may remain alive due to internal kernel references. As a result, code executed after the BO handle is closed may dereference a NULL abo->client pointer. Remove accesses to abo->client from code paths that may execute after the BO handle has been closed. Fixes: d76856beb4a4 ("accel/amdxdna: Refactor GEM BO handling and add helper APIs for address retrieval") Reviewed-by: Max Zhen <max.zhen@amd.com> Signed-off-by: Lizhi Hou <lizhi.hou@amd.com> Link: https://patch.msgid.link/20260707201556.562191-1-lizhi.hou@amd.com
Diffstat (limited to 'drivers')
-rw-r--r--drivers/accel/amdxdna/aie2_message.c4
-rw-r--r--drivers/accel/amdxdna/amdxdna_gem.c11
-rw-r--r--drivers/accel/amdxdna/amdxdna_gem.h11
3 files changed, 20 insertions, 6 deletions
diff --git a/drivers/accel/amdxdna/aie2_message.c b/drivers/accel/amdxdna/aie2_message.c
index c4b364801cc0..dfe0fbdf066d 100644
--- a/drivers/accel/amdxdna/aie2_message.c
+++ b/drivers/accel/amdxdna/aie2_message.c
@@ -840,7 +840,7 @@ static struct aie2_exec_msg_ops npu_exec_message_ops = {
static int aie2_init_exec_req(void *req, struct amdxdna_gem_obj *cmd_abo,
size_t *size, u32 *msg_op)
{
- struct amdxdna_dev *xdna = cmd_abo->client->xdna;
+ struct amdxdna_dev *xdna = to_xdna_dev(to_gobj(cmd_abo)->dev);
int ret;
u32 op;
@@ -874,7 +874,7 @@ static int
aie2_cmdlist_fill_slot(void *slot, struct amdxdna_gem_obj *cmd_abo,
size_t *size, u32 *cmd_op)
{
- struct amdxdna_dev *xdna = cmd_abo->client->xdna;
+ struct amdxdna_dev *xdna = to_xdna_dev(to_gobj(cmd_abo)->dev);
int ret;
u32 op;
diff --git a/drivers/accel/amdxdna/amdxdna_gem.c b/drivers/accel/amdxdna/amdxdna_gem.c
index 1275f91ca705..4628a2787265 100644
--- a/drivers/accel/amdxdna/amdxdna_gem.c
+++ b/drivers/accel/amdxdna/amdxdna_gem.c
@@ -198,6 +198,7 @@ amdxdna_gem_destroy_obj(struct amdxdna_gem_obj *abo)
*/
void *amdxdna_gem_vmap(struct amdxdna_gem_obj *abo)
{
+ struct amdxdna_dev *xdna = to_xdna_dev(to_gobj(abo)->dev);
struct iosys_map map = IOSYS_MAP_INIT_VADDR(NULL);
int ret;
@@ -210,7 +211,7 @@ void *amdxdna_gem_vmap(struct amdxdna_gem_obj *abo)
if (!abo->mem.kva) {
ret = drm_gem_vmap(to_gobj(abo), &map);
if (ret)
- XDNA_ERR(abo->client->xdna, "Vmap bo failed, ret %d", ret);
+ XDNA_ERR(xdna, "Vmap bo failed, ret %d", ret);
else
abo->mem.kva = map.vaddr;
}
@@ -354,7 +355,13 @@ static int amdxdna_hmm_register(struct amdxdna_gem_obj *abo,
unsigned long nr_pages;
int ret;
- if (!amdxdna_pasid_on(abo->client)) {
+ /*
+ * When PASID is off, amdxdna_gem_obj_open() called amdxdna_dma_map_bo()
+ * and mem.dma_addr is valid; use the DMA address directly and skip HMM.
+ * Avoid dereferencing abo->client which may be NULL (cleared in close())
+ * while internal kernel references are still held.
+ */
+ if (abo->mem.dma_addr != AMDXDNA_INVALID_ADDR) {
/* Need to set uva for heap uva validation */
abo->mem.uva = addr;
return 0;
diff --git a/drivers/accel/amdxdna/amdxdna_gem.h b/drivers/accel/amdxdna/amdxdna_gem.h
index a35d2f15d32c..1e90e32bf3cd 100644
--- a/drivers/accel/amdxdna/amdxdna_gem.h
+++ b/drivers/accel/amdxdna/amdxdna_gem.h
@@ -88,12 +88,19 @@ u64 amdxdna_gem_dev_addr(struct amdxdna_gem_obj *abo);
static inline u64 amdxdna_dev_bo_offset(struct amdxdna_gem_obj *abo)
{
- return amdxdna_gem_dev_addr(abo) - abo->client->xdna->dev_info->dev_mem_base;
+ return amdxdna_gem_dev_addr(abo) - to_xdna_dev(to_gobj(abo)->dev)->dev_info->dev_mem_base;
}
static inline u64 amdxdna_obj_dma_addr(struct amdxdna_gem_obj *abo)
{
- return amdxdna_pasid_on(abo->client) ? amdxdna_gem_uva(abo) : abo->mem.dma_addr;
+ /*
+ * amdxdna_gem_obj_open() calls amdxdna_dma_map_bo() only when PASID is
+ * off, leaving mem.dma_addr at AMDXDNA_INVALID_ADDR when PASID is on.
+ * Avoid dereferencing abo->client, which is cleared to NULL by
+ * amdxdna_gem_obj_close() while internal kernel references remain.
+ */
+ return (abo->mem.dma_addr != AMDXDNA_INVALID_ADDR) ?
+ abo->mem.dma_addr : amdxdna_gem_uva(abo);
}
void amdxdna_umap_put(struct amdxdna_umap *mapp);