diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c
index 01693e8f24b7..aece2024c1fd 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_vm.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c
@@ -42,6 +42,8 @@
 #include <linux/uaccess.h>
 #include <linux/mem_encrypt.h>
 
+#include "ttm_trace.h"
+
 static vm_fault_t ttm_bo_vm_fault_idle(struct ttm_buffer_object *bo,
 				struct vm_fault *vmf)
 {
@@ -429,15 +431,17 @@ vm_fault_t ttm_bo_vm_fault(struct vm_fault *vmf)
 
 	ret = ttm_bo_vm_reserve(bo, vmf);
 	if (ret)
-		return ret;
+		goto out;
 
 	prot = vma->vm_page_prot;
 	ret = ttm_bo_vm_fault_reserved(vmf, prot, TTM_BO_VM_NUM_PREFAULT, 1);
 	if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT))
-		return ret;
+		goto out;
 
 	dma_resv_unlock(bo->base.resv);
 
+out:
+	trace_ttm_bo_vm_fault(bo, vmf, ret);
 	return ret;
 }
 EXPORT_SYMBOL(ttm_bo_vm_fault);
@@ -516,6 +520,8 @@ int ttm_bo_vm_access(struct vm_area_struct *vma, unsigned long addr,
 	if (ret)
 		return ret;
 
+	trace_ttm_bo_vm_access(bo, !!write, offset, len);
+
 	switch (bo->mem.mem_type) {
 	case TTM_PL_SYSTEM:
 		if (unlikely(bo->ttm->page_flags & TTM_PAGE_FLAG_SWAPPED)) {
@@ -618,6 +624,7 @@ int ttm_bo_mmap(struct file *filp, struct vm_area_struct *vma,
 		goto out_unref;
 
 	ttm_bo_mmap_vma_setup(bo, vma);
+	trace_ttm_bo_mmap(bo, vma);
 	return 0;
 out_unref:
 	ttm_bo_put(bo);
@@ -629,6 +636,7 @@ int ttm_bo_mmap_obj(struct vm_area_struct *vma, struct ttm_buffer_object *bo)
 {
 	ttm_bo_get(bo);
 	ttm_bo_mmap_vma_setup(bo, vma);
+	trace_ttm_bo_mmap(bo, vma);
 	return 0;
 }
 EXPORT_SYMBOL(ttm_bo_mmap_obj);
diff --git a/drivers/gpu/drm/ttm/ttm_trace.h b/drivers/gpu/drm/ttm/ttm_trace.h
index 7c5e55725e8e..9f7cc34b243b 100644
--- a/drivers/gpu/drm/ttm/ttm_trace.h
+++ b/drivers/gpu/drm/ttm/ttm_trace.h
@@ -34,6 +34,7 @@
 #include <drm/ttm/ttm_page_alloc.h>
 #include <linux/types.h>
 #include <linux/tracepoint.h>
+#include <trace/events/mmflags.h>
 
 #define TTM_PLACEMENT_FLAGS_TRACE \
 	{ TTM_PL_FLAG_SYSTEM,		"SYSTEM"	},\
@@ -310,6 +311,83 @@ TRACE_EVENT(ttm_bo_release,
 	    TP_printk("bo:%p", __entry->bo)
 );
 
+TRACE_EVENT(ttm_bo_mmap,
+	    TP_PROTO(struct ttm_buffer_object *bo, struct vm_area_struct *vma),
+	    TP_ARGS(bo, vma),
+	    TP_STRUCT__entry(
+			     __field(struct ttm_buffer_object *, bo)
+			     __field(unsigned long, vm_start)
+			     __field(unsigned long, vm_end)
+			     __field(unsigned long, vm_pgoff)
+			     __field(unsigned long, vm_flags)
+			     ),
+
+	    TP_fast_assign(
+			   __entry->bo = bo;
+			   __entry->vm_start = vma->vm_start;
+			   __entry->vm_end = vma->vm_end;
+			   __entry->vm_pgoff = vma->vm_pgoff;
+			   __entry->vm_flags = vma->vm_flags;
+			   ),
+
+	    TP_printk("bo:%p, vm_start=%lx, vm_end=%lx, vm_pgoff=%lx, vm_flags=%s",
+		      __entry->bo,
+		      __entry->vm_start, __entry->vm_end, __entry->vm_pgoff,
+		      show_vma_flags(__entry->vm_flags))
+);
+
+TRACE_EVENT(ttm_bo_vm_fault,
+	    TP_PROTO(struct ttm_buffer_object *bo, struct vm_fault *vmf, int result),
+	    TP_ARGS(bo, vmf, result),
+	    TP_STRUCT__entry(
+			     __field(struct ttm_buffer_object *, bo)
+			     __field(struct vm_area_struct *, vma)
+			     __field(unsigned long, fault_address)
+			     __field(unsigned long, fault_pgoff)
+			     __field(int, result)
+			     __field(unsigned int, flags)
+			     ),
+
+	    TP_fast_assign(
+			   __entry->bo = bo;
+			   __entry->vma = vmf->vma;
+			   __entry->fault_address = vmf->address;
+			   __entry->fault_pgoff = vmf->pgoff;
+			   __entry->flags = vmf->flags;
+			   __entry->result = result;
+			   ),
+
+	    TP_printk("bo:%p, vma=%p, fault_address=%lx, fault_pgoff=%lx, fault_flags=%s %s",
+		      __entry->bo, __entry->vma,
+		      __entry->fault_address, __entry->fault_pgoff,
+		      __entry->flags ? __print_flags(__entry->flags, "|", FAULT_FLAG_TRACE) : "none",
+		      __print_flags(__entry->result, "|", VM_FAULT_RESULT_TRACE))
+);
+
+TRACE_EVENT(ttm_bo_vm_access,
+	    TP_PROTO(struct ttm_buffer_object *bo, bool write, unsigned long offset, unsigned long len),
+	    TP_ARGS(bo, write, offset, len),
+	    TP_STRUCT__entry(
+			     __field(struct ttm_buffer_object *, bo)
+			     __field(bool, write)
+			     __field(unsigned long, offset)
+			     __field(unsigned long, len)
+			     __field(uint32_t, mem_type)
+			     ),
+
+	    TP_fast_assign(
+			   __entry->bo = bo;
+			   __entry->write = write;
+			   __entry->offset = offset;
+			   __entry->len = len;
+			   __entry->mem_type = bo->mem.mem_type;
+			   ),
+
+	    TP_printk("bo:%p, %s offset=%lx, len=%lx, mtype=%d",
+		      __entry->bo, __entry->write ? "write" : "read",
+		      __entry->offset, __entry->len, __entry->mem_type)
+);
+
 #endif
 
 #undef TRACE_INCLUDE_PATH
