diff options
Diffstat (limited to '0020-x86-ioapic-RTE-modifications-must-use-ioapic_write_e.patch')
-rw-r--r-- | 0020-x86-ioapic-RTE-modifications-must-use-ioapic_write_e.patch | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/0020-x86-ioapic-RTE-modifications-must-use-ioapic_write_e.patch b/0020-x86-ioapic-RTE-modifications-must-use-ioapic_write_e.patch new file mode 100644 index 0000000..43faeeb --- /dev/null +++ b/0020-x86-ioapic-RTE-modifications-must-use-ioapic_write_e.patch @@ -0,0 +1,180 @@ +From 1bd4523d696d26976f64a919df8c7a1b3ea32f6f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= <roger.pau@citrix.com> +Date: Tue, 5 Sep 2023 08:49:37 +0200 +Subject: [PATCH 20/55] x86/ioapic: RTE modifications must use + ioapic_write_entry +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Do not allow to write to RTE registers using io_apic_write and instead +require changes to RTE to be performed using ioapic_write_entry. + +This is in preparation for passing the full contents of the RTE to the +IOMMU interrupt remapping handlers, so remapping entries for IO-APIC +RTEs can be updated atomically when possible. + +While immediately this commit might expand the number of MMIO accesses +in order to update an IO-APIC RTE, further changes will benefit from +getting the full RTE value passed to the IOMMU handlers, as the logic +is greatly simplified when the IOMMU handlers can get the complete RTE +value in one go. + +Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> +Reviewed-by: Jan Beulich <jbeulich@suse.com> +master commit: ef7995ed1bcd7eac37fb3c3fe56eaa54ea9baf6c +master date: 2023-07-28 09:40:20 +0200 +--- + xen/arch/x86/include/asm/io_apic.h | 8 ++--- + xen/arch/x86/io_apic.c | 43 ++++++++++++------------ + xen/drivers/passthrough/amd/iommu_intr.c | 6 ---- + 3 files changed, 25 insertions(+), 32 deletions(-) + +diff --git a/xen/arch/x86/include/asm/io_apic.h b/xen/arch/x86/include/asm/io_apic.h +index a558bb063c..6b514b4e3d 100644 +--- a/xen/arch/x86/include/asm/io_apic.h ++++ b/xen/arch/x86/include/asm/io_apic.h +@@ -161,8 +161,8 @@ static inline void __io_apic_write(unsigned int apic, unsigned int reg, unsigned + + static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value) + { +- if ( ioapic_reg_remapped(reg) ) +- return iommu_update_ire_from_apic(apic, reg, value); ++ /* RTE writes must use ioapic_write_entry. */ ++ BUG_ON(reg >= 0x10); + __io_apic_write(apic, reg, value); + } + +@@ -172,8 +172,8 @@ static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned i + */ + static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value) + { +- if ( ioapic_reg_remapped(reg) ) +- return iommu_update_ire_from_apic(apic, reg, value); ++ /* RTE writes must use ioapic_write_entry. */ ++ BUG_ON(reg >= 0x10); + *(IO_APIC_BASE(apic) + 4) = value; + } + +diff --git a/xen/arch/x86/io_apic.c b/xen/arch/x86/io_apic.c +index aada2ef96c..041233b9b7 100644 +--- a/xen/arch/x86/io_apic.c ++++ b/xen/arch/x86/io_apic.c +@@ -237,15 +237,15 @@ struct IO_APIC_route_entry __ioapic_read_entry( + { + union entry_union eu; + +- if ( raw ) ++ if ( raw || !iommu_intremap ) + { + eu.w1 = __io_apic_read(apic, 0x10 + 2 * pin); + eu.w2 = __io_apic_read(apic, 0x11 + 2 * pin); + } + else + { +- eu.w1 = io_apic_read(apic, 0x10 + 2 * pin); +- eu.w2 = io_apic_read(apic, 0x11 + 2 * pin); ++ eu.w1 = iommu_read_apic_from_ire(apic, 0x10 + 2 * pin); ++ eu.w2 = iommu_read_apic_from_ire(apic, 0x11 + 2 * pin); + } + + return eu.entry; +@@ -269,15 +269,15 @@ void __ioapic_write_entry( + { + union entry_union eu = { .entry = e }; + +- if ( raw ) ++ if ( raw || !iommu_intremap ) + { + __io_apic_write(apic, 0x11 + 2 * pin, eu.w2); + __io_apic_write(apic, 0x10 + 2 * pin, eu.w1); + } + else + { +- io_apic_write(apic, 0x11 + 2 * pin, eu.w2); +- io_apic_write(apic, 0x10 + 2 * pin, eu.w1); ++ iommu_update_ire_from_apic(apic, 0x11 + 2 * pin, eu.w2); ++ iommu_update_ire_from_apic(apic, 0x10 + 2 * pin, eu.w1); + } + } + +@@ -433,16 +433,17 @@ static void modify_IO_APIC_irq(unsigned int irq, unsigned int enable, + unsigned int disable) + { + struct irq_pin_list *entry = irq_2_pin + irq; +- unsigned int pin, reg; + + for (;;) { +- pin = entry->pin; ++ unsigned int pin = entry->pin; ++ struct IO_APIC_route_entry rte; ++ + if (pin == -1) + break; +- reg = io_apic_read(entry->apic, 0x10 + pin*2); +- reg &= ~disable; +- reg |= enable; +- io_apic_modify(entry->apic, 0x10 + pin*2, reg); ++ rte = __ioapic_read_entry(entry->apic, pin, false); ++ rte.raw &= ~(uint64_t)disable; ++ rte.raw |= enable; ++ __ioapic_write_entry(entry->apic, pin, false, rte); + if (!entry->next) + break; + entry = irq_2_pin + entry->next; +@@ -584,16 +585,16 @@ set_ioapic_affinity_irq(struct irq_desc *desc, const cpumask_t *mask) + dest = SET_APIC_LOGICAL_ID(dest); + entry = irq_2_pin + irq; + for (;;) { +- unsigned int data; ++ struct IO_APIC_route_entry rte; ++ + pin = entry->pin; + if (pin == -1) + break; + +- io_apic_write(entry->apic, 0x10 + 1 + pin*2, dest); +- data = io_apic_read(entry->apic, 0x10 + pin*2); +- data &= ~IO_APIC_REDIR_VECTOR_MASK; +- data |= MASK_INSR(desc->arch.vector, IO_APIC_REDIR_VECTOR_MASK); +- io_apic_modify(entry->apic, 0x10 + pin*2, data); ++ rte = __ioapic_read_entry(entry->apic, pin, false); ++ rte.dest.dest32 = dest; ++ rte.vector = desc->arch.vector; ++ __ioapic_write_entry(entry->apic, pin, false, rte); + + if (!entry->next) + break; +@@ -2127,10 +2128,8 @@ void ioapic_resume(void) + reg_00.bits.ID = mp_ioapics[apic].mpc_apicid; + __io_apic_write(apic, 0, reg_00.raw); + } +- for (i = 0; i < nr_ioapic_entries[apic]; i++, entry++) { +- __io_apic_write(apic, 0x11+2*i, *(((int *)entry)+1)); +- __io_apic_write(apic, 0x10+2*i, *(((int *)entry)+0)); +- } ++ for (i = 0; i < nr_ioapic_entries[apic]; i++, entry++) ++ __ioapic_write_entry(apic, i, true, *entry); + } + spin_unlock_irqrestore(&ioapic_lock, flags); + } +diff --git a/xen/drivers/passthrough/amd/iommu_intr.c b/xen/drivers/passthrough/amd/iommu_intr.c +index 9e6be3be35..f32c418a7e 100644 +--- a/xen/drivers/passthrough/amd/iommu_intr.c ++++ b/xen/drivers/passthrough/amd/iommu_intr.c +@@ -361,12 +361,6 @@ void cf_check amd_iommu_ioapic_update_ire( + struct amd_iommu *iommu; + unsigned int idx; + +- if ( !iommu_intremap ) +- { +- __io_apic_write(apic, reg, value); +- return; +- } +- + idx = ioapic_id_to_index(IO_APIC_ID(apic)); + if ( idx == MAX_IO_APICS ) + return; +-- +2.42.0 + |