1 // SPDX-License-Identifier: GPL-2.0 2 3 //! Direct memory access (DMA). 4 //! 5 //! C header: [`include/linux/dma-mapping.h`](srctree/include/linux/dma-mapping.h) 6 7 use crate::{ 8 bindings, build_assert, device, 9 device::{Bound, Core}, 10 error::{to_result, Result}, 11 prelude::*, 12 transmute::{AsBytes, FromBytes}, 13 types::ARef, 14 }; 15 16 /// Trait to be implemented by DMA capable bus devices. 17 /// 18 /// The [`dma::Device`](Device) trait should be implemented by bus specific device representations, 19 /// where the underlying bus is DMA capable, such as [`pci::Device`](::kernel::pci::Device) or 20 /// [`platform::Device`](::kernel::platform::Device). 21 pub trait Device: AsRef<device::Device<Core>> { 22 /// Set up the device's DMA streaming addressing capabilities. 23 /// 24 /// This method is usually called once from `probe()` as soon as the device capabilities are 25 /// known. 26 /// 27 /// # Safety 28 /// 29 /// This method must not be called concurrently with any DMA allocation or mapping primitives, 30 /// such as [`CoherentAllocation::alloc_attrs`]. 31 unsafe fn dma_set_mask(&self, mask: DmaMask) -> Result { 32 // SAFETY: 33 // - By the type invariant of `device::Device`, `self.as_ref().as_raw()` is valid. 34 // - The safety requirement of this function guarantees that there are no concurrent calls 35 // to DMA allocation and mapping primitives using this mask. 36 to_result(unsafe { bindings::dma_set_mask(self.as_ref().as_raw(), mask.value()) }) 37 } 38 39 /// Set up the device's DMA coherent addressing capabilities. 40 /// 41 /// This method is usually called once from `probe()` as soon as the device capabilities are 42 /// known. 43 /// 44 /// # Safety 45 /// 46 /// This method must not be called concurrently with any DMA allocation or mapping primitives, 47 /// such as [`CoherentAllocation::alloc_attrs`]. 48 unsafe fn dma_set_coherent_mask(&self, mask: DmaMask) -> Result { 49 // SAFETY: 50 // - By the type invariant of `device::Device`, `self.as_ref().as_raw()` is valid. 51 // - The safety requirement of this function guarantees that there are no concurrent calls 52 // to DMA allocation and mapping primitives using this mask. 53 to_result(unsafe { bindings::dma_set_coherent_mask(self.as_ref().as_raw(), mask.value()) }) 54 } 55 56 /// Set up the device's DMA addressing capabilities. 57 /// 58 /// This is a combination of [`Device::dma_set_mask`] and [`Device::dma_set_coherent_mask`]. 59 /// 60 /// This method is usually called once from `probe()` as soon as the device capabilities are 61 /// known. 62 /// 63 /// # Safety 64 /// 65 /// This method must not be called concurrently with any DMA allocation or mapping primitives, 66 /// such as [`CoherentAllocation::alloc_attrs`]. 67 unsafe fn dma_set_mask_and_coherent(&self, mask: DmaMask) -> Result { 68 // SAFETY: 69 // - By the type invariant of `device::Device`, `self.as_ref().as_raw()` is valid. 70 // - The safety requirement of this function guarantees that there are no concurrent calls 71 // to DMA allocation and mapping primitives using this mask. 72 to_result(unsafe { 73 bindings::dma_set_mask_and_coherent(self.as_ref().as_raw(), mask.value()) 74 }) 75 } 76 } 77 78 /// A DMA mask that holds a bitmask with the lowest `n` bits set. 79 /// 80 /// Use [`DmaMask::new`] or [`DmaMask::try_new`] to construct a value. Values 81 /// are guaranteed to never exceed the bit width of `u64`. 82 /// 83 /// This is the Rust equivalent of the C macro `DMA_BIT_MASK()`. 84 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 85 pub struct DmaMask(u64); 86 87 impl DmaMask { 88 /// Constructs a `DmaMask` with the lowest `n` bits set to `1`. 89 /// 90 /// For `n <= 64`, sets exactly the lowest `n` bits. 91 /// For `n > 64`, results in a build error. 92 /// 93 /// # Examples 94 /// 95 /// ``` 96 /// use kernel::dma::DmaMask; 97 /// 98 /// let mask0 = DmaMask::new::<0>(); 99 /// assert_eq!(mask0.value(), 0); 100 /// 101 /// let mask1 = DmaMask::new::<1>(); 102 /// assert_eq!(mask1.value(), 0b1); 103 /// 104 /// let mask64 = DmaMask::new::<64>(); 105 /// assert_eq!(mask64.value(), u64::MAX); 106 /// 107 /// // Build failure. 108 /// // let mask_overflow = DmaMask::new::<100>(); 109 /// ``` 110 #[inline] 111 pub const fn new<const N: u32>() -> Self { 112 let Ok(mask) = Self::try_new(N) else { 113 build_error!("Invalid DMA Mask."); 114 }; 115 116 mask 117 } 118 119 /// Constructs a `DmaMask` with the lowest `n` bits set to `1`. 120 /// 121 /// For `n <= 64`, sets exactly the lowest `n` bits. 122 /// For `n > 64`, returns [`EINVAL`]. 123 /// 124 /// # Examples 125 /// 126 /// ``` 127 /// use kernel::dma::DmaMask; 128 /// 129 /// let mask0 = DmaMask::try_new(0)?; 130 /// assert_eq!(mask0.value(), 0); 131 /// 132 /// let mask1 = DmaMask::try_new(1)?; 133 /// assert_eq!(mask1.value(), 0b1); 134 /// 135 /// let mask64 = DmaMask::try_new(64)?; 136 /// assert_eq!(mask64.value(), u64::MAX); 137 /// 138 /// let mask_overflow = DmaMask::try_new(100); 139 /// assert!(mask_overflow.is_err()); 140 /// # Ok::<(), Error>(()) 141 /// ``` 142 #[inline] 143 pub const fn try_new(n: u32) -> Result<Self> { 144 Ok(Self(match n { 145 0 => 0, 146 1..=64 => u64::MAX >> (64 - n), 147 _ => return Err(EINVAL), 148 })) 149 } 150 151 /// Returns the underlying `u64` bitmask value. 152 #[inline] 153 pub const fn value(&self) -> u64 { 154 self.0 155 } 156 } 157 158 /// Possible attributes associated with a DMA mapping. 159 /// 160 /// They can be combined with the operators `|`, `&`, and `!`. 161 /// 162 /// Values can be used from the [`attrs`] module. 163 /// 164 /// # Examples 165 /// 166 /// ``` 167 /// # use kernel::device::{Bound, Device}; 168 /// use kernel::dma::{attrs::*, CoherentAllocation}; 169 /// 170 /// # fn test(dev: &Device<Bound>) -> Result { 171 /// let attribs = DMA_ATTR_FORCE_CONTIGUOUS | DMA_ATTR_NO_WARN; 172 /// let c: CoherentAllocation<u64> = 173 /// CoherentAllocation::alloc_attrs(dev, 4, GFP_KERNEL, attribs)?; 174 /// # Ok::<(), Error>(()) } 175 /// ``` 176 #[derive(Clone, Copy, PartialEq)] 177 #[repr(transparent)] 178 pub struct Attrs(u32); 179 180 impl Attrs { 181 /// Get the raw representation of this attribute. 182 pub(crate) fn as_raw(self) -> crate::ffi::c_ulong { 183 self.0 as _ 184 } 185 186 /// Check whether `flags` is contained in `self`. 187 pub fn contains(self, flags: Attrs) -> bool { 188 (self & flags) == flags 189 } 190 } 191 192 impl core::ops::BitOr for Attrs { 193 type Output = Self; 194 fn bitor(self, rhs: Self) -> Self::Output { 195 Self(self.0 | rhs.0) 196 } 197 } 198 199 impl core::ops::BitAnd for Attrs { 200 type Output = Self; 201 fn bitand(self, rhs: Self) -> Self::Output { 202 Self(self.0 & rhs.0) 203 } 204 } 205 206 impl core::ops::Not for Attrs { 207 type Output = Self; 208 fn not(self) -> Self::Output { 209 Self(!self.0) 210 } 211 } 212 213 /// DMA mapping attributes. 214 pub mod attrs { 215 use super::Attrs; 216 217 /// Specifies that reads and writes to the mapping may be weakly ordered, that is that reads 218 /// and writes may pass each other. 219 pub const DMA_ATTR_WEAK_ORDERING: Attrs = Attrs(bindings::DMA_ATTR_WEAK_ORDERING); 220 221 /// Specifies that writes to the mapping may be buffered to improve performance. 222 pub const DMA_ATTR_WRITE_COMBINE: Attrs = Attrs(bindings::DMA_ATTR_WRITE_COMBINE); 223 224 /// Lets the platform to avoid creating a kernel virtual mapping for the allocated buffer. 225 pub const DMA_ATTR_NO_KERNEL_MAPPING: Attrs = Attrs(bindings::DMA_ATTR_NO_KERNEL_MAPPING); 226 227 /// Allows platform code to skip synchronization of the CPU cache for the given buffer assuming 228 /// that it has been already transferred to 'device' domain. 229 pub const DMA_ATTR_SKIP_CPU_SYNC: Attrs = Attrs(bindings::DMA_ATTR_SKIP_CPU_SYNC); 230 231 /// Forces contiguous allocation of the buffer in physical memory. 232 pub const DMA_ATTR_FORCE_CONTIGUOUS: Attrs = Attrs(bindings::DMA_ATTR_FORCE_CONTIGUOUS); 233 234 /// This is a hint to the DMA-mapping subsystem that it's probably not worth the time to try 235 /// to allocate memory to in a way that gives better TLB efficiency. 236 pub const DMA_ATTR_ALLOC_SINGLE_PAGES: Attrs = Attrs(bindings::DMA_ATTR_ALLOC_SINGLE_PAGES); 237 238 /// This tells the DMA-mapping subsystem to suppress allocation failure reports (similarly to 239 /// `__GFP_NOWARN`). 240 pub const DMA_ATTR_NO_WARN: Attrs = Attrs(bindings::DMA_ATTR_NO_WARN); 241 242 /// Used to indicate that the buffer is fully accessible at an elevated privilege level (and 243 /// ideally inaccessible or at least read-only at lesser-privileged levels). 244 pub const DMA_ATTR_PRIVILEGED: Attrs = Attrs(bindings::DMA_ATTR_PRIVILEGED); 245 } 246 247 /// An abstraction of the `dma_alloc_coherent` API. 248 /// 249 /// This is an abstraction around the `dma_alloc_coherent` API which is used to allocate and map 250 /// large consistent DMA regions. 251 /// 252 /// A [`CoherentAllocation`] instance contains a pointer to the allocated region (in the 253 /// processor's virtual address space) and the device address which can be given to the device 254 /// as the DMA address base of the region. The region is released once [`CoherentAllocation`] 255 /// is dropped. 256 /// 257 /// # Invariants 258 /// 259 /// For the lifetime of an instance of [`CoherentAllocation`], the `cpu_addr` is a valid pointer 260 /// to an allocated region of consistent memory and `dma_handle` is the DMA address base of 261 /// the region. 262 // TODO 263 // 264 // DMA allocations potentially carry device resources (e.g.IOMMU mappings), hence for soundness 265 // reasons DMA allocation would need to be embedded in a `Devres` container, in order to ensure 266 // that device resources can never survive device unbind. 267 // 268 // However, it is neither desirable nor necessary to protect the allocated memory of the DMA 269 // allocation from surviving device unbind; it would require RCU read side critical sections to 270 // access the memory, which may require subsequent unnecessary copies. 271 // 272 // Hence, find a way to revoke the device resources of a `CoherentAllocation`, but not the 273 // entire `CoherentAllocation` including the allocated memory itself. 274 pub struct CoherentAllocation<T: AsBytes + FromBytes> { 275 dev: ARef<device::Device>, 276 dma_handle: bindings::dma_addr_t, 277 count: usize, 278 cpu_addr: *mut T, 279 dma_attrs: Attrs, 280 } 281 282 impl<T: AsBytes + FromBytes> CoherentAllocation<T> { 283 /// Allocates a region of `size_of::<T> * count` of consistent memory. 284 /// 285 /// # Examples 286 /// 287 /// ``` 288 /// # use kernel::device::{Bound, Device}; 289 /// use kernel::dma::{attrs::*, CoherentAllocation}; 290 /// 291 /// # fn test(dev: &Device<Bound>) -> Result { 292 /// let c: CoherentAllocation<u64> = 293 /// CoherentAllocation::alloc_attrs(dev, 4, GFP_KERNEL, DMA_ATTR_NO_WARN)?; 294 /// # Ok::<(), Error>(()) } 295 /// ``` 296 pub fn alloc_attrs( 297 dev: &device::Device<Bound>, 298 count: usize, 299 gfp_flags: kernel::alloc::Flags, 300 dma_attrs: Attrs, 301 ) -> Result<CoherentAllocation<T>> { 302 build_assert!( 303 core::mem::size_of::<T>() > 0, 304 "It doesn't make sense for the allocated type to be a ZST" 305 ); 306 307 let size = count 308 .checked_mul(core::mem::size_of::<T>()) 309 .ok_or(EOVERFLOW)?; 310 let mut dma_handle = 0; 311 // SAFETY: Device pointer is guaranteed as valid by the type invariant on `Device`. 312 let ret = unsafe { 313 bindings::dma_alloc_attrs( 314 dev.as_raw(), 315 size, 316 &mut dma_handle, 317 gfp_flags.as_raw(), 318 dma_attrs.as_raw(), 319 ) 320 }; 321 if ret.is_null() { 322 return Err(ENOMEM); 323 } 324 // INVARIANT: We just successfully allocated a coherent region which is accessible for 325 // `count` elements, hence the cpu address is valid. We also hold a refcounted reference 326 // to the device. 327 Ok(Self { 328 dev: dev.into(), 329 dma_handle, 330 count, 331 cpu_addr: ret as *mut T, 332 dma_attrs, 333 }) 334 } 335 336 /// Performs the same functionality as [`CoherentAllocation::alloc_attrs`], except the 337 /// `dma_attrs` is 0 by default. 338 pub fn alloc_coherent( 339 dev: &device::Device<Bound>, 340 count: usize, 341 gfp_flags: kernel::alloc::Flags, 342 ) -> Result<CoherentAllocation<T>> { 343 CoherentAllocation::alloc_attrs(dev, count, gfp_flags, Attrs(0)) 344 } 345 346 /// Returns the base address to the allocated region in the CPU's virtual address space. 347 pub fn start_ptr(&self) -> *const T { 348 self.cpu_addr 349 } 350 351 /// Returns the base address to the allocated region in the CPU's virtual address space as 352 /// a mutable pointer. 353 pub fn start_ptr_mut(&mut self) -> *mut T { 354 self.cpu_addr 355 } 356 357 /// Returns a DMA handle which may given to the device as the DMA address base of 358 /// the region. 359 pub fn dma_handle(&self) -> bindings::dma_addr_t { 360 self.dma_handle 361 } 362 363 /// Returns a pointer to an element from the region with bounds checking. `offset` is in 364 /// units of `T`, not the number of bytes. 365 /// 366 /// Public but hidden since it should only be used from [`dma_read`] and [`dma_write`] macros. 367 #[doc(hidden)] 368 pub fn item_from_index(&self, offset: usize) -> Result<*mut T> { 369 if offset >= self.count { 370 return Err(EINVAL); 371 } 372 // SAFETY: 373 // - The pointer is valid due to type invariant on `CoherentAllocation` 374 // and we've just checked that the range and index is within bounds. 375 // - `offset` can't overflow since it is smaller than `self.count` and we've checked 376 // that `self.count` won't overflow early in the constructor. 377 Ok(unsafe { self.cpu_addr.add(offset) }) 378 } 379 380 /// Reads the value of `field` and ensures that its type is [`FromBytes`]. 381 /// 382 /// # Safety 383 /// 384 /// This must be called from the [`dma_read`] macro which ensures that the `field` pointer is 385 /// validated beforehand. 386 /// 387 /// Public but hidden since it should only be used from [`dma_read`] macro. 388 #[doc(hidden)] 389 pub unsafe fn field_read<F: FromBytes>(&self, field: *const F) -> F { 390 // SAFETY: 391 // - By the safety requirements field is valid. 392 // - Using read_volatile() here is not sound as per the usual rules, the usage here is 393 // a special exception with the following notes in place. When dealing with a potential 394 // race from a hardware or code outside kernel (e.g. user-space program), we need that 395 // read on a valid memory is not UB. Currently read_volatile() is used for this, and the 396 // rationale behind is that it should generate the same code as READ_ONCE() which the 397 // kernel already relies on to avoid UB on data races. Note that the usage of 398 // read_volatile() is limited to this particular case, it cannot be used to prevent 399 // the UB caused by racing between two kernel functions nor do they provide atomicity. 400 unsafe { field.read_volatile() } 401 } 402 403 /// Writes a value to `field` and ensures that its type is [`AsBytes`]. 404 /// 405 /// # Safety 406 /// 407 /// This must be called from the [`dma_write`] macro which ensures that the `field` pointer is 408 /// validated beforehand. 409 /// 410 /// Public but hidden since it should only be used from [`dma_write`] macro. 411 #[doc(hidden)] 412 pub unsafe fn field_write<F: AsBytes>(&self, field: *mut F, val: F) { 413 // SAFETY: 414 // - By the safety requirements field is valid. 415 // - Using write_volatile() here is not sound as per the usual rules, the usage here is 416 // a special exception with the following notes in place. When dealing with a potential 417 // race from a hardware or code outside kernel (e.g. user-space program), we need that 418 // write on a valid memory is not UB. Currently write_volatile() is used for this, and the 419 // rationale behind is that it should generate the same code as WRITE_ONCE() which the 420 // kernel already relies on to avoid UB on data races. Note that the usage of 421 // write_volatile() is limited to this particular case, it cannot be used to prevent 422 // the UB caused by racing between two kernel functions nor do they provide atomicity. 423 unsafe { field.write_volatile(val) } 424 } 425 } 426 427 /// Note that the device configured to do DMA must be halted before this object is dropped. 428 impl<T: AsBytes + FromBytes> Drop for CoherentAllocation<T> { 429 fn drop(&mut self) { 430 let size = self.count * core::mem::size_of::<T>(); 431 // SAFETY: Device pointer is guaranteed as valid by the type invariant on `Device`. 432 // The cpu address, and the dma handle are valid due to the type invariants on 433 // `CoherentAllocation`. 434 unsafe { 435 bindings::dma_free_attrs( 436 self.dev.as_raw(), 437 size, 438 self.cpu_addr as _, 439 self.dma_handle, 440 self.dma_attrs.as_raw(), 441 ) 442 } 443 } 444 } 445 446 // SAFETY: It is safe to send a `CoherentAllocation` to another thread if `T` 447 // can be sent to another thread. 448 unsafe impl<T: AsBytes + FromBytes + Send> Send for CoherentAllocation<T> {} 449 450 /// Reads a field of an item from an allocated region of structs. 451 /// 452 /// # Examples 453 /// 454 /// ``` 455 /// use kernel::device::Device; 456 /// use kernel::dma::{attrs::*, CoherentAllocation}; 457 /// 458 /// struct MyStruct { field: u32, } 459 /// 460 /// // SAFETY: All bit patterns are acceptable values for `MyStruct`. 461 /// unsafe impl kernel::transmute::FromBytes for MyStruct{}; 462 /// // SAFETY: Instances of `MyStruct` have no uninitialized portions. 463 /// unsafe impl kernel::transmute::AsBytes for MyStruct{}; 464 /// 465 /// # fn test(alloc: &kernel::dma::CoherentAllocation<MyStruct>) -> Result { 466 /// let whole = kernel::dma_read!(alloc[2]); 467 /// let field = kernel::dma_read!(alloc[1].field); 468 /// # Ok::<(), Error>(()) } 469 /// ``` 470 #[macro_export] 471 macro_rules! dma_read { 472 ($dma:expr, $idx: expr, $($field:tt)*) => {{ 473 let item = $crate::dma::CoherentAllocation::item_from_index(&$dma, $idx)?; 474 // SAFETY: `item_from_index` ensures that `item` is always a valid pointer and can be 475 // dereferenced. The compiler also further validates the expression on whether `field` 476 // is a member of `item` when expanded by the macro. 477 unsafe { 478 let ptr_field = ::core::ptr::addr_of!((*item) $($field)*); 479 $crate::dma::CoherentAllocation::field_read(&$dma, ptr_field) 480 } 481 }}; 482 ($dma:ident [ $idx:expr ] $($field:tt)* ) => { 483 $crate::dma_read!($dma, $idx, $($field)*); 484 }; 485 ($($dma:ident).* [ $idx:expr ] $($field:tt)* ) => { 486 $crate::dma_read!($($dma).*, $idx, $($field)*); 487 }; 488 } 489 490 /// Writes to a field of an item from an allocated region of structs. 491 /// 492 /// # Examples 493 /// 494 /// ``` 495 /// use kernel::device::Device; 496 /// use kernel::dma::{attrs::*, CoherentAllocation}; 497 /// 498 /// struct MyStruct { member: u32, } 499 /// 500 /// // SAFETY: All bit patterns are acceptable values for `MyStruct`. 501 /// unsafe impl kernel::transmute::FromBytes for MyStruct{}; 502 /// // SAFETY: Instances of `MyStruct` have no uninitialized portions. 503 /// unsafe impl kernel::transmute::AsBytes for MyStruct{}; 504 /// 505 /// # fn test(alloc: &kernel::dma::CoherentAllocation<MyStruct>) -> Result { 506 /// kernel::dma_write!(alloc[2].member = 0xf); 507 /// kernel::dma_write!(alloc[1] = MyStruct { member: 0xf }); 508 /// # Ok::<(), Error>(()) } 509 /// ``` 510 #[macro_export] 511 macro_rules! dma_write { 512 ($dma:ident [ $idx:expr ] $($field:tt)*) => {{ 513 $crate::dma_write!($dma, $idx, $($field)*); 514 }}; 515 ($($dma:ident).* [ $idx:expr ] $($field:tt)* ) => {{ 516 $crate::dma_write!($($dma).*, $idx, $($field)*); 517 }}; 518 ($dma:expr, $idx: expr, = $val:expr) => { 519 let item = $crate::dma::CoherentAllocation::item_from_index(&$dma, $idx)?; 520 // SAFETY: `item_from_index` ensures that `item` is always a valid item. 521 unsafe { $crate::dma::CoherentAllocation::field_write(&$dma, item, $val) } 522 }; 523 ($dma:expr, $idx: expr, $(.$field:ident)* = $val:expr) => { 524 let item = $crate::dma::CoherentAllocation::item_from_index(&$dma, $idx)?; 525 // SAFETY: `item_from_index` ensures that `item` is always a valid pointer and can be 526 // dereferenced. The compiler also further validates the expression on whether `field` 527 // is a member of `item` when expanded by the macro. 528 unsafe { 529 let ptr_field = ::core::ptr::addr_of_mut!((*item) $(.$field)*); 530 $crate::dma::CoherentAllocation::field_write(&$dma, ptr_field, $val) 531 } 532 }; 533 } 534