Skip to content

Commit 975f31a

Browse files
committed
drm/asahi: file: Update to newer VM_BIND API
Signed-off-by: Asahi Lina <lina@asahilina.net>
1 parent 16634ea commit 975f31a

5 files changed

Lines changed: 99 additions & 88 deletions

File tree

drivers/gpu/drm/asahi/file.rs

Lines changed: 71 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99
1010
use crate::debug::*;
1111
use crate::driver::AsahiDevice;
12-
use crate::{alloc, buffer, driver, gem, mmu, queue};
12+
use crate::{alloc, buffer, driver, gem, mmu, queue, util::RangeExt};
1313
use core::mem::MaybeUninit;
14+
use core::ops::Range;
1415
use kernel::dma_fence::RawDmaFence;
1516
use kernel::drm::gem::BaseObject;
1617
use kernel::error::code::*;
@@ -30,16 +31,29 @@ struct Vm {
3031
ualloc: Arc<Mutex<alloc::DefaultAllocator>>,
3132
ualloc_priv: Arc<Mutex<alloc::DefaultAllocator>>,
3233
vm: mmu::Vm,
34+
kernel_range: Range<u64>,
3335
_dummy_mapping: mmu::KernelMapping,
3436
}
3537

3638
impl Drop for Vm {
3739
fn drop(&mut self) {
3840
// When the user Vm is dropped, unmap everything in the user range
39-
if self
40-
.vm
41-
.unmap_range(mmu::IOVA_USER_BASE, VM_USER_END)
42-
.is_err()
41+
let left_range = VM_USER_RANGE.start..self.kernel_range.start;
42+
let right_range = self.kernel_range.end..VM_USER_RANGE.end;
43+
44+
if !left_range.is_empty()
45+
&& self
46+
.vm
47+
.unmap_range(left_range.start, left_range.range())
48+
.is_err()
49+
{
50+
pr_err!("Vm::Drop: vm.unmap_range() failed\n");
51+
}
52+
if !right_range.is_empty()
53+
&& self
54+
.vm
55+
.unmap_range(right_range.start, right_range.range())
56+
.is_err()
4357
{
4458
pr_err!("Vm::Drop: vm.unmap_range() failed\n");
4559
}
@@ -153,23 +167,11 @@ pub(crate) struct File {
153167
/// Convenience type alias for our DRM `File` type.
154168
pub(crate) type DrmFile = drm::file::File<File>;
155169

156-
/// Start address of the 32-bit USC address space.
157-
const VM_SHADER_START: u64 = 0x11_00000000;
158-
/// End address of the 32-bit USC address space.
159-
const VM_SHADER_END: u64 = 0x11_ffffffff;
160-
/// Start address of the general user mapping region.
161-
const VM_USER_START: u64 = 0x20_00000000;
162-
/// End address of the general user mapping region.
163-
const VM_USER_END: u64 = 0x6f_ffff0000;
164-
165-
/// Start address of the kernel-managed GPU-only mapping region.
166-
const VM_DRV_GPU_START: u64 = 0x70_00000000;
167-
/// End address of the kernel-managed GPU-only mapping region.
168-
const VM_DRV_GPU_END: u64 = 0x70_ffffffff;
169-
/// Start address of the kernel-managed GPU/FW shared mapping region.
170-
const VM_DRV_GPUFW_START: u64 = 0x71_00000000;
171-
/// End address of the kernel-managed GPU/FW shared mapping region.
172-
const VM_DRV_GPUFW_END: u64 = 0x71_ffffffff;
170+
/// Available VM range for the user
171+
const VM_USER_RANGE: Range<u64> = mmu::IOVA_USER_USABLE_RANGE;
172+
173+
/// Minimum reserved AS for kernel mappings
174+
const VM_KERNEL_MIN_SIZE: u64 = 0x20000000;
173175

174176
impl drm::file::DriverFile for File {
175177
type Driver = driver::AsahiDriver;
@@ -245,10 +247,11 @@ impl File {
245247

246248
vm_page_size: mmu::UAT_PGSZ as u32,
247249
pad1: 0,
248-
vm_user_start: VM_USER_START,
249-
vm_user_end: VM_USER_END,
250-
vm_shader_start: VM_SHADER_START,
251-
vm_shader_end: VM_SHADER_END,
250+
vm_user_start: VM_USER_RANGE.start,
251+
vm_user_end: VM_USER_RANGE.end,
252+
vm_usc_start: 0, // Arbitrary
253+
vm_usc_end: 0,
254+
vm_kernel_min_size: VM_KERNEL_MIN_SIZE,
252255

253256
max_syncs_per_submission: 0,
254257
max_commands_per_submission: MAX_COMMANDS_PER_SUBMISSION,
@@ -297,9 +300,25 @@ impl File {
297300
return Err(EINVAL);
298301
}
299302

303+
let kernel_range = data.kernel_start..data.kernel_end;
304+
305+
// Validate requested kernel range
306+
if !VM_USER_RANGE.is_superset(kernel_range.clone())
307+
|| kernel_range.range() < VM_KERNEL_MIN_SIZE
308+
|| kernel_range.start & (mmu::UAT_PGMSK as u64) != 0
309+
|| kernel_range.end & (mmu::UAT_PGMSK as u64) != 0
310+
{
311+
cls_pr_debug!(Errors, "vm_create: Invalid kernel range\n");
312+
return Err(EINVAL);
313+
}
314+
315+
let kernel_half_size = (kernel_range.range() >> 1) & !(mmu::UAT_PGMSK as u64);
316+
let kernel_gpu_range = kernel_range.start..(kernel_range.start + kernel_half_size);
317+
let kernel_gpufw_range = kernel_gpu_range.end..kernel_range.end;
318+
300319
let gpu = &device.data().gpu;
301320
let file_id = file.inner().id;
302-
let vm = gpu.new_vm()?;
321+
let vm = gpu.new_vm(kernel_range.clone())?;
303322

304323
let resv = file.inner().vms().reserve()?;
305324
let id: u32 = resv.index().try_into()?;
@@ -314,7 +333,7 @@ impl File {
314333
let ualloc = Arc::pin_init(Mutex::new(alloc::DefaultAllocator::new(
315334
device,
316335
&vm,
317-
VM_DRV_GPU_START..VM_DRV_GPU_END,
336+
kernel_gpu_range,
318337
buffer::PAGE_SIZE,
319338
mmu::PROT_GPU_SHARED_RW,
320339
512 * 1024,
@@ -325,7 +344,7 @@ impl File {
325344
let ualloc_priv = Arc::pin_init(Mutex::new(alloc::DefaultAllocator::new(
326345
device,
327346
&vm,
328-
VM_DRV_GPUFW_START..VM_DRV_GPUFW_END,
347+
kernel_gpufw_range,
329348
buffer::PAGE_SIZE,
330349
mmu::PROT_GPU_FW_PRIV_RW,
331350
64 * 1024,
@@ -350,6 +369,7 @@ impl File {
350369
ualloc,
351370
ualloc_priv,
352371
vm,
372+
kernel_range,
353373
_dummy_mapping: dummy_mapping,
354374
})?)?;
355375

@@ -510,47 +530,17 @@ impl File {
510530
let bo = gem::lookup_handle(file, data.handle)?;
511531

512532
let start = data.addr;
513-
let end = data.addr + data.range - 1;
514-
515-
if (VM_SHADER_START..=VM_SHADER_END).contains(&start) {
516-
if !(VM_SHADER_START..=VM_SHADER_END).contains(&end) {
517-
cls_pr_debug!(
518-
Errors,
519-
"gem_bind: Invalid map range {:#x}..{:#x} (straddles shader range)\n",
520-
start,
521-
end
522-
);
523-
return Err(EINVAL); // Invalid map range
524-
}
525-
} else if (VM_USER_START..=VM_USER_END).contains(&start) {
526-
if !(VM_USER_START..=VM_USER_END).contains(&end) {
527-
cls_pr_debug!(
528-
Errors,
529-
"gem_bind: Invalid map range {:#x}..{:#x} (straddles user range)\n",
530-
start,
531-
end
532-
);
533-
return Err(EINVAL); // Invalid map range
534-
}
535-
} else {
536-
cls_pr_debug!(
537-
Errors,
538-
"gem_bind: Invalid map range {:#x}..{:#x}\n",
539-
start,
540-
end
541-
);
542-
return Err(EINVAL); // Invalid map range
543-
}
533+
let end = data.addr.checked_add(data.range).ok_or(EINVAL)?;
534+
let range = start..end;
544535

545-
// Just in case
546-
if end >= VM_DRV_GPU_START {
536+
if !VM_USER_RANGE.is_superset(range.clone()) {
547537
cls_pr_debug!(
548538
Errors,
549-
"gem_bind: Invalid map range {:#x}..{:#x} (intrudes in kernel range)\n",
539+
"gem_bind: Invalid map range {:#x}..{:#x} (not contained in user range)\n",
550540
start,
551541
end
552542
);
553-
return Err(EINVAL);
543+
return Err(EINVAL); // Invalid map range
554544
}
555545

556546
let prot = if data.flags & uapi::ASAHI_BIND_READ != 0 {
@@ -570,15 +560,26 @@ impl File {
570560
return Err(EINVAL); // Must specify one of ASAHI_BIND_{READ,WRITE}
571561
};
572562

573-
// Clone it immediately so we aren't holding the XArray lock
574-
let vm = file
563+
let guard = file
575564
.inner()
576565
.vms()
577566
.get(data.vm_id.try_into()?)
578-
.ok_or(ENOENT)?
579-
.borrow()
580-
.vm
581-
.clone();
567+
.ok_or(ENOENT)?;
568+
569+
// Clone it immediately so we aren't holding the XArray lock
570+
let vm = guard.borrow().vm.clone();
571+
let kernel_range = guard.borrow().kernel_range.clone();
572+
core::mem::drop(guard);
573+
574+
if kernel_range.overlaps(range) {
575+
cls_pr_debug!(
576+
Errors,
577+
"gem_bind: Invalid map range {:#x}..{:#x} (intrudes in kernel range)\n",
578+
start,
579+
end
580+
);
581+
return Err(EINVAL);
582+
}
582583

583584
vm.bind_object(&bo.gem, data.addr, data.range, data.offset, prot)?;
584585

drivers/gpu/drm/asahi/gpu.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ pub(crate) trait GpuManager: Send + Sync {
229229
/// Get a reference to the KernelAllocators.
230230
fn alloc(&self) -> Guard<'_, KernelAllocators, MutexBackend>;
231231
/// Create a new `Vm` given a unique `File` ID.
232-
fn new_vm(&self) -> Result<mmu::Vm>;
232+
fn new_vm(&self, kernel_range: Range<u64>) -> Result<mmu::Vm>;
233233
/// Bind a `Vm` to an available slot and return the `VmBind`.
234234
fn bind_vm(&self, vm: &mmu::Vm) -> Result<mmu::VmBind>;
235235
/// Create a new user command queue.
@@ -1164,8 +1164,8 @@ impl GpuManager for GpuManager::ver {
11641164
guard
11651165
}
11661166

1167-
fn new_vm(&self) -> Result<mmu::Vm> {
1168-
self.uat.new_vm(self.ids.vm.next())
1167+
fn new_vm(&self, kernel_range: Range<u64>) -> Result<mmu::Vm> {
1168+
self.uat.new_vm(self.ids.vm.next(), kernel_range)
11691169
}
11701170

11711171
fn bind_vm(&self, vm: &mmu::Vm) -> Result<mmu::VmBind> {

drivers/gpu/drm/asahi/mmu.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ const PTE_TABLE: u64 = 0x3; // BIT(0) | BIT(1)
9090
/// Address of a special dummy page?
9191
//const IOVA_UNK_PAGE: u64 = 0x6f_ffff8000;
9292
pub(crate) const IOVA_UNK_PAGE: u64 = IOVA_USER_TOP - 2 * UAT_PGSZ as u64;
93+
/// User VA range excluding the unk page
94+
pub(crate) const IOVA_USER_USABLE_RANGE: Range<u64> = IOVA_USER_BASE..IOVA_UNK_PAGE;
9395

9496
// KernelMapping protection types
9597

@@ -1004,6 +1006,7 @@ impl Vm {
10041006
fn new(
10051007
dev: &driver::AsahiDevice,
10061008
uat_inner: Arc<UatInner>,
1009+
kernel_range: Range<u64>,
10071010
cfg: &'static hw::HwConfig,
10081011
is_kernel: bool,
10091012
id: u64,
@@ -1021,10 +1024,10 @@ impl Vm {
10211024
},
10221025
(),
10231026
)?;
1024-
let va_range = if is_kernel {
1025-
IOVA_KERN_RANGE
1027+
let (va_range, gpuvm_range) = if is_kernel {
1028+
(IOVA_KERN_RANGE, kernel_range.clone())
10261029
} else {
1027-
IOVA_USER_RANGE
1030+
(IOVA_USER_RANGE, IOVA_USER_USABLE_RANGE)
10281031
};
10291032

10301033
let mm = mm::Allocator::new(va_range.start, va_range.range(), ())?;
@@ -1047,8 +1050,8 @@ impl Vm {
10471050
c_str!("Asahi::GpuVm"),
10481051
dev,
10491052
&*(dummy_obj.gem),
1050-
va_range.clone(),
1051-
0..0,
1053+
gpuvm_range,
1054+
kernel_range,
10521055
init!(VmInner {
10531056
dev: dev.into(),
10541057
va_range,
@@ -1497,8 +1500,15 @@ impl Uat {
14971500
}
14981501

14991502
/// Creates a new `Vm` linked to this UAT.
1500-
pub(crate) fn new_vm(&self, id: u64) -> Result<Vm> {
1501-
Vm::new(&self.dev, self.inner.clone(), self.cfg, false, id)
1503+
pub(crate) fn new_vm(&self, id: u64, kernel_range: Range<u64>) -> Result<Vm> {
1504+
Vm::new(
1505+
&self.dev,
1506+
self.inner.clone(),
1507+
kernel_range,
1508+
self.cfg,
1509+
false,
1510+
id,
1511+
)
15021512
}
15031513

15041514
/// Creates the reference-counted inner data for a new `Uat` instance.
@@ -1541,8 +1551,8 @@ impl Uat {
15411551
let pagetables_rgn = Self::map_region(dev, c_str!("pagetables"), PAGETABLES_SIZE, true)?;
15421552

15431553
dev_info!(dev, "MMU: Creating kernel page tables\n");
1544-
let kernel_lower_vm = Vm::new(dev, inner.clone(), cfg, false, 1)?;
1545-
let kernel_vm = Vm::new(dev, inner.clone(), cfg, true, 0)?;
1554+
let kernel_lower_vm = Vm::new(dev, inner.clone(), IOVA_USER_RANGE, cfg, false, 1)?;
1555+
let kernel_vm = Vm::new(dev, inner.clone(), IOVA_KERN_RANGE, cfg, true, 0)?;
15461556

15471557
dev_info!(dev, "MMU: Kernel page tables created\n");
15481558

drivers/gpu/drm/asahi/queue/compute.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ impl super::QueueInner::ver {
283283
preempt_buf3: inner.preempt_buf.gpu_offset_pointer(preempt3_off),
284284
preempt_buf4: inner.preempt_buf.gpu_offset_pointer(preempt4_off),
285285
preempt_buf5: inner.preempt_buf.gpu_offset_pointer(preempt5_off),
286-
pipeline_base: U64(0x11_00000000),
286+
pipeline_base: U64(cmdbuf.usc_base),
287287
unk_38: U64(0x8c60),
288288
helper_program: cmdbuf.helper_program, // Internal program addr | 1
289289
unk_44: 0,
@@ -306,7 +306,7 @@ impl super::QueueInner::ver {
306306
r.add(0x1a4d8, inner.preempt_buf.gpu_offset_pointer(preempt3_off).into());
307307
r.add(0x1a4e0, inner.preempt_buf.gpu_offset_pointer(preempt4_off).into());
308308
r.add(0x1a4e8, inner.preempt_buf.gpu_offset_pointer(preempt5_off).into());
309-
r.add(0x10071, 0x1100000000); // USC_EXEC_BASE_CP
309+
r.add(0x10071, cmdbuf.usc_base); // USC_EXEC_BASE_CP
310310
r.add(0x11841, cmdbuf.helper_program.into());
311311
r.add(0x11849, cmdbuf.helper_arg);
312312
r.add(0x11f81, cmdbuf.helper_cfg.into());

drivers/gpu/drm/asahi/queue/render.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,7 @@ impl super::QueueInner::ver {
839839
tile_config: U64(tile_config),
840840
aux_fb: inner.aux_fb.gpu_pointer(),
841841
unk_108: Default::default(),
842-
pipeline_base: U64(0x11_00000000),
842+
pipeline_base: U64(cmdbuf.fragment_usc_base),
843843
unk_140: U64(unks.frg_unk_140),
844844
helper_program: cmdbuf.fragment_helper_program,
845845
unk_14c: 0,
@@ -944,7 +944,7 @@ impl super::QueueInner::ver {
944944
r.add(0x11829, cmdbuf.fragment_helper_arg);
945945
r.add(0x11f79, cmdbuf.fragment_helper_cfg.into());
946946
r.add(0x15359, 0);
947-
r.add(0x10069, 0x11_00000000); // USC_EXEC_BASE_ISP
947+
r.add(0x10069, cmdbuf.fragment_usc_base); // USC_EXEC_BASE_ISP
948948
r.add(0x16020, 0);
949949
r.add(0x16461, inner.aux_fb.gpu_pointer().into());
950950
r.add(0x16090, inner.aux_fb.gpu_pointer().into());
@@ -1341,7 +1341,7 @@ impl super::QueueInner::ver {
13411341
#[ver(G < G14)]
13421342
unk_ac: unks.tiling_control_2 as u32, // fixed
13431343
unk_b0: Default::default(), // fixed
1344-
pipeline_base: U64(0x11_00000000),
1344+
pipeline_base: U64(cmdbuf.vertex_usc_base),
13451345
#[ver(G < G14)]
13461346
tvb_cluster_meta4: inner
13471347
.scene
@@ -1433,7 +1433,7 @@ impl super::QueueInner::ver {
14331433
r.add(0x1c1a9, 0); // 0x10151 bit 1 enables
14341434
r.add(0x1c1b1, 0);
14351435
r.add(0x1c1b9, 0);
1436-
r.add(0x10061, 0x11_00000000); // USC_EXEC_BASE_TA
1436+
r.add(0x10061, cmdbuf.vertex_usc_base); // USC_EXEC_BASE_TA
14371437
r.add(0x11801, cmdbuf.vertex_helper_program.into());
14381438
r.add(0x11809, cmdbuf.vertex_helper_arg);
14391439
r.add(0x11f71, cmdbuf.vertex_helper_cfg.into());

0 commit comments

Comments
 (0)