Skip to content

Commit 7c16dea

Browse files
committed
Merge branch 'bits/210-gpu' into asahi-wip
2 parents d9598d6 + 57a2096 commit 7c16dea

File tree

4 files changed

+104
-1
lines changed

4 files changed

+104
-1
lines changed

drivers/gpu/drm/asahi/driver.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ impl drv::Driver for AsahiDriver {
7777
ioctl::AUTH | ioctl::RENDER_ALLOW, crate::file::File::queue_destroy),
7878
(ASAHI_SUBMIT, drm_asahi_submit,
7979
ioctl::AUTH | ioctl::RENDER_ALLOW, crate::file::File::submit),
80+
(ASAHI_GET_TIME, drm_asahi_get_time,
81+
ioctl::AUTH | ioctl::RENDER_ALLOW, crate::file::File::get_time),
8082
}
8183
}
8284

drivers/gpu/drm/asahi/file.rs

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,7 @@ impl File {
519519

520520
match data.op {
521521
uapi::drm_asahi_bind_op_ASAHI_BIND_OP_BIND => Self::do_gem_bind(device, data, file),
522-
uapi::drm_asahi_bind_op_ASAHI_BIND_OP_UNBIND => Err(ENOTSUPP),
522+
uapi::drm_asahi_bind_op_ASAHI_BIND_OP_UNBIND => Self::do_gem_unbind(device, data, file),
523523
uapi::drm_asahi_bind_op_ASAHI_BIND_OP_UNBIND_ALL => {
524524
Self::do_gem_unbind_all(device, data, file)
525525
}
@@ -609,6 +609,66 @@ impl File {
609609
Ok(0)
610610
}
611611

612+
pub(crate) fn do_gem_unbind(
613+
_device: &AsahiDevice,
614+
data: &mut uapi::drm_asahi_gem_bind,
615+
file: &DrmFile,
616+
) -> Result<u32> {
617+
if data.offset != 0 || data.flags != 0 || data.handle != 0 {
618+
cls_pr_debug!(Errors, "gem_unbind: offset/flags/handle not zero\n");
619+
return Err(EINVAL);
620+
}
621+
622+
if (data.addr | data.range) as usize & mmu::UAT_PGMSK != 0 {
623+
cls_pr_debug!(
624+
Errors,
625+
"gem_bind: Addr/range/offset not page aligned: {:#x} {:#x}\n",
626+
data.addr,
627+
data.range
628+
);
629+
return Err(EINVAL); // Must be page aligned
630+
}
631+
632+
let start = data.addr;
633+
let end = data.addr.checked_add(data.range).ok_or(EINVAL)?;
634+
let range = start..end;
635+
636+
if !VM_USER_RANGE.is_superset(range.clone()) {
637+
cls_pr_debug!(
638+
Errors,
639+
"gem_bind: Invalid unmap range {:#x}..{:#x} (not contained in user range)\n",
640+
start,
641+
end
642+
);
643+
return Err(EINVAL); // Invalid map range
644+
}
645+
646+
let guard = file
647+
.inner()
648+
.vms()
649+
.get(data.vm_id.try_into()?)
650+
.ok_or(ENOENT)?;
651+
652+
// Clone it immediately so we aren't holding the XArray lock
653+
let vm = guard.borrow().vm.clone();
654+
let kernel_range = guard.borrow().kernel_range.clone();
655+
core::mem::drop(guard);
656+
657+
if kernel_range.overlaps(range.clone()) {
658+
cls_pr_debug!(
659+
Errors,
660+
"gem_bind: Invalid unmap range {:#x}..{:#x} (intrudes in kernel range)\n",
661+
start,
662+
end
663+
);
664+
return Err(EINVAL);
665+
}
666+
667+
vm.unmap_range(range.start, range.range())?;
668+
669+
Ok(0)
670+
}
671+
612672
pub(crate) fn unbind_gem_object(file: &DrmFile, bo: &gem::Object) -> Result {
613673
let mut index = 0;
614674
loop {
@@ -865,6 +925,39 @@ impl File {
865925
Ok(_) => Ok(0),
866926
}
867927
}
928+
929+
/// IOCTL: get_time: Get the current GPU timer value.
930+
pub(crate) fn get_time(
931+
device: &AsahiDevice,
932+
data: &mut uapi::drm_asahi_get_time,
933+
file: &DrmFile,
934+
) -> Result<u32> {
935+
936+
if data.extensions != 0 || data.flags != 0 {
937+
cls_pr_debug!(Errors, "get_time: Unexpected extensions or flags\n");
938+
return Err(EINVAL);
939+
}
940+
941+
let mut tp: kernel::bindings::timespec64 = Default::default();
942+
let mut gputime: u64 = 0;
943+
944+
// TODO: bindings
945+
// SAFETY: These functions are safe to call as long as the argument pointer is valid
946+
unsafe {
947+
core::arch::asm!(
948+
"mrs {x}, CNTPCT_EL0",
949+
x = out(reg) gputime
950+
);
951+
kernel::bindings::ktime_get_raw_ts64(&mut tp);
952+
kernel::bindings::timens_add_monotonic(&mut tp);
953+
}
954+
955+
data.gpu_timestamp = gputime;
956+
data.tv_sec = tp.tv_sec;
957+
data.tv_nsec = tp.tv_nsec;
958+
959+
Ok(0)
960+
}
868961
}
869962

870963
impl Drop for File {

rust/helpers/helpers.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "slab.c"
3535
#include "spinlock.c"
3636
#include "task.c"
37+
#include "time_namespace.c"
3738
#include "timekeeping.c"
3839
#include "uaccess.c"
3940
#include "wait.c"

rust/helpers/time_namespace.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
#include <linux/time_namespace.h>
4+
5+
void rust_helper_timens_add_monotonic(struct timespec64 *ts) {
6+
timens_add_monotonic(ts);
7+
}

0 commit comments

Comments
 (0)