Skip to content

Commit ea932e8

Browse files
hoshinolinajannau
authored andcommitted
drm/asahi: Implement missing ASAHI_BIND_OP_UNBIND
Trivial now that we have GPUVM. Signed-off-by: Asahi Lina <lina@asahilina.net>
1 parent f890ad5 commit ea932e8

1 file changed

Lines changed: 61 additions & 1 deletion

File tree

drivers/gpu/drm/asahi/file.rs

Lines changed: 61 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 {

0 commit comments

Comments
 (0)