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

[PATCH 3/3] drivers/char: Panic when the requested UART fails to initialise


  • To: <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Michal Orzel <michal.orzel@xxxxxxx>
  • Date: Wed, 2 Sep 2026 09:36:06 +0200
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lists.xenproject.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0)
  • 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=yoClwoPRx+rVoH90jrgZnJbWUIYvOiLRrYE1TxOYvoM=; b=T/vfSFtavqWzoFZbDgXyBYju2y2P4tItG7FhM6FaTgjztusA8oVXEl4yNlZx5gk0VF9mlv5avoPqv73a2Y2YiCX727LtQRvT/AiC2ophep0DzpV0hYlXj6J88ly+qfvvjL8T0U153FzhV0cF2N080sRT+nZIwCnpS0h2noElyy+wes6uDIB8ZbaKhHZydy+DkmIRKnxLtFneGKt4D5uQsEV8hGpxGE19MsdEl9SIOCx/LYWTS/nZJVgI/TvzX60Zb5Vm8mRmVC6rY9FUH4N5TJXl0VwElWholBDbJaeKkrB9J2Ozv8skObY4XsLt25JJ2R0cHfDxtsBqVtlEuZ+8Qw==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=YEzISwQ84XgqB0ZzR1HbpBwRw+me3Pm80+4F6xlRKJhI6NXRTtSV4PxrT+74THsr11Et3WcIv8q3uRncc6FN5s5+stBlH7sE/9mOlkjsUq+djPzR+cipHZEvL6QirrbxtrqYWhc4j3zMFlhJSLx6d+jnNa6QJbRWDT8t1HtO3KpQGmVMz2JTIdn9ArF+ongc+KECMzJH3Z1y1Yv2mtw0ZDFnwBWVHLMt5hWYUCP6Acut2yK+lD1kjjceAATQOz904F5BrMRgeahIUmB2RlWBEAHTnPraOVVNYo6nd/kmd652cheIz5rjWuLGSRue+Qcv7y8gF+xVilFeTSjPGdd4+g==
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=amd.com header.i="@amd.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck"
  • Cc: Michal Orzel <michal.orzel@xxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Anthony PERARD <anthony.perard@xxxxxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Roger Pau Monné <roger@xxxxxxxxxxxxxx>, Alistair Francis <alistair.francis@xxxxxxx>, Connor Davis <connojdavis@xxxxxxxxx>, "Oleksii Kurochko" <oleksii.kurochko@xxxxxxxxx>
  • Delivery-date: Wed, 02 Sep 2026 07:36:29 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

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>
---
With this change diagnosibility decreases only for a single scenario:
when dom0 is reachable not via console (e.g. network) and you'd have used xl
dmesg to read messages from the conring.

On Arm (I suppose RISC-V is similar), given that safety becomes the major
use-case and we need to satisfy all the user/guest-xen contracts, I think the
patch moves us in a direction we already chose (i.e. we panic on every boot
failure where we cannot meet the requests).
---
 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 6310a47d68b6..d0066db42e7c 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -379,7 +379,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 56a0907a855f..07f46ac3ce27 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 eb7f85549593..b79135be9620 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 8e1844555208..3a71da767dd7 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);
-- 
2.43.0




 


Rackspace

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