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, 9 debugfs, 10 device::{ 11 self, 12 Bound, 13 Core, // 14 }, 15 error::to_result, 16 fs::file, 17 prelude::*, 18 ptr::KnownSize, 19 sync::aref::ARef, 20 transmute::{ 21 AsBytes, 22 FromBytes, // 23 }, // 24 uaccess::UserSliceWriter, 25 }; 26 use core::{ 27 ops::{ 28 Deref, 29 DerefMut, // 30 }, 31 ptr::NonNull, // 32 }; 33 34 /// DMA address type. 35 /// 36 /// Represents a bus address used for Direct Memory Access (DMA) operations. 37 /// 38 /// This is an alias of the kernel's `dma_addr_t`, which may be `u32` or `u64` depending on 39 /// `CONFIG_ARCH_DMA_ADDR_T_64BIT`. 40 /// 41 /// Note that this may be `u64` even on 32-bit architectures. 42 pub type DmaAddress = bindings::dma_addr_t; 43 44 /// Trait to be implemented by DMA capable bus devices. 45 /// 46 /// The [`dma::Device`](Device) trait should be implemented by bus specific device representations, 47 /// where the underlying bus is DMA capable, such as: 48 #[cfg_attr(CONFIG_PCI, doc = "* [`pci::Device`](kernel::pci::Device)")] 49 /// * [`platform::Device`](::kernel::platform::Device) 50 pub trait Device: AsRef<device::Device<Core>> { 51 /// Set up the device's DMA streaming addressing capabilities. 52 /// 53 /// This method is usually called once from `probe()` as soon as the device capabilities are 54 /// known. 55 /// 56 /// # Safety 57 /// 58 /// This method must not be called concurrently with any DMA allocation or mapping primitives, 59 /// such as [`Coherent::zeroed`]. 60 unsafe fn dma_set_mask(&self, mask: DmaMask) -> Result { 61 // SAFETY: 62 // - By the type invariant of `device::Device`, `self.as_ref().as_raw()` is valid. 63 // - The safety requirement of this function guarantees that there are no concurrent calls 64 // to DMA allocation and mapping primitives using this mask. 65 to_result(unsafe { bindings::dma_set_mask(self.as_ref().as_raw(), mask.value()) }) 66 } 67 68 /// Set up the device's DMA coherent addressing capabilities. 69 /// 70 /// This method is usually called once from `probe()` as soon as the device capabilities are 71 /// known. 72 /// 73 /// # Safety 74 /// 75 /// This method must not be called concurrently with any DMA allocation or mapping primitives, 76 /// such as [`Coherent::zeroed`]. 77 unsafe fn dma_set_coherent_mask(&self, mask: DmaMask) -> Result { 78 // SAFETY: 79 // - By the type invariant of `device::Device`, `self.as_ref().as_raw()` is valid. 80 // - The safety requirement of this function guarantees that there are no concurrent calls 81 // to DMA allocation and mapping primitives using this mask. 82 to_result(unsafe { bindings::dma_set_coherent_mask(self.as_ref().as_raw(), mask.value()) }) 83 } 84 85 /// Set up the device's DMA addressing capabilities. 86 /// 87 /// This is a combination of [`Device::dma_set_mask`] and [`Device::dma_set_coherent_mask`]. 88 /// 89 /// This method is usually called once from `probe()` as soon as the device capabilities are 90 /// known. 91 /// 92 /// # Safety 93 /// 94 /// This method must not be called concurrently with any DMA allocation or mapping primitives, 95 /// such as [`Coherent::zeroed`]. 96 unsafe fn dma_set_mask_and_coherent(&self, mask: DmaMask) -> Result { 97 // SAFETY: 98 // - By the type invariant of `device::Device`, `self.as_ref().as_raw()` is valid. 99 // - The safety requirement of this function guarantees that there are no concurrent calls 100 // to DMA allocation and mapping primitives using this mask. 101 to_result(unsafe { 102 bindings::dma_set_mask_and_coherent(self.as_ref().as_raw(), mask.value()) 103 }) 104 } 105 106 /// Set the maximum size of a single DMA segment the device may request. 107 /// 108 /// This method is usually called once from `probe()` as soon as the device capabilities are 109 /// known. 110 /// 111 /// # Safety 112 /// 113 /// This method must not be called concurrently with any DMA allocation or mapping primitives, 114 /// such as [`Coherent::zeroed`]. 115 unsafe fn dma_set_max_seg_size(&self, size: u32) { 116 // SAFETY: 117 // - By the type invariant of `device::Device`, `self.as_ref().as_raw()` is valid. 118 // - The safety requirement of this function guarantees that there are no concurrent calls 119 // to DMA allocation and mapping primitives using this parameter. 120 unsafe { bindings::dma_set_max_seg_size(self.as_ref().as_raw(), size) } 121 } 122 } 123 124 /// A DMA mask that holds a bitmask with the lowest `n` bits set. 125 /// 126 /// Use [`DmaMask::new`] or [`DmaMask::try_new`] to construct a value. Values 127 /// are guaranteed to never exceed the bit width of `u64`. 128 /// 129 /// This is the Rust equivalent of the C macro `DMA_BIT_MASK()`. 130 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 131 pub struct DmaMask(u64); 132 133 impl DmaMask { 134 /// Constructs a `DmaMask` with the lowest `n` bits set to `1`. 135 /// 136 /// For `n <= 64`, sets exactly the lowest `n` bits. 137 /// For `n > 64`, results in a build error. 138 /// 139 /// # Examples 140 /// 141 /// ``` 142 /// use kernel::dma::DmaMask; 143 /// 144 /// let mask0 = DmaMask::new::<0>(); 145 /// assert_eq!(mask0.value(), 0); 146 /// 147 /// let mask1 = DmaMask::new::<1>(); 148 /// assert_eq!(mask1.value(), 0b1); 149 /// 150 /// let mask64 = DmaMask::new::<64>(); 151 /// assert_eq!(mask64.value(), u64::MAX); 152 /// 153 /// // Build failure. 154 /// // let mask_overflow = DmaMask::new::<100>(); 155 /// ``` 156 #[inline] 157 pub const fn new<const N: u32>() -> Self { 158 let Ok(mask) = Self::try_new(N) else { 159 build_error!("Invalid DMA Mask."); 160 }; 161 162 mask 163 } 164 165 /// Constructs a `DmaMask` with the lowest `n` bits set to `1`. 166 /// 167 /// For `n <= 64`, sets exactly the lowest `n` bits. 168 /// For `n > 64`, returns [`EINVAL`]. 169 /// 170 /// # Examples 171 /// 172 /// ``` 173 /// use kernel::dma::DmaMask; 174 /// 175 /// let mask0 = DmaMask::try_new(0)?; 176 /// assert_eq!(mask0.value(), 0); 177 /// 178 /// let mask1 = DmaMask::try_new(1)?; 179 /// assert_eq!(mask1.value(), 0b1); 180 /// 181 /// let mask64 = DmaMask::try_new(64)?; 182 /// assert_eq!(mask64.value(), u64::MAX); 183 /// 184 /// let mask_overflow = DmaMask::try_new(100); 185 /// assert!(mask_overflow.is_err()); 186 /// # Ok::<(), Error>(()) 187 /// ``` 188 #[inline] 189 pub const fn try_new(n: u32) -> Result<Self> { 190 Ok(Self(match n { 191 0 => 0, 192 1..=64 => u64::MAX >> (64 - n), 193 _ => return Err(EINVAL), 194 })) 195 } 196 197 /// Returns the underlying `u64` bitmask value. 198 #[inline] 199 pub const fn value(&self) -> u64 { 200 self.0 201 } 202 } 203 204 /// Possible attributes associated with a DMA mapping. 205 /// 206 /// They can be combined with the operators `|`, `&`, and `!`. 207 /// 208 /// Values can be used from the [`attrs`] module. 209 /// 210 /// # Examples 211 /// 212 /// ``` 213 /// # use kernel::device::{Bound, Device}; 214 /// use kernel::dma::{attrs::*, Coherent}; 215 /// 216 /// # fn test(dev: &Device<Bound>) -> Result { 217 /// let attribs = DMA_ATTR_FORCE_CONTIGUOUS | DMA_ATTR_NO_WARN; 218 /// let c: Coherent<[u64]> = 219 /// Coherent::zeroed_slice_with_attrs(dev, 4, GFP_KERNEL, attribs)?; 220 /// # Ok::<(), Error>(()) } 221 /// ``` 222 #[derive(Clone, Copy, PartialEq)] 223 #[repr(transparent)] 224 pub struct Attrs(u32); 225 226 impl Attrs { 227 /// Get the raw representation of this attribute. 228 pub(crate) fn as_raw(self) -> crate::ffi::c_ulong { 229 self.0 as crate::ffi::c_ulong 230 } 231 232 /// Check whether `flags` is contained in `self`. 233 pub fn contains(self, flags: Attrs) -> bool { 234 (self & flags) == flags 235 } 236 } 237 238 impl core::ops::BitOr for Attrs { 239 type Output = Self; 240 fn bitor(self, rhs: Self) -> Self::Output { 241 Self(self.0 | rhs.0) 242 } 243 } 244 245 impl core::ops::BitAnd for Attrs { 246 type Output = Self; 247 fn bitand(self, rhs: Self) -> Self::Output { 248 Self(self.0 & rhs.0) 249 } 250 } 251 252 impl core::ops::Not for Attrs { 253 type Output = Self; 254 fn not(self) -> Self::Output { 255 Self(!self.0) 256 } 257 } 258 259 /// DMA mapping attributes. 260 pub mod attrs { 261 use super::Attrs; 262 263 /// Specifies that reads and writes to the mapping may be weakly ordered, that is that reads 264 /// and writes may pass each other. 265 pub const DMA_ATTR_WEAK_ORDERING: Attrs = Attrs(bindings::DMA_ATTR_WEAK_ORDERING); 266 267 /// Specifies that writes to the mapping may be buffered to improve performance. 268 pub const DMA_ATTR_WRITE_COMBINE: Attrs = Attrs(bindings::DMA_ATTR_WRITE_COMBINE); 269 270 /// Lets the platform to avoid creating a kernel virtual mapping for the allocated buffer. 271 pub const DMA_ATTR_NO_KERNEL_MAPPING: Attrs = Attrs(bindings::DMA_ATTR_NO_KERNEL_MAPPING); 272 273 /// Allows platform code to skip synchronization of the CPU cache for the given buffer assuming 274 /// that it has been already transferred to 'device' domain. 275 pub const DMA_ATTR_SKIP_CPU_SYNC: Attrs = Attrs(bindings::DMA_ATTR_SKIP_CPU_SYNC); 276 277 /// Forces contiguous allocation of the buffer in physical memory. 278 pub const DMA_ATTR_FORCE_CONTIGUOUS: Attrs = Attrs(bindings::DMA_ATTR_FORCE_CONTIGUOUS); 279 280 /// Hints DMA-mapping subsystem that it's probably not worth the time to try 281 /// to allocate memory to in a way that gives better TLB efficiency. 282 pub const DMA_ATTR_ALLOC_SINGLE_PAGES: Attrs = Attrs(bindings::DMA_ATTR_ALLOC_SINGLE_PAGES); 283 284 /// This tells the DMA-mapping subsystem to suppress allocation failure reports (similarly to 285 /// `__GFP_NOWARN`). 286 pub const DMA_ATTR_NO_WARN: Attrs = Attrs(bindings::DMA_ATTR_NO_WARN); 287 288 /// Indicates that the buffer is fully accessible at an elevated privilege level (and 289 /// ideally inaccessible or at least read-only at lesser-privileged levels). 290 pub const DMA_ATTR_PRIVILEGED: Attrs = Attrs(bindings::DMA_ATTR_PRIVILEGED); 291 292 /// Indicates that the buffer is MMIO memory. 293 pub const DMA_ATTR_MMIO: Attrs = Attrs(bindings::DMA_ATTR_MMIO); 294 } 295 296 /// DMA data direction. 297 /// 298 /// Corresponds to the C [`enum dma_data_direction`]. 299 /// 300 /// [`enum dma_data_direction`]: srctree/include/linux/dma-direction.h 301 #[derive(Copy, Clone, PartialEq, Eq, Debug)] 302 #[repr(u32)] 303 pub enum DataDirection { 304 /// The DMA mapping is for bidirectional data transfer. 305 /// 306 /// This is used when the buffer can be both read from and written to by the device. 307 /// The cache for the corresponding memory region is both flushed and invalidated. 308 Bidirectional = Self::const_cast(bindings::dma_data_direction_DMA_BIDIRECTIONAL), 309 310 /// The DMA mapping is for data transfer from memory to the device (write). 311 /// 312 /// The CPU has prepared data in the buffer, and the device will read it. 313 /// The cache for the corresponding memory region is flushed before device access. 314 ToDevice = Self::const_cast(bindings::dma_data_direction_DMA_TO_DEVICE), 315 316 /// The DMA mapping is for data transfer from the device to memory (read). 317 /// 318 /// The device will write data into the buffer for the CPU to read. 319 /// The cache for the corresponding memory region is invalidated before CPU access. 320 FromDevice = Self::const_cast(bindings::dma_data_direction_DMA_FROM_DEVICE), 321 322 /// The DMA mapping is not for data transfer. 323 /// 324 /// This is primarily for debugging purposes. With this direction, the DMA mapping API 325 /// will not perform any cache coherency operations. 326 None = Self::const_cast(bindings::dma_data_direction_DMA_NONE), 327 } 328 329 impl DataDirection { 330 /// Casts the bindgen-generated enum type to a `u32` at compile time. 331 /// 332 /// This function will cause a compile-time error if the underlying value of the 333 /// C enum is out of bounds for `u32`. 334 const fn const_cast(val: bindings::dma_data_direction) -> u32 { 335 // CAST: The C standard allows compilers to choose different integer types for enums. 336 // To safely check the value, we cast it to a wide signed integer type (`i128`) 337 // which can hold any standard C integer enum type without truncation. 338 let wide_val = val as i128; 339 340 // Check if the value is outside the valid range for the target type `u32`. 341 // CAST: `u32::MAX` is cast to `i128` to match the type of `wide_val` for the comparison. 342 if wide_val < 0 || wide_val > u32::MAX as i128 { 343 // Trigger a compile-time error in a const context. 344 build_error!("C enum value is out of bounds for the target type `u32`."); 345 } 346 347 // CAST: This cast is valid because the check above guarantees that `wide_val` 348 // is within the representable range of `u32`. 349 wide_val as u32 350 } 351 } 352 353 impl From<DataDirection> for bindings::dma_data_direction { 354 /// Returns the raw representation of [`enum dma_data_direction`]. 355 fn from(direction: DataDirection) -> Self { 356 // CAST: `direction as u32` gets the underlying representation of our `#[repr(u32)]` enum. 357 // The subsequent cast to `Self` (the bindgen type) assumes the C enum is compatible 358 // with the enum variants of `DataDirection`, which is a valid assumption given our 359 // compile-time checks. 360 direction as u32 as Self 361 } 362 } 363 364 /// CPU-owned DMA allocation that can be converted into a device-shared [`Coherent`] object. 365 /// 366 /// Unlike [`Coherent`], a [`CoherentBox`] is guaranteed to be fully owned by the CPU -- its DMA 367 /// address is not exposed and it cannot be accessed by a device. This means it can safely be used 368 /// like a normal boxed allocation (e.g. direct reads, writes, and mutable slices are all safe). 369 /// 370 /// A typical use is to allocate a [`CoherentBox`], populate it with normal CPU access, and then 371 /// convert it into a [`Coherent`] object to share it with the device. 372 /// 373 /// # Examples 374 /// 375 /// `CoherentBox<T>`: 376 /// 377 /// ``` 378 /// # use kernel::device::{ 379 /// # Bound, 380 /// # Device, 381 /// # }; 382 /// use kernel::dma::{attrs::*, 383 /// Coherent, 384 /// CoherentBox, 385 /// }; 386 /// 387 /// # fn test(dev: &Device<Bound>) -> Result { 388 /// let mut dmem: CoherentBox<u64> = CoherentBox::zeroed(dev, GFP_KERNEL)?; 389 /// *dmem = 42; 390 /// let dmem: Coherent<u64> = dmem.into(); 391 /// # Ok::<(), Error>(()) } 392 /// ``` 393 /// 394 /// `CoherentBox<[T]>`: 395 /// 396 /// 397 /// ``` 398 /// # use kernel::device::{ 399 /// # Bound, 400 /// # Device, 401 /// # }; 402 /// use kernel::dma::{attrs::*, 403 /// Coherent, 404 /// CoherentBox, 405 /// }; 406 /// 407 /// # fn test(dev: &Device<Bound>) -> Result { 408 /// let mut dmem: CoherentBox<[u64]> = CoherentBox::zeroed_slice(dev, 4, GFP_KERNEL)?; 409 /// dmem.fill(42); 410 /// let dmem: Coherent<[u64]> = dmem.into(); 411 /// # Ok::<(), Error>(()) } 412 /// ``` 413 pub struct CoherentBox<T: KnownSize + ?Sized>(Coherent<T>); 414 415 impl<T: AsBytes + FromBytes> CoherentBox<[T]> { 416 /// [`CoherentBox`] variant of [`Coherent::zeroed_slice_with_attrs`]. 417 #[inline] 418 pub fn zeroed_slice_with_attrs( 419 dev: &device::Device<Bound>, 420 count: usize, 421 gfp_flags: kernel::alloc::Flags, 422 dma_attrs: Attrs, 423 ) -> Result<Self> { 424 Coherent::zeroed_slice_with_attrs(dev, count, gfp_flags, dma_attrs).map(Self) 425 } 426 427 /// Same as [CoherentBox::zeroed_slice_with_attrs], but with `dma::Attrs(0)`. 428 #[inline] 429 pub fn zeroed_slice( 430 dev: &device::Device<Bound>, 431 count: usize, 432 gfp_flags: kernel::alloc::Flags, 433 ) -> Result<Self> { 434 Self::zeroed_slice_with_attrs(dev, count, gfp_flags, Attrs(0)) 435 } 436 437 /// Initializes the element at `i` using the given initializer. 438 /// 439 /// Returns `EINVAL` if `i` is out of bounds. 440 pub fn init_at<E>(&mut self, i: usize, init: impl Init<T, E>) -> Result 441 where 442 Error: From<E>, 443 { 444 if i >= self.0.len() { 445 return Err(EINVAL); 446 } 447 448 let ptr = &raw mut self[i]; 449 450 // SAFETY: 451 // - `ptr` is valid, properly aligned, and within this allocation. 452 // - `T: AsBytes + FromBytes` guarantees all bit patterns are valid, so partial writes on 453 // error cannot leave the element in an invalid state. 454 // - The DMA address has not been exposed yet, so there is no concurrent device access. 455 unsafe { init.__init(ptr)? }; 456 457 Ok(()) 458 } 459 } 460 461 impl<T: AsBytes + FromBytes> CoherentBox<T> { 462 /// Same as [`CoherentBox::zeroed_slice_with_attrs`], but for a single element. 463 #[inline] 464 pub fn zeroed_with_attrs( 465 dev: &device::Device<Bound>, 466 gfp_flags: kernel::alloc::Flags, 467 dma_attrs: Attrs, 468 ) -> Result<Self> { 469 Coherent::zeroed_with_attrs(dev, gfp_flags, dma_attrs).map(Self) 470 } 471 472 /// Same as [`CoherentBox::zeroed_slice`], but for a single element. 473 #[inline] 474 pub fn zeroed(dev: &device::Device<Bound>, gfp_flags: kernel::alloc::Flags) -> Result<Self> { 475 Self::zeroed_with_attrs(dev, gfp_flags, Attrs(0)) 476 } 477 } 478 479 impl<T: KnownSize + ?Sized> Deref for CoherentBox<T> { 480 type Target = T; 481 482 #[inline] 483 fn deref(&self) -> &Self::Target { 484 // SAFETY: 485 // - We have not exposed the DMA address yet, so there can't be any concurrent access by a 486 // device. 487 // - We have exclusive access to `self.0`. 488 unsafe { self.0.as_ref() } 489 } 490 } 491 492 impl<T: AsBytes + FromBytes + KnownSize + ?Sized> DerefMut for CoherentBox<T> { 493 #[inline] 494 fn deref_mut(&mut self) -> &mut Self::Target { 495 // SAFETY: 496 // - We have not exposed the DMA address yet, so there can't be any concurrent access by a 497 // device. 498 // - We have exclusive access to `self.0`. 499 unsafe { self.0.as_mut() } 500 } 501 } 502 503 impl<T: AsBytes + FromBytes + KnownSize + ?Sized> From<CoherentBox<T>> for Coherent<T> { 504 #[inline] 505 fn from(value: CoherentBox<T>) -> Self { 506 value.0 507 } 508 } 509 510 /// An abstraction of the `dma_alloc_coherent` API. 511 /// 512 /// This is an abstraction around the `dma_alloc_coherent` API which is used to allocate and map 513 /// large coherent DMA regions. 514 /// 515 /// A [`Coherent`] instance contains a pointer to the allocated region (in the 516 /// processor's virtual address space) and the device address which can be given to the device 517 /// as the DMA address base of the region. The region is released once [`Coherent`] 518 /// is dropped. 519 /// 520 /// # Invariants 521 /// 522 /// - For the lifetime of an instance of [`Coherent`], the `cpu_addr` is a valid pointer 523 /// to an allocated region of coherent memory and `dma_handle` is the DMA address base of the 524 /// region. 525 /// - The size in bytes of the allocation is equal to size information via pointer. 526 // TODO 527 // 528 // DMA allocations potentially carry device resources (e.g.IOMMU mappings), hence for soundness 529 // reasons DMA allocation would need to be embedded in a `Devres` container, in order to ensure 530 // that device resources can never survive device unbind. 531 // 532 // However, it is neither desirable nor necessary to protect the allocated memory of the DMA 533 // allocation from surviving device unbind; it would require RCU read side critical sections to 534 // access the memory, which may require subsequent unnecessary copies. 535 // 536 // Hence, find a way to revoke the device resources of a `Coherent`, but not the 537 // entire `Coherent` including the allocated memory itself. 538 pub struct Coherent<T: KnownSize + ?Sized> { 539 dev: ARef<device::Device>, 540 dma_handle: DmaAddress, 541 cpu_addr: NonNull<T>, 542 dma_attrs: Attrs, 543 } 544 545 impl<T: KnownSize + ?Sized> Coherent<T> { 546 /// Returns the size in bytes of this allocation. 547 #[inline] 548 pub fn size(&self) -> usize { 549 T::size(self.cpu_addr.as_ptr()) 550 } 551 552 /// Returns the raw pointer to the allocated region in the CPU's virtual address space. 553 #[inline] 554 pub fn as_ptr(&self) -> *const T { 555 self.cpu_addr.as_ptr() 556 } 557 558 /// Returns the raw pointer to the allocated region in the CPU's virtual address space as 559 /// a mutable pointer. 560 #[inline] 561 pub fn as_mut_ptr(&self) -> *mut T { 562 self.cpu_addr.as_ptr() 563 } 564 565 /// Returns a DMA handle which may be given to the device as the DMA address base of 566 /// the region. 567 #[inline] 568 pub fn dma_handle(&self) -> DmaAddress { 569 self.dma_handle 570 } 571 572 /// Returns a reference to the data in the region. 573 /// 574 /// # Safety 575 /// 576 /// * Callers must ensure that the device does not read/write to/from memory while the returned 577 /// slice is live. 578 /// * Callers must ensure that this call does not race with a write to the same region while 579 /// the returned slice is live. 580 #[inline] 581 pub unsafe fn as_ref(&self) -> &T { 582 // SAFETY: per safety requirement. 583 unsafe { &*self.as_ptr() } 584 } 585 586 /// Returns a mutable reference to the data in the region. 587 /// 588 /// # Safety 589 /// 590 /// * Callers must ensure that the device does not read/write to/from memory while the returned 591 /// slice is live. 592 /// * Callers must ensure that this call does not race with a read or write to the same region 593 /// while the returned slice is live. 594 #[expect(clippy::mut_from_ref, reason = "unsafe to use API")] 595 #[inline] 596 pub unsafe fn as_mut(&self) -> &mut T { 597 // SAFETY: per safety requirement. 598 unsafe { &mut *self.as_mut_ptr() } 599 } 600 601 /// Reads the value of `field` and ensures that its type is [`FromBytes`]. 602 /// 603 /// # Safety 604 /// 605 /// This must be called from the [`dma_read`] macro which ensures that the `field` pointer is 606 /// validated beforehand. 607 /// 608 /// Public but hidden since it should only be used from [`dma_read`] macro. 609 #[doc(hidden)] 610 pub unsafe fn field_read<F: FromBytes>(&self, field: *const F) -> F { 611 // SAFETY: 612 // - By the safety requirements field is valid. 613 // - Using read_volatile() here is not sound as per the usual rules, the usage here is 614 // a special exception with the following notes in place. When dealing with a potential 615 // race from a hardware or code outside kernel (e.g. user-space program), we need that 616 // read on a valid memory is not UB. Currently read_volatile() is used for this, and the 617 // rationale behind is that it should generate the same code as READ_ONCE() which the 618 // kernel already relies on to avoid UB on data races. Note that the usage of 619 // read_volatile() is limited to this particular case, it cannot be used to prevent 620 // the UB caused by racing between two kernel functions nor do they provide atomicity. 621 unsafe { field.read_volatile() } 622 } 623 624 /// Writes a value to `field` and ensures that its type is [`AsBytes`]. 625 /// 626 /// # Safety 627 /// 628 /// This must be called from the [`dma_write`] macro which ensures that the `field` pointer is 629 /// validated beforehand. 630 /// 631 /// Public but hidden since it should only be used from [`dma_write`] macro. 632 #[doc(hidden)] 633 pub unsafe fn field_write<F: AsBytes>(&self, field: *mut F, val: F) { 634 // SAFETY: 635 // - By the safety requirements field is valid. 636 // - Using write_volatile() here is not sound as per the usual rules, the usage here is 637 // a special exception with the following notes in place. When dealing with a potential 638 // race from a hardware or code outside kernel (e.g. user-space program), we need that 639 // write on a valid memory is not UB. Currently write_volatile() is used for this, and the 640 // rationale behind is that it should generate the same code as WRITE_ONCE() which the 641 // kernel already relies on to avoid UB on data races. Note that the usage of 642 // write_volatile() is limited to this particular case, it cannot be used to prevent 643 // the UB caused by racing between two kernel functions nor do they provide atomicity. 644 unsafe { field.write_volatile(val) } 645 } 646 } 647 648 impl<T: AsBytes + FromBytes> Coherent<T> { 649 /// Allocates a region of `T` of coherent memory. 650 fn alloc_with_attrs( 651 dev: &device::Device<Bound>, 652 gfp_flags: kernel::alloc::Flags, 653 dma_attrs: Attrs, 654 ) -> Result<Self> { 655 const { 656 assert!( 657 core::mem::size_of::<T>() > 0, 658 "It doesn't make sense for the allocated type to be a ZST" 659 ); 660 } 661 662 let mut dma_handle = 0; 663 // SAFETY: Device pointer is guaranteed as valid by the type invariant on `Device`. 664 let addr = unsafe { 665 bindings::dma_alloc_attrs( 666 dev.as_raw(), 667 core::mem::size_of::<T>(), 668 &mut dma_handle, 669 gfp_flags.as_raw(), 670 dma_attrs.as_raw(), 671 ) 672 }; 673 let cpu_addr = NonNull::new(addr.cast()).ok_or(ENOMEM)?; 674 // INVARIANT: 675 // - We just successfully allocated a coherent region which is adequately sized for `T`, 676 // hence the cpu address is valid. 677 // - We also hold a refcounted reference to the device. 678 Ok(Self { 679 dev: dev.into(), 680 dma_handle, 681 cpu_addr, 682 dma_attrs, 683 }) 684 } 685 686 /// Allocates a region of type `T` of coherent memory. 687 /// 688 /// # Examples 689 /// 690 /// ``` 691 /// # use kernel::device::{ 692 /// # Bound, 693 /// # Device, 694 /// # }; 695 /// use kernel::dma::{ 696 /// attrs::*, 697 /// Coherent, 698 /// }; 699 /// 700 /// # fn test(dev: &Device<Bound>) -> Result { 701 /// let c: Coherent<[u64; 4]> = 702 /// Coherent::zeroed_with_attrs(dev, GFP_KERNEL, DMA_ATTR_NO_WARN)?; 703 /// # Ok::<(), Error>(()) } 704 /// ``` 705 #[inline] 706 pub fn zeroed_with_attrs( 707 dev: &device::Device<Bound>, 708 gfp_flags: kernel::alloc::Flags, 709 dma_attrs: Attrs, 710 ) -> Result<Self> { 711 Self::alloc_with_attrs(dev, gfp_flags | __GFP_ZERO, dma_attrs) 712 } 713 714 /// Performs the same functionality as [`Coherent::zeroed_with_attrs`], except the 715 /// `dma_attrs` is 0 by default. 716 #[inline] 717 pub fn zeroed(dev: &device::Device<Bound>, gfp_flags: kernel::alloc::Flags) -> Result<Self> { 718 Self::zeroed_with_attrs(dev, gfp_flags, Attrs(0)) 719 } 720 721 /// Same as [`Coherent::zeroed_with_attrs`], but instead of a zero-initialization the memory is 722 /// initialized with `init`. 723 pub fn init_with_attrs<E>( 724 dev: &device::Device<Bound>, 725 gfp_flags: kernel::alloc::Flags, 726 dma_attrs: Attrs, 727 init: impl Init<T, E>, 728 ) -> Result<Self> 729 where 730 Error: From<E>, 731 { 732 let dmem = Self::alloc_with_attrs(dev, gfp_flags, dma_attrs)?; 733 let ptr = dmem.as_mut_ptr(); 734 735 // SAFETY: 736 // - `ptr` is valid, properly aligned, and points to exclusively owned memory. 737 // - If `__init` fails, `self` is dropped, which safely frees the underlying `Coherent`'s 738 // DMA memory. `T: AsBytes + FromBytes` ensures there are no complex `Drop` requirements 739 // we are bypassing. 740 unsafe { init.__init(ptr)? }; 741 742 Ok(dmem) 743 } 744 745 /// Same as [`Coherent::zeroed`], but instead of a zero-initialization the memory is initialized 746 /// with `init`. 747 #[inline] 748 pub fn init<E>( 749 dev: &device::Device<Bound>, 750 gfp_flags: kernel::alloc::Flags, 751 init: impl Init<T, E>, 752 ) -> Result<Self> 753 where 754 Error: From<E>, 755 { 756 Self::init_with_attrs(dev, gfp_flags, Attrs(0), init) 757 } 758 759 /// Allocates a region of `[T; len]` of coherent memory. 760 fn alloc_slice_with_attrs( 761 dev: &device::Device<Bound>, 762 len: usize, 763 gfp_flags: kernel::alloc::Flags, 764 dma_attrs: Attrs, 765 ) -> Result<Coherent<[T]>> { 766 const { 767 assert!( 768 core::mem::size_of::<T>() > 0, 769 "It doesn't make sense for the allocated type to be a ZST" 770 ); 771 } 772 773 // `dma_alloc_attrs` cannot handle zero-length allocation, bail early. 774 if len == 0 { 775 Err(EINVAL)?; 776 } 777 778 let size = core::mem::size_of::<T>().checked_mul(len).ok_or(ENOMEM)?; 779 let mut dma_handle = 0; 780 // SAFETY: Device pointer is guaranteed as valid by the type invariant on `Device`. 781 let addr = unsafe { 782 bindings::dma_alloc_attrs( 783 dev.as_raw(), 784 size, 785 &mut dma_handle, 786 gfp_flags.as_raw(), 787 dma_attrs.as_raw(), 788 ) 789 }; 790 let cpu_addr = NonNull::slice_from_raw_parts(NonNull::new(addr.cast()).ok_or(ENOMEM)?, len); 791 // INVARIANT: 792 // - We just successfully allocated a coherent region which is adequately sized for 793 // `[T; len]`, hence the cpu address is valid. 794 // - We also hold a refcounted reference to the device. 795 Ok(Coherent { 796 dev: dev.into(), 797 dma_handle, 798 cpu_addr, 799 dma_attrs, 800 }) 801 } 802 803 /// Allocates a zeroed region of type `T` of coherent memory. 804 /// 805 /// Unlike `Coherent::<[T; N]>::zeroed_with_attrs`, `Coherent::<T>::zeroed_slices` support 806 /// a runtime length. 807 /// 808 /// # Examples 809 /// 810 /// ``` 811 /// # use kernel::device::{ 812 /// # Bound, 813 /// # Device, 814 /// # }; 815 /// use kernel::dma::{ 816 /// attrs::*, 817 /// Coherent, 818 /// }; 819 /// 820 /// # fn test(dev: &Device<Bound>) -> Result { 821 /// let c: Coherent<[u64]> = 822 /// Coherent::zeroed_slice_with_attrs(dev, 4, GFP_KERNEL, DMA_ATTR_NO_WARN)?; 823 /// # Ok::<(), Error>(()) } 824 /// ``` 825 #[inline] 826 pub fn zeroed_slice_with_attrs( 827 dev: &device::Device<Bound>, 828 len: usize, 829 gfp_flags: kernel::alloc::Flags, 830 dma_attrs: Attrs, 831 ) -> Result<Coherent<[T]>> { 832 Coherent::alloc_slice_with_attrs(dev, len, gfp_flags | __GFP_ZERO, dma_attrs) 833 } 834 835 /// Performs the same functionality as [`Coherent::zeroed_slice_with_attrs`], except the 836 /// `dma_attrs` is 0 by default. 837 #[inline] 838 pub fn zeroed_slice( 839 dev: &device::Device<Bound>, 840 len: usize, 841 gfp_flags: kernel::alloc::Flags, 842 ) -> Result<Coherent<[T]>> { 843 Self::zeroed_slice_with_attrs(dev, len, gfp_flags, Attrs(0)) 844 } 845 } 846 847 impl<T> Coherent<[T]> { 848 /// Returns the number of elements `T` in this allocation. 849 /// 850 /// Note that this is not the size of the allocation in bytes, which is provided by 851 /// [`Self::size`]. 852 #[inline] 853 #[expect(clippy::len_without_is_empty, reason = "Coherent slice is never empty")] 854 pub fn len(&self) -> usize { 855 self.cpu_addr.len() 856 } 857 } 858 859 /// Note that the device configured to do DMA must be halted before this object is dropped. 860 impl<T: KnownSize + ?Sized> Drop for Coherent<T> { 861 fn drop(&mut self) { 862 let size = T::size(self.cpu_addr.as_ptr()); 863 // SAFETY: Device pointer is guaranteed as valid by the type invariant on `Device`. 864 // The cpu address, and the dma handle are valid due to the type invariants on 865 // `Coherent`. 866 unsafe { 867 bindings::dma_free_attrs( 868 self.dev.as_raw(), 869 size, 870 self.cpu_addr.as_ptr().cast(), 871 self.dma_handle, 872 self.dma_attrs.as_raw(), 873 ) 874 } 875 } 876 } 877 878 // SAFETY: It is safe to send a `Coherent` to another thread if `T` 879 // can be sent to another thread. 880 unsafe impl<T: KnownSize + Send + ?Sized> Send for Coherent<T> {} 881 882 // SAFETY: Sharing `&Coherent` across threads is safe if `T` is `Sync`, because all 883 // methods that access the buffer contents (`field_read`, `field_write`, `as_slice`, 884 // `as_slice_mut`) are `unsafe`, and callers are responsible for ensuring no data races occur. 885 // The safe methods only return metadata or raw pointers whose use requires `unsafe`. 886 unsafe impl<T: KnownSize + ?Sized + AsBytes + FromBytes + Sync> Sync for Coherent<T> {} 887 888 impl debugfs::BinaryWriter for Coherent<[u8]> { 889 fn write_to_slice( 890 &self, 891 writer: &mut UserSliceWriter, 892 offset: &mut file::Offset, 893 ) -> Result<usize> { 894 if offset.is_negative() { 895 return Err(EINVAL); 896 } 897 898 // If the offset is too large for a usize (e.g. on 32-bit platforms), 899 // then consider that as past EOF and just return 0 bytes. 900 let Ok(offset_val) = usize::try_from(*offset) else { 901 return Ok(0); 902 }; 903 904 let count = self.size().saturating_sub(offset_val).min(writer.len()); 905 906 writer.write_dma(self, offset_val, count)?; 907 908 *offset += count as i64; 909 Ok(count) 910 } 911 } 912 913 /// Reads a field of an item from an allocated region of structs. 914 /// 915 /// The syntax is of the form `kernel::dma_read!(dma, proj)` where `dma` is an expression evaluating 916 /// to a [`Coherent`] and `proj` is a [projection specification](kernel::ptr::project!). 917 /// 918 /// # Examples 919 /// 920 /// ``` 921 /// use kernel::device::Device; 922 /// use kernel::dma::{attrs::*, Coherent}; 923 /// 924 /// struct MyStruct { field: u32, } 925 /// 926 /// // SAFETY: All bit patterns are acceptable values for `MyStruct`. 927 /// unsafe impl kernel::transmute::FromBytes for MyStruct{}; 928 /// // SAFETY: Instances of `MyStruct` have no uninitialized portions. 929 /// unsafe impl kernel::transmute::AsBytes for MyStruct{}; 930 /// 931 /// # fn test(alloc: &kernel::dma::Coherent<[MyStruct]>) -> Result { 932 /// let whole = kernel::dma_read!(alloc, [2]?); 933 /// let field = kernel::dma_read!(alloc, [1]?.field); 934 /// # Ok::<(), Error>(()) } 935 /// ``` 936 #[macro_export] 937 macro_rules! dma_read { 938 ($dma:expr, $($proj:tt)*) => {{ 939 let dma = &$dma; 940 let ptr = $crate::ptr::project!( 941 $crate::dma::Coherent::as_ptr(dma), $($proj)* 942 ); 943 // SAFETY: The pointer created by the projection is within the DMA region. 944 unsafe { $crate::dma::Coherent::field_read(dma, ptr) } 945 }}; 946 } 947 948 /// Writes to a field of an item from an allocated region of structs. 949 /// 950 /// The syntax is of the form `kernel::dma_write!(dma, proj, val)` where `dma` is an expression 951 /// evaluating to a [`Coherent`], `proj` is a 952 /// [projection specification](kernel::ptr::project!), and `val` is the value to be written to the 953 /// projected location. 954 /// 955 /// # Examples 956 /// 957 /// ``` 958 /// use kernel::device::Device; 959 /// use kernel::dma::{attrs::*, Coherent}; 960 /// 961 /// struct MyStruct { member: u32, } 962 /// 963 /// // SAFETY: All bit patterns are acceptable values for `MyStruct`. 964 /// unsafe impl kernel::transmute::FromBytes for MyStruct{}; 965 /// // SAFETY: Instances of `MyStruct` have no uninitialized portions. 966 /// unsafe impl kernel::transmute::AsBytes for MyStruct{}; 967 /// 968 /// # fn test(alloc: &kernel::dma::Coherent<[MyStruct]>) -> Result { 969 /// kernel::dma_write!(alloc, [2]?.member, 0xf); 970 /// kernel::dma_write!(alloc, [1]?, MyStruct { member: 0xf }); 971 /// # Ok::<(), Error>(()) } 972 /// ``` 973 #[macro_export] 974 macro_rules! dma_write { 975 (@parse [$dma:expr] [$($proj:tt)*] [, $val:expr]) => {{ 976 let dma = &$dma; 977 let ptr = $crate::ptr::project!( 978 mut $crate::dma::Coherent::as_mut_ptr(dma), $($proj)* 979 ); 980 let val = $val; 981 // SAFETY: The pointer created by the projection is within the DMA region. 982 unsafe { $crate::dma::Coherent::field_write(dma, ptr, val) } 983 }}; 984 (@parse [$dma:expr] [$($proj:tt)*] [.$field:tt $($rest:tt)*]) => { 985 $crate::dma_write!(@parse [$dma] [$($proj)* .$field] [$($rest)*]) 986 }; 987 (@parse [$dma:expr] [$($proj:tt)*] [[$index:expr]? $($rest:tt)*]) => { 988 $crate::dma_write!(@parse [$dma] [$($proj)* [$index]?] [$($rest)*]) 989 }; 990 (@parse [$dma:expr] [$($proj:tt)*] [[$index:expr] $($rest:tt)*]) => { 991 $crate::dma_write!(@parse [$dma] [$($proj)* [$index]] [$($rest)*]) 992 }; 993 ($dma:expr, $($rest:tt)*) => { 994 $crate::dma_write!(@parse [$dma] [] [$($rest)*]) 995 }; 996 } 997