From: John Hubbard <jhubbard@nvidia.com>
To: Danilo Krummrich <dakr@kernel.org>,
Alexandre Courbot <acourbot@nvidia.com>
Cc: "Timur Tabi" <ttabi@nvidia.com>,
"Alistair Popple" <apopple@nvidia.com>,
"Eliot Courtney" <ecourtney@nvidia.com>,
"Zhi Wang" <zhiw@nvidia.com>, "David Airlie" <airlied@gmail.com>,
"Simona Vetter" <simona@ffwll.ch>,
"Bjorn Helgaas" <bhelgaas@google.com>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Alex Gaynor" <alex.gaynor@gmail.com>,
"Boqun Feng" <boqun.feng@gmail.com>,
"Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <lossin@kernel.org>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
nova-gpu@lists.linux.dev, LKML <linux-kernel@vger.kernel.org>,
"John Hubbard" <jhubbard@nvidia.com>,
"Will Pierce" <wpierce@nvidia.com>
Subject: [PATCH v3 05/14] gpu: nova-core: add the per-architecture GIN CPU interrupt HAL
Date: Wed, 2 Sep 2026 20:15:04 -0700 [thread overview]
Message-ID: <20260903031514.1515905-6-jhubbard@nvidia.com> (raw)
In-Reply-To: <20260903031514.1515905-1-jhubbard@nvidia.com>
GIN, the GPU Interrupt and Notification unit, is the GPU's interrupt
controller. Each PCIe function has its own tree, whose leaf count
depends on the GPU family.
Message-signaled delivery stops after each edge until the CPU rearms it,
and the rearm write differs by family and interrupt type:
* Pre-Hopper MSI writes an EOI through the BAR0 PCI configuration space
mirror.
* MSI for Hopper and later cycles the TOP enable bits of every serviced
subtree.
* MSI-X on any family cycles the bits of the handler's own subtree.
Provide the leaf count and the rearm method through a per-architecture
interrupt HAL, and name the interrupt type with nova-core's own two
variants rather than the PCI core's three, which include the
level-triggered INTx that nova-core never allocates.
Assisted-by: Cursor:claude-opus-5
Reviewed-by: Will Pierce <wpierce@nvidia.com>
Signed-off-by: John Hubbard <jhubbard@nvidia.com>
---
drivers/gpu/nova-core/irq.rs | 14 ++++
drivers/gpu/nova-core/irq/hal.rs | 106 +++++++++++++++++++++++++
drivers/gpu/nova-core/irq/hal/gh100.rs | 29 +++++++
drivers/gpu/nova-core/irq/hal/tu102.rs | 28 +++++++
4 files changed, 177 insertions(+)
create mode 100644 drivers/gpu/nova-core/irq/hal.rs
create mode 100644 drivers/gpu/nova-core/irq/hal/gh100.rs
create mode 100644 drivers/gpu/nova-core/irq/hal/tu102.rs
diff --git a/drivers/gpu/nova-core/irq.rs b/drivers/gpu/nova-core/irq.rs
index 3066ceeb850c..d21dee1b89a0 100644
--- a/drivers/gpu/nova-core/irq.rs
+++ b/drivers/gpu/nova-core/irq.rs
@@ -8,5 +8,19 @@
//!
//! See `Documentation/gpu/nova/core/interrupts.rst`.
+mod hal;
mod interrupt_tree;
mod regs;
+
+/// The message-signaled interrupt type a vector allocation obtained.
+///
+/// nova-core allocates MSI-X or MSI and nothing else, so the level-triggered INTx that
+/// [`kernel::pci::IrqType`] also names has no representation here.
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub(crate) enum MsiType {
+ /// One message, raised by every subtree of the tree.
+ Msi,
+
+ /// One table entry per subtree.
+ MsiX,
+}
diff --git a/drivers/gpu/nova-core/irq/hal.rs b/drivers/gpu/nova-core/irq/hal.rs
new file mode 100644
index 000000000000..1ea677e37e56
--- /dev/null
+++ b/drivers/gpu/nova-core/irq/hal.rs
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: GPL-2.0
+// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+//! Per-architecture properties of the GIN CPU interrupt tree.
+
+mod gh100;
+mod tu102;
+
+use kernel::{
+ io::Io,
+ prelude::*, //
+};
+
+use crate::{
+ driver::Bar0,
+ gpu::{
+ Architecture,
+ Chipset, //
+ }, //
+};
+
+use super::{
+ interrupt_tree::{
+ LeafCount,
+ Subtree,
+ SubtreeSet, //
+ },
+ regs,
+ MsiType, //
+};
+
+/// Register write that restores PCI interrupt delivery to the CPU.
+///
+/// A message-signaled interrupt is delivered once per edge, and the PCI side delivers no further
+/// interrupt until the CPU rearms it. A handler that returns without this write receives no more
+/// interrupts.
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub(super) enum PciIrqRearmMethod {
+ /// The MSI end-of-interrupt register in the BAR0 PCI configuration-space mirror, used by
+ /// MSI on pre-Hopper GPUs.
+ ConfigMirrorEoi,
+
+ /// A clear then a set of the `TOP` enable bits of every serviced subtree, which produces the
+ /// edge that delivers the next interrupt.
+ ///
+ /// MSI has a single message that every subtree raises, so the rearm covers the whole serviced
+ /// set.
+ TopEnableCycleServiced,
+
+ /// The same enable cycle, restricted to the one subtree the handler serves.
+ ///
+ /// MSI-X gives each subtree its own table entry and its own handler.
+ TopEnableCycleSubtree,
+}
+
+impl PciIrqRearmMethod {
+ /// Performs this method's register write.
+ ///
+ /// `serviced` holds every subtree the driver services, and `subtree` is the one subtree the
+ /// calling handler serves. Each method uses whichever of the two its interrupt type delivers
+ /// on, so both are required.
+ pub(super) fn rearm(self, bar: Bar0<'_>, serviced: SubtreeSet, subtree: Subtree) {
+ let subtrees = match self {
+ // The written value is ignored, so any write rearms delivery.
+ Self::ConfigMirrorEoi => {
+ bar.write(regs::NV_XVE_CYA_2, 0u32.into());
+ return;
+ }
+ Self::TopEnableCycleServiced => serviced,
+ Self::TopEnableCycleSubtree => SubtreeSet::from(subtree),
+ };
+
+ bar.write_reg(
+ regs::NV_VIRTUAL_FUNCTION_PRIV_CPU_INTR_TOP_EN_CLEAR::zeroed().with_subtrees(subtrees),
+ );
+ bar.write_reg(
+ regs::NV_VIRTUAL_FUNCTION_PRIV_CPU_INTR_TOP_EN_SET::zeroed().with_subtrees(subtrees),
+ );
+ }
+}
+
+/// Per-architecture properties of the GIN CPU interrupt tree.
+///
+/// The tree size and the method that rearms PCI interrupt delivery differ by family.
+///
+/// See `Documentation/gpu/nova/core/interrupts.rst`.
+pub(super) trait CpuInterruptHal {
+ /// Returns the number of leaves the CPU tree implements.
+ ///
+ /// [`LeafCount::subtree_set`] gives the subtrees behind them, and
+ /// [`LeafCount::vector_count`] the vectors they carry.
+ fn leaf_count(&self) -> LeafCount;
+
+ /// Returns the method that rearms PCI interrupt delivery for `msi_type`.
+ fn pci_irq_rearm_method(&self, msi_type: MsiType) -> PciIrqRearmMethod;
+}
+
+/// Returns the [`CpuInterruptHal`] for `chipset`.
+pub(super) fn cpu_interrupt_hal(chipset: Chipset) -> &'static dyn CpuInterruptHal {
+ match chipset.arch() {
+ Architecture::Turing | Architecture::Ampere | Architecture::Ada => tu102::TU102_HAL,
+ Architecture::Hopper | Architecture::BlackwellGB10x | Architecture::BlackwellGB20x => {
+ gh100::GH100_HAL
+ }
+ }
+}
diff --git a/drivers/gpu/nova-core/irq/hal/gh100.rs b/drivers/gpu/nova-core/irq/hal/gh100.rs
new file mode 100644
index 000000000000..10744ac3ab77
--- /dev/null
+++ b/drivers/gpu/nova-core/irq/hal/gh100.rs
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0
+// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+use super::{
+ CpuInterruptHal,
+ LeafCount,
+ MsiType,
+ PciIrqRearmMethod, //
+};
+
+/// GIN parameters for Hopper and Blackwell, which implement a 16-leaf CPU tree. Only 12 leaves
+/// carry sources.
+struct Gh100;
+
+impl CpuInterruptHal for Gh100 {
+ fn leaf_count(&self) -> LeafCount {
+ LeafCount::Sixteen
+ }
+
+ fn pci_irq_rearm_method(&self, msi_type: MsiType) -> PciIrqRearmMethod {
+ match msi_type {
+ MsiType::Msi => PciIrqRearmMethod::TopEnableCycleServiced,
+ MsiType::MsiX => PciIrqRearmMethod::TopEnableCycleSubtree,
+ }
+ }
+}
+
+const GH100: Gh100 = Gh100;
+pub(super) const GH100_HAL: &dyn CpuInterruptHal = &GH100;
diff --git a/drivers/gpu/nova-core/irq/hal/tu102.rs b/drivers/gpu/nova-core/irq/hal/tu102.rs
new file mode 100644
index 000000000000..fb8ded59c792
--- /dev/null
+++ b/drivers/gpu/nova-core/irq/hal/tu102.rs
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0
+// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+use super::{
+ CpuInterruptHal,
+ LeafCount,
+ MsiType,
+ PciIrqRearmMethod, //
+};
+
+/// GIN parameters for Turing, Ampere, and Ada, which implement an 8-leaf CPU tree.
+struct Tu102;
+
+impl CpuInterruptHal for Tu102 {
+ fn leaf_count(&self) -> LeafCount {
+ LeafCount::Eight
+ }
+
+ fn pci_irq_rearm_method(&self, msi_type: MsiType) -> PciIrqRearmMethod {
+ match msi_type {
+ MsiType::Msi => PciIrqRearmMethod::ConfigMirrorEoi,
+ MsiType::MsiX => PciIrqRearmMethod::TopEnableCycleSubtree,
+ }
+ }
+}
+
+const TU102: Tu102 = Tu102;
+pub(super) const TU102_HAL: &dyn CpuInterruptHal = &TU102;
--
2.55.0
next prev parent reply other threads:[~2026-09-03 3:15 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-03 3:14 [PATCH v3 00/14] nova-core: GPU interrupt support and GSP event delivery John Hubbard
2026-09-03 3:15 ` [PATCH v3 01/14] rust: pci: declare IrqType and IrqTypes with impl_flags John Hubbard
2026-09-03 3:15 ` [PATCH v3 02/14] rust: sync: completion: add wait_for_completion_timeout() John Hubbard
2026-09-03 3:15 ` [PATCH v3 03/14] gpu: nova-core: add the GIN vector and subtree newtypes John Hubbard
2026-09-03 3:15 ` [PATCH v3 04/14] gpu: nova-core: add the GIN CPU interrupt tree and MSI EOI registers John Hubbard
2026-09-03 3:15 ` John Hubbard [this message]
2026-09-03 3:15 ` [PATCH v3 06/14] gpu: nova-core: add the GIN interrupt tree and allocate its vectors John Hubbard
2026-09-03 3:15 ` [PATCH v3 07/14] gpu: nova-core: add an interrupt delivery self-test John Hubbard
2026-09-03 3:29 ` sashiko-bot
2026-09-03 3:57 ` John Hubbard
2026-09-03 3:15 ` [PATCH v3 08/14] gpu: nova-core: log GSP events instead of discarding them John Hubbard
2026-09-03 3:15 ` [PATCH v3 09/14] gpu: nova-core: recover the GSP receive path from corrupt framing John Hubbard
2026-09-04 10:53 ` Alexandre Courbot
2026-09-04 11:17 ` Gary Guo
2026-09-04 13:45 ` Alexandre Courbot
2026-09-03 3:15 ` [PATCH v3 10/14] gpu: nova-core: bound a GSP wait by a single deadline John Hubbard
2026-09-04 11:13 ` Alexandre Courbot
2026-09-04 11:26 ` Gary Guo
2026-09-04 13:32 ` Alexandre Courbot
2026-09-04 13:41 ` Gary Guo
2026-09-03 3:15 ` [PATCH v3 11/14] gpu: nova-core: add the falcon interrupt status and routing registers John Hubbard
2026-09-03 3:15 ` [PATCH v3 12/14] gpu: nova-core: drive GSP events with the SWGEN0 interrupt John Hubbard
2026-09-03 3:28 ` sashiko-bot
2026-09-03 3:55 ` John Hubbard
2026-09-04 1:53 ` John Hubbard
2026-09-03 3:15 ` [PATCH v3 13/14] gpu: nova-core: add KUnit tests for the interrupt tree and HALs John Hubbard
2026-09-03 3:15 ` [PATCH v3 14/14] gpu: nova-core: document the GIN interrupt controller and GSP events John Hubbard
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260903031514.1515905-6-jhubbard@nvidia.com \
--to=jhubbard@nvidia.com \
--cc=a.hindborg@kernel.org \
--cc=acourbot@nvidia.com \
--cc=airlied@gmail.com \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=apopple@nvidia.com \
--cc=bhelgaas@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=dakr@kernel.org \
--cc=ecourtney@nvidia.com \
--cc=gary@garyguo.net \
--cc=linux-kernel@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=nova-gpu@lists.linux.dev \
--cc=ojeda@kernel.org \
--cc=simona@ffwll.ch \
--cc=tmgross@umich.edu \
--cc=ttabi@nvidia.com \
--cc=wpierce@nvidia.com \
--cc=zhiw@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox