Skip to content

Commit 10a132e

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 300ed97 commit 10a132e

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
@@ -531,7 +531,7 @@ impl File {
531531

532532
match data.op {
533533
uapi::drm_asahi_bind_op_ASAHI_BIND_OP_BIND => Self::do_gem_bind(device, data, file),
534-
uapi::drm_asahi_bind_op_ASAHI_BIND_OP_UNBIND => Err(ENOTSUPP),
534+
uapi::drm_asahi_bind_op_ASAHI_BIND_OP_UNBIND => Self::do_gem_unbind(device, data, file),
535535
uapi::drm_asahi_bind_op_ASAHI_BIND_OP_UNBIND_ALL => {
536536
Self::do_gem_unbind_all(device, data, file)
537537
}
@@ -621,6 +621,66 @@ impl File {
621621
Ok(0)
622622
}
623623

624+
pub(crate) fn do_gem_unbind(
625+
_device: &AsahiDevice,
626+
data: &mut uapi::drm_asahi_gem_bind,
627+
file: &DrmFile,
628+
) -> Result<u32> {
629+
if data.offset != 0 || data.flags != 0 || data.handle != 0 {
630+
cls_pr_debug!(Errors, "gem_unbind: offset/flags/handle not zero\n");
631+
return Err(EINVAL);
632+
}
633+
634+
if (data.addr | data.range) as usize & mmu::UAT_PGMSK != 0 {
635+
cls_pr_debug!(
636+
Errors,
637+
"gem_bind: Addr/range/offset not page aligned: {:#x} {:#x}\n",
638+
data.addr,
639+
data.range
640+
);
641+
return Err(EINVAL); // Must be page aligned
642+
}
643+
644+
let start = data.addr;
645+
let end = data.addr.checked_add(data.range).ok_or(EINVAL)?;
646+
let range = start..end;
647+
648+
if !VM_USER_RANGE.is_superset(range.clone()) {
649+
cls_pr_debug!(
650+
Errors,
651+
"gem_bind: Invalid unmap range {:#x}..{:#x} (not contained in user range)\n",
652+
start,
653+
end
654+
);
655+
return Err(EINVAL); // Invalid map range
656+
}
657+
658+
let guard = file
659+
.inner()
660+
.vms()
661+
.get(data.vm_id.try_into()?)
662+
.ok_or(ENOENT)?;
663+
664+
// Clone it immediately so we aren't holding the XArray lock
665+
let vm = guard.borrow().vm.clone();
666+
let kernel_range = guard.borrow().kernel_range.clone();
667+
core::mem::drop(guard);
668+
669+
if kernel_range.overlaps(range.clone()) {
670+
cls_pr_debug!(
671+
Errors,
672+
"gem_bind: Invalid unmap range {:#x}..{:#x} (intrudes in kernel range)\n",
673+
start,
674+
end
675+
);
676+
return Err(EINVAL);
677+
}
678+
679+
vm.unmap_range(range.start, range.range())?;
680+
681+
Ok(0)
682+
}
683+
624684
pub(crate) fn unbind_gem_object(file: &DrmFile, bo: &gem::Object) -> Result {
625685
let mut index = 0;
626686
loop {

0 commit comments

Comments
 (0)