diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c index 82e4af8f09bb..263670d36fed 100644 --- a/drivers/iommu/amd/init.c +++ b/drivers/iommu/amd/init.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -1966,10 +1965,16 @@ static int iommu_setup_msi(struct amd_iommu *iommu) return 0; } -#define XT_INT_DEST_MODE(x) (((x) & 0x1ULL) << 2) -#define XT_INT_DEST_LO(x) (((x) & 0xFFFFFFULL) << 8) -#define XT_INT_VEC(x) (((x) & 0xFFULL) << 32) -#define XT_INT_DEST_HI(x) ((((x) >> 24) & 0xFFULL) << 56) +union intcapxt { + u64 capxt; + u64 reserved_0 : 2, + dest_mode_logical : 1, + reserved_1 : 5, + destid_0_23 : 24, + vector : 8, + reserved_2 : 16, + destid_24_31 : 8; +} __attribute__ ((packed)); /* * Setup the IntCapXT registers with interrupt routing information @@ -1978,28 +1983,29 @@ static int iommu_setup_msi(struct amd_iommu *iommu) */ static void iommu_update_intcapxt(struct amd_iommu *iommu) { - u64 val; - u32 addr_lo = readl(iommu->mmio_base + MMIO_MSI_ADDR_LO_OFFSET); - u32 addr_hi = readl(iommu->mmio_base + MMIO_MSI_ADDR_HI_OFFSET); - u32 data = readl(iommu->mmio_base + MMIO_MSI_DATA_OFFSET); - bool dm = (addr_lo >> MSI_ADDR_DEST_MODE_SHIFT) & 0x1; - u32 dest = ((addr_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xFF); + struct msi_msg msg; + union intcapxt xt; + u32 destid; - if (x2apic_enabled()) - dest |= MSI_ADDR_EXT_DEST_ID(addr_hi); + msg.address_lo = readl(iommu->mmio_base + MMIO_MSI_ADDR_LO_OFFSET); + msg.address_hi = readl(iommu->mmio_base + MMIO_MSI_ADDR_HI_OFFSET); + msg.data = readl(iommu->mmio_base + MMIO_MSI_DATA_OFFSET); - val = XT_INT_VEC(data & 0xFF) | - XT_INT_DEST_MODE(dm) | - XT_INT_DEST_LO(dest) | - XT_INT_DEST_HI(dest); + destid = x86_msi_msg_get_destid(&msg, x2apic_enabled()); + + xt.capxt = 0ULL; + xt.dest_mode_logical = msg.arch_data.dest_mode_logical; + xt.vector = msg.arch_data.vector; + xt.destid_0_23 = destid & GENMASK(23, 0); + xt.destid_24_31 = destid >> 24; /** * Current IOMMU implemtation uses the same IRQ for all * 3 IOMMU interrupts. */ - writeq(val, iommu->mmio_base + MMIO_INTCAPXT_EVT_OFFSET); - writeq(val, iommu->mmio_base + MMIO_INTCAPXT_PPR_OFFSET); - writeq(val, iommu->mmio_base + MMIO_INTCAPXT_GALOG_OFFSET); + writeq(xt.capxt, iommu->mmio_base + MMIO_INTCAPXT_EVT_OFFSET); + writeq(xt.capxt, iommu->mmio_base + MMIO_INTCAPXT_PPR_OFFSET); + writeq(xt.capxt, iommu->mmio_base + MMIO_INTCAPXT_GALOG_OFFSET); } static void _irq_notifier_notify(struct irq_affinity_notify *notify, diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index d7f0c8908602..473de0920b64 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include @@ -3656,13 +3655,20 @@ struct irq_remap_ops amd_iommu_irq_ops = { .get_irq_domain = get_irq_domain, }; +static void fill_msi_msg(struct msi_msg *msg, u32 index) +{ + msg->data = index; + msg->address_lo = 0; + msg->arch_addr_lo.base_address = X86_MSI_BASE_ADDRESS_LOW; + msg->address_hi = X86_MSI_BASE_ADDRESS_HIGH; +} + static void irq_remapping_prepare_irte(struct amd_ir_data *data, struct irq_cfg *irq_cfg, struct irq_alloc_info *info, int devid, int index, int sub_handle) { struct irq_2_irte *irte_info = &data->irq_2_irte; - struct msi_msg *msg = &data->msi_entry; struct IO_APIC_route_entry *entry; struct amd_iommu *iommu = amd_iommu_rlookup_table[devid]; @@ -3693,9 +3699,7 @@ 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: - msg->address_hi = MSI_ADDR_BASE_HI; - msg->address_lo = MSI_ADDR_BASE_LO; - msg->data = irte_info->index; + fill_msi_msg(&data->msi_entry, irte_info->index); break; default: