Skip to content

Commit

Permalink
Merge branch 'bits/210-gpu' into asahi-wip
Browse files Browse the repository at this point in the history
  • Loading branch information
jannau committed Nov 3, 2024
2 parents d9598d6 + 57a2096 commit 7c16dea
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 1 deletion.
2 changes: 2 additions & 0 deletions drivers/gpu/drm/asahi/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ impl drv::Driver for AsahiDriver {
ioctl::AUTH | ioctl::RENDER_ALLOW, crate::file::File::queue_destroy),
(ASAHI_SUBMIT, drm_asahi_submit,
ioctl::AUTH | ioctl::RENDER_ALLOW, crate::file::File::submit),
(ASAHI_GET_TIME, drm_asahi_get_time,
ioctl::AUTH | ioctl::RENDER_ALLOW, crate::file::File::get_time),
}
}

Expand Down
95 changes: 94 additions & 1 deletion drivers/gpu/drm/asahi/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ impl File {

match data.op {
uapi::drm_asahi_bind_op_ASAHI_BIND_OP_BIND => Self::do_gem_bind(device, data, file),
uapi::drm_asahi_bind_op_ASAHI_BIND_OP_UNBIND => Err(ENOTSUPP),
uapi::drm_asahi_bind_op_ASAHI_BIND_OP_UNBIND => Self::do_gem_unbind(device, data, file),
uapi::drm_asahi_bind_op_ASAHI_BIND_OP_UNBIND_ALL => {
Self::do_gem_unbind_all(device, data, file)
}
Expand Down Expand Up @@ -609,6 +609,66 @@ impl File {
Ok(0)
}

pub(crate) fn do_gem_unbind(
_device: &AsahiDevice,
data: &mut uapi::drm_asahi_gem_bind,
file: &DrmFile,
) -> Result<u32> {
if data.offset != 0 || data.flags != 0 || data.handle != 0 {
cls_pr_debug!(Errors, "gem_unbind: offset/flags/handle not zero\n");
return Err(EINVAL);
}

if (data.addr | data.range) as usize & mmu::UAT_PGMSK != 0 {
cls_pr_debug!(
Errors,
"gem_bind: Addr/range/offset not page aligned: {:#x} {:#x}\n",
data.addr,
data.range
);
return Err(EINVAL); // Must be page aligned
}

let start = data.addr;
let end = data.addr.checked_add(data.range).ok_or(EINVAL)?;
let range = start..end;

if !VM_USER_RANGE.is_superset(range.clone()) {
cls_pr_debug!(
Errors,
"gem_bind: Invalid unmap range {:#x}..{:#x} (not contained in user range)\n",
start,
end
);
return Err(EINVAL); // Invalid map range
}

let guard = file
.inner()
.vms()
.get(data.vm_id.try_into()?)
.ok_or(ENOENT)?;

// Clone it immediately so we aren't holding the XArray lock
let vm = guard.borrow().vm.clone();
let kernel_range = guard.borrow().kernel_range.clone();
core::mem::drop(guard);

if kernel_range.overlaps(range.clone()) {
cls_pr_debug!(
Errors,
"gem_bind: Invalid unmap range {:#x}..{:#x} (intrudes in kernel range)\n",
start,
end
);
return Err(EINVAL);
}

vm.unmap_range(range.start, range.range())?;

Ok(0)
}

pub(crate) fn unbind_gem_object(file: &DrmFile, bo: &gem::Object) -> Result {
let mut index = 0;
loop {
Expand Down Expand Up @@ -865,6 +925,39 @@ impl File {
Ok(_) => Ok(0),
}
}

/// IOCTL: get_time: Get the current GPU timer value.
pub(crate) fn get_time(
device: &AsahiDevice,
data: &mut uapi::drm_asahi_get_time,
file: &DrmFile,
) -> Result<u32> {

if data.extensions != 0 || data.flags != 0 {
cls_pr_debug!(Errors, "get_time: Unexpected extensions or flags\n");
return Err(EINVAL);
}

let mut tp: kernel::bindings::timespec64 = Default::default();
let mut gputime: u64 = 0;

// TODO: bindings
// SAFETY: These functions are safe to call as long as the argument pointer is valid
unsafe {
core::arch::asm!(
"mrs {x}, CNTPCT_EL0",
x = out(reg) gputime
);
kernel::bindings::ktime_get_raw_ts64(&mut tp);
kernel::bindings::timens_add_monotonic(&mut tp);
}

data.gpu_timestamp = gputime;
data.tv_sec = tp.tv_sec;
data.tv_nsec = tp.tv_nsec;

Ok(0)
}
}

impl Drop for File {
Expand Down
1 change: 1 addition & 0 deletions rust/helpers/helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "slab.c"
#include "spinlock.c"
#include "task.c"
#include "time_namespace.c"
#include "timekeeping.c"
#include "uaccess.c"
#include "wait.c"
Expand Down
7 changes: 7 additions & 0 deletions rust/helpers/time_namespace.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// SPDX-License-Identifier: GPL-2.0

#include <linux/time_namespace.h>

void rust_helper_timens_add_monotonic(struct timespec64 *ts) {
timens_add_monotonic(ts);
}

0 comments on commit 7c16dea

Please sign in to comment.