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
