The IO-APIC RTEs are unconditionally programmed with physical destination
mode, and hence the field to set in the RTE is always physical_dest.

Remove the mode parameter from SET_DEST() and take the opportunity to
convert it into a function, there's no need for it to be a macro.

This is a benign fix, because due to the endianness of x86 the start of the
physical_dest and logical_dest fields on the RTE overlap.

While there also adjust setup_IO_APIC_irqs() to use the target CPU set by
the assign_irq_vector(), rather than using TARGET_CPUS and possibly
creating a mismatch between the target CPU in desc->arch.cpu_mask and the
one programmed in the IO-APIC RTE.

Fixes: 032d6733a458 ("x86/apic: remove delivery and destination mode fields 
from drivers")
Signed-off-by: Roger Pau MonnĂ© <[email protected]>
---
 xen/arch/x86/io_apic.c | 27 +++++++++++++++------------
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/xen/arch/x86/io_apic.c b/xen/arch/x86/io_apic.c
index 46c2a43dac6d..3c59bf0e15da 100644
--- a/xen/arch/x86/io_apic.c
+++ b/xen/arch/x86/io_apic.c
@@ -1037,12 +1037,14 @@ static hw_irq_controller ioapic_edge_type;
 #define IOAPIC_EDGE    0
 #define IOAPIC_LEVEL   1
 
-#define SET_DEST(ent, mode, val) do { \
-    if (x2apic_enabled && iommu_intremap) \
-        (ent).dest.dest32 = (val); \
-    else \
-        (ent).dest.mode.mode##_dest = (val); \
-} while (0)
+static void set_entry_dest(struct IO_APIC_route_entry *entry,
+                           unsigned int apic_id)
+{
+    if ( x2apic_enabled && iommu_intremap )
+        entry->dest.dest32 = apic_id;
+    else
+        entry->dest.physical.physical_dest = apic_id;
+}
 
 static inline void ioapic_register_intr(int irq, unsigned long trigger)
 {
@@ -1109,7 +1111,8 @@ static void __init setup_IO_APIC_irqs(void)
             if (platform_legacy_irq(irq))
                 disable_8259A_irq(irq_to_desc(irq));
 
-            SET_DEST(entry, logical, cpu_mask_to_apicid(TARGET_CPUS));
+            set_entry_dest(&entry,
+                           
cpu_mask_to_apicid(irq_to_desc(irq)->arch.cpu_mask));
             spin_lock_irqsave(&ioapic_lock, flags);
             __ioapic_write_entry(apic, pin, false, entry);
             spin_unlock_irqrestore(&ioapic_lock, flags);
@@ -1140,7 +1143,7 @@ static void __init setup_ExtINT_IRQ0_pin(unsigned int 
apic, unsigned int pin, in
      */
     entry.dest_mode = 0; /* physical delivery */
     entry.mask = 0;                                    /* unmask IRQ now */
-    SET_DEST(entry, logical, cpu_mask_to_apicid(TARGET_CPUS));
+    set_entry_dest(&entry, cpu_mask_to_apicid(TARGET_CPUS));
     entry.delivery_mode = dest_Fixed;
     entry.polarity = 0;
     entry.trigger = 0;
@@ -1432,7 +1435,7 @@ void disable_IO_APIC(void)
         entry.dest_mode       = 0; /* Physical */
         entry.delivery_mode   = dest_ExtINT; /* ExtInt */
         entry.vector          = 0;
-        SET_DEST(entry, physical, get_apic_id());
+        set_entry_dest(&entry, get_apic_id());
 
         /*
          * Add it to the IO-APIC irq-routing table:
@@ -1806,7 +1809,7 @@ static void __init unlock_ExtINT_logic(void)
 
     entry1.dest_mode = 0;                      /* physical delivery */
     entry1.mask = 0;                   /* unmask IRQ now */
-    SET_DEST(entry1, physical, get_apic_id());
+    set_entry_dest(&entry1, get_apic_id());
     entry1.delivery_mode = dest_ExtINT;
     entry1.polarity = entry0.polarity;
     entry1.trigger = 0;
@@ -2137,7 +2140,7 @@ int io_apic_set_pci_routing (int ioapic, int pin, int 
irq, int edge_level, int a
         cpumask_t *mask = this_cpu(scratch_cpumask);
 
         cpumask_and(mask, desc->arch.cpu_mask, TARGET_CPUS);
-        SET_DEST(entry, logical, cpu_mask_to_apicid(mask));
+        set_entry_dest(&entry, cpu_mask_to_apicid(mask));
     } else {
         printk(XENLOG_ERR "IRQ%d: no target CPU (%*pb vs %*pb)\n",
                irq, CPUMASK_PR(desc->arch.cpu_mask), CPUMASK_PR(TARGET_CPUS));
@@ -2334,7 +2337,7 @@ int ioapic_guest_write(unsigned long physbase, unsigned 
int reg, u32 val)
         cpumask_t *mask = this_cpu(scratch_cpumask);
 
         cpumask_and(mask, desc->arch.cpu_mask, TARGET_CPUS);
-        SET_DEST(rte, logical, cpu_mask_to_apicid(mask));
+        set_entry_dest(&rte, cpu_mask_to_apicid(mask));
     }
     else
     {
-- 
2.51.0


Reply via email to