Skip to content

Commit baacdff

Browse files
hoshinolinajannau
authored andcommitted
drm/asahi: file: Update to newer VM_BIND API
Signed-off-by: Asahi Lina <lina@asahilina.net>
1 parent e0b541f commit baacdff

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;
@@ -248,10 +250,11 @@ impl File {
248250

249251
vm_page_size: mmu::UAT_PGSZ as u32,
250252
pad1: 0,
251-
vm_user_start: VM_USER_START,
252-
vm_user_end: VM_USER_END,
253-
vm_shader_start: VM_SHADER_START,
254-
vm_shader_end: VM_SHADER_END,
253+
vm_user_start: VM_USER_RANGE.start,
254+
vm_user_end: VM_USER_RANGE.end,
255+
vm_usc_start: 0, // Arbitrary
256+
vm_usc_end: 0,
257+
vm_kernel_min_size: VM_KERNEL_MIN_SIZE,
255258

256259
max_syncs_per_submission: 0,
257260
max_commands_per_submission: MAX_COMMANDS_PER_SUBMISSION,
@@ -300,9 +303,25 @@ impl File {
300303
return Err(EINVAL);
301304
}
302305

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

307326
let resv = file.inner().vms().reserve()?;
308327
let id: u32 = resv.index().try_into()?;
@@ -318,7 +337,7 @@ impl File {
318337
Mutex::new(alloc::DefaultAllocator::new(
319338
device,
320339
&vm,
321-
VM_DRV_GPU_START..VM_DRV_GPU_END,
340+
kernel_gpu_range,
322341
buffer::PAGE_SIZE,
323342
mmu::PROT_GPU_SHARED_RW,
324343
512 * 1024,
@@ -332,7 +351,7 @@ impl File {
332351
Mutex::new(alloc::DefaultAllocator::new(
333352
device,
334353
&vm,
335-
VM_DRV_GPUFW_START..VM_DRV_GPUFW_END,
354+
kernel_gpufw_range,
336355
buffer::PAGE_SIZE,
337356
mmu::PROT_GPU_FW_PRIV_RW,
338357
64 * 1024,
@@ -360,6 +379,7 @@ impl File {
360379
ualloc,
361380
ualloc_priv,
362381
vm,
382+
kernel_range,
363383
_dummy_mapping: dummy_mapping,
364384
},
365385
GFP_KERNEL,
@@ -522,47 +542,17 @@ impl File {
522542
let bo = gem::lookup_handle(file, data.handle)?;
523543

524544
let start = data.addr;
525-
let end = data.addr + data.range - 1;
526-
527-
if (VM_SHADER_START..=VM_SHADER_END).contains(&start) {
528-
if !(VM_SHADER_START..=VM_SHADER_END).contains(&end) {
529-
cls_pr_debug!(
530-
Errors,
531-
"gem_bind: Invalid map range {:#x}..{:#x} (straddles shader range)\n",
532-
start,
533-
end
534-
);
535-
return Err(EINVAL); // Invalid map range
536-
}
537-
} else if (VM_USER_START..=VM_USER_END).contains(&start) {
538-
if !(VM_USER_START..=VM_USER_END).contains(&end) {
539-
cls_pr_debug!(
540-
Errors,
541-
"gem_bind: Invalid map range {:#x}..{:#x} (straddles user range)\n",
542-
start,
543-
end
544-
);
545-
return Err(EINVAL); // Invalid map range
546-
}
547-
} else {
548-
cls_pr_debug!(
549-
Errors,
550-
"gem_bind: Invalid map range {:#x}..{:#x}\n",
551-
start,
552-
end
553-
);
554-
return Err(EINVAL); // Invalid map range
555-
}
545+
let end = data.addr.checked_add(data.range).ok_or(EINVAL)?;
546+
let range = start..end;
556547

557-
// Just in case
558-
if end >= VM_DRV_GPU_START {
548+
if !VM_USER_RANGE.is_superset(range.clone()) {
559549
cls_pr_debug!(
560550
Errors,
561-
"gem_bind: Invalid map range {:#x}..{:#x} (intrudes in kernel range)\n",
551+
"gem_bind: Invalid map range {:#x}..{:#x} (not contained in user range)\n",
562552
start,
563553
end
564554
);
565-
return Err(EINVAL);
555+
return Err(EINVAL); // Invalid map range
566556
}
567557

568558
let prot = if data.flags & uapi::ASAHI_BIND_READ != 0 {
@@ -582,15 +572,26 @@ impl File {
582572
return Err(EINVAL); // Must specify one of ASAHI_BIND_{READ,WRITE}
583573
};
584574

585-
// Clone it immediately so we aren't holding the XArray lock
586-
let vm = file
575+
let guard = file
587576
.inner()
588577
.vms()
589578
.get(data.vm_id.try_into()?)
590-
.ok_or(ENOENT)?
591-
.borrow()
592-
.vm
593-
.clone();
579+
.ok_or(ENOENT)?;
580+
581+
// Clone it immediately so we aren't holding the XArray lock
582+
let vm = guard.borrow().vm.clone();
583+
let kernel_range = guard.borrow().kernel_range.clone();
584+
core::mem::drop(guard);
585+
586+
if kernel_range.overlaps(range) {
587+
cls_pr_debug!(
588+
Errors,
589+
"gem_bind: Invalid map range {:#x}..{:#x} (intrudes in kernel range)\n",
590+
start,
591+
end
592+
);
593+
return Err(EINVAL);
594+
}
594595

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

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.
@@ -1200,8 +1200,8 @@ impl GpuManager for GpuManager::ver {
12001200
guard
12011201
}
12021202

1203-
fn new_vm(&self) -> Result<mmu::Vm> {
1204-
self.uat.new_vm(self.ids.vm.next())
1203+
fn new_vm(&self, kernel_range: Range<u64>) -> Result<mmu::Vm> {
1204+
self.uat.new_vm(self.ids.vm.next(), kernel_range)
12051205
}
12061206

12071207
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(), ())?;
@@ -1050,8 +1053,8 @@ impl Vm {
10501053
c_str!("Asahi::GpuVm"),
10511054
dev,
10521055
&*(dummy_obj.gem),
1053-
va_range.clone(),
1054-
0..0,
1056+
gpuvm_range,
1057+
kernel_range,
10551058
init!(VmInner {
10561059
dev: dev.into(),
10571060
va_range,
@@ -1500,8 +1503,15 @@ impl Uat {
15001503
}
15011504

15021505
/// Creates a new `Vm` linked to this UAT.
1503-
pub(crate) fn new_vm(&self, id: u64) -> Result<Vm> {
1504-
Vm::new(&self.dev, self.inner.clone(), self.cfg, false, id)
1506+
pub(crate) fn new_vm(&self, id: u64, kernel_range: Range<u64>) -> Result<Vm> {
1507+
Vm::new(
1508+
&self.dev,
1509+
self.inner.clone(),
1510+
kernel_range,
1511+
self.cfg,
1512+
false,
1513+
id,
1514+
)
15051515
}
15061516

15071517
/// Creates the reference-counted inner data for a new `Uat` instance.
@@ -1547,8 +1557,8 @@ impl Uat {
15471557
let pagetables_rgn = Self::map_region(dev, c_str!("pagetables"), PAGETABLES_SIZE, true)?;
15481558

15491559
dev_info!(dev, "MMU: Creating kernel page tables\n");
1550-
let kernel_lower_vm = Vm::new(dev, inner.clone(), cfg, false, 1)?;
1551-
let kernel_vm = Vm::new(dev, inner.clone(), cfg, true, 0)?;
1560+
let kernel_lower_vm = Vm::new(dev, inner.clone(), IOVA_USER_RANGE, cfg, false, 1)?;
1561+
let kernel_vm = Vm::new(dev, inner.clone(), IOVA_KERN_RANGE, cfg, true, 0)?;
15521562

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

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ impl super::QueueInner::ver {
286286
preempt_buf3: inner.preempt_buf.gpu_offset_pointer(preempt3_off),
287287
preempt_buf4: inner.preempt_buf.gpu_offset_pointer(preempt4_off),
288288
preempt_buf5: inner.preempt_buf.gpu_offset_pointer(preempt5_off),
289-
pipeline_base: U64(0x11_00000000),
289+
pipeline_base: U64(cmdbuf.usc_base),
290290
unk_38: U64(0x8c60),
291291
helper_program: cmdbuf.helper_program, // Internal program addr | 1
292292
unk_44: 0,
@@ -309,7 +309,7 @@ impl super::QueueInner::ver {
309309
r.add(0x1a4d8, inner.preempt_buf.gpu_offset_pointer(preempt3_off).into());
310310
r.add(0x1a4e0, inner.preempt_buf.gpu_offset_pointer(preempt4_off).into());
311311
r.add(0x1a4e8, inner.preempt_buf.gpu_offset_pointer(preempt5_off).into());
312-
r.add(0x10071, 0x1100000000); // USC_EXEC_BASE_CP
312+
r.add(0x10071, cmdbuf.usc_base); // USC_EXEC_BASE_CP
313313
r.add(0x11841, cmdbuf.helper_program.into());
314314
r.add(0x11849, cmdbuf.helper_arg);
315315
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
@@ -842,7 +842,7 @@ impl super::QueueInner::ver {
842842
tile_config: U64(tile_config),
843843
aux_fb: inner.aux_fb.gpu_pointer(),
844844
unk_108: Default::default(),
845-
pipeline_base: U64(0x11_00000000),
845+
pipeline_base: U64(cmdbuf.fragment_usc_base),
846846
unk_140: U64(unks.frg_unk_140),
847847
helper_program: cmdbuf.fragment_helper_program,
848848
unk_14c: 0,
@@ -947,7 +947,7 @@ impl super::QueueInner::ver {
947947
r.add(0x11829, cmdbuf.fragment_helper_arg);
948948
r.add(0x11f79, cmdbuf.fragment_helper_cfg.into());
949949
r.add(0x15359, 0);
950-
r.add(0x10069, 0x11_00000000); // USC_EXEC_BASE_ISP
950+
r.add(0x10069, cmdbuf.fragment_usc_base); // USC_EXEC_BASE_ISP
951951
r.add(0x16020, 0);
952952
r.add(0x16461, inner.aux_fb.gpu_pointer().into());
953953
r.add(0x16090, inner.aux_fb.gpu_pointer().into());
@@ -1344,7 +1344,7 @@ impl super::QueueInner::ver {
13441344
#[ver(G < G14)]
13451345
unk_ac: unks.tiling_control_2 as u32, // fixed
13461346
unk_b0: Default::default(), // fixed
1347-
pipeline_base: U64(0x11_00000000),
1347+
pipeline_base: U64(cmdbuf.vertex_usc_base),
13481348
#[ver(G < G14)]
13491349
tvb_cluster_meta4: inner
13501350
.scene
@@ -1436,7 +1436,7 @@ impl super::QueueInner::ver {
14361436
r.add(0x1c1a9, 0); // 0x10151 bit 1 enables
14371437
r.add(0x1c1b1, 0);
14381438
r.add(0x1c1b9, 0);
1439-
r.add(0x10061, 0x11_00000000); // USC_EXEC_BASE_TA
1439+
r.add(0x10061, cmdbuf.vertex_usc_base); // USC_EXEC_BASE_TA
14401440
r.add(0x11801, cmdbuf.vertex_helper_program.into());
14411441
r.add(0x11809, cmdbuf.vertex_helper_arg);
14421442
r.add(0x11f71, cmdbuf.vertex_helper_cfg.into());

0 commit comments

Comments
 (0)