[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 05/12] x86/io-apic: purge usage of logical mode


  • To: xen-devel@xxxxxxxxxxxxxxxxxxxx
  • From: Roger Pau Monne <roger.pau@xxxxxxxxxx>
  • Date: Thu, 20 Nov 2025 10:06:30 +0100
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=WBn0wIUSagCcNXuxdruRc9da5j6+arDekcJulY68nFw=; b=T6rfh7nTS0cFO2U34ZTUpc0b4KD9dsZu2ksFz3A7/qD/OOr+3dtihA8zQANk4mVH0rryFPcOn4p6K8iCHgCSR2RhpP4NTyl8WlE99oX30C0D6FrLYSVwpTnd48wCwSISDsw1Y/y3n1Y9evmO1u+WRqx5LqusEUj+RwklgJs0AwDi5xD/HYwr7CBH64NaBN9j2ppMf2dvig94o3HHxMh1dWevAoxcF364+aBWrr67WbuHncAMV0vqAczSo2PTN++sPmJRKtK+FfqAfvmokumgyLowWmuMOFtPNbaeONG7ZU2zXHkY9mgCrIKO0N3ZrDvlfWSgvDiSIxT+exXuPmbgCg==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=MvqEzQQE/tXzbWUMyH9NoZ24Au6t/lP4787+plUMNo4PiwsfGV4CnFq1QNM+uS7rLHUlDpehnXU6zUSFdACLqgNdI9aR8RMBXqdNCBmS09u5c7yOl1AFxFAaLv9QmDEWWzaalgXADG/LOB89AEITkTQm75z5bwoT9HeBAOJu4d0yrLJXLSHnl/J/lN/EHDTHgRGLgPwPdV0RP8MlHzBkpf4EN7Bci2kDWXzGx6qWHkLqf9qg8pV8NT9rgyLlpt4SMt46vThOZqWLo/7i9UypuRuL098ZoP2OlbUXU+teq0EAeCkLTFhhFPVRabEwUjWQhics7D8EmxYNQ0DGMh3Hjw==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=citrix.com;
  • Cc: Roger Pau Monne <roger.pau@xxxxxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
  • Delivery-date: Thu, 20 Nov 2025 09:09:44 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

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é <roger.pau@xxxxxxxxxx>
---
 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




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.