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

[PATCH v3 4/5] xen/console: remove max_init_domid dependency



From: Denis Mukhin <dmukhin@xxxxxxxx>

The physical console input rotation depends on max_init_domid symbol, which is
managed differently across architectures.

Instead of trying to manage max_init_domid in the arch-common code the console
input rotation code can be reworked by removing dependency on max_init_domid
entirely.

To do that, introduce domid_find_with_input_allowed() in arch-independent
location to find the ID of the next possible console owner domain. The IDs
are rotated across non-system domain IDs and DOMID_XEN.

Also, introduce helper console_set_domid() for updating identifier of the
current console input owner (points to Xen or domain).

Use domid_find_with_input_allowed() and console_set_domid() in
console_switch_input().

Remove uses of max_init_domid in the code.

Signed-off-by: Denis Mukhin <dmukhin@xxxxxxxx>
---
Changes since v2:
- reworked to traversing domain list directly
- Link to v2: 
https://lore.kernel.org/xen-devel/20250331230508.440198-7-dmukhin@xxxxxxxx/
---
 xen/arch/arm/include/asm/setup.h        |   2 -
 xen/arch/arm/setup.c                    |   2 -
 xen/arch/ppc/include/asm/setup.h        |   2 -
 xen/arch/riscv/include/asm/setup.h      |   2 -
 xen/arch/x86/include/asm/setup.h        |   2 -
 xen/common/device-tree/dom0less-build.c |   2 -
 xen/common/domain.c                     |  29 +++++++
 xen/drivers/char/console.c              | 102 +++++++++---------------
 xen/include/xen/domain.h                |   1 +
 9 files changed, 66 insertions(+), 78 deletions(-)

diff --git a/xen/arch/arm/include/asm/setup.h b/xen/arch/arm/include/asm/setup.h
index 6cf272c160..f107e8eebb 100644
--- a/xen/arch/arm/include/asm/setup.h
+++ b/xen/arch/arm/include/asm/setup.h
@@ -25,8 +25,6 @@ struct map_range_data
     struct rangeset *irq_ranges;
 };
 
-extern domid_t max_init_domid;
-
 void copy_from_paddr(void *dst, paddr_t paddr, unsigned long len);
 
 size_t estimate_efi_size(unsigned int mem_nr_banks);
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index 10b46d0684..53e2f8b537 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -61,8 +61,6 @@ struct cpuinfo_arm __read_mostly system_cpuinfo;
 bool __read_mostly acpi_disabled;
 #endif
 
-domid_t __read_mostly max_init_domid;
-
 static __used void init_done(void)
 {
     int rc;
diff --git a/xen/arch/ppc/include/asm/setup.h b/xen/arch/ppc/include/asm/setup.h
index e4f64879b6..956fa6985a 100644
--- a/xen/arch/ppc/include/asm/setup.h
+++ b/xen/arch/ppc/include/asm/setup.h
@@ -1,6 +1,4 @@
 #ifndef __ASM_PPC_SETUP_H__
 #define __ASM_PPC_SETUP_H__
 
-#define max_init_domid (0)
-
 #endif /* __ASM_PPC_SETUP_H__ */
diff --git a/xen/arch/riscv/include/asm/setup.h 
b/xen/arch/riscv/include/asm/setup.h
index c9d69cdf51..d1fc64b673 100644
--- a/xen/arch/riscv/include/asm/setup.h
+++ b/xen/arch/riscv/include/asm/setup.h
@@ -5,8 +5,6 @@
 
 #include <xen/types.h>
 
-#define max_init_domid (0)
-
 void setup_mm(void);
 
 void copy_from_paddr(void *dst, paddr_t paddr, unsigned long len);
diff --git a/xen/arch/x86/include/asm/setup.h b/xen/arch/x86/include/asm/setup.h
index ac34c69855..b67de8577f 100644
--- a/xen/arch/x86/include/asm/setup.h
+++ b/xen/arch/x86/include/asm/setup.h
@@ -69,6 +69,4 @@ extern bool opt_dom0_verbose;
 extern bool opt_dom0_cpuid_faulting;
 extern bool opt_dom0_msr_relaxed;
 
-#define max_init_domid (0)
-
 #endif
diff --git a/xen/common/device-tree/dom0less-build.c 
b/xen/common/device-tree/dom0less-build.c
index 8e38affd0c..4c050b9ded 100644
--- a/xen/common/device-tree/dom0less-build.c
+++ b/xen/common/device-tree/dom0less-build.c
@@ -977,8 +977,6 @@ void __init create_domUs(void)
         domid = domid_alloc(DOMID_INVALID);
         if ( domid == DOMID_INVALID )
             panic("Error allocating ID for domain %s\n", dt_node_name(node));
-        if ( max_init_domid < domid )
-            max_init_domid = domid;
 
         d = domain_create(domid, &d_cfg, flags);
         if ( IS_ERR(d) )
diff --git a/xen/common/domain.c b/xen/common/domain.c
index 6a6cdd991b..90bd42b633 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -2460,6 +2460,35 @@ void domid_free(domid_t domid)
     spin_unlock(&domid_lock);
 }
 
