[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2 2/5] x86/ioapic: RTE modifications must use ioapic_write_entry
On 19.07.2023 17:20, Roger Pau Monné wrote: > On Tue, Jul 18, 2023 at 05:40:18PM +0200, Jan Beulich wrote: >> On 18.07.2023 14:43, Roger Pau Monne wrote: >>> --- 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); >>> } >>> } >> >> I think __ioapic_read_entry() wants updating similarly, so that both >> remain consistent. > > My plan was to deal with __ioapic_read_entry() separately, as I would > also like to convert iommu_read_apic_from_ire() to get passed a pin > instead of a register, but I could make your requested adjustment here > for consistency with __ioapic_write_entry(). I would indeed prefer if you did, to avoid the functions going out of sync. >>> @@ -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); >> >> While this isn't going to happen overly often, ... >> >>> @@ -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); >> >> ... this makes me wonder whether there shouldn't be an >> __ioapic_modify_entry() capable of suppressing one of the two >> writes (but still being handed the full RTE). > > We would then need the original RTE to be passed to > __ioapic_modify_entry() in order for it to decide whether one of the > accesses can be eliminated (as I don't think we want to read the RTE > to check for differences, as we would then perform even more > accesses). I was actually thinking of a 2-bit hint that the caller would pass: Low half unmodified and high half unmodified. > This would only be relevant for systems without IOMMU IRTEs, as > otherwise the IO-APIC RTE gets modified by the IOMMU handlers. Initially yes. I think there's room there to avoid one half of the write as well. Jan
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |