It can be useful when getting a page fault.

Signed-off-by: Pierre-Eric Pelloux-Prayer <[email protected]>
---
 .../gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c  | 36 +++++++++++++++++++
 .../gpu/drm/amd/amdgpu/amdgpu_dev_coredump.h  |  1 +
 2 files changed, 37 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c
index 1dfc5473d2ab..9fa7189bf852 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c
@@ -319,6 +319,11 @@ __amdgpu_devcoredump_read(char *buffer, size_t count, 
struct amdgpu_coredump_inf
        else if (coredump->reset_vram_lost)
                drm_printf(&p, "VRAM is lost due to GPU reset!\n");
 
+       if (coredump->vm_dump) {
+               drm_puts(&p, "\nVM Dump\n");
+               drm_puts(&p, coredump->vm_dump);
+       }
+
        return count - iter.remain;
 }
 
@@ -360,6 +365,7 @@ static void amdgpu_devcoredump_free(void *data)
        struct amdgpu_coredump_info *coredump = data;
 
        kvfree(coredump->read.buffer);
+       kvfree(coredump->vm_dump);
        kfree(data);
 }
 
@@ -383,12 +389,42 @@ void amdgpu_coredump(struct amdgpu_device *adev, bool 
skip_vram_check,
 
        if (job && job->pasid) {
                struct amdgpu_task_info *ti;
+               struct amdgpu_vm *vm;
+               unsigned long flags;
 
                ti = amdgpu_vm_get_task_info_pasid(adev, job->pasid);
                if (ti) {
                        coredump->reset_task_info = *ti;
                        amdgpu_vm_put_task_info(ti);
                }
+
+               xa_lock_irqsave(&adev->vm_manager.pasids, flags);
+               vm = xa_load(&adev->vm_manager.pasids, job->pasid);
+               xa_unlock_irqrestore(&adev->vm_manager.pasids, flags);
+
+               if (vm && amdgpu_bo_reserve(vm->root.bo, true) == 0) {
+                       struct drm_printer p;
+                       struct drm_print_iterator iter;
+                       ssize_t vm_dump_size;
+
+                       iter.data = NULL;
+                       iter.offset = 0;
+                       iter.remain = AMDGPU_CORE_DUMP_SIZE_MAX;
+
+                       p = drm_coredump_printer(&iter);
+                       amdgpu_debugfs_vm_bo_info(vm, &p);
+
+                       vm_dump_size = AMDGPU_CORE_DUMP_SIZE_MAX - iter.remain;
+                       coredump->vm_dump = kvmalloc(vm_dump_size, GFP_USER);
+                       if (coredump->vm_dump) {
+                               iter.remain = vm_dump_size;
+                               iter.data = coredump->vm_dump;
+                               p = drm_coredump_printer(&iter);
+                               amdgpu_debugfs_vm_bo_info(vm, &p);
+                       }
+
+                       amdgpu_bo_unreserve(vm->root.bo);
+               }
        }
 
        if (job) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.h
index 38ccdd3d6213..bc8d71219bc8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.h
@@ -39,6 +39,7 @@ struct amdgpu_coredump_info {
        bool                            reset_vram_lost;
        struct amdgpu_vm_fault_info     fault_info;
        struct amdgpu_ring              *ring;
+       char *vm_dump;
        /* Readable form of coredevdump, generate once to speed up
         * reading it (see drm_coredump_printer's documentation).
         */
-- 
2.43.0

Reply via email to