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

[xen staging] drivers/char: Panic when the requested UART fails to initialise



commit 20ee984e1df26b83d0b29565afe20354ea5a4f87
Author:     Michal Orzel <michal.orzel@xxxxxxx>
AuthorDate: Wed Sep 2 09:36:06 2026 +0200
Commit:     Michal Orzel <michal.orzel@xxxxxxx>
CommitDate: Tue Sep 15 17:13:02 2026 +0200

    drivers/char: Panic when the requested UART fails to initialise
    
    uart_init() cannot tell its caller that the UART the user asked for did
    not come up: every failure path only printks. Arm and RISC-V carry on
    into console_init_preirq() and boot without a console, rather than
    refusing to boot as they do elsewhere when a user request cannot be met.
    
    Return an error from dt_uart_init() and panic in start_xen(). An
    explicit request Xen cannot satisfy should stop the boot rather than
    silently degrade it, which is what start_xen() already does for the rest
    of the boot configuration.
    
    Only a path given on the command line counts as a request we have to
    satisfy. Falling back to /chosen/stdout-path or acpi_uart_init()
    therefore never fails. SPCR is firmware provided, the analogue of
    stdout-path, and there is no ACPI equivalent of dtuart= to make an
    explicit request with.
    
    While here, decide whether the SPCR table was found from the returned
    acpi_status rather than from the table pointer, which was only NULL
    because the caller initialised it - acpi_get_table() writes it solely
    on success.
    
    Signed-off-by: Michal Orzel <michal.orzel@xxxxxxx>
    Reviewed-by: Ayan Kumar Halder <ayan.kumar.halder@xxxxxxx>
---
 xen/arch/arm/setup.c         |  5 ++++-
 xen/arch/riscv/setup.c       |  6 ++++-
 xen/drivers/char/uart-init.c | 52 +++++++++++++++++++++++++-------------------
 xen/include/xen/serial.h     |  6 ++++-
 4 files changed, 44 insertions(+), 25 deletions(-)

diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index 86532d0a35..79bbf24305 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -377,7 +377,10 @@ void asmlinkage __init noreturn start_xen(unsigned long 
fdt_paddr)
 
     gic_preinit();
 
-    uart_init();
+    rc = uart_init();
+    if ( rc )
+        panic("Failed to initialize the requested UART (%d)\n", rc);
+
     console_init_preirq();
     console_init_ring();
 
diff --git a/xen/arch/riscv/setup.c b/xen/arch/riscv/setup.c
index 56a0907a85..07f46ac3ce 100644
--- a/xen/arch/riscv/setup.c
+++ b/xen/arch/riscv/setup.c
@@ -77,6 +77,7 @@ void __init noreturn start_xen(unsigned long bootcpu_id,
 {
     const char *cmdline;
     size_t fdt_size;
+    int rc;
 
     remove_identity_mapping();
 
@@ -149,7 +150,10 @@ void __init noreturn start_xen(unsigned long bootcpu_id,
 
     intc_preinit();
 
-    uart_init();
+    rc = uart_init();
+    if ( rc )
+        panic("Failed to initialize the requested UART (%d)\n", rc);
+
     console_init_preirq();
 
     intc_init();
diff --git a/xen/drivers/char/uart-init.c b/xen/drivers/char/uart-init.c
index eb7f855495..b79135be96 100644
--- a/xen/drivers/char/uart-init.c
+++ b/xen/drivers/char/uart-init.c
@@ -30,15 +30,17 @@
 static char __initdata opt_dtuart[256] = "";
 string_param("dtuart", opt_dtuart);
 
-static void __init dt_uart_init(void)
+static int __init dt_uart_init(void)
 {
     struct dt_device_node *dev;
     int ret;
     const char *devpath = opt_dtuart;
     const char *options;
     char *split;
+    /* Set on the command line, as opposed to inherited from /chosen */
+    bool explicit_request = strcmp(opt_dtuart, "") != 0;
 
-    if ( !strcmp(opt_dtuart, "") )
+    if ( !explicit_request )
     {
         const struct dt_device_node *chosen = dt_find_node_by_path("/chosen");
 
@@ -62,7 +64,12 @@ static void __init dt_uart_init(void)
     if ( !strcmp(opt_dtuart, "") )
     {
         printk("No dtuart path configured\n");
-        return;
+
+        /*
+         * console=dtuart is the compiled-in default, so an absent dtuart= is
+         * not a failed user request.
+         */
+        return 0;
     }
 
     split = strchr(opt_dtuart, ':');
@@ -83,48 +90,49 @@ static void __init dt_uart_init(void)
     if ( !dev )
     {
         printk("Unable to find device \"%s\"\n", devpath);
-        return;
+        return explicit_request ? -ENODEV : 0;
     }
 
     ret = device_init(dev, DEVICE_SERIAL, options);
-
     if ( ret )
         printk("Unable to initialize dtuart: %d\n", ret);
+
+    return explicit_request ? ret : 0;
 }
 
 #ifdef CONFIG_ACPI
-static void __init acpi_uart_init(void)
+static int __init acpi_uart_init(void)
 {
-    struct acpi_table_spcr *spcr = NULL;
+    struct acpi_table_spcr *spcr;
+    acpi_status status;
     int ret;
 
-    acpi_get_table(ACPI_SIG_SPCR, 0, (struct acpi_table_header **)&spcr);
+    /* SPCR is firmware provided, so nothing here is a failed user request */
+    status = acpi_get_table(ACPI_SIG_SPCR, 0,
+                            (struct acpi_table_header **)&spcr);
 
-    if ( spcr == NULL )
+    if ( ACPI_FAILURE(status) )
     {
         printk("Unable to get spcr table\n");
+        return 0;
     }
-    else
-    {
-        ret = acpi_device_init(DEVICE_SERIAL, NULL, spcr->interface_type);
 
-        if ( ret )
-            printk("Unable to initialize acpi uart: %d\n", ret);
-    }
+    ret = acpi_device_init(DEVICE_SERIAL, NULL, spcr->interface_type);
+    if ( ret )
+        printk("Unable to initialize acpi uart: %d\n", ret);
+
+    return 0;
 }
 #else
-static void __init acpi_uart_init(void) { }
+static int __init acpi_uart_init(void) { return 0; }
 #endif
 
-void __init uart_init(void)
+int __init uart_init(void)
 {
     if ( !console_has("dtuart") )
-        return; /* Not for us */
+        return 0; /* Not for us */
 
-    if ( acpi_disabled )
-        dt_uart_init();
-    else
-        acpi_uart_init();
+    return acpi_disabled ? dt_uart_init() : acpi_uart_init();
 }
 
 /*
diff --git a/xen/include/xen/serial.h b/xen/include/xen/serial.h
index 8e18445552..3a71da767d 100644
--- a/xen/include/xen/serial.h
+++ b/xen/include/xen/serial.h
@@ -170,7 +170,11 @@ void xhci_dbc_uart_init(void);
 static void inline xhci_dbc_uart_init(void) {}
 #endif
 
-void uart_init(void);
+/*
+ * Returns 0 unless a UART explicitly requested via dtuart= failed to
+ * initialise.
+ */
+int uart_init(void);
 
 struct physdev_dbgp_op;
 int dbgp_op(const struct physdev_dbgp_op *op);
--
generated by git-patchbot for /home/xen/git/xen.git#staging



 


Rackspace

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