There are many places where we use interesting ways of reading 32-bits components of the RTE. Introduce and use low and high components directly to the rte structure instead.
Also take the opportunity to simplify "x & 1 ? 1 : 0". Signed-off-by: Teddy Astie <[email protected]> Acked-by: Jan Beulich <[email protected]> --- v2.1: - fix trailing spaces v2: - make rte_upper to use bool instead xen/arch/x86/include/asm/io_apic.h | 1 + xen/arch/x86/io_apic.c | 29 ++++++++++---------------- xen/drivers/passthrough/vtd/intremap.c | 7 ++----- 3 files changed, 14 insertions(+), 23 deletions(-) diff --git a/xen/arch/x86/include/asm/io_apic.h b/xen/arch/x86/include/asm/io_apic.h index 4680dce9e1..0e85f2a860 100644 --- a/xen/arch/x86/include/asm/io_apic.h +++ b/xen/arch/x86/include/asm/io_apic.h @@ -122,6 +122,7 @@ struct IO_APIC_route_entry { } dest; }; uint64_t raw; + struct { uint32_t low, high; }; }; }; diff --git a/xen/arch/x86/io_apic.c b/xen/arch/x86/io_apic.c index d20ab2aa98..46c2a43dac 100644 --- a/xen/arch/x86/io_apic.c +++ b/xen/arch/x86/io_apic.c @@ -254,28 +254,23 @@ nomem: return NULL; } -union entry_union { - struct { u32 w1, w2; }; - struct IO_APIC_route_entry entry; -}; - struct IO_APIC_route_entry __ioapic_read_entry( unsigned int apic, unsigned int pin, bool raw) { - union entry_union eu; + struct IO_APIC_route_entry entry; if ( raw || !iommu_intremap ) { - eu.w1 = __io_apic_read(apic, 0x10 + 2 * pin); - eu.w2 = __io_apic_read(apic, 0x11 + 2 * pin); + entry.low = __io_apic_read(apic, 0x10 + 2 * pin); + entry.high = __io_apic_read(apic, 0x11 + 2 * pin); } else { - eu.w1 = iommu_read_apic_from_ire(apic, 0x10 + 2 * pin); - eu.w2 = iommu_read_apic_from_ire(apic, 0x11 + 2 * pin); + entry.low = iommu_read_apic_from_ire(apic, 0x10 + 2 * pin); + entry.high = iommu_read_apic_from_ire(apic, 0x11 + 2 * pin); } - return eu.entry; + return entry; } static struct IO_APIC_route_entry ioapic_read_entry( @@ -294,12 +289,10 @@ void __ioapic_write_entry( unsigned int apic, unsigned int pin, bool raw, struct IO_APIC_route_entry e) { - union entry_union eu = { .entry = e }; - if ( raw || !iommu_intremap ) { - __io_apic_write(apic, 0x11 + 2 * pin, eu.w2); - __io_apic_write(apic, 0x10 + 2 * pin, eu.w1); + __io_apic_write(apic, 0x11 + 2 * pin, e.high); + __io_apic_write(apic, 0x10 + 2 * pin, e.low); /* * Might be called before io_apic_pin_eoi is allocated. Entry will be * initialized to the RTE value once the cache is allocated. @@ -2218,7 +2211,7 @@ int ioapic_guest_read(unsigned long physbase, unsigned int reg, u32 *pval) dprintk(XENLOG_INFO, "IO-APIC: apic=%d, pin=%d, irq=%d\n" \ XENLOG_INFO "IO-APIC: new_entry=%08x\n" \ XENLOG_INFO "IO-APIC: " f "\n", \ - apic, pin, irq, *(u32 *)&rte, ##a ) + apic, pin, irq, rte.low, ##a ) int ioapic_guest_write(unsigned long physbase, unsigned int reg, u32 val) { @@ -2237,7 +2230,7 @@ int ioapic_guest_write(unsigned long physbase, unsigned int reg, u32 val) pin = (reg - 0x10) >> 1; /* Write first half from guest; second half is target info. */ - *(u32 *)&rte = val; + rte.low = val; /* * What about weird destination types? @@ -2288,7 +2281,7 @@ int ioapic_guest_write(unsigned long physbase, unsigned int reg, u32 val) ret = io_apic_read(apic, 0x10 + 2 * pin); spin_unlock_irqrestore(&ioapic_lock, flags); rte.vector = desc->arch.vector; - if ( *(u32*)&rte != ret ) + if ( rte.low != ret ) WARN_BOGUS_WRITE("old_entry=%08x pirq=%d\n" XENLOG_INFO "IO-APIC: Attempt to modify IO-APIC pin for in-use IRQ!", ret, pirq); diff --git a/xen/drivers/passthrough/vtd/intremap.c b/xen/drivers/passthrough/vtd/intremap.c index 116c2e75ae..ac39405c0d 100644 --- a/xen/drivers/passthrough/vtd/intremap.c +++ b/xen/drivers/passthrough/vtd/intremap.c @@ -399,7 +399,7 @@ unsigned int cf_check io_apic_read_remap_rte( unsigned int ioapic_pin = (reg - 0x10) / 2; int index; struct IO_APIC_route_entry old_rte = {}; - int rte_upper = (reg & 1) ? 1 : 0; + bool rte_upper = reg & 1; struct vtd_iommu *iommu = ioapic_to_iommu(IO_APIC_ID(apic)); if ( !iommu->intremap.num || @@ -411,10 +411,7 @@ unsigned int cf_check io_apic_read_remap_rte( if ( remap_entry_to_ioapic_rte(iommu, index, &old_rte) ) return __io_apic_read(apic, reg); - if ( rte_upper ) - return (*(((u32 *)&old_rte) + 1)); - else - return (*(((u32 *)&old_rte) + 0)); + return rte_upper ? old_rte.high : old_rte.low; } void cf_check io_apic_write_remap_rte( -- 2.51.2 -- Teddy Astie | Vates XCP-ng Developer XCP-ng & Xen Orchestra - Vates solutions web: https://vates.tech
