|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v8 01/26] emul/vuart: introduce framework for UART emulators
On 11/11/26 8:47 PM, dmukhin@xxxxxxxx wrote: From: Denis Mukhin <dmukhin@xxxxxxxx> Introduce a driver framework to abstract UART emulators in the hypervisor. That allows for architecture-independent handling of virtual UARTs in the console driver and simplifies enabling new UART emulators. The framework is built under CONFIG_VUART_FRAMEWORK, which will be automatically enabled once the user enables any UART emulator. Current implementation supports maximum of one vUART of each kind per domain. d->console->vuart is a single pointer and vuart_init() returns -EBUSY if it is already set, so it is one vUART per domain in total, not one of each kind. Use new domain_has_vuart() in the console driver code to check whether to forward console input to the domain using vUART. Enable console forwarding over vUART for hardware domains with a vUART. That enables console forwarding to dom0 on x86, since console can be forwarded only to Xen, dom0 and pvshim on x86 as of now. Note: existing vUARTs are deliberately *not* hooked to the new framework to minimize the scope of the patch: vpl011 (i.e. SBSA) emulator and "vuart" (i.e. minimalistic MMIO-mapped dtuart for hwdoms on Arm) are kept unmodified. No functional changes for non-x86 architectures. Signed-off-by: Denis Mukhin <dmukhin@xxxxxxxx> --- xen/arch/arm/xen.lds.S | 1 + xen/arch/ppc/xen.lds.S | 1 + xen/arch/riscv/xen.lds.S | 1 + xen/arch/x86/xen.lds.S | 1 + xen/common/Kconfig | 2 + xen/common/Makefile | 1 + xen/common/emul/Kconfig | 6 ++ xen/common/emul/Makefile | 1 + xen/common/emul/vuart/Kconfig | 6 ++ xen/common/emul/vuart/Makefile | 1 + xen/common/emul/vuart/ns165x50.c | 0 This adds an empty file whose name looks like a typo of ns16x50.c. Please drop it. xen/common/emul/vuart/vuart.c | 173 +++++++++++++++++++++++++++++++ xen/common/keyhandler.c | 3 + xen/drivers/char/console.c | 6 +- xen/include/xen/sched.h | 5 + xen/include/xen/serial.h | 5 + xen/include/xen/vuart.h | 115 ++++++++++++++++++++ xen/include/xen/xen.lds.h | 10 ++ 18 files changed, 337 insertions(+), 1 deletion(-) create mode 100644 xen/common/emul/Kconfig create mode 100644 xen/common/emul/Makefile create mode 100644 xen/common/emul/vuart/Kconfig create mode 100644 xen/common/emul/vuart/Makefile create mode 100644 xen/common/emul/vuart/ns165x50.c create mode 100644 xen/common/emul/vuart/vuart.c create mode 100644 xen/include/xen/vuart.h [...] diff --git a/xen/common/Makefile b/xen/common/Makefile index f69d47d18934..60f2d9087589 100644 --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_DEVICE_TREE_PARSE) += device-tree/ obj-$(CONFIG_IOREQ_SERVER) += dm.o obj-y += domain.o obj-y += domid.o +obj-y += emul/ I think this doesn't make much difference at the moment, but it might be useful to make this conditional so that architectures that don't need any emulators can exclude them and save some space. [...] diff --git a/xen/common/emul/vuart/ns165x50.c b/xen/common/emul/vuart/ns165x50.c new file mode 100644 index 000000000000..e69de29bb2d1 This adds an empty file whose name looks like a typo of ns16x50.c. Please drop it. diff --git a/xen/common/emul/vuart/vuart.c b/xen/common/emul/vuart/vuart.c new file mode 100644 index 000000000000..bd3b756fb4d6 --- /dev/null +++ b/xen/common/emul/vuart/vuart.c @@ -0,0 +1,173 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * UART emulator framework. + * Is this line with only one start really needed? + */ + +#include <asm/types.h> Nit: xen/ headers usually come before asm/ ones.Also, I think it will be better to use xen/types.h to avoid depenendcy in common code from arch-specific headers. This is a prefix match: "ns16550foo" matches "ns16550", and if one emulator's compatible is a prefix of another's, whichever is linked first wins. Is that intended? If not, a plain strcmp() would do. Also, d is unused, and struct vuart_emulator documents compatible as "Cannot be NULL or empty", so the NULL check either isn't needed or the comment should say otherwise, or just ASSERT() will be enough here. + + return NULL; +} + +const static struct vuart * Nit: static const. This has no user in this patch; Wouldn't it better to introduce together with its first user? Also, base_addr is paddr_t while addr/size are unsigned long, and addr + size can wrap; checking "size <= base_addr + vuart->info->size - addr" after the lower bound avoids that. vuart comes from xzalloc() but is released with xvfree() here and with XVFREE() in vuart_deinit(). That works, since xvfree() falls back to xfree(), but please pair the allocators. Also, why a separate allocation for info? Embedding a struct vuart_info in struct vuart would drop one allocation, one error path and the memcpy(). input_allowed is set regardless of VUART_CONSOLE_INPUT, whereas vuart_put_rx() and domain_has_vuart() act only on a vUART with that flag. For a vUART without the flag, the domain becomes selectable with CTRL-a, but all input to it is dropped silently. Should this be conditional on info->flags & VUART_CONSOLE_INPUT? + + return 0; + + err_out2: + xvfree(vuart->info); + err_out1: + xvfree(vuart); + + return rc; +} + +/* + * Release any resources taken by UART emulators. + * + * NB: no flags are cleared, since currently exit() is called only during + * domain destroy. s/exit()/vuart_deinit()/ ? The only caller, dump_domains(), holds rcu_read_lock(&domlist_read_lock) rather than rcu_lock_domain(). That is fine, but the comment should match. [...] --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -33,6 +33,7 @@ #include <xen/dom0less-build.h> #include <xen/sections.h> #include <xen/consoled.h> +#include <xen/vuart.h>#ifdef CONFIG_X86 The NB is now inside the block it refers to, which makes it hard to follow. Since the condition itself excludes a hwdom with a vUART, does the order still matter? If it does, I'd put the note above the if (). ns16x50_put_rx() (10/26) returns -EBUSY while LCR.DLAB is set, DLL is 0 or MCR.LOOP is set, i.e. while the guest is programming the UART, so every character typed in that window is dropped and the warning belowis printed for each of them. Are we okay with that spam even during a short peroid? struct domain_console only needs a pointer, so a forward declaration "struct vuart;" is enough.
Today struct vuart_info describes a *physical* UART: ns16550.c, cadence-uart.c and mvebu-uart.c fill it in for Arm's hwdom vuart. With this change it also becomes the configuration of an *emulated* one, so every physical driver's instance grows fields that are meaningless for it, and data_off/status_off/status are meaningless for an emulator. A separate structure for the emulator configuration would keep the two apart. struct serial_port {diff --git a/xen/include/xen/vuart.h b/xen/include/xen/vuart.h new file mode 100644 index 000000000000..b5785b3c6b8f --- /dev/null +++ b/xen/include/xen/vuart.h @@ -0,0 +1,115 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * UART emulator framework. + * It seems like this line with start should be dropped, shouldn't it? As long as the name clashes with Arm's struct vuart, the framework can't be enabled on Arm. Picking a non-clashing name now looks simpler than carrying the FIXME. These two are declared outside the #ifdef with no stubs. The console.c call builds with the framework off only because domain_has_vuart() is an inline returning false and the call gets eliminated. I'd move both under the #ifdef, next to the other declarations, with a stub for vuart_put_rx(). git reports "new blank line at EOF" here. diff --git a/xen/include/xen/xen.lds.h b/xen/include/xen/xen.lds.h index 958f8256b0fa..5e630d371471 100644 --- a/xen/include/xen/xen.lds.h +++ b/xen/include/xen/xen.lds.h @@ -231,6 +231,16 @@ #define VPCI_ARRAY #endif+#ifdef CONFIG_VUART_FRAMEWORK+#define VUART_ARRAY \ + . = ALIGN(POINTER_ALIGN); \ + vuart_array_start = .; \ + *(.data.rel.ro.vuart) \ + vuart_array_end = .; Nit: VPCI_ARRAY right above uses __start_vpci_array/__end_vpci_array; __start_vuart_array/__end_vuart_array would be consistent. ~ Oleksii
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |