Skip to content

Commit dd34543

Browse files
hoshinolinajannau
authored andcommitted
drm/asahi: Implement ASAHI_BIND_SINGLE_PAGE
Signed-off-by: Asahi Lina <lina@asahilina.net>
1 parent 1a802b5 commit dd34543

4 files changed

Lines changed: 59 additions & 16 deletions

File tree

drivers/gpu/drm/asahi/file.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,8 @@ impl File {
249249

250250
feat_compat: gpu.get_cfg().gpu_feat_compat
251251
| hw::feat::compat::GETTIME
252-
| hw::feat::compat::USER_TIMESTAMPS,
252+
| hw::feat::compat::USER_TIMESTAMPS
253+
| hw::feat::compat::SINGLE_PAGE_MAP,
253254
feat_incompat: gpu.get_cfg().gpu_feat_incompat,
254255

255256
gpu_generation: gpu.get_dyncfg().id.gpu_gen as u32,
@@ -561,11 +562,16 @@ impl File {
561562
return Err(EINVAL); // Must be page aligned
562563
}
563564

564-
if (data.flags & !(uapi::ASAHI_BIND_READ | uapi::ASAHI_BIND_WRITE)) != 0 {
565+
if (data.flags
566+
& !(uapi::ASAHI_BIND_READ | uapi::ASAHI_BIND_WRITE | uapi::ASAHI_BIND_SINGLE_PAGE))
567+
!= 0
568+
{
565569
cls_pr_debug!(Errors, "gem_bind: Invalid flags {:#x}\n", data.flags);
566570
return Err(EINVAL);
567571
}
568572

573+
let single_page = data.flags & uapi::ASAHI_BIND_SINGLE_PAGE != 0;
574+
569575
let bo = gem::lookup_handle(file, data.handle)?;
570576

571577
let start = data.addr;
@@ -625,7 +631,14 @@ impl File {
625631
return Err(EINVAL);
626632
}
627633

628-
vm.bind_object(&bo.gem, data.addr, data.range, data.offset, prot)?;
634+
vm.bind_object(
635+
&bo.gem,
636+
data.addr,
637+
data.range,
638+
data.offset,
639+
prot,
640+
single_page,
641+
)?;
629642

630643
Ok(0)
631644
}

drivers/gpu/drm/asahi/hw/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ pub(crate) mod feat {
9999
/// User timestamps extension supported
100100
pub(crate) const USER_TIMESTAMPS: u64 =
101101
uapi::drm_asahi_feat_compat_DRM_ASAHI_FEAT_USER_TIMESTAMPS as u64;
102+
/// User timestamps extension supported
103+
pub(crate) const SINGLE_PAGE_MAP: u64 =
104+
uapi::drm_asahi_feat_compat_DRM_ASAHI_FEAT_SINGLE_PAGE_MAP as u64;
102105
}
103106

104107
/// Backwards-incompatible features.

drivers/gpu/drm/asahi/mmu.rs

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,8 @@ impl gpuvm::DriverGpuVm for VmInner {
192192

193193
let bo = ctx.vm_bo.as_ref().expect("step_map with no BO");
194194

195+
let one_page = op.flags().contains(gpuvm::GpuVaFlags::SINGLE_PAGE);
196+
195197
let guard = bo.inner().sgt.lock();
196198
for range in guard.as_ref().expect("step_map with no SGT").iter() {
197199
let mut addr = range.dma_address();
@@ -214,18 +216,27 @@ impl gpuvm::DriverGpuVm for VmInner {
214216

215217
assert!(offset == 0);
216218

217-
len = len.min(left);
219+
if one_page {
220+
len = left;
221+
} else {
222+
len = len.min(left);
223+
}
218224

219225
mod_dev_dbg!(
220226
self.dev,
221-
"MMU: map: {:#x}:{:#x} -> {:#x}\n",
227+
"MMU: map: {:#x}:{:#x} -> {:#x} [OP={}]\n",
222228
addr,
223229
len,
224-
iova
230+
iova,
231+
one_page
225232
);
226233

227-
self.page_table
228-
.map_pages(iova..(iova + len as u64), addr as PhysicalAddr, ctx.prot)?;
234+
self.page_table.map_pages(
235+
iova..(iova + len as u64),
236+
addr as PhysicalAddr,
237+
ctx.prot,
238+
one_page,
239+
)?;
229240

230241
left -= len;
231242
iova += len as u64;
@@ -437,8 +448,12 @@ impl VmInner {
437448
iova
438449
);
439450

440-
self.page_table
441-
.map_pages(iova..(iova + len as u64), addr as PhysicalAddr, prot)?;
451+
self.page_table.map_pages(
452+
iova..(iova + len as u64),
453+
addr as PhysicalAddr,
454+
prot,
455+
false,
456+
)?;
442457

443458
iova += len as u64;
444459
left -= len;
@@ -1084,6 +1099,7 @@ impl Vm {
10841099
size: u64,
10851100
offset: u64,
10861101
prot: Prot,
1102+
single_page: bool,
10871103
) -> Result {
10881104
// Mapping needs a complete context
10891105
let mut ctx = StepContext {
@@ -1118,14 +1134,20 @@ impl Vm {
11181134
return Err(EINVAL);
11191135
}
11201136

1137+
let flags = if single_page {
1138+
gpuvm::GpuVaFlags::SINGLE_PAGE
1139+
} else {
1140+
gpuvm::GpuVaFlags::NONE
1141+
};
1142+
11211143
mod_dev_dbg!(
11221144
inner.dev,
11231145
"MMU: sm_map: {:#x} [{:#x}] -> {:#x}\n",
11241146
offset,
11251147
size,
11261148
addr
11271149
);
1128-
inner.sm_map(&mut ctx, addr, size, offset)
1150+
inner.sm_map(&mut ctx, addr, size, offset, flags)
11291151
}
11301152

11311153
/// Add a direct MMIO mapping to this Vm at a free address.
@@ -1173,10 +1195,12 @@ impl Vm {
11731195
0,
11741196
)?;
11751197

1176-
let ret =
1177-
inner
1178-
.page_table
1179-
.map_pages(iova..(iova + size as u64), phys as PhysicalAddr, prot);
1198+
let ret = inner.page_table.map_pages(
1199+
iova..(iova + size as u64),
1200+
phys as PhysicalAddr,
1201+
prot,
1202+
false,
1203+
);
11801204
// Drop the exec_lock first, so that if map_node failed the
11811205
// KernelMappingInner destructur does not deadlock.
11821206
core::mem::drop(inner);

drivers/gpu/drm/asahi/pgtable.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ impl UatPageTable {
385385
iova_range: Range<u64>,
386386
mut phys: PhysicalAddr,
387387
prot: Prot,
388+
one_page: bool,
388389
) -> Result {
389390
mod_pr_debug!(
390391
"UATPageTable::map_pages: {:#x?} {:#x?} {:?}\n",
@@ -411,7 +412,9 @@ impl UatPageTable {
411412
phys | prot.as_pte() | PTE_TYPE_LEAF_TABLE,
412413
Ordering::Relaxed,
413414
);
414-
phys += UAT_PGSZ as PhysicalAddr;
415+
if !one_page {
416+
phys += UAT_PGSZ as PhysicalAddr;
417+
}
415418
}
416419
})
417420
}

0 commit comments

Comments
 (0)