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

[xen master] x86/apic: Avoid infinite loop in io_apic_level_ack_pending()



commit ad8d3d7f4001046c03b9bfb3919884d74dad96ed
Author:     Jason Andryuk <jason.andryuk@xxxxxxx>
AuthorDate: Mon Oct 20 13:03:10 2025 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Mon Oct 20 13:03:10 2025 +0200

    x86/apic: Avoid infinite loop in io_apic_level_ack_pending()
    
    io_apic_level_ack_pending() will end up in an infinite loop if
    entry->pin == -1.  entry does not change, so it will keep reading -1.
    
    Convert to a proper for loop so that continue works.  Add a new helper,
    pin_list_next(), to handle advancing to the next irq_pin_list entry.
    
    Noticed during code inspection.  The infinite loop was not observed.
    
    Fixes: f821102450a1 ("x86: IRQ Migration logic enhancement.")
    Signed-off-by: Jason Andryuk <jason.andryuk@xxxxxxx>
    Acked-by: Jan Beulich <jbeulich@xxxxxxxx>
    Release-Acked-by: Oleksii Kurochko <oleksii.kurochko@xxxxxxxxx>
---
 xen/arch/x86/io_apic.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/xen/arch/x86/io_apic.c b/xen/arch/x86/io_apic.c
index c384f10c1b..24447aef6c 100644
--- a/xen/arch/x86/io_apic.c
+++ b/xen/arch/x86/io_apic.c
@@ -191,6 +191,14 @@ static void remove_pin_from_irq(unsigned int irq, int 
apic, int pin)
     irq_2_pin_free_entry = entry - irq_2_pin;
 }
 
+static struct irq_pin_list *pin_list_next(const struct irq_pin_list *entry)
+{
+    if ( !entry->next )
+        return NULL;
+
+    return irq_2_pin + entry->next;
+}
+
 /*
  * Reroute an IRQ to a different pin.
  */
@@ -1592,14 +1600,10 @@ static bool io_apic_level_ack_pending(unsigned int irq)
     unsigned long flags;
 
     spin_lock_irqsave(&ioapic_lock, flags);
-    entry = &irq_2_pin[irq];
-    for (;;) {
+    for (entry = &irq_2_pin[irq]; entry; entry = pin_list_next(entry)) {
         unsigned int reg;
         int pin;
 
-        if (!entry)
-            break;
-
         pin = entry->pin;
         if (pin == -1)
             continue;
@@ -1609,9 +1613,6 @@ static bool io_apic_level_ack_pending(unsigned int irq)
             spin_unlock_irqrestore(&ioapic_lock, flags);
             return 1;
         }
-        if (!entry->next)
-            break;
-        entry = irq_2_pin + entry->next;
     }
     spin_unlock_irqrestore(&ioapic_lock, flags);
 
--
generated by git-patchbot for /home/xen/git/xen.git#master



 


Rackspace

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