+/*
+ * Find the ID of the next possible console owner domain.
+ *
+ * @return Domain ID: DOMID_XEN or non-system domain IDs within
+ * the range of [0..CONFIG_MAX_DOMID-1].
+ */
+domid_t domid_find_with_input_allowed(domid_t hint)
+{
+    struct domain *d;
+    domid_t domid = DOMID_XEN;
+
+    spin_lock(&domlist_update_lock);
+
+    for ( d = domid_to_domain(hint);
+          d && likely(get_domain(d)) && (d->domain_id < CONFIG_MAX_DOMID);
+          d = d->next_in_list )
+    {
+        if ( d->console.input_allowed )
+        {
+            domid = d->domain_id;
+            break;
+        }
+    }
+
+    spin_unlock(&domlist_update_lock);
+
+    return domid;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c
index ccecda6523..ff20706ac9 100644
--- a/xen/drivers/char/console.c
+++ b/xen/drivers/char/console.c
@@ -462,26 +462,17 @@ static void cf_check dump_console_ring_key(unsigned char 
key)
 
 /*
  * CTRL-<switch_char> changes input direction, rotating among Xen, Dom0,
- * and the DomUs started from Xen at boot.
+ * and the DomUs.
  */
 #define switch_code (opt_conswitch[0]-'a'+1)
-/*
- * console_rx=0 => input to xen
- * console_rx=1 => input to dom0 (or the sole shim domain)
- * console_rx=N => input to dom(N-1)
- */
-static unsigned int __read_mostly console_rx = 0;
 
-#define max_console_rx (max_init_domid + 1)
+/* Console owner domain identifier. */
+static domid_t __read_mostly console_rx = DOMID_XEN;
 
 static struct domain *console_get_domain(void)
 {
-    struct domain *d;
+    struct domain *d = rcu_lock_domain_by_id(console_rx);
 
-    if ( console_rx == 0 )
-            return NULL;
-
-    d = rcu_lock_domain_by_id(console_rx - 1);
     if ( !d )
         return NULL;
 
@@ -499,50 +490,14 @@ static void console_put_domain(struct domain *d)
         rcu_unlock_domain(d);
 }
 
-domid_t console_get_domid(void)
+static void console_set_domid(domid_t domid)
 {
-    if ( console_rx == 0 )
-        return DOMID_XEN;
-    return console_rx - 1;
-}
+    if ( domid == DOMID_XEN )
+        printk("*** Serial input to Xen");
+    else
+        printk("*** Serial input to DOM%u", domid);
 
-static void console_switch_input(void)
-{
-    unsigned int next_rx = console_rx;
-
-    /*
-     * Rotate among Xen, dom0 and boot-time created domUs while skipping
-     * switching serial input to non existing domains.
-     */
-    for ( ; ; )
-    {
-        domid_t domid;
-        struct domain *d;
-
-        if ( next_rx++ >= max_console_rx )
-        {
-            console_rx = 0;
-            printk("*** Serial input to Xen");
-            break;
-        }
-
-        if ( consoled_is_enabled() && next_rx == 1 )
-            domid = get_initial_domain_id();
-        else
-            domid = next_rx - 1;
-        d = rcu_lock_domain_by_id(domid);
-        if ( d )
-        {
-            rcu_unlock_domain(d);
-
-            if ( !d->console.input_allowed )
-                break;
-
-            console_rx = next_rx;
-            printk("*** Serial input to DOM%u", domid);
-            break;
-        }
-    }
+    console_rx = domid;
 
     if ( switch_code )
         printk(" (type 'CTRL-%c' three times to switch input)",
@@ -550,12 +505,35 @@ static void console_switch_input(void)
     printk("\n");
 }
 
+domid_t console_get_domid(void)
+{
+    return console_rx;
+}
+
+/*
+ * Switch console focus.
+ * Rotates input focus among Xen and domains with console input permission.
+ */
+static void console_switch_input(void)
+{
+    domid_t hint;
+
+    if ( console_rx == DOMID_XEN )
+        hint = get_initial_domain_id();
+    else
+        hint = console_rx + 1;
+
+    hint = domid_find_with_input_allowed(hint);
+
+    console_set_domid(hint);
+}
+
 static void __serial_rx(char c)
 {
     struct domain *d;
     int rc = 0;
 
-    if ( console_rx == 0 )
+    if ( console_rx == DOMID_XEN )
         return handle_keypress(c, false);
 
     d = console_get_domain();
@@ -1130,14 +1108,6 @@ void __init console_endboot(void)
 
     video_endboot();
 
-    /*
-     * If user specifies so, we fool the switch routine to redirect input
-     * straight back to Xen. I use this convoluted method so we still print
-     * a useful 'how to switch' message.
-     */
-    if ( opt_conswitch[1] == 'x' )
-        console_rx = max_console_rx;
-
     register_keyhandler('w', dump_console_ring_key,
                         "synchronously dump console ring buffer (dmesg)", 0);
     register_irq_keyhandler('+', &do_inc_thresh,
@@ -1147,8 +1117,8 @@ void __init console_endboot(void)
     register_irq_keyhandler('G', &do_toggle_guest,
                             "toggle host/guest log level adjustment", 0);
 
-    /* Serial input is directed to DOM0 by default. */
-    console_switch_input();
+    if ( opt_conswitch[1] != 'x' )
+        (void)console_set_domid(get_initial_domain_id());
 }
 
 int __init console_has(const char *device)
diff --git a/xen/include/xen/domain.h b/xen/include/xen/domain.h
index 8aab05ae93..a88eb34f3f 100644
--- a/xen/include/xen/domain.h
+++ b/xen/include/xen/domain.h
@@ -36,6 +36,7 @@ void getdomaininfo(struct domain *d, struct 
xen_domctl_getdomaininfo *info);
 void arch_get_domain_info(const struct domain *d,
                           struct xen_domctl_getdomaininfo *info);
 
+domid_t domid_find_with_input_allowed(domid_t hint);
 domid_t get_initial_domain_id(void);
 
 domid_t domid_alloc(domid_t domid);
-- 
2.34.1





 


Rackspace

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