Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b1b7add9 authored by Suravee Suthikulpanit's avatar Suravee Suthikulpanit Committed by Greg Kroah-Hartman
Browse files

iommu/amd: Check feature support bit before accessing MSI capability registers



[ Upstream commit 813071438e83d338ba5cfe98b3b26c890dc0a6c0 ]

The IOMMU MMIO access to MSI capability registers is available only if
the EFR[MsiCapMmioSup] is set. Current implementation assumes this bit
is set if the EFR[XtSup] is set, which might not be the case.

Fix by checking the EFR[MsiCapMmioSup] before accessing the MSI address
low/high and MSI data registers via the MMIO.

Fixes: 66929812 ('iommu/amd: Add support for X2APIC IOMMU interrupts')
Signed-off-by: default avatarSuravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 0c09d9dc
Loading
Loading
Loading
Loading
+12 −5
Original line number Diff line number Diff line
@@ -147,7 +147,7 @@ bool amd_iommu_dump;
bool amd_iommu_irq_remap __read_mostly;

int amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_VAPIC;
static int amd_iommu_xt_mode = IRQ_REMAP_X2APIC_MODE;
static int amd_iommu_xt_mode = IRQ_REMAP_XAPIC_MODE;

static bool amd_iommu_detected;
static bool __initdata amd_iommu_disabled;
@@ -1534,8 +1534,15 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
			iommu->mmio_phys_end = MMIO_CNTR_CONF_OFFSET;
		if (((h->efr_reg & (0x1 << IOMMU_EFR_GASUP_SHIFT)) == 0))
			amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY;
		if (((h->efr_reg & (0x1 << IOMMU_EFR_XTSUP_SHIFT)) == 0))
			amd_iommu_xt_mode = IRQ_REMAP_XAPIC_MODE;
		/*
		 * Note: Since iommu_update_intcapxt() leverages
		 * the IOMMU MMIO access to MSI capability block registers
		 * for MSI address lo/hi/data, we need to check both
		 * EFR[XtSup] and EFR[MsiCapMmioSup] for x2APIC support.
		 */
		if ((h->efr_reg & BIT(IOMMU_EFR_XTSUP_SHIFT)) &&
		    (h->efr_reg & BIT(IOMMU_EFR_MSICAPMMIOSUP_SHIFT)))
			amd_iommu_xt_mode = IRQ_REMAP_X2APIC_MODE;
		break;
	default:
		return -EINVAL;
@@ -1996,8 +2003,8 @@ static int iommu_init_intcapxt(struct amd_iommu *iommu)
	struct irq_affinity_notify *notify = &iommu->intcapxt_notify;

	/**
	 * IntCapXT requires XTSup=1, which can be inferred
	 * amd_iommu_xt_mode.
	 * IntCapXT requires XTSup=1 and MsiCapMmioSup=1,
	 * which can be inferred from amd_iommu_xt_mode.
	 */
	if (amd_iommu_xt_mode != IRQ_REMAP_X2APIC_MODE)
		return 0;
+1 −0
Original line number Diff line number Diff line
@@ -383,6 +383,7 @@
/* IOMMU Extended Feature Register (EFR) */
#define IOMMU_EFR_XTSUP_SHIFT	2
#define IOMMU_EFR_GASUP_SHIFT	7
#define IOMMU_EFR_MSICAPMMIOSUP_SHIFT	46

#define MAX_DOMAIN_ID 65536