The function amdgpu_gmc_flush_gpu_tlb_pasid() can be called before
adev->gmc.gmc_funcs or adev->gmc.gmc_funcs->flush_gpu_tlb_pasid is
properly initialized. Check it before calling to avoid NULL pointer
dereference.

[   41.700098] BUG: kernel NULL pointer dereference, address: 0000000000000000
[   41.701028] #PF: supervisor instruction fetch in kernel mode
[   41.701875] #PF: error_code(0x0010) - not-present page
[   41.702534] PGD 15a62067 P4D 15a62067 PUD 0
[   41.703135] Oops: Oops: 0010 [#1] SMP KASAN NOPTI
[   41.703767] CPU: 0 UID: 0 PID: 10 Comm: kworker/0:1 Not tainted 6.18.0 #3 
PREEMPT(voluntary)
[   41.704869] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS Arch 
Linux 1.17.0-2-2 04/01/2014
[   41.705962] Workqueue: events amdgpu_tlb_fence_work
[   41.706635] RIP: 0010:0x0
[   41.706975] Code: Unable to access opcode bytes at 0xffffffffffffffd6.
[   41.708155] RSP: 0000:ffff88800bd9fb68 EFLAGS: 00010246
[   41.708768] RAX: 0000000000000000 RBX: 1ffff110017b3f76 RCX: 0000000000000001
[   41.710007] RDX: 0000000000000002 RSI: 0000000000008000 RDI: ffff888015a80000
[   41.710920] RBP: ffff888015a80000 R08: 0000000000000000 R09: 0000000000000231
[   41.711817] R10: 0000000000000200 R11: ffff88800bd8a4e8 R12: ffffffff86e05be0
[   41.712630] R13: 0000000000000000 R14: 0000000000008000 R15: 0000000000000002
[   41.713475] FS:  0000000000000000(0000) GS:ffff8880df7ce000(0000) 
knlGS:0000000000000000
[   41.714425] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   41.715128] CR2: ffffffffffffffd6 CR3: 0000000015cdc000 CR4: 00000000000006f0
[   41.715994] Call Trace:
[   41.716297]  <TASK>
[   41.716571]  amdgpu_gmc_flush_gpu_tlb_pasid+0x226/0xa80
[   41.717204]  ? __pfx_dma_fence_default_wait+0x10/0x10
[   41.717867]  ? __pfx_amdgpu_gmc_flush_gpu_tlb_pasid+0x10/0x10
[   41.718555]  amdgpu_tlb_fence_work+0x12b/0x200
[   41.719117]  process_one_work+0x934/0x1740
[   41.719616]  ? __pfx_process_one_work+0x10/0x10
[   41.720179]  ? lock_acquire+0x14e/0x2d0
[   41.720649]  ? move_linked_works+0x1a6/0x270
[   41.721203]  ? assign_work+0x196/0x240
[   41.721688]  worker_thread+0x5d6/0xe30
[   41.722172]  ? __pfx_worker_thread+0x10/0x10
[   41.722711]  ? kthread+0x17c/0x6e0
[   41.723160]  ? __pfx_worker_thread+0x10/0x10
[   41.723691]  kthread+0x3a8/0x6e0
[   41.724121]  ? __pfx_kthread+0x10/0x10
[   41.724602]  ? ret_from_fork+0x25/0x470
[   41.725115]  ? lock_release+0xd4/0x2f0
[   41.725590]  ? __pfx_kthread+0x10/0x10
[   41.726072]  ret_from_fork+0x382/0x470
[   41.726541]  ? __pfx_kthread+0x10/0x10
[   41.727027]  ret_from_fork_asm+0x1a/0x30
[   41.727526]  </TASK>
[   41.727813] Modules linked in:
[   41.728225] CR2: 0000000000000000
[   41.728652] ---[ end trace 0000000000000000 ]---

Signed-off-by: Yang Zi <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
index 869bceb0fe2c..138f9dd1eac8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
@@ -732,6 +732,12 @@ int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device 
*adev, uint16_t pasid,
                return 0;
 
        if (!adev->gmc.flush_pasid_uses_kiq || !ring->sched.ready) {
+               if (!adev->gmc.gmc_funcs ||
+                   !adev->gmc.gmc_funcs->flush_gpu_tlb_pasid) {
+                       r = -EINVAL;
+                       goto error_unlock_reset;
+               }
+
                if (adev->gmc.flush_tlb_needs_extra_type_2)
                        adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid,
                                                                 2, all_hub,
-- 
2.52.0

Reply via email to