[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH RFC 3/6] x86/ioapic: RTE modifications must use ioapic_write_entry
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. Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> --- xen/arch/x86/include/asm/io_apic.h | 15 ++---------- xen/arch/x86/io_apic.c | 37 +++++++++++++++--------------- 2 files changed, 20 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..c26261aecb 100644 --- a/xen/arch/x86/include/asm/io_apic.h +++ b/xen/arch/x86/include/asm/io_apic.h @@ -161,22 +161,11 @@ 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); } -/* - * Re-write a value: to be used for read-modify-write - * cycles where the read already set up the index register. - */ -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); - *(IO_APIC_BASE(apic) + 4) = value; -} - /* 1 if "noapic" boot option passed */ extern bool skip_ioapic_setup; extern bool ioapic_ack_new; diff --git a/xen/arch/x86/io_apic.c b/xen/arch/x86/io_apic.c index 2e5964640b..3a5e3b7872 100644 --- a/xen/arch/x86/io_apic.c +++ b/xen/arch/x86/io_apic.c @@ -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; @@ -2129,10 +2130,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); } -- 2.35.1
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |