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

[xen master] xen/drivers/char/pl011: fix IRQ registration failure propagation



commit 233d555df9795c0c12c1b54e0a7e96d9e485d374
Author:     Oleksii Moisieiev <Oleksii_Moisieiev@xxxxxxxx>
AuthorDate: Thu Apr 23 16:11:41 2026 +0000
Commit:     Michal Orzel <michal.orzel@xxxxxxx>
CommitDate: Mon Apr 27 08:52:38 2026 +0200

    xen/drivers/char/pl011: fix IRQ registration failure propagation
    
    In pl011_init_postirq(), two code paths could reach the
    interrupt-unmask write to IMSC without a handler being registered:
    
    - When no valid IRQ number was provided (uart->irq <= 0), the original
      positive-condition guard (if uart->irq > 0) skipped the irqaction
      setup but still fell through to the IMSC write, unmasking
      RTI|OEI|BEI|PEI|FEI|TXI|RXI with no handler installed.
    
    - When setup_irq() returned an error, only an error message was
      printed and execution continued to the IMSC write, arming all
      hardware interrupt lines with no handler to service them. On
      platforms where the GIC receives these asserted lines, the result
      is either repeated spurious-interrupt warnings or an unhandled
      interrupt fault.
    
    Restructure pl011_init_postirq() to use early returns: return
    immediately when no valid IRQ is provided, and return after logging
    the error when setup_irq() fails. The interrupt-enable write to IMSC
    is only reached when IRQ registration succeeds.
    
    Signed-off-by: Oleksii Moisieiev <oleksii_moisieiev@xxxxxxxx>
    Reviewed-by: Michal Orzel <michal.orzel@xxxxxxx>
---
 xen/drivers/char/pl011.c | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/xen/drivers/char/pl011.c b/xen/drivers/char/pl011.c
index 5f9913367d..a336241033 100644
--- a/xen/drivers/char/pl011.c
+++ b/xen/drivers/char/pl011.c
@@ -150,18 +150,24 @@ static void __init pl011_init_postirq(struct serial_port 
*port)
     struct pl011 *uart = port->uart;
     int rc;
 
-    if ( uart->irq > 0 )
-    {
-        uart->irqaction.handler = pl011_interrupt;
-        uart->irqaction.name    = "pl011";
-        uart->irqaction.dev_id  = port;
-        if ( (rc = setup_irq(uart->irq, 0, &uart->irqaction)) != 0 )
-            printk("ERROR: Failed to allocate pl011 IRQ %d\n", uart->irq);
-    }
+    /* Don't unmask interrupts if no valid irq was provided */
+    if ( uart->irq == 0 )
+        return;
+
+    uart->irqaction.handler = pl011_interrupt;
+    uart->irqaction.name    = "pl011";
+    uart->irqaction.dev_id  = port;
 
     /* Clear pending error interrupts */
     pl011_write(uart, ICR, OEI|BEI|PEI|FEI);
 
+    if ( (rc = setup_irq(uart->irq, 0, &uart->irqaction)) != 0 )
+    {
+        printk("ERROR: Failed to allocate pl011 IRQ %u\n", uart->irq);
+        /* Do not unmask interrupts if irq handler wasn't set */
+        return;
+    }
+
     /* Unmask interrupts */
     pl011_write(uart, IMSC, RTI|OEI|BEI|PEI|FEI|TXI|RXI);
 }
--
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®.