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