[PATCH v7 11/24] iommu/amd: Compose MSI messages for NMIs in non-IR format
From: Ricardo Neri
Date: Wed Mar 01 2023 - 18:38:36 EST
If NMIPass is enabled in a Device Table Entry, the IOMMU lets NMI interrupt
messages pass through unmapped. The contents of the MSI message, not an
IRTE, determine how and where the NMI is delivered.
The IOMMU driver owns the MSI message of the NMI. Compose it using the non-
interrupt-remapping format. Let descendant irqchips write the composed
message.
Cc: Andi Kleen <ak@xxxxxxxxxxxxxxx>
Cc: "Ravi V. Shankar" <ravi.v.shankar@xxxxxxxxx>
Cc: Joerg Roedel <joro@xxxxxxxxxx>
Cc: Suravee Suthikulpanit <suravee.suthikulpanit@xxxxxxx>
Cc: Stephane Eranian <eranian@xxxxxxxxxx>
Cc: iommu@xxxxxxxxxxxxxxxxxxxxxxxxxx
Cc: linuxppc-dev@xxxxxxxxxxxxxxxx
Signed-off-by: Ricardo Neri <ricardo.neri-calderon@xxxxxxxxxxxxxxx>
---
Changes since v6:
* Reworded changelog to remove acronyms. (Thomas)
* Removed confusing comment regarding interrupt vector cleanup after
changing the affinity of an interrupt. (Thomas)
Changes since v5:
* Introduced this patch
Changes since v4:
* N/A
Changes since v3:
* N/A
Changes since v2:
* N/A
Changes since v1:
* N/A
---
drivers/iommu/amd/iommu.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 9bf71e7335f5..c6b0c365bf33 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -3254,7 +3254,16 @@ static void irq_remapping_prepare_irte(struct amd_ir_data *data,
case X86_IRQ_ALLOC_TYPE_HPET:
case X86_IRQ_ALLOC_TYPE_PCI_MSI:
case X86_IRQ_ALLOC_TYPE_PCI_MSIX:
- fill_msi_msg(&data->msi_entry, irte_info->index);
+ if (irq_cfg->delivery_mode == APIC_DELIVERY_MODE_NMI)
+ /*
+ * The IOMMU lets NMIs pass through unmapped. Thus, the
+ * MSI message, not the IRTE, determines the interrupt
+ * configuration. Since we own the MSI message,
+ * compose it.
+ */
+ __irq_msi_compose_msg(irq_cfg, &data->msi_entry, true);
+ else
+ fill_msi_msg(&data->msi_entry, irte_info->index);
break;
default:
@@ -3643,6 +3652,15 @@ static int amd_ir_set_affinity(struct irq_data *data,
*/
send_cleanup_vector(cfg);
+ /*
+ * When the delivery mode of an interrupt is NMI, the IOMMU lets the NMI
+ * interrupt messages pass through unmapped. Changes in the destination
+ * must be reflected in the MSI message, not the IRTE. Descendant
+ * irqchips must set the affinity and write the MSI message.
+ */
+ if (cfg->delivery_mode == APIC_DELIVERY_MODE_NMI)
+ return IRQ_SET_MASK_OK;
+
return IRQ_SET_MASK_OK_DONE;
}
--
2.25.1