Expose GPU VM name and kernel-reserved VA so drivers can dump GPU VA
state in debugfs.

Signed-off-by: Alvin Sun <[email protected]>
---
 rust/kernel/drm/gpuvm/mod.rs | 14 ++++++++++++++
 rust/kernel/drm/gpuvm/va.rs  | 37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+)

diff --git a/rust/kernel/drm/gpuvm/mod.rs b/rust/kernel/drm/gpuvm/mod.rs
index 20e512842dfc6..3186df9f740cf 100644
--- a/rust/kernel/drm/gpuvm/mod.rs
+++ b/rust/kernel/drm/gpuvm/mod.rs
@@ -165,6 +165,13 @@ pub fn as_raw(&self) -> *mut bindings::drm_gpuvm {
         self.vm.get()
     }
 
+    /// Returns the name of this GpuVm.
+    #[inline]
+    pub fn name(&self) -> &CStr {
+        // SAFETY: The `name` field is immutable and points to a 
NUL-terminated string.
+        unsafe { CStr::from_char_ptr((*self.as_raw()).name) }
+    }
+
     /// The start of the VA space.
     #[inline]
     pub fn va_start(&self) -> u64 {
@@ -188,6 +195,13 @@ pub fn va_range(&self) -> Range<u64> {
         Range { start, end }
     }
 
+    /// Returns the kernel-allocated VA for this GpuVm.
+    #[inline]
+    pub fn kernel_alloc_va(&self) -> &RawGpuVa {
+        // SAFETY: The `self.as_raw()` is guaranteed to be a valid pointer to 
a drm_gpuvm.
+        unsafe { RawGpuVa::from_raw(&raw mut 
(*self.as_raw()).kernel_alloc_node) }
+    }
+
     /// Get or create the [`GpuVmBo`] for this gem object.
     #[inline]
     pub fn obtain(
diff --git a/rust/kernel/drm/gpuvm/va.rs b/rust/kernel/drm/gpuvm/va.rs
index a31122ff22282..8b8fd500b3c5f 100644
--- a/rust/kernel/drm/gpuvm/va.rs
+++ b/rust/kernel/drm/gpuvm/va.rs
@@ -81,6 +81,43 @@ pub fn vm_bo(&self) -> &GpuVmBo<T> {
     }
 }
 
+/// Represents that a range of a GEM object is mapped in the kernel.
+#[repr(transparent)]
+pub struct RawGpuVa(Opaque<bindings::drm_gpuva>);
+
+impl RawGpuVa {
+    /// Access this [`RawGpuVa`] from a raw pointer.
+    ///
+    /// # Safety
+    ///
+    /// For the duration of `'a`, the pointer must reference a valid 
`drm_gpuva`.
+    #[inline]
+    pub unsafe fn from_raw<'a>(ptr: *mut bindings::drm_gpuva) -> &'a Self {
+        // SAFETY: `drm_gpuva` and `RawGpuVa` have the same layout.
+        unsafe { &*(ptr.cast()) }
+    }
+
+    /// Returns a raw pointer to underlying C value.
+    #[inline]
+    pub fn as_raw(&self) -> *mut bindings::drm_gpuva {
+        self.0.get()
+    }
+
+    /// Returns the address of this mapping in the GPU virtual address space.
+    #[inline]
+    pub fn addr(&self) -> u64 {
+        // SAFETY: `self.as_raw()` is guaranteed to be a valid pointer to a 
`drm_gpuva`.
+        unsafe { (*self.as_raw()).va.addr }
+    }
+
+    /// Returns the length of this mapping.
+    #[inline]
+    pub fn length(&self) -> u64 {
+        // SAFETY: `self.as_raw()` is guaranteed to be a valid pointer to a 
`drm_gpuva`.
+        unsafe { (*self.as_raw()).va.range }
+    }
+}
+
 /// A pre-allocated [`GpuVa`] object.
 ///
 /// # Invariants

-- 
2.43.0


Reply via email to