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 <teddy.astie@vates.tech>
---
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 | 9 +++-----
3 files changed, 15 insertions(+), 24 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 24447aef6c..9d2edec179 100644
--- a/xen/arch/x86/io_apic.c
+++ b/xen/arch/x86/io_apic.c
@@ -257,28 +257,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(
@@ -297,12 +292,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.
@@ -2235,7 +2228,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)
{
@@ -2254,7 +2247,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?
@@ -2305,7 +2298,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 612e08bcec..a276518c52 100644
--- a/xen/drivers/passthrough/vtd/intremap.c
+++ b/xen/drivers/passthrough/vtd/intremap.c
@@ -400,7 +400,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,11 +411,8 @@ 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.1
--
Teddy Astie | Vates XCP-ng Developer
XCP-ng & Xen Orchestra - Vates solutions
web: https://vates.tech
On 23/10/2025 10:12 am, Teddy Astie wrote: > diff --git a/xen/drivers/passthrough/vtd/intremap.c b/xen/drivers/passthrough/vtd/intremap.c > index 612e08bcec..a276518c52 100644 > --- a/xen/drivers/passthrough/vtd/intremap.c > +++ b/xen/drivers/passthrough/vtd/intremap.c > @@ -411,11 +411,8 @@ 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; > } This hunk introduces trailing whitespace where there was none previously. ~Andrew
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 <teddy.astie@vates.tech>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
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
On 19.11.2025 12:02, Teddy Astie wrote: > 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 <teddy.astie@vates.tech> > Acked-by: Jan Beulich <jbeulich@suse.com> > --- > v2.1: > - fix trailing spaces You did notice v2 was committed already, didn't you? I suppose that's what made Andrew notice the style issue. Jan
© 2016 - 2026 Red Hat, Inc.