diff --git a/src/cross_domain/mod.rs b/src/cross_domain/mod.rs index fa3c469..5d67e00 100644 --- a/src/cross_domain/mod.rs +++ b/src/cross_domain/mod.rs @@ -30,8 +30,6 @@ use mesa3d_util::TubeType; use mesa3d_util::WaitContext; use mesa3d_util::WaitTimeout; use mesa3d_util::WritePipe; -use mesa3d_util::MESA_HANDLE_TYPE_MEM_DMABUF; -use mesa3d_util::MESA_HANDLE_TYPE_MEM_SHM; use zerocopy::FromBytes; use zerocopy::Immutable; use zerocopy::IntoBytes; @@ -54,7 +52,6 @@ use crate::rutabaga_utils::RutabagaPath; use crate::rutabaga_utils::RutabagaResult; use crate::rutabaga_utils::RUTABAGA_BLOB_FLAG_USE_MAPPABLE; use crate::rutabaga_utils::RUTABAGA_BLOB_MEM_GUEST; -use crate::rutabaga_utils::RUTABAGA_MAP_ACCESS_READ; use crate::rutabaga_utils::RUTABAGA_MAP_ACCESS_RW; use crate::rutabaga_utils::RUTABAGA_MAP_CACHE_CACHED; use crate::DrmFormat; @@ -876,14 +873,10 @@ impl RutabagaContext for CrossDomainContext { // Items that are removed from the table after one usage. match item { CrossDomainItem::Blob(hnd) => { - let map_access = if hnd.handle_type == MESA_HANDLE_TYPE_MEM_SHM { - RUTABAGA_MAP_ACCESS_READ - } else if hnd.handle_type == MESA_HANDLE_TYPE_MEM_DMABUF { - RUTABAGA_MAP_ACCESS_RW - } else { - // Default to READ for unknown types - RUTABAGA_MAP_ACCESS_READ - }; + let map_access = hnd + .os_handle + .determine_map_access_mode() + .map_err(|e| RutabagaError::MesaError(e.into()))?; let map_info = Some(RUTABAGA_MAP_CACHE_CACHED | map_access); Ok(RutabagaResource { diff --git a/third_party/mesa3d/src/util/rust/sys/linux/descriptor.rs b/third_party/mesa3d/src/util/rust/sys/linux/descriptor.rs index 801b3b4..9ea330d 100644 --- a/third_party/mesa3d/src/util/rust/sys/linux/descriptor.rs +++ b/third_party/mesa3d/src/util/rust/sys/linux/descriptor.rs @@ -14,10 +14,13 @@ use std::os::unix::io::FromRawFd; use std::os::unix::io::IntoRawFd; use std::os::unix::io::RawFd; +use rustix::fs::fcntl_get_seals; use rustix::fs::fcntl_getfl; use rustix::fs::seek; use rustix::fs::OFlags; +use rustix::fs::SealFlags; use rustix::fs::SeekFrom; +use rustix::io::Errno; use crate::descriptor::AsRawDescriptor; use crate::descriptor::FromRawDescriptor; @@ -25,6 +28,9 @@ use crate::descriptor::IntoRawDescriptor; use crate::DescriptorType; use crate::MESA_HANDLE_TYPE_MEM_DMABUF; use crate::MESA_HANDLE_TYPE_MEM_SHM; +use crate::MESA_MAP_ACCESS_READ; +use crate::MESA_MAP_ACCESS_RW; +use crate::MESA_MAP_ACCESS_WRITE; pub type RawDescriptor = RawFd; pub const DEFAULT_RAW_DESCRIPTOR: RawDescriptor = -1; @@ -61,6 +67,26 @@ impl OwnedDescriptor { } } + pub fn determine_map_access_mode(&self) -> Result { + let flags = fcntl_getfl(&self.owned)?; + let mut access = match flags & OFlags::ACCMODE { + OFlags::RDONLY => MESA_MAP_ACCESS_READ, + OFlags::WRONLY => MESA_MAP_ACCESS_WRITE, + OFlags::RDWR => MESA_MAP_ACCESS_RW, + _ => return Err(Error::from(ErrorKind::Unsupported)), + }; + // Access mode can be RDWR, but a write seal would still prevent RW mappings! + let seals = match fcntl_get_seals(&self.owned) { + Ok(seals) => seals, + Err(Errno::INVAL) => SealFlags::empty(), // It's fine if the file does not support sealing + Err(err) => return Err(err.into()), + }; + if seals.contains(SealFlags::WRITE) || seals.contains(SealFlags::FUTURE_WRITE) { + access &= !MESA_MAP_ACCESS_WRITE; + } + Ok(access) + } + fn get_memory_handle_type(&self) -> Result { let fd_path = read_link(format!("/proc/self/fd/{}", self.as_raw_descriptor())) .map_err(|_| Error::from(ErrorKind::Unsupported))?; diff --git a/third_party/mesa3d/src/util/rust/sys/stub/descriptor.rs b/third_party/mesa3d/src/util/rust/sys/stub/descriptor.rs index a8e4fb9..232a449 100644 --- a/third_party/mesa3d/src/util/rust/sys/stub/descriptor.rs +++ b/third_party/mesa3d/src/util/rust/sys/stub/descriptor.rs @@ -34,6 +34,10 @@ impl OwnedDescriptor { pub fn determine_type(&self) -> Result { Err(Error::from(ErrorKind::Unsupported)) } + + pub fn determine_map_access_mode(&self) -> Result { + Err(Error::from(ErrorKind::Unsupported)) + } } impl AsRawDescriptor for OwnedDescriptor { diff --git a/third_party/mesa3d/src/util/rust/sys/windows/descriptor.rs b/third_party/mesa3d/src/util/rust/sys/windows/descriptor.rs index b5f74ab..00ffe8b 100644 --- a/third_party/mesa3d/src/util/rust/sys/windows/descriptor.rs +++ b/third_party/mesa3d/src/util/rust/sys/windows/descriptor.rs @@ -34,6 +34,10 @@ impl OwnedDescriptor { pub fn determine_type(&self) -> Result { Err(Error::from(ErrorKind::Unsupported)) } + + pub fn determine_map_access_mode(&self) -> Result { + Err(Error::from(ErrorKind::Unsupported)) + } } impl AsRawDescriptor for OwnedDescriptor {