1 // SPDX-License-Identifier: GPL-2.0 2 // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 4 //! The GIN CPU interrupt tree for one PCIe function. 5 //! 6 //! A [`GinVector`] names an interrupt source, a [`LeafIndex`] the leaf register that latches it, 7 //! a [`LeafMask`] a set of vectors within one leaf, and a [`Subtree`] one `TOP` bit. The types 8 //! keep the four from being confused with one another. 9 //! 10 //! Servicing a leaf requires reading its pending bits before clearing them. Only 11 //! [`Tree::read_pending`] produces a [`LeafPending`], and only a [`LeafPending`] clears a leaf, 12 //! so that the wrong order does not compile. This module does not serialize access to the tree. 13 //! 14 //! See `Documentation/gpu/nova/core/interrupts.rst`. 15 16 use kernel::{ 17 device::Bound, 18 io::{ 19 register::Array, 20 Io, // 21 }, 22 irq, 23 num::Bounded, 24 pci::{ 25 self, 26 IrqType, // 27 }, 28 prelude::*, // 29 }; 30 31 use crate::{ 32 driver::Bar0, 33 gpu::Chipset, 34 num, // 35 }; 36 37 use super::{ 38 hal::{ 39 cpu_interrupt_hal, 40 CpuInterruptHal, // 41 }, 42 regs::*, 43 MsiType, // 44 }; 45 46 /// Number of vectors one leaf register carries, one per bit. 47 const VECTORS_PER_LEAF: u32 = u32::BITS; 48 49 /// Number of leaves one subtree covers. 50 const LEAVES_PER_SUBTREE: u32 = 2; 51 52 /// Number of subtrees the widest supported tree implements. 53 const MAX_NUM_SUBTREES: u32 = 8; 54 55 /// Number of leaves the widest supported tree implements. 56 const MAX_NUM_LEAVES: u32 = MAX_NUM_SUBTREES * LEAVES_PER_SUBTREE; 57 58 /// Number of bits needed to address every vector in the widest supported tree. 59 const VECTOR_BITS: u32 = (MAX_NUM_LEAVES * VECTORS_PER_LEAF).ilog2(); 60 61 /// Width of the vector field in the leaf trigger register. 62 const TRIGGER_VECTOR_BITS: u32 = { 63 let range = NV_VIRTUAL_FUNCTION_PRIV_CPU_INTR_LEAF_TRIGGER::VECTOR_RANGE; 64 num::u8_as_u32(*range.end() - *range.start() + 1) 65 }; 66 67 /// Index of a leaf register within the widest supported tree. An 8-leaf tree implements only the 68 /// lower half of the range. 69 pub(super) type LeafIndex = Bounded<usize, { MAX_NUM_LEAVES.ilog2() }>; 70 71 /// Number of leaves a tree implements. 72 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 73 #[repr(u32)] 74 pub(super) enum LeafCount { 75 /// Turing through Ada. 76 Eight = 8, 77 78 /// Hopper and later. 79 Sixteen = 16, 80 } 81 82 impl LeafCount { 83 pub(super) const fn into_u32(self) -> u32 { 84 // CAST: `LeafCount` is `repr(u32)`, so the cast is lossless. 85 self as u32 86 } 87 88 pub(super) const fn into_raw(self) -> usize { 89 num::u32_as_usize(self.into_u32()) 90 } 91 92 /// Returns the number of subtrees a tree of this size implements. 93 pub(super) const fn subtree_count(self) -> u32 { 94 self.into_u32() / LEAVES_PER_SUBTREE 95 } 96 97 /// Returns the set of every subtree a tree of this size implements. 98 pub(super) const fn subtree_set(self) -> SubtreeSet { 99 SubtreeSet((1u32 << self.subtree_count()) - 1) 100 } 101 102 /// Returns the number of vectors a tree of this size carries. 103 pub(super) const fn vector_count(self) -> u32 { 104 self.into_u32() * VECTORS_PER_LEAF 105 } 106 107 /// Returns every leaf a tree of this size implements. 108 pub(super) fn iter(self) -> impl Iterator<Item = LeafIndex> { 109 (0..self.into_raw()).filter_map(LeafIndex::try_new) 110 } 111 } 112 113 // `VECTOR_BITS` and `LeafCount::Sixteen` are written separately. This assert keeps them in 114 // agreement about the widest supported tree. 115 static_assert!(1 << VECTOR_BITS == LeafCount::Sixteen.vector_count()); 116 117 /// Set of vectors within one leaf, one bit per vector. 118 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 119 pub(super) struct LeafMask(u32); 120 121 impl LeafMask { 122 /// Returns the mask with every vector set. 123 pub(super) const fn all() -> Self { 124 Self(u32::MAX) 125 } 126 127 pub(super) const fn from_raw(raw: u32) -> Self { 128 Self(raw) 129 } 130 131 pub(super) const fn into_raw(self) -> u32 { 132 self.0 133 } 134 135 pub(super) const fn is_empty(self) -> bool { 136 self.0 == 0 137 } 138 139 /// Returns whether every vector in `other` is also in this mask. 140 pub(super) const fn contains(self, other: Self) -> bool { 141 self.0 & other.0 == other.0 142 } 143 } 144 145 impl From<Bounded<u32, 32>> for LeafMask { 146 fn from(vectors: Bounded<u32, 32>) -> Self { 147 Self(vectors.get()) 148 } 149 } 150 151 impl From<LeafMask> for Bounded<u32, 32> { 152 fn from(vectors: LeafMask) -> Self { 153 vectors.0.into() 154 } 155 } 156 157 /// One subtree, held as the `TOP` bit that covers it. 158 /// 159 /// # Invariants 160 /// 161 /// Exactly one bit is set. 162 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 163 pub(super) struct Subtree(u32); 164 165 impl Subtree { 166 /// Returns the subtree at index `idx`. 167 const fn new(idx: u32) -> Self { 168 // INVARIANT: shifting `1` left leaves exactly one bit set. 169 Self(1 << idx) 170 } 171 172 /// Returns this subtree's index within the tree. 173 pub(super) const fn index(self) -> u32 { 174 self.0.trailing_zeros() 175 } 176 177 pub(super) const fn into_raw(self) -> u32 { 178 self.0 179 } 180 } 181 182 /// Set of subtrees, one bit per subtree, in the layout of the `TOP` registers. 183 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 184 pub(crate) struct SubtreeSet(u32); 185 186 impl SubtreeSet { 187 pub(super) const fn contains(self, subtree: Subtree) -> bool { 188 self.0 & subtree.into_raw() != 0 189 } 190 191 pub(super) const fn is_empty(self) -> bool { 192 self.0 == 0 193 } 194 195 pub(super) const fn intersection(self, other: Self) -> Self { 196 Self(self.0 & other.0) 197 } 198 199 /// Returns one more than the highest index in this set, or `0` for an empty set. An MSI-X 200 /// allocation that covers the set needs this many entries. 201 pub(super) const fn span(self) -> u32 { 202 u32::BITS - self.0.leading_zeros() 203 } 204 205 /// Returns the subtrees of this set, lowest index first. 206 pub(super) fn iter(self) -> impl Iterator<Item = Subtree> { 207 (0..u32::BITS) 208 .map(Subtree::new) 209 .filter(move |subtree| self.contains(*subtree)) 210 } 211 } 212 213 impl From<Subtree> for SubtreeSet { 214 fn from(subtree: Subtree) -> Self { 215 Self(subtree.into_raw()) 216 } 217 } 218 219 impl From<Bounded<u32, 32>> for SubtreeSet { 220 fn from(subtrees: Bounded<u32, 32>) -> Self { 221 Self(subtrees.get()) 222 } 223 } 224 225 impl From<SubtreeSet> for Bounded<u32, 32> { 226 fn from(subtrees: SubtreeSet) -> Self { 227 subtrees.0.into() 228 } 229 } 230 231 /// A GIN interrupt vector, bounded to the widest tree that any supported chipset implements. 232 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 233 pub(super) struct GinVector(Bounded<u32, VECTOR_BITS>); 234 235 impl GinVector { 236 /// Returns vector number `VECTOR`. 237 /// 238 /// Fails to compile if `VECTOR` is beyond the widest supported tree. 239 pub(super) const fn new<const VECTOR: u32>() -> Self { 240 Self(Bounded::<u32, VECTOR_BITS>::new::<VECTOR>()) 241 } 242 243 pub(super) const fn into_raw(self) -> u32 { 244 self.0.get() 245 } 246 247 /// Returns this vector's leaf. 248 pub(super) fn leaf_index(self) -> LeafIndex { 249 // CALC: `self.0 / VECTORS_PER_LEAF`. 250 self.0.shr::<{ VECTORS_PER_LEAF.ilog2() }, _>().cast() 251 } 252 253 /// Returns this vector's bit within its leaf. 254 pub(super) const fn leaf_mask(self) -> LeafMask { 255 LeafMask(1 << (self.0.get() % VECTORS_PER_LEAF)) 256 } 257 258 /// Returns this vector's subtree. 259 pub(super) const fn subtree(self) -> Subtree { 260 Subtree::new(self.0.get() / (VECTORS_PER_LEAF * LEAVES_PER_SUBTREE)) 261 } 262 263 /// Checks that a tree with `leaves` leaves implements this vector. 264 /// 265 /// # Errors 266 /// 267 /// `EINVAL` if it does not. 268 pub(super) const fn validate(self, leaves: LeafCount) -> Result { 269 if self.0.get() >= leaves.vector_count() { 270 Err(EINVAL) 271 } else { 272 Ok(()) 273 } 274 } 275 } 276 277 impl From<GinVector> for Bounded<u32, TRIGGER_VECTOR_BITS> { 278 fn from(vector: GinVector) -> Self { 279 vector.0.extend() 280 } 281 } 282 283 /// Disables `vectors` in `leaf`. 284 fn clear_leaf_enables(bar: Bar0<'_>, leaf: LeafIndex, vectors: LeafMask) { 285 bar.write( 286 Array::at(*leaf), 287 NV_VIRTUAL_FUNCTION_PRIV_CPU_INTR_LEAF_EN_CLEAR::zeroed().with_vectors(vectors), 288 ); 289 } 290 291 /// Disables the subtrees in `serviced` at `TOP`. 292 fn clear_top_enables(bar: Bar0<'_>, serviced: SubtreeSet) { 293 bar.write_reg(NV_VIRTUAL_FUNCTION_PRIV_CPU_INTR_TOP_EN_CLEAR::zeroed().with_subtrees(serviced)); 294 } 295 296 /// The CPU tree of one PCIe function, the subtrees that nova-core services, and the PCI vectors 297 /// that deliver them. 298 /// 299 /// A subtree may be enabled at `TOP` only once a handler is registered on the PCI vector that 300 /// delivers it. See "The serviced-subtree invariant" in 301 /// `Documentation/gpu/nova/core/interrupts.rst`. 302 pub(crate) struct Tree<'a> { 303 bar: Bar0<'a>, 304 hal: &'static dyn CpuInterruptHal, 305 serviced: SubtreeSet, 306 /// The interrupt type that Linux granted for `vectors`. 307 pub(super) msi_type: MsiType, 308 vectors: pci::IrqVectorRegistration<'a>, 309 } 310 311 impl<'a> Tree<'a> { 312 /// Creates the tree of `chipset` and allocates the PCI vectors for the subtrees in `serviced`. 313 /// 314 /// Requests MSI-X entries `0` through the highest subtree in `serviced`, since an allocation 315 /// cannot be sparse, and falls back to a single MSI message for the whole tree. 316 /// 317 /// # Errors 318 /// 319 /// `EINVAL` if `serviced` is empty or names a subtree that `chipset` does not implement. 320 /// Otherwise, when neither interrupt type could be allocated, the error from the MSI request. 321 pub(crate) fn new( 322 pdev: &'a pci::Device<Bound>, 323 bar: Bar0<'a>, 324 chipset: Chipset, 325 serviced: SubtreeSet, 326 ) -> Result<Self> { 327 let hal = cpu_interrupt_hal(chipset); 328 let num_leaves = hal.leaf_count(); 329 330 if serviced.is_empty() || serviced.intersection(num_leaves.subtree_set()) != serviced { 331 return Err(EINVAL); 332 } 333 334 let entries = serviced.span(); 335 let (vectors, msi_type) = pdev 336 .alloc_irq_vectors(entries, entries, IrqType::MsiX.into()) 337 .map(|vectors| (vectors, MsiType::MsiX)) 338 // Every subtree raises the one MSI message, so one MSI vector serves the whole tree. 339 // See "Delivery over PCI" in `Documentation/gpu/nova/core/interrupts.rst`. 340 .or_else(|_| { 341 pdev.alloc_irq_vectors(1, 1, IrqType::Msi.into()) 342 .map(|vectors| (vectors, MsiType::Msi)) 343 })?; 344 345 Ok(Self { 346 bar, 347 hal, 348 serviced, 349 msi_type, 350 vectors, 351 }) 352 } 353 354 /// Returns the [`irq::IrqRequest`] for the PCI vector that delivers `subtree`. 355 /// 356 /// # Errors 357 /// 358 /// `EINVAL` if `subtree` is not one of the serviced subtrees. 359 pub(super) fn request_for(&self, subtree: Subtree) -> Result<irq::IrqRequest<'_>> { 360 if !self.serviced.contains(subtree) { 361 return Err(EINVAL); 362 } 363 364 let entry = match self.msi_type { 365 MsiType::MsiX => num::u32_as_usize(subtree.index()), 366 MsiType::Msi => 0, 367 }; 368 369 self.vectors.index(entry).map(Into::into) 370 } 371 372 /// Rearms PCI interrupt delivery to the CPU after servicing `subtree`, the one subtree that 373 /// the calling handler serves. 374 /// 375 /// A handler must call this before returning, or it receives no further interrupts. 376 pub(super) fn rearm_pci_irq(&self, subtree: Subtree) { 377 self.hal 378 .rearm_pci_irq(self.bar, self.msi_type, self.serviced, subtree); 379 } 380 381 /// Enables the serviced subtrees at `TOP`. 382 /// 383 /// Each of them must have a handler registered on its PCI vector. 384 pub(super) fn enable_top(&self) { 385 self.bar.write_reg( 386 NV_VIRTUAL_FUNCTION_PRIV_CPU_INTR_TOP_EN_SET::zeroed().with_subtrees(self.serviced), 387 ); 388 } 389 390 /// Disables the serviced subtrees at `TOP`. 391 pub(super) fn disable_top(&self) { 392 clear_top_enables(self.bar, self.serviced); 393 } 394 395 /// Enables the serviced subtrees at `TOP` until the returned guard drops. 396 pub(crate) fn enable_top_guarded(&self) -> TopEnableGuard<'a> { 397 self.enable_top(); 398 399 TopEnableGuard { 400 bar: self.bar, 401 serviced: self.serviced, 402 } 403 } 404 405 /// Enables `vectors` in `leaf`. 406 pub(super) fn enable_leaf(&self, leaf: LeafIndex, vectors: LeafMask) { 407 self.bar.write( 408 Array::at(*leaf), 409 NV_VIRTUAL_FUNCTION_PRIV_CPU_INTR_LEAF_EN_SET::zeroed().with_vectors(vectors), 410 ); 411 } 412 413 /// Disables `vectors` in `leaf`. 414 pub(super) fn disable_leaf(&self, leaf: LeafIndex, vectors: LeafMask) { 415 clear_leaf_enables(self.bar, leaf, vectors); 416 } 417 418 /// Enables `vectors` in `leaf` until the returned guard drops. 419 pub(super) fn enable_leaf_guarded( 420 &self, 421 leaf: LeafIndex, 422 vectors: LeafMask, 423 ) -> LeafEnableGuard<'a> { 424 self.enable_leaf(leaf, vectors); 425 426 LeafEnableGuard { 427 bar: self.bar, 428 leaf, 429 vectors, 430 } 431 } 432 433 /// Reads the pending bits of `leaf`, and returns the handle that clears them. 434 pub(super) fn read_pending(&self, leaf: LeafIndex) -> LeafPending<'a> { 435 let pending = self 436 .bar 437 .read(NV_VIRTUAL_FUNCTION_PRIV_CPU_INTR_LEAF::at(*leaf)) 438 .vectors(); 439 440 LeafPending { 441 bar: self.bar, 442 leaf, 443 pending, 444 } 445 } 446 447 /// Disables every vector in every implemented leaf, including the subtrees that nova-core does 448 /// not service. Call this only during probe. 449 pub(super) fn disable_all_leaves(&self) { 450 for leaf in self.hal.leaf_count().iter() { 451 self.disable_leaf(leaf, LeafMask::all()); 452 } 453 } 454 455 /// Clears every pending bit in every implemented leaf, including the subtrees that nova-core 456 /// does not service. 457 /// 458 /// The serviced subtrees are disabled at `TOP` on return. Call this only during probe, with no 459 /// interrupt handler registered. 460 pub(super) fn drain(&self) { 461 self.disable_top(); 462 463 // A vector that latched while disabled does not show in `TOP`, so read every leaf rather 464 // than descending from it. 465 for leaf in self.hal.leaf_count().iter() { 466 self.read_pending(leaf).clear(); 467 } 468 } 469 470 /// Disables every vector, clears every pending bit, and rearms PCI interrupt delivery. 471 /// 472 /// The serviced subtrees are disabled at `TOP` on return. Call this only during probe, with 473 /// no interrupt handler registered. 474 pub(super) fn reset(&self) { 475 self.disable_all_leaves(); 476 self.drain(); 477 for subtree in self.serviced.iter() { 478 self.rearm_pci_irq(subtree); 479 } 480 481 // A `TOP`-enable rearm leaves the subtrees that it cycles enabled, and a subtree may be 482 // enabled only once a handler is registered on its vector. 483 self.disable_top(); 484 } 485 } 486 487 /// The pending bits of one leaf as they were read, and the handle that clears them. 488 pub(super) struct LeafPending<'a> { 489 bar: Bar0<'a>, 490 leaf: LeafIndex, 491 pending: LeafMask, 492 } 493 494 impl LeafPending<'_> { 495 pub(super) fn vectors(&self) -> LeafMask { 496 self.pending 497 } 498 499 /// Clears the vectors that were pending at the read. A vector that latched since stays pending. 500 pub(super) fn clear(&self) { 501 self.clear_vectors(self.pending); 502 } 503 504 /// Clears `vectors` and no other bit. 505 pub(super) fn clear_vectors(&self, vectors: LeafMask) { 506 if !vectors.is_empty() { 507 self.bar.write( 508 Array::at(*self.leaf), 509 NV_VIRTUAL_FUNCTION_PRIV_CPU_INTR_LEAF::zeroed().with_vectors(vectors), 510 ); 511 } 512 } 513 } 514 515 /// Disables a set of vectors in one leaf when dropped. 516 pub(super) struct LeafEnableGuard<'a> { 517 bar: Bar0<'a>, 518 leaf: LeafIndex, 519 vectors: LeafMask, 520 } 521 522 impl Drop for LeafEnableGuard<'_> { 523 fn drop(&mut self) { 524 clear_leaf_enables(self.bar, self.leaf, self.vectors); 525 } 526 } 527 528 /// Disables the serviced subtrees at `TOP` when dropped. 529 pub(crate) struct TopEnableGuard<'a> { 530 bar: Bar0<'a>, 531 serviced: SubtreeSet, 532 } 533 534 impl Drop for TopEnableGuard<'_> { 535 fn drop(&mut self) { 536 clear_top_enables(self.bar, self.serviced); 537 } 538 } 539