[PATCH v4 11/11] drm/tyr: gem: map cached BOs for DRM_PANTHOR_BO_WB_MMAP
From: Ke Sun via B4 Relay
Date: Tue Oct 20 2026 - 04:31:57 EST
From: Sami Tolvanen <samitolvanen@xxxxxxxxxx>
Userspace may request a cacheable CPU mapping for a buffer it accesses
frequently. Accept DRM_PANTHOR_BO_WB_MMAP in bo_create and map the
buffer cached when the flag is set. Coherent devices already map
cached. NO_MMAP and WB_MMAP together are rejected with EINVAL.
On non-coherent platforms userspace owns the CPU cache maintenance
around GPU access to these buffers.
Signed-off-by: Sami Tolvanen <samitolvanen@xxxxxxxxxx>
[ Split the BO_CREATE validation and add the WB_MMAP flag checks
from the original. - Alvin ]
Co-developed-by: Alvin Sun <alvin.sun@xxxxxxxxx>
Signed-off-by: Alvin Sun <alvin.sun@xxxxxxxxx>
---
drivers/gpu/drm/tyr/file.rs | 25 +++++++++++++++++++------
drivers/gpu/drm/tyr/gem.rs | 18 +++++++++++-------
2 files changed, 30 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/tyr/file.rs b/drivers/gpu/drm/tyr/file.rs
index d4d6a6742b2e1..6f4550d14bb39 100644
--- a/drivers/gpu/drm/tyr/file.rs
+++ b/drivers/gpu/drm/tyr/file.rs
@@ -258,19 +258,32 @@ pub(crate) fn bo_create(
bocreate: &mut uapi::drm_panthor_bo_create,
file: &TyrDrmFile,
) -> Result<u32> {
- if bocreate.size == 0
- || bocreate.pad != 0
- || bocreate.flags & !uapi::drm_panthor_bo_flags_DRM_PANTHOR_BO_NO_MMAP != 0
- {
+ if bocreate.size == 0 || bocreate.pad != 0 {
dev_dbg!(
ddev.as_ref(),
- "Invalid BO_CREATE params: size={}, pad={}, flags={:#x}\n",
+ "Invalid BO_CREATE params: size={}, pad={}\n",
bocreate.size,
- bocreate.pad,
+ bocreate.pad
+ );
+ return Err(EINVAL);
+ }
+
+ let no_mmap = uapi::drm_panthor_bo_flags_DRM_PANTHOR_BO_NO_MMAP;
+ let wb_mmap = uapi::drm_panthor_bo_flags_DRM_PANTHOR_BO_WB_MMAP;
+ let valid_flags = no_mmap | wb_mmap;
+
+ if bocreate.flags & !valid_flags != 0 {
+ dev_dbg!(
+ ddev.as_ref(),
+ "Invalid BO_CREATE flags: {:#x}\n",
bocreate.flags
);
return Err(EINVAL);
}
+ if bocreate.flags & no_mmap != 0 && bocreate.flags & wb_mmap != 0 {
+ dev_dbg!(ddev.as_ref(), "BO_CREATE: NO_MMAP conflicts with WB_MMAP\n");
+ return Err(EINVAL);
+ }
if bocreate.exclusive_vm_id != 0 {
dev_dbg!(ddev.as_ref(), "BO_CREATE: exclusive_vm_id not supported\n");
diff --git a/drivers/gpu/drm/tyr/gem.rs b/drivers/gpu/drm/tyr/gem.rs
index fad0720ce7123..d3791b62d5a7b 100644
--- a/drivers/gpu/drm/tyr/gem.rs
+++ b/drivers/gpu/drm/tyr/gem.rs
@@ -17,7 +17,8 @@
sync::{
aref::ARef,
Arc, //
- }, //
+ },
+ uapi, //
};
use crate::{
@@ -63,13 +64,16 @@ fn new(_dev: &TyrDrmDevice, _size: usize, args: BoCreateArgs) -> impl PinInit<Se
/// Type alias for Tyr GEM buffer objects.
pub(crate) type Bo = gem::shmem::Object<BoData>;
-/// Returns whether a BO should be mapped write-combine given the device's
-/// DMA coherence.
-pub(crate) fn should_map_wc(coherent: bool) -> bool {
+/// Returns whether a BO should be mapped write-combine.
+pub(crate) fn should_map_wc(coherent: bool, flags: u32) -> bool {
if coherent {
return false;
}
+ if flags & uapi::drm_panthor_bo_flags_DRM_PANTHOR_BO_WB_MMAP != 0 {
+ return false;
+ }
+
true
}
@@ -86,7 +90,7 @@ pub(crate) fn new_object(
let aligned_size = size.checked_next_multiple_of(PAGE_SIZE).ok_or(EINVAL)?;
- let map_wc = should_map_wc(coherent);
+ let map_wc = should_map_wc(coherent, flags);
let bo = Bo::new(
ddev,
aligned_size,
@@ -116,7 +120,7 @@ pub(crate) fn new_dummy_object(ddev: &TyrDrmDevice, coherent: bool) -> Result<AR
ddev,
4096,
shmem::ObjectConfig {
- map_wc: should_map_wc(coherent),
+ map_wc: should_map_wc(coherent, 0),
parent_resv_obj: None,
},
BoCreateArgs { flags: 0 },
@@ -174,7 +178,7 @@ pub(crate) fn new(
ddev,
bo_size,
shmem::ObjectConfig {
- map_wc: should_map_wc(coherent),
+ map_wc: should_map_wc(coherent, 0),
parent_resv_obj: None,
},
BoCreateArgs { flags: 0 },
--
2.43.0