From 1eb68618ada706fa0e03b41f625080c8ef5aedf7 Mon Sep 17 00:00:00 2001 From: "Rob Herring (Arm)" <robh@kernel.org> Date: Thu, 1 Aug 2024 15:37:16 -0600 Subject: [PATCH] drm: panthor-rs: Hook-up ioctls to C code All but bo_mmap_offset hooked up. Signed-off-by: Rob Herring (Arm) <robh@kernel.org> --- drivers/gpu/drm/panthor-rs/Makefile | 9 + drivers/gpu/drm/panthor-rs/file.rs | 200 +++++++++++++++++++ drivers/gpu/drm/panthor-rs/panthor_drv.c | 239 +---------------------- rust/bindings/bindings_helper.h | 3 + 4 files changed, 222 insertions(+), 229 deletions(-) diff --git a/drivers/gpu/drm/panthor-rs/Makefile b/drivers/gpu/drm/panthor-rs/Makefile index c39521d5ca9e3..6be31c5cfdcf4 100644 --- a/drivers/gpu/drm/panthor-rs/Makefile +++ b/drivers/gpu/drm/panthor-rs/Makefile @@ -1,6 +1,15 @@ # SPDX-License-Identifier: GPL-2.0 or MIT panthor_rs-y := \ + panthor_devfreq.o \ + panthor_device.o \ + panthor_drv.o \ + panthor_fw.o \ + panthor_gem.o \ + panthor_gpu.o \ + panthor_heap.o \ + panthor_mmu.o \ + panthor_sched.o \ panthor.o obj-$(CONFIG_DRM_PANTHOR_RS) += panthor_rs.o diff --git a/drivers/gpu/drm/panthor-rs/file.rs b/drivers/gpu/drm/panthor-rs/file.rs index 7ebbce7c88150..4976f45ad93c6 100644 --- a/drivers/gpu/drm/panthor-rs/file.rs +++ b/drivers/gpu/drm/panthor-rs/file.rs @@ -18,15 +18,58 @@ use core::ffi; use core::ptr; use kernel::prelude::*; use kernel::{ + bindings, drm::file::GenericFile, drm::{self, device::Device as DrmDevice}, error::to_result, + uaccess::UserSlice, uapi, }; /// Convenience type alias for our DRM `File` type. pub(crate) type DrmFile = drm::file::File<File>; +extern "C" { + fn _panthor_ioctl_dev_query( + ptdev: *mut bindings::panthor_device, + args: *mut uapi::drm_panthor_dev_query, + ) -> ffi::c_int; + fn panthor_vm_pool_create_vm( + ptdev: *mut bindings::panthor_device, + pool: *mut bindings::panthor_vm_pool, + data: *mut uapi::drm_panthor_vm_create, + ) -> ffi::c_int; + fn panthor_ioctl_vm_bind_async( + args: *mut uapi::drm_panthor_vm_bind, + file: *mut bindings::drm_file, + ) -> ffi::c_int; + fn panthor_ioctl_vm_bind_sync( + args: *mut uapi::drm_panthor_vm_bind, + file: *mut bindings::drm_file, + ) -> ffi::c_int; + fn panthor_group_submit( + ddev: *mut bindings::drm_device, + args: *mut uapi::drm_panthor_group_submit, + file: *mut bindings::drm_file, + ) -> core::ffi::c_int; + fn panthor_tiler_heap_create( + pfile: *mut bindings::panthor_file, + args: *mut uapi::drm_panthor_tiler_heap_create, + ) -> core::ffi::c_int; + fn panthor_tiler_heap_destroy( + pfile: *mut bindings::panthor_file, + args: *const uapi::drm_panthor_tiler_heap_destroy, + ) -> core::ffi::c_int; + fn _panthor_group_create( + args: *mut uapi::drm_panthor_group_create, + pfile: *mut bindings::panthor_file, + ) -> core::ffi::c_int; + fn panthor_group_get_state( + pfile: *mut bindings::panthor_file, + get_state: *mut uapi::drm_panthor_group_get_state, + ) -> core::ffi::c_int; +} + /// State associated with a client. #[repr(C)] pub(crate) struct File { @@ -56,6 +99,12 @@ impl drm::file::DriverFile for File { } } +fn struct_to_slice<T>(data: &T) -> &[u8] { + let ptr = data as *const T as *const u8; + let len = core::mem::size_of::<T>(); + unsafe { core::slice::from_raw_parts(ptr, len) } +} + impl File { /// IOCTL: dev_query pub(crate) fn dev_query( @@ -63,6 +112,38 @@ impl File { data: &mut uapi::drm_panthor_dev_query, _file: &DrmFile, ) -> Result<u32> { + if data.pointer == 0 { + let size = match data.type_ { + uapi::drm_panthor_dev_query_type_DRM_PANTHOR_DEV_QUERY_GPU_INFO => { + core::mem::size_of::<uapi::drm_panthor_gpu_info>() + } + uapi::drm_panthor_dev_query_type_DRM_PANTHOR_DEV_QUERY_CSIF_INFO => { + core::mem::size_of::<uapi::drm_panthor_csif_info>() + } + _ => return Err(EINVAL), + }; + data.size = size as u32; + return Ok(0); + } + + let mut write = UserSlice::new(data.pointer as usize, data.size as usize).writer(); + let ptdev = device.data().ptdev; + + match data.type_ { + // TODO: worry about userspace expect old, smaller size struct + uapi::drm_panthor_dev_query_type_DRM_PANTHOR_DEV_QUERY_GPU_INFO => { + write.write_slice(struct_to_slice::<kernel::bindings::drm_panthor_gpu_info>( + unsafe { &(*ptdev).gpu_info }, + ))? + } + uapi::drm_panthor_dev_query_type_DRM_PANTHOR_DEV_QUERY_CSIF_INFO => { + write.write_slice(struct_to_slice::<kernel::bindings::drm_panthor_csif_info>( + unsafe { &(*ptdev).csif_info }, + ))? + } + _ => return Err(EINVAL), + }; + Ok(0) } @@ -72,6 +153,16 @@ impl File { data: &mut uapi::drm_panthor_vm_create, file: &DrmFile, ) -> Result<u32> { + let devdata = device.data(); + + to_result(unsafe { + let pfile: *mut bindings::panthor_file = (*file.raw()).driver_priv as *mut _; + let id = panthor_vm_pool_create_vm(devdata.ptdev, (*pfile).vms, data); + if id >= 0 { + data.id = id.try_into()?; + } + id + })?; Ok(0) } @@ -81,6 +172,14 @@ impl File { data: &mut uapi::drm_panthor_vm_destroy, file: &DrmFile, ) -> Result<u32> { + if data.pad != 0 { + return Err(EINVAL); + } + + to_result(unsafe { + let pfile: *mut bindings::panthor_file = (*file.raw()).driver_priv as *mut _; + bindings::panthor_vm_pool_destroy_vm((*pfile).vms, data.id) + })?; Ok(0) } @@ -90,6 +189,13 @@ impl File { data: &mut uapi::drm_panthor_vm_bind, file: &DrmFile, ) -> Result<u32> { + //TODO: drm_dev_enter(device., &cookie)) + + if data.flags == uapi::drm_panthor_vm_bind_flags_DRM_PANTHOR_VM_BIND_ASYNC { + to_result(unsafe { panthor_ioctl_vm_bind_async(data, file.raw() as *mut _) })?; + } else { + to_result(unsafe { panthor_ioctl_vm_bind_sync(data, file.raw() as *mut _) })?; + } Ok(0) } @@ -99,6 +205,20 @@ impl File { data: &mut uapi::drm_panthor_vm_get_state, file: &DrmFile, ) -> Result<u32> { + let pfile: *mut bindings::panthor_file = unsafe { (*file.raw()).driver_priv as *mut _ }; + let vm = unsafe { bindings::panthor_vm_pool_get_vm((*pfile).vms, data.vm_id) }; + + if vm.is_null() { + return Err(EINVAL); + } + + if unsafe { bindings::panthor_vm_is_unusable(vm) } { + data.state = uapi::drm_panthor_vm_state_DRM_PANTHOR_VM_STATE_UNUSABLE; + } else { + data.state = uapi::drm_panthor_vm_state_DRM_PANTHOR_VM_STATE_USABLE; + } + + unsafe { bindings::panthor_vm_put(vm) }; Ok(0) } @@ -108,6 +228,40 @@ impl File { data: &mut uapi::drm_panthor_bo_create, file: &DrmFile, ) -> Result<u32> { + //TODO if (!drm_dev_enter(ddev, &cookie)) + // return -ENODEV; + + if data.size == 0 + || data.pad != 0 + || (data.flags & !uapi::drm_panthor_bo_flags_DRM_PANTHOR_BO_NO_MMAP != 0) + { + return Err(EINVAL); + } + + let mut vm = ptr::null_mut(); + if data.exclusive_vm_id != 0 { + let pfile: *mut bindings::panthor_file = unsafe { (*file.raw()).driver_priv as *mut _ }; + vm = unsafe { bindings::panthor_vm_pool_get_vm((*pfile).vms, data.exclusive_vm_id) }; + + if vm.is_null() { + return Err(EINVAL); + } + } + + let ret = unsafe { + let ptdev = device.data().ptdev; + bindings::panthor_gem_create_with_handle( + file.raw() as *mut _, + (*ptdev).base, + vm, + &mut data.size as *mut _, + data.flags, + &mut data.handle as *mut _, + ) + }; + unsafe { bindings::panthor_vm_put(vm) }; + + to_result(ret)?; Ok(0) } @@ -120,12 +274,38 @@ impl File { Ok(0) } + fn _group_priority_permit(file: &DrmFile, priority: u32) -> Result<u32> { + /* Ensure that priority is valid */ + if priority > uapi::drm_panthor_group_priority_PANTHOR_GROUP_PRIORITY_HIGH { + return Err(EINVAL); + } + + /* Medium priority and below are always allowed */ + if priority <= uapi::drm_panthor_group_priority_PANTHOR_GROUP_PRIORITY_MEDIUM { + return Ok(0); + } + + /* Higher priorities require CAP_SYS_NICE or DRM_MASTER */ + if unsafe { bindings::capable(uapi::CAP_SYS_NICE.try_into().unwrap()) } + || file.is_current_master() + { + return Ok(0); + } + + Err(EACCES) + } + /// IOCTL: group_create pub(crate) fn group_create( _device: &PanthorDevice, data: &mut uapi::drm_panthor_group_create, file: &DrmFile, ) -> Result<u32> { + let pfile: *mut bindings::panthor_file = unsafe { (*file.raw()).driver_priv as *mut _ }; + + Self::_group_priority_permit(file, data.priority.into())?; + + to_result(unsafe { _panthor_group_create(data, pfile) })?; Ok(0) } @@ -135,6 +315,13 @@ impl File { data: &mut uapi::drm_panthor_group_destroy, file: &DrmFile, ) -> Result<u32> { + if data.pad != 0 { + return Err(EINVAL); + } + + let pfile: *mut bindings::panthor_file = unsafe { (*file.raw()).driver_priv as *mut _ }; + + to_result(unsafe { bindings::panthor_group_destroy(pfile, data.group_handle) })?; Ok(0) } @@ -144,6 +331,9 @@ impl File { data: &mut uapi::drm_panthor_group_get_state, file: &DrmFile, ) -> Result<u32> { + let pfile: *mut bindings::panthor_file = unsafe { (*file.raw()).driver_priv as *mut _ }; + + to_result(unsafe { panthor_group_get_state(pfile, data) })?; Ok(0) } @@ -153,6 +343,9 @@ impl File { data: &mut uapi::drm_panthor_tiler_heap_create, file: &DrmFile, ) -> Result<u32> { + let pfile: *mut bindings::panthor_file = unsafe { (*file.raw()).driver_priv as *mut _ }; + + to_result(unsafe { panthor_tiler_heap_create(pfile, data) })?; Ok(0) } @@ -162,6 +355,9 @@ impl File { data: &mut uapi::drm_panthor_tiler_heap_destroy, file: &DrmFile, ) -> Result<u32> { + let pfile: *mut bindings::panthor_file = unsafe { (*file.raw()).driver_priv as *mut _ }; + + to_result(unsafe { panthor_tiler_heap_destroy(pfile, data) })?; Ok(0) } @@ -171,6 +367,10 @@ impl File { data: &mut uapi::drm_panthor_group_submit, file: &DrmFile, ) -> Result<u32> { + to_result(unsafe { + let ptdev = device.data().ptdev; + panthor_group_submit((*ptdev).base, data, file.raw() as *mut _) + })?; Ok(0) } } diff --git a/drivers/gpu/drm/panthor-rs/panthor_drv.c b/drivers/gpu/drm/panthor-rs/panthor_drv.c index d2e50d2d737f3..f70f691a7b6d1 100644 --- a/drivers/gpu/drm/panthor-rs/panthor_drv.c +++ b/drivers/gpu/drm/panthor-rs/panthor_drv.c @@ -747,140 +747,12 @@ static void panthor_submit_ctx_cleanup(struct panthor_submit_ctx *ctx, kvfree(ctx->jobs); } -static int panthor_ioctl_dev_query(struct drm_device *ddev, void *data, struct drm_file *file) -{ - struct panthor_device *ptdev = container_of(ddev, struct panthor_device, base); - struct drm_panthor_dev_query *args = data; - - if (!args->pointer) { - switch (args->type) { - case DRM_PANTHOR_DEV_QUERY_GPU_INFO: - args->size = sizeof(ptdev->gpu_info); - return 0; - - case DRM_PANTHOR_DEV_QUERY_CSIF_INFO: - args->size = sizeof(ptdev->csif_info); - return 0; - - default: - return -EINVAL; - } - } - - switch (args->type) { - case DRM_PANTHOR_DEV_QUERY_GPU_INFO: - return PANTHOR_UOBJ_SET(args->pointer, args->size, ptdev->gpu_info); - - case DRM_PANTHOR_DEV_QUERY_CSIF_INFO: - return PANTHOR_UOBJ_SET(args->pointer, args->size, ptdev->csif_info); - - default: - return -EINVAL; - } -} - -#define PANTHOR_VM_CREATE_FLAGS 0 - -static int panthor_ioctl_vm_create(struct drm_device *ddev, void *data, - struct drm_file *file) -{ - struct panthor_device *ptdev = container_of(ddev, struct panthor_device, base); - struct panthor_file *pfile = file->driver_priv; - struct drm_panthor_vm_create *args = data; - int cookie, ret; - - if (!drm_dev_enter(ddev, &cookie)) - return -ENODEV; - - ret = panthor_vm_pool_create_vm(ptdev, pfile->vms, args); - if (ret >= 0) { - args->id = ret; - ret = 0; - } - - drm_dev_exit(cookie); - return ret; -} - -static int panthor_ioctl_vm_destroy(struct drm_device *ddev, void *data, - struct drm_file *file) -{ - struct panthor_file *pfile = file->driver_priv; - struct drm_panthor_vm_destroy *args = data; - - if (args->pad) - return -EINVAL; - - return panthor_vm_pool_destroy_vm(pfile->vms, args->id); -} - #define PANTHOR_BO_FLAGS DRM_PANTHOR_BO_NO_MMAP -static int panthor_ioctl_bo_create(struct drm_device *ddev, void *data, - struct drm_file *file) +int panthor_group_submit(struct drm_device *ddev, struct drm_panthor_group_submit *args, + struct drm_file *file) { struct panthor_file *pfile = file->driver_priv; - struct drm_panthor_bo_create *args = data; - struct panthor_vm *vm = NULL; - int cookie, ret; - - if (!drm_dev_enter(ddev, &cookie)) - return -ENODEV; - - if (!args->size || args->pad || - (args->flags & ~PANTHOR_BO_FLAGS)) { - ret = -EINVAL; - goto out_dev_exit; - } - - if (args->exclusive_vm_id) { - vm = panthor_vm_pool_get_vm(pfile->vms, args->exclusive_vm_id); - if (!vm) { - ret = -EINVAL; - goto out_dev_exit; - } - } - - ret = panthor_gem_create_with_handle(file, ddev, vm, &args->size, - args->flags, &args->handle); - - panthor_vm_put(vm); - -out_dev_exit: - drm_dev_exit(cookie); - return ret; -} - -static int panthor_ioctl_bo_mmap_offset(struct drm_device *ddev, void *data, - struct drm_file *file) -{ - struct drm_panthor_bo_mmap_offset *args = data; - struct drm_gem_object *obj; - int ret; - - if (args->pad) - return -EINVAL; - - obj = drm_gem_object_lookup(file, args->handle); - if (!obj) - return -ENOENT; - - ret = drm_gem_create_mmap_offset(obj); - if (ret) - goto out; - - args->offset = drm_vma_node_offset_addr(&obj->vma_node); - -out: - drm_gem_object_put(obj); - return ret; -} - -static int panthor_ioctl_group_submit(struct drm_device *ddev, void *data, - struct drm_file *file) -{ - struct panthor_file *pfile = file->driver_priv; - struct drm_panthor_group_submit *args = data; struct drm_panthor_queue_submit *jobs_args; struct panthor_submit_ctx ctx; int ret = 0, cookie; @@ -981,41 +853,9 @@ static int panthor_ioctl_group_submit(struct drm_device *ddev, void *data, return ret; } -static int panthor_ioctl_group_destroy(struct drm_device *ddev, void *data, - struct drm_file *file) -{ - struct panthor_file *pfile = file->driver_priv; - struct drm_panthor_group_destroy *args = data; - - if (args->pad) - return -EINVAL; - - return panthor_group_destroy(pfile, args->group_handle); -} - -static int group_priority_permit(struct drm_file *file, - u8 priority) +int _panthor_group_create(struct drm_panthor_group_create *args, + struct panthor_file *pfile) { - /* Ensure that priority is valid */ - if (priority > PANTHOR_GROUP_PRIORITY_HIGH) - return -EINVAL; - - /* Medium priority and below are always allowed */ - if (priority <= PANTHOR_GROUP_PRIORITY_MEDIUM) - return 0; - - /* Higher priorities require CAP_SYS_NICE or DRM_MASTER */ - if (capable(CAP_SYS_NICE) || drm_is_current_master(file)) - return 0; - - return -EACCES; -} - -static int panthor_ioctl_group_create(struct drm_device *ddev, void *data, - struct drm_file *file) -{ - struct panthor_file *pfile = file->driver_priv; - struct drm_panthor_group_create *args = data; struct drm_panthor_queue_create *queue_args; int ret; @@ -1026,10 +866,6 @@ static int panthor_ioctl_group_create(struct drm_device *ddev, void *data, if (ret) return ret; - ret = group_priority_permit(file, args->priority); - if (ret) - return ret; - ret = panthor_group_create(pfile, args, queue_args); if (ret >= 0) { args->group_handle = ret; @@ -1040,20 +876,9 @@ static int panthor_ioctl_group_create(struct drm_device *ddev, void *data, return ret; } -static int panthor_ioctl_group_get_state(struct drm_device *ddev, void *data, - struct drm_file *file) -{ - struct panthor_file *pfile = file->driver_priv; - struct drm_panthor_group_get_state *args = data; - - return panthor_group_get_state(pfile, args); -} - -static int panthor_ioctl_tiler_heap_create(struct drm_device *ddev, void *data, - struct drm_file *file) +int panthor_tiler_heap_create(struct panthor_file *pfile, + struct drm_panthor_tiler_heap_create *args) { - struct panthor_file *pfile = file->driver_priv; - struct drm_panthor_tiler_heap_create *args = data; struct panthor_heap_pool *pool; struct panthor_vm *vm; int ret; @@ -1092,11 +917,9 @@ static int panthor_ioctl_tiler_heap_create(struct drm_device *ddev, void *data, return ret; } -static int panthor_ioctl_tiler_heap_destroy(struct drm_device *ddev, void *data, - struct drm_file *file) +int panthor_tiler_heap_destroy(struct panthor_file *pfile, + const struct drm_panthor_tiler_heap_destroy *args) { - struct panthor_file *pfile = file->driver_priv; - struct drm_panthor_tiler_heap_destroy *args = data; struct panthor_heap_pool *pool; struct panthor_vm *vm; int ret; @@ -1122,8 +945,7 @@ static int panthor_ioctl_tiler_heap_destroy(struct drm_device *ddev, void *data, return ret; } -static int panthor_ioctl_vm_bind_async(struct drm_device *ddev, - struct drm_panthor_vm_bind *args, +int panthor_ioctl_vm_bind_async(struct drm_panthor_vm_bind *args, struct drm_file *file) { struct panthor_file *pfile = file->driver_priv; @@ -1191,8 +1013,7 @@ static int panthor_ioctl_vm_bind_async(struct drm_device *ddev, return ret; } -static int panthor_ioctl_vm_bind_sync(struct drm_device *ddev, - struct drm_panthor_vm_bind *args, +int panthor_ioctl_vm_bind_sync(struct drm_panthor_vm_bind *args, struct drm_file *file) { struct panthor_file *pfile = file->driver_priv; @@ -1224,46 +1045,6 @@ static int panthor_ioctl_vm_bind_sync(struct drm_device *ddev, return ret; } -#define PANTHOR_VM_BIND_FLAGS DRM_PANTHOR_VM_BIND_ASYNC - -static int panthor_ioctl_vm_bind(struct drm_device *ddev, void *data, - struct drm_file *file) -{ - struct drm_panthor_vm_bind *args = data; - int cookie, ret; - - if (!drm_dev_enter(ddev, &cookie)) - return -ENODEV; - - if (args->flags & DRM_PANTHOR_VM_BIND_ASYNC) - ret = panthor_ioctl_vm_bind_async(ddev, args, file); - else - ret = panthor_ioctl_vm_bind_sync(ddev, args, file); - - drm_dev_exit(cookie); - return ret; -} - -static int panthor_ioctl_vm_get_state(struct drm_device *ddev, void *data, - struct drm_file *file) -{ - struct panthor_file *pfile = file->driver_priv; - struct drm_panthor_vm_get_state *args = data; - struct panthor_vm *vm; - - vm = panthor_vm_pool_get_vm(pfile->vms, args->vm_id); - if (!vm) - return -EINVAL; - - if (panthor_vm_is_unusable(vm)) - args->state = DRM_PANTHOR_VM_STATE_UNUSABLE; - else - args->state = DRM_PANTHOR_VM_STATE_USABLE; - - panthor_vm_put(vm); - return 0; -} - static void panthor_postclose(struct drm_device *ddev, struct drm_file *file) { diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h index 8de125de72254..35d5f29e81c83 100644 --- a/rust/bindings/bindings_helper.h +++ b/rust/bindings/bindings_helper.h @@ -33,6 +33,9 @@ #include <linux/workqueue.h> #include <../drivers/gpu/drm/panthor-rs/panthor_device.h> +#include <../drivers/gpu/drm/panthor-rs/panthor_gem.h> +#include <../drivers/gpu/drm/panthor-rs/panthor_mmu.h> +#include <../drivers/gpu/drm/panthor-rs/panthor_sched.h> /* `bindgen` gets confused at certain things. */ const size_t RUST_CONST_HELPER_ARCH_SLAB_MINALIGN = ARCH_SLAB_MINALIGN; -- GitLab