From 632de37c746abd4c9908e2e64d92dbe107c153b1 Mon Sep 17 00:00:00 2001 From: Asahi Lina Date: Thu, 3 Oct 2024 22:46:54 +0900 Subject: [PATCH] drm/asahi: Align kernel range to buffer::PAGE_SIZE We only require alignment to the UAT page size from userspace, but internally we need more, so just align it if userspace gives us lower alignment. Signed-off-by: Asahi Lina --- drivers/gpu/drm/asahi/file.rs | 11 +++++++++-- drivers/gpu/drm/asahi/util.rs | 20 ++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/asahi/file.rs b/drivers/gpu/drm/asahi/file.rs index 5baf5f54631a9a..5d1bcb4b04f874 100644 --- a/drivers/gpu/drm/asahi/file.rs +++ b/drivers/gpu/drm/asahi/file.rs @@ -9,7 +9,10 @@ use crate::debug::*; use crate::driver::AsahiDevice; -use crate::{alloc, buffer, driver, gem, hw, mmu, queue, util::RangeExt}; +use crate::{ + alloc, buffer, driver, gem, hw, mmu, queue, + util::{align, align_down, RangeExt}, +}; use core::mem::MaybeUninit; use core::ops::Range; use kernel::dma_fence::RawDmaFence; @@ -319,7 +322,11 @@ impl File { return Err(EINVAL); } - let kernel_half_size = (kernel_range.range() >> 1) & !(mmu::UAT_PGMSK as u64); + // Align to buffer::PAGE_SIZE so the allocators are happy + let kernel_range = align(kernel_range.start, buffer::PAGE_SIZE as u64) + ..align_down(kernel_range.end, buffer::PAGE_SIZE as u64); + + let kernel_half_size = align_down(kernel_range.range() >> 1, buffer::PAGE_SIZE as u64); let kernel_gpu_range = kernel_range.start..(kernel_range.start + kernel_half_size); let kernel_gpufw_range = kernel_gpu_range.end..kernel_range.end; diff --git a/drivers/gpu/drm/asahi/util.rs b/drivers/gpu/drm/asahi/util.rs index ad1c61920d5ee4..74f71568b90592 100644 --- a/drivers/gpu/drm/asahi/util.rs +++ b/drivers/gpu/drm/asahi/util.rs @@ -25,6 +25,26 @@ where (a + b - one) & !(b - one) } +/// Aligns an integer type down to a power of two. +pub(crate) fn align_down(a: T, b: T) -> T +where + T: Copy + + Default + + BitAnd + + Not + + Sub + + Div + + core::cmp::PartialEq, +{ + let def: T = Default::default(); + #[allow(clippy::eq_op)] + let one: T = !def / !def; + + assert!((b & (b - one)) == def); + + a & !(b - one) +} + /// Integer division rounding up. pub(crate) fn div_ceil(a: T, b: T) -> T where