From nobody Tue Sep 9 16:44:13 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1757114864; cv=none; d=zohomail.com; s=zohoarc; b=aBc0Oy6EChJnRMIJ8F55EaBP3fjVMBEjePjFotx28/CWvY2dCiYAd5BoOmIJkc1FENYyqfmcTt09PcSCKiziib6gh9bSIxDNQeCzbq5Q/18hlD9LLDuOLFIYkXvJbVIL+1iPATGQv/gLyCPreWRbUShfiRzwJmepv1DZtdphruE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757114864; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=MYkyC6HYAaTUnjoaK5ptXN+ThND9+Vyev3ekOb2IdWs=; b=GvbUIDWvTKfvMQy7415DYOlDJC11vg83xcnbpyNy0em8iJK1osZl3FKtN6SuxctZE+mB74TxIu5Bz2Jh+emEk72VNQ8hxdcl0vmpx9Fuv2BSRepGRz53z0zAg2lc0mhvLlq9z3ABPsrJqsjjp4/CVx6uAFE2G2asY1fMNfjJHzo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1757114864409979.5550121323216; Fri, 5 Sep 2025 16:27:44 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1112629.1460833 (Exim 4.92) (envelope-from ) id 1uufpy-0001RU-Pq; Fri, 05 Sep 2025 23:27:22 +0000 Received: by outflank-mailman (output) from mailman id 1112629.1460833; Fri, 05 Sep 2025 23:27:22 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufpy-0001RN-N2; Fri, 05 Sep 2025 23:27:22 +0000 Received: by outflank-mailman (input) for mailman id 1112629; Fri, 05 Sep 2025 23:27:20 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufpw-0001D3-5F for xen-devel@lists.xenproject.org; Fri, 05 Sep 2025 23:27:20 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uufpv-008AAR-1f; Fri, 05 Sep 2025 23:27:19 +0000 Received: from [19.12.91.86] (helo=localhost) by xenbits.xenproject.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1uufpv-0005Cq-1W; Fri, 05 Sep 2025 23:27:19 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org; s=20200302mail; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From; bh=MYkyC6HYAaTUnjoaK5ptXN+ThND9+Vyev3ekOb2IdWs=; b=xvoeLoJZGZHuCKx2sFifB+DACp 3ZajkUZdufXzQrU1RtfyA3KBzWWw3frwXnuaByOFGCNivT0ozEAHgDS3Q/DjX/jL7Brs9Kmh+1MO9 KmDrkBg2qzULo5xzGEGV8kGeruFJFZYR82vHZHvydO8j1kh2oLl4aM3rDrUlOlFknrmI=; From: dmukhin@xen.org To: xen-devel@lists.xenproject.org Cc: andrew.cooper3@citrix.com, anthony.perard@vates.tech, jbeulich@suse.com, julien@xen.org, michal.orzel@amd.com, roger.pau@citrix.com, sstabellini@kernel.org, dmukhin@ford.com Subject: [PATCH v6 01/15] emul/vuart: introduce framework for UART emulators Date: Fri, 5 Sep 2025 16:27:00 -0700 Message-ID: <20250905232715.440758-2-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250905232715.440758-1-dmukhin@ford.com> References: <20250905232715.440758-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757114866603116600 Content-Type: text/plain; charset="utf-8" From: Denis Mukhin =20 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 domai= n. 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 o= nly 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 Reviewed-by: Stefano Stabellini --- Changes since v5: - addressed v5 feedback - Link to v5: https://lore.kernel.org/xen-devel/20250828235409.2835815-2-dm= ukhin@ford.com/ --- 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/vuart.c | 157 +++++++++++++++++++++++++++++++++ xen/common/keyhandler.c | 3 + xen/drivers/char/console.c | 6 +- xen/include/xen/sched.h | 4 + xen/include/xen/serial.h | 3 + xen/include/xen/vuart.h | 116 ++++++++++++++++++++++++ xen/include/xen/xen.lds.h | 10 +++ 17 files changed, 319 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/vuart.c create mode 100644 xen/include/xen/vuart.h diff --git a/xen/arch/arm/xen.lds.S b/xen/arch/arm/xen.lds.S index db17ff1efa98..cd05b18770f4 100644 --- a/xen/arch/arm/xen.lds.S +++ b/xen/arch/arm/xen.lds.S @@ -58,6 +58,7 @@ SECTIONS *(.rodata) *(.rodata.*) VPCI_ARRAY + VUART_ARRAY *(.data.rel.ro) *(.data.rel.ro.*) =20 diff --git a/xen/arch/ppc/xen.lds.S b/xen/arch/ppc/xen.lds.S index 1de0b77fc6b9..f9d4e5b0dcd8 100644 --- a/xen/arch/ppc/xen.lds.S +++ b/xen/arch/ppc/xen.lds.S @@ -52,6 +52,7 @@ SECTIONS *(.rodata) *(.rodata.*) VPCI_ARRAY + VUART_ARRAY *(.data.rel.ro) *(.data.rel.ro.*) =20 diff --git a/xen/arch/riscv/xen.lds.S b/xen/arch/riscv/xen.lds.S index edcadff90bfe..59dcaa5fef9a 100644 --- a/xen/arch/riscv/xen.lds.S +++ b/xen/arch/riscv/xen.lds.S @@ -47,6 +47,7 @@ SECTIONS *(.rodata) *(.rodata.*) VPCI_ARRAY + VUART_ARRAY *(.data.rel.ro) *(.data.rel.ro.*) =20 diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S index 966e514f2034..d877b93a6964 100644 --- a/xen/arch/x86/xen.lds.S +++ b/xen/arch/x86/xen.lds.S @@ -132,6 +132,7 @@ SECTIONS *(.rodata) *(.rodata.*) VPCI_ARRAY + VUART_ARRAY *(.data.rel.ro) *(.data.rel.ro.*) =20 diff --git a/xen/common/Kconfig b/xen/common/Kconfig index 76f9ce705f7a..78a32b69e2b2 100644 --- a/xen/common/Kconfig +++ b/xen/common/Kconfig @@ -676,4 +676,6 @@ config PM_STATS Enable collection of performance management statistics to aid in analyzing and tuning power/performance characteristics of the system =20 +source "common/emul/Kconfig" + endmenu diff --git a/xen/common/Makefile b/xen/common/Makefile index 0c7d0f5d46e1..8c8462565050 100644 --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_DEVICE_TREE_PARSE) +=3D device-tree/ obj-$(CONFIG_IOREQ_SERVER) +=3D dm.o obj-y +=3D domain.o obj-y +=3D domid.o +obj-y +=3D emul/ obj-y +=3D event_2l.o obj-y +=3D event_channel.o obj-$(CONFIG_EVTCHN_FIFO) +=3D event_fifo.o diff --git a/xen/common/emul/Kconfig b/xen/common/emul/Kconfig new file mode 100644 index 000000000000..7c6764d1756b --- /dev/null +++ b/xen/common/emul/Kconfig @@ -0,0 +1,6 @@ +menu "Domain Emulation Features" + visible if EXPERT + +source "common/emul/vuart/Kconfig" + +endmenu diff --git a/xen/common/emul/Makefile b/xen/common/emul/Makefile new file mode 100644 index 000000000000..ae0b575c3901 --- /dev/null +++ b/xen/common/emul/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_VUART_FRAMEWORK) +=3D vuart/ diff --git a/xen/common/emul/vuart/Kconfig b/xen/common/emul/vuart/Kconfig new file mode 100644 index 000000000000..ce1b976b7da7 --- /dev/null +++ b/xen/common/emul/vuart/Kconfig @@ -0,0 +1,6 @@ +config VUART_FRAMEWORK + bool + +menu "UART Emulation" + +endmenu diff --git a/xen/common/emul/vuart/Makefile b/xen/common/emul/vuart/Makefile new file mode 100644 index 000000000000..97f792dc6641 --- /dev/null +++ b/xen/common/emul/vuart/Makefile @@ -0,0 +1 @@ +obj-y +=3D vuart.o diff --git a/xen/common/emul/vuart/vuart.c b/xen/common/emul/vuart/vuart.c new file mode 100644 index 000000000000..3dfcba217248 --- /dev/null +++ b/xen/common/emul/vuart/vuart.c @@ -0,0 +1,157 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * UART emulator framework. + * + * Copyright 2025 Ford Motor Company + */ + +#include +#include +#include +#include + +#define for_each_emulator(e) \ + for ( e =3D vuart_array_start; e < vuart_array_end; e++ ) + +extern const struct vuart_emulator vuart_array_start[]; +extern const struct vuart_emulator vuart_array_end[]; + +static const struct vuart_emulator * +vuart_match_by_compatible(const struct domain *d, const char *compat) +{ + const struct vuart_emulator *emulator; + + for_each_emulator(emulator) + if ( emulator->compatible && + !strncmp(compat, emulator->compatible, + strlen(emulator->compatible)) ) + return emulator; + + return NULL; +} + +const static struct vuart * +vuart_find_by_console_permission(const struct domain *d) +{ + const struct vuart *vuart =3D d->console.vuart; + + if ( !vuart || !vuart->emulator || !vuart->emulator->put_rx || + !(vuart->flags & VUART_CONSOLE_INPUT)) + return NULL; + + return vuart; +} + +struct vuart *vuart_find_by_io_range(struct domain *d, unsigned long addr, + unsigned long size) +{ + struct vuart *vuart =3D d->console.vuart; + + if ( !vuart || !vuart->info ) + return NULL; + + if ( addr >=3D vuart->info->base_addr && + addr + size - 1 <=3D vuart->info->base_addr + vuart->info->size -= 1 ) + return vuart; + + return NULL; +} + +int vuart_init(struct domain *d, struct vuart_info *info) +{ + const struct vuart_emulator *emulator; + struct vuart *vuart; + int rc; + + if ( d->console.vuart ) + return -EBUSY; + + emulator =3D vuart_match_by_compatible(d, info->compatible); + if ( !emulator ) + return -ENODEV; + + vuart =3D xzalloc(typeof(*vuart)); + if ( !vuart ) + return -ENOMEM; + + vuart->info =3D xvzalloc(typeof(*info)); + if ( !vuart->info ) + { + rc =3D -ENOMEM; + goto err_out; + } + memcpy(vuart->info, info, sizeof(*info)); + + vuart->vdev =3D emulator->alloc(d, vuart->info); + if ( IS_ERR(vuart->vdev) ) + { + rc =3D PTR_ERR(vuart->vdev); + goto err_out; + } + + vuart->emulator =3D emulator; + vuart->owner =3D d; + vuart->flags |=3D VUART_CONSOLE_INPUT; + + d->console.input_allowed =3D true; + d->console.vuart =3D vuart; + + return 0; + + err_out: + if ( vuart ) + xvfree(vuart->info); + 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. + */ +void vuart_deinit(struct domain *d) +{ + struct vuart *vuart =3D d->console.vuart; + + if ( vuart ) + { + vuart->emulator->free(vuart->vdev); + xvfree(vuart->info); + } + XVFREE(d->console.vuart); +} + +void vuart_dump_state(const struct domain *d) +{ + struct vuart *vuart =3D d->console.vuart; + + if ( vuart ) + vuart->emulator->dump_state(vuart->vdev); +} + +/* + * Put character to the *first* suitable emulated UART's FIFO. + */ +int vuart_put_rx(struct domain *d, char c) +{ + const struct vuart *vuart =3D vuart_find_by_console_permission(d); + + return vuart ? vuart->emulator->put_rx(vuart->vdev, c) : -ENODEV; +} + +bool domain_has_vuart(const struct domain *d) +{ + return vuart_find_by_console_permission(d); +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/common/keyhandler.c b/xen/common/keyhandler.c index cb6df2823b00..156e64d9eb58 100644 --- a/xen/common/keyhandler.c +++ b/xen/common/keyhandler.c @@ -22,6 +22,7 @@ #include #include #include +#include #include =20 static unsigned char keypress_key; @@ -352,6 +353,8 @@ static void cf_check dump_domains(unsigned char key) v->periodic_period / 1000000); } } + + vuart_dump_state(d); } =20 for_each_domain ( d ) diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c index 9bd5b4825da6..d5164897a776 100644 --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -33,6 +33,7 @@ #include #include #include +#include =20 #ifdef CONFIG_X86 #include @@ -596,11 +597,12 @@ static void __serial_rx(char c) if ( !d ) return; =20 - if ( is_hardware_domain(d) ) + if ( is_hardware_domain(d) && !domain_has_vuart(d) ) { /* * Deliver input to the hardware domain buffer, unless it is * already full. + * NB: must be the first check: hardware domain may have emulated = UART. */ if ( (serial_rx_prod - serial_rx_cons) !=3D SERIAL_RX_SIZE ) serial_rx_ring[SERIAL_RX_MASK(serial_rx_prod++)] =3D c; @@ -611,6 +613,8 @@ static void __serial_rx(char c) */ send_global_virq(VIRQ_CONSOLE); } + else if ( domain_has_vuart(d) ) + rc =3D vuart_put_rx(d, c); #ifdef CONFIG_SBSA_VUART_CONSOLE else /* Deliver input to the emulated UART. */ diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 02bdc256ce37..613f4596e33d 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -660,6 +661,9 @@ struct domain struct { /* Permission to take ownership of the physical console input. */ bool input_allowed; +#ifdef CONFIG_VUART_FRAMEWORK + struct vuart *vuart; +#endif } console; } __aligned(PAGE_SIZE); =20 diff --git a/xen/include/xen/serial.h b/xen/include/xen/serial.h index 8e1844555208..123eee67df35 100644 --- a/xen/include/xen/serial.h +++ b/xen/include/xen/serial.h @@ -36,6 +36,9 @@ struct vuart_info { unsigned long data_off; /* Data register offset */ unsigned long status_off; /* Status register offset */ unsigned long status; /* Ready status value */ + unsigned int irq; /* Interrupt */ + char compatible[16]; /* Compatible string */ + char name[16]; /* User-friendly name */ }; =20 struct serial_port { diff --git a/xen/include/xen/vuart.h b/xen/include/xen/vuart.h new file mode 100644 index 000000000000..54f2f29f3f4a --- /dev/null +++ b/xen/include/xen/vuart.h @@ -0,0 +1,116 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * UART emulator framework. + * + * Copyright 2025 Ford Motor Company + */ + +#ifndef XEN_VUART_H +#define XEN_VUART_H + +#include +#include + +struct vuart_emulator; + +enum { + VUART_CONSOLE_INPUT =3D BIT(0, U), /* Physical console input forwardin= g. */ +}; + + +/* + * FIXME: #ifdef is temporary to avoid clash with + * arch/arm/include/asm/domain.h + */ +#ifdef CONFIG_VUART_FRAMEWORK +struct vuart { + const struct vuart_emulator *emulator; + struct vuart_info *info; + struct domain *owner; + uint32_t flags; + void *vdev; +}; +#endif + +struct vuart_emulator { + /* UART compatible string. Cannot be NULL or empty. */ + const char *compatible; + + /* + * Allocate emulated UART state (RX/TX FIFOs, locks, initialize regist= ers, + * hook I/O handlers, etc.) + * Cannot be NULL. + */ + void *(*alloc)(struct domain *d, const struct vuart_info *info); + + /* + * Release resources used to emulate UART state (flush RX/TX FIFOs, un= hook + * I/O handlers, etc.). + * Cannot be NULL. + */ + void (*free)(void *arg); + + /* + * Print emulated UART state, including registers, on the console. + * Can be NULL. + */ + void (*dump_state)(void *arg); + + /* + * Place character to the emulated RX FIFO. + * Used to forward physical console input to the guest OS. + * Can be NULL. + */ + int (*put_rx)(void *arg, char c); +}; + +#define VUART_REGISTER(name, x) \ + static const struct vuart_emulator name##_entry \ + __used_section(".data.rel.ro.vuart") =3D x + +struct vuart *vuart_find_by_io_range(struct domain *d, + unsigned long base_addr, + unsigned long size); + +int vuart_put_rx(struct domain *d, char c); + +#ifdef CONFIG_VUART_FRAMEWORK + +int vuart_init(struct domain *d, struct vuart_info *info); +void vuart_deinit(struct domain *d); +void vuart_dump_state(const struct domain *d); +bool domain_has_vuart(const struct domain *d); + +#else + +static inline int vuart_init(struct domain *d, struct vuart_info *info) +{ + return 0; +} + +static inline void vuart_deinit(struct domain *d) +{ +} + +static inline void vuart_dump_state(const struct domain *d) +{ +} + +static inline bool domain_has_vuart(const struct domain *d) +{ + return false; +} + +#endif /* CONFIG_VUART_FRAMEWORK */ + +#endif /* XEN_VUART_H */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ + diff --git a/xen/include/xen/xen.lds.h b/xen/include/xen/xen.lds.h index b126dfe88792..2d65f32ddad3 100644 --- a/xen/include/xen/xen.lds.h +++ b/xen/include/xen/xen.lds.h @@ -194,4 +194,14 @@ #define VPCI_ARRAY #endif =20 +#ifdef CONFIG_VUART_FRAMEWORK +#define VUART_ARRAY \ + . =3D ALIGN(POINTER_ALIGN); \ + vuart_array_start =3D .; \ + *(.data.rel.ro.vuart) \ + vuart_array_end =3D .; +#else +#define VUART_ARRAY +#endif + #endif /* __XEN_LDS_H__ */ --=20 2.51.0 From nobody Tue Sep 9 16:44:13 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1757114868; cv=none; d=zohomail.com; s=zohoarc; b=hHIKgckASo4ww79Zyp6DdHUyf2YOwgqNISi3pccexv7DiA5RSp3/i90dWG/GmbiaOB/XHZ0kKXybu3+5hI75X95r+4cbZZ6L19Y2Gsrr0wQqExNPRN+/hWW3NaijmcLcyOJytQ2mJv5nSS8a6G5ztljlLbA1DYnVUW2QqIC85rM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757114868; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=BLpK09VTDg88f7evdVDCZeeMR5D19RIklWweqNvteTE=; b=hEq1M4h4Rer+MxItXEyftDFgTQbnkmO7NJeu8p7bXf9tBt34hnh8XLySX8GKT9Jr5t0Rrjz/ZzUp87IuKGIk//XusUvg8h16Idileeo/8C9qHUhpTg1tWYRqkRTinltsDt7o+OxS2D7o5oacZGQ8CAaN30PDgIcLpKONhwtRio0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1757114868568687.9361689812828; Fri, 5 Sep 2025 16:27:48 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1112630.1460840 (Exim 4.92) (envelope-from ) id 1uufpz-0001Ue-4M; Fri, 05 Sep 2025 23:27:23 +0000 Received: by outflank-mailman (output) from mailman id 1112630.1460840; Fri, 05 Sep 2025 23:27:23 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufpy-0001Tp-T2; Fri, 05 Sep 2025 23:27:22 +0000 Received: by outflank-mailman (input) for mailman id 1112630; Fri, 05 Sep 2025 23:27:21 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufpx-0001Qb-93 for xen-devel@lists.xenproject.org; Fri, 05 Sep 2025 23:27:21 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uufpw-008AAa-28; Fri, 05 Sep 2025 23:27:20 +0000 Received: from [19.12.91.86] (helo=localhost) by xenbits.xenproject.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1uufpw-0005Cu-1y; Fri, 05 Sep 2025 23:27:20 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org; s=20200302mail; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From; bh=BLpK09VTDg88f7evdVDCZeeMR5D19RIklWweqNvteTE=; b=B3yHWL2D8KrVQOzUca14u0fQ/r Z1XbAhgdfMP6xZpMdCJlLmAjoxj5x5Z4dqTvA9M8L8nXzsv607MCjND/0YJsUeHjwzewx6pRzEdP2 /T5rxeeTKKAmDQxoQ/CUdp4tKjJjtTMqm6xRcnWyl6YGaSfha8bnydcDo7Y4A3XQouSU=; From: dmukhin@xen.org To: xen-devel@lists.xenproject.org Cc: andrew.cooper3@citrix.com, anthony.perard@vates.tech, jbeulich@suse.com, julien@xen.org, michal.orzel@amd.com, roger.pau@citrix.com, sstabellini@kernel.org, dmukhin@ford.com Subject: [PATCH v6 02/15] xen/8250-uart: update definitions Date: Fri, 5 Sep 2025 16:27:01 -0700 Message-ID: <20250905232715.440758-3-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250905232715.440758-1-dmukhin@ford.com> References: <20250905232715.440758-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757114870774116600 Content-Type: text/plain; charset="utf-8" From: Denis Mukhin =20 Added missing definitions needed for NS16550 UART emulator. Newly introduced MSR definitions re-used in the existing ns16550 driver. Also, corrected FCR DMA definition bit#3 (0x08) as per: https://www.ti.com/lit/ds/symlink/tl16c550c.pdf See "7.7.2 FIFO Control Register (FCR)". Signed-off-by: Denis Mukhin Reviewed-by: Stefano Stabellini --- Changes since v5: - fixed commentaries - Link to v5: https://lore.kernel.org/xen-devel/20250828235409.2835815-3-dm= ukhin@ford.com/ --- xen/drivers/char/ns16550.c | 16 ++++++------ xen/include/xen/8250-uart.h | 50 ++++++++++++++++++++++++++++++------- 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c index df7fff7f81df..0e80fadbb894 100644 --- a/xen/drivers/char/ns16550.c +++ b/xen/drivers/char/ns16550.c @@ -388,7 +388,7 @@ static void __init cf_check ns16550_init_preirq(struct = serial_port *port) =20 /* Check this really is a 16550+. Otherwise we have no FIFOs. */ if ( uart->fifo_size <=3D 1 && - ((ns_read_reg(uart, UART_IIR) & 0xc0) =3D=3D 0xc0) && + ((ns_read_reg(uart, UART_IIR) & UART_IIR_FE) =3D=3D UART_IIR_FE) = && ((ns_read_reg(uart, UART_FCR) & UART_FCR_TRG14) =3D=3D UART_FCR_T= RG14) ) uart->fifo_size =3D 16; } @@ -728,20 +728,20 @@ static int __init check_existence(struct ns16550 *uar= t) * Mask out IER[7:4] bits for test as some UARTs (e.g. TL * 16C754B) allow only to modify them if an EFR bit is set. */ - scratch2 =3D ns_read_reg(uart, UART_IER) & 0x0f; - ns_write_reg(uart,UART_IER, 0x0F); - scratch3 =3D ns_read_reg(uart, UART_IER) & 0x0f; + scratch2 =3D ns_read_reg(uart, UART_IER) & UART_IER_MASK; + ns_write_reg(uart, UART_IER, UART_IER_MASK); + scratch3 =3D ns_read_reg(uart, UART_IER) & UART_IER_MASK; ns_write_reg(uart, UART_IER, scratch); - if ( (scratch2 !=3D 0) || (scratch3 !=3D 0x0F) ) + if ( (scratch2 !=3D 0) || (scratch3 !=3D UART_IER_MASK) ) return 0; =20 /* * Check to see if a UART is really there. * Use loopback test mode. */ - ns_write_reg(uart, UART_MCR, UART_MCR_LOOP | 0x0A); - status =3D ns_read_reg(uart, UART_MSR) & 0xF0; - return (status =3D=3D 0x90); + ns_write_reg(uart, UART_MCR, UART_MCR_LOOP | UART_MCR_RTS | UART_MCR_O= UT2); + status =3D ns_read_reg(uart, UART_MSR) & UART_MSR_STATUS; + return (status =3D=3D (UART_MSR_CTS | UART_MSR_DCD)); } =20 #ifdef CONFIG_HAS_PCI diff --git a/xen/include/xen/8250-uart.h b/xen/include/xen/8250-uart.h index d13352940c13..bbbffb14d320 100644 --- a/xen/include/xen/8250-uart.h +++ b/xen/include/xen/8250-uart.h @@ -32,6 +32,7 @@ #define UART_MCR 0x04 /* Modem control */ #define UART_LSR 0x05 /* line status */ #define UART_MSR 0x06 /* Modem status */ +#define UART_SCR 0x07 /* Scratch pad */ #define UART_USR 0x1f /* Status register (DW) */ #define UART_DLL 0x00 /* divisor latch (ls) (DLAB=3D1) */ #define UART_DLM 0x01 /* divisor latch (ms) (DLAB=3D1) */ @@ -42,6 +43,8 @@ #define UART_IER_ETHREI 0x02 /* tx reg. empty */ #define UART_IER_ELSI 0x04 /* rx line status */ #define UART_IER_EMSI 0x08 /* MODEM status */ +#define UART_IER_MASK \ + (UART_IER_ERDAI | UART_IER_ETHREI | UART_IER_ELSI | UART_IER_EMSI) =20 /* Interrupt Identification Register */ #define UART_IIR_NOINT 0x01 /* no interrupt pending */ @@ -51,12 +54,19 @@ #define UART_IIR_THR 0x02 /* - tx reg. empty */ #define UART_IIR_MSI 0x00 /* - MODEM status */ #define UART_IIR_BSY 0x07 /* - busy detect (DW) */ +#define UART_IIR_FE 0xc0 /* FIFO enabled (2 bits) */ =20 /* FIFO Control Register */ -#define UART_FCR_ENABLE 0x01 /* enable FIFO */ -#define UART_FCR_CLRX 0x02 /* clear Rx FIFO */ -#define UART_FCR_CLTX 0x04 /* clear Tx FIFO */ -#define UART_FCR_DMA 0x10 /* enter DMA mode */ +#define UART_FCR_ENABLE BIT(0, U) /* enable FIFO */ +#define UART_FCR_CLRX BIT(1, U) /* clear Rx FIFO */ +#define UART_FCR_CLTX BIT(2, U) /* clear Tx FIFO */ +#define UART_FCR_DMA BIT(3, U) /* enter DMA mode */ +#define UART_FCR_RESERVED0 BIT(4, U) /* reserved; always 0 */ +#define UART_FCR_RESERVED1 BIT(5, U) /* reserved; always 0 */ +#define UART_FCR_RTB0 BIT(6, U) /* receiver trigger bit #0 */ +#define UART_FCR_RTB1 BIT(7, U) /* receiver trigger bit #1 */ +#define UART_FCR_TRG_MASK (UART_FCR_RTB0 | UART_FCR_RTB1) + #define UART_FCR_TRG1 0x00 /* Rx FIFO trig lev 1 */ #define UART_FCR_TRG4 0x40 /* Rx FIFO trig lev 4 */ #define UART_FCR_TRG8 0x80 /* Rx FIFO trig lev 8 */ @@ -96,11 +106,32 @@ #define UART_LCR_CONF_MODE_B 0xBF /* Configuration mode B */ =20 /* Modem Control Register */ -#define UART_MCR_DTR 0x01 /* Data Terminal Ready */ -#define UART_MCR_RTS 0x02 /* Request to Send */ -#define UART_MCR_OUT2 0x08 /* OUT2: interrupt mask */ -#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */ -#define UART_MCR_TCRTLR 0x40 /* Access TCR/TLR (TI16C752, EFR[4]=3D1)= */ +#define UART_MCR_DTR BIT(0, U) /* Data Terminal Ready */ +#define UART_MCR_RTS BIT(1, U) /* Request to Send */ +#define UART_MCR_OUT1 BIT(2, U) /* Output #1 */ +#define UART_MCR_OUT2 BIT(3, U) /* Output #2 */ +#define UART_MCR_LOOP BIT(4, U) /* Enable loopback test mode */ +#define UART_MCR_RESERVED0 BIT(5, U) /* Reserved #0 */ +#define UART_MCR_TCRTLR BIT(6, U) /* Access TCR/TLR (TI16C752, E= FR[4]=3D1) */ +#define UART_MCR_RESERVED1 BIT(7, U) /* Reserved #1 */ +#define UART_MCR_MASK \ + (UART_MCR_DTR | UART_MCR_RTS | \ + UART_MCR_OUT1 | UART_MCR_OUT2 | \ + UART_MCR_LOOP | UART_MCR_TCRTLR) + +/* Modem Status Register */ +#define UART_MSR_DCTS BIT(0, U) /* Change in CTS */ +#define UART_MSR_DDSR BIT(1, U) /* Change in DSR */ +#define UART_MSR_TERI BIT(2, U) /* Change in RI */ +#define UART_MSR_DDCD BIT(3, U) /* Change in DCD */ +#define UART_MSR_CTS BIT(4, U) +#define UART_MSR_DSR BIT(5, U) +#define UART_MSR_RI BIT(6, U) +#define UART_MSR_DCD BIT(7, U) +#define UART_MSR_CHANGE \ + (UART_MSR_DCTS | UART_MSR_DDSR | UART_MSR_TERI | UART_MSR_DDCD) +#define UART_MSR_STATUS \ + (UART_MSR_CTS | UART_MSR_DSR | UART_MSR_RI | UART_MSR_DCD) =20 /* Line Status Register */ #define UART_LSR_DR 0x01 /* Data ready */ @@ -111,6 +142,7 @@ #define UART_LSR_THRE 0x20 /* Xmit hold reg empty */ #define UART_LSR_TEMT 0x40 /* Xmitter empty */ #define UART_LSR_ERR 0x80 /* Error */ +#define UART_LSR_MASK (UART_LSR_OE | UART_LSR_BI) =20 /* These parity settings can be ORed directly into the LCR. */ #define UART_PARITY_NONE (0<<3) --=20 2.51.0 From nobody Tue Sep 9 16:44:13 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1757114865; cv=none; d=zohomail.com; s=zohoarc; b=FGRfJE/8zmxwLkFXXJUcx6h1NEZ1Aq5Mk6B9TzSMO+IaEb4ctPFLc23D8OrHTbMBccvmdnUNgDRYg0tOc8IpM93oYg5E37kfRFlG3Ga0JNwUpHESSNBpdCbEYDWHzglauE/w6MAe7PGsOjAS/iioRRBR39AJkhSiPXk5bO9SosE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757114865; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=a/PKwkvx+jRfizPoTGFi+ZYi2s0jTs51XDlTfdQiefc=; b=nQIsj9kdjScl+nWmHr3jSQCjX34Tp/Ywmkrs6qr7LxQlnckBkbzzBy9bAmVya2tKYoJMoOJiB2uUdujNTfEzXBLSFsbvIq1LlaXgVrraMJGi8EjLdYgBJSNB/6P8G7lb8lKnJQuV3ueWEmALs11O6jK9HBb2RoINMKBh86s4HlU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1757114864999600.9765602292059; Fri, 5 Sep 2025 16:27:44 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1112631.1460853 (Exim 4.92) (envelope-from ) id 1uufq0-0001th-At; Fri, 05 Sep 2025 23:27:24 +0000 Received: by outflank-mailman (output) from mailman id 1112631.1460853; Fri, 05 Sep 2025 23:27:24 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufq0-0001tR-53; Fri, 05 Sep 2025 23:27:24 +0000 Received: by outflank-mailman (input) for mailman id 1112631; Fri, 05 Sep 2025 23:27:22 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufpy-0001R9-FT for xen-devel@lists.xenproject.org; Fri, 05 Sep 2025 23:27:22 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uufpx-008AAl-2a; Fri, 05 Sep 2025 23:27:22 +0000 Received: from [19.12.91.86] (helo=localhost) by xenbits.xenproject.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1uufpx-0005Cy-2T; Fri, 05 Sep 2025 23:27:21 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org; s=20200302mail; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From; bh=a/PKwkvx+jRfizPoTGFi+ZYi2s0jTs51XDlTfdQiefc=; b=NU8wi0uDuTeYxPBth12ouKpgqn 3doxCkbMyORTJZ1lDYrN7PSMUW8RKxO2an3Mstd3CLAXSOuySjk4lQwMPiBDNVCjpc/UNCqgPVP6Y bBa44ogdVmpQFmG+UQaq38mV9dO9Wtpna9lZnYHRZPIBSxPEmSRV49BlzfkoYNdTF55M=; From: dmukhin@xen.org To: xen-devel@lists.xenproject.org Cc: andrew.cooper3@citrix.com, anthony.perard@vates.tech, jbeulich@suse.com, julien@xen.org, michal.orzel@amd.com, roger.pau@citrix.com, sstabellini@kernel.org, dmukhin@ford.com Subject: [PATCH v6 03/15] emul/ns16x50: implement emulator stub Date: Fri, 5 Sep 2025 16:27:02 -0700 Message-ID: <20250905232715.440758-4-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250905232715.440758-1-dmukhin@ford.com> References: <20250905232715.440758-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757114866557116600 Content-Type: text/plain; charset="utf-8" From: Denis Mukhin =20 The change is the first on the way on introducing minimally functional NS16550-compatible UART emulator. Define UART state and a set of emulated registers. Implement alloc/free vUART hooks. Stub out I/O port handler. Add initialization of the NS16x50-compatible UART emulator state machine. Plumb debug logging. Signed-off-by: Denis Mukhin --- Changes since v5: - v5 feedback - Link to v5: https://lore.kernel.org/xen-devel/20250828235409.2835815-4-dm= ukhin@ford.com/ --- xen/arch/x86/hvm/hvm.c | 21 ++ xen/common/emul/vuart/Kconfig | 19 ++ xen/common/emul/vuart/Makefile | 1 + xen/common/emul/vuart/ns16x50.c | 366 ++++++++++++++++++++++++++++++++ 4 files changed, 407 insertions(+) create mode 100644 xen/common/emul/vuart/ns16x50.c diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 23bd7f078a1d..91c971f11e14 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -689,6 +690,22 @@ int hvm_domain_initialise(struct domain *d, if ( rc !=3D 0 ) goto fail1; =20 + /* Limit NS16550 emulator for dom0 only for now. */ + if ( IS_ENABLED(CONFIG_VUART_NS16X50) && is_hardware_domain(d) ) + { + struct vuart_info info =3D { + .name =3D "COM2", + .compatible =3D "ns16550", + .base_addr =3D 0x2f8, + .size =3D 8, + .irq =3D 3, + }; + + rc =3D vuart_init(d, &info); + if ( rc ) + goto out_vioapic_deinit; + } + stdvga_init(d); =20 rtc_init(d); @@ -712,6 +729,8 @@ int hvm_domain_initialise(struct domain *d, return 0; =20 fail2: + vuart_deinit(d); + out_vioapic_deinit: vioapic_deinit(d); fail1: if ( is_hardware_domain(d) ) @@ -774,6 +793,8 @@ void hvm_domain_destroy(struct domain *d) if ( hvm_funcs.domain_destroy ) alternative_vcall(hvm_funcs.domain_destroy, d); =20 + vuart_deinit(d); + vioapic_deinit(d); =20 XFREE(d->arch.hvm.pl_time); diff --git a/xen/common/emul/vuart/Kconfig b/xen/common/emul/vuart/Kconfig index ce1b976b7da7..a27d7ca135af 100644 --- a/xen/common/emul/vuart/Kconfig +++ b/xen/common/emul/vuart/Kconfig @@ -3,4 +3,23 @@ config VUART_FRAMEWORK =20 menu "UART Emulation" =20 +config VUART_NS16X50 + bool "NS16550-compatible UART Emulator" if EXPERT + depends on X86 && HVM + select VUART_FRAMEWORK + default n + help + In-hypervisor NS16x50 UART emulation. + + Only legacy PC COM2 port is emulated. + + This is strictly for testing purposes (such as early HVM guest console), + and not appropriate for use in production. + +config VUART_NS16X50_DEBUG + bool "NS16550-compatible UART Emulator Debugging" + depends on VUART_NS16X50 && DEBUG + help + Enable development debugging. + endmenu diff --git a/xen/common/emul/vuart/Makefile b/xen/common/emul/vuart/Makefile index 97f792dc6641..fe904f6cb65d 100644 --- a/xen/common/emul/vuart/Makefile +++ b/xen/common/emul/vuart/Makefile @@ -1 +1,2 @@ obj-y +=3D vuart.o +obj-$(CONFIG_VUART_NS16X50) +=3D ns16x50.o diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x5= 0.c new file mode 100644 index 000000000000..0462a961e785 --- /dev/null +++ b/xen/common/emul/vuart/ns16x50.c @@ -0,0 +1,366 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * NS16550-compatible UART Emulator. + * + * See: + * - Serial and UART Tutorial: + * https://download.freebsd.org/doc/en/articles/serial-uart/serial-uar= t_en.pdf + * - UART w/ 16 byte FIFO: + * https://www.ti.com/lit/ds/symlink/tl16c550c.pdf + * - UART w/ 64 byte FIFO: + * https://www.ti.com/lit/ds/symlink/tl16c750.pdf + * + * Limitations: + * - Only x86; + * - Only Xen console as a backend, no inter-domain communication (similar= to + * vpl011 on Arm); + * - Only 8n1 emulation (8-bit data, no parity, 1 stop bit); + * - No baud rate emulation (reports 115200 baud to the guest OS); + * - No FIFO-less mode emulation; + * - No RX FIFO interrupt moderation (FCR) emulation; + * - No integration w/ VM snapshotting (HVM_REGISTER_SAVE_RESTORE() and + * friends); + * - No ISA IRQ sharing allowed; + * - No MMIO-based UART emulation. + */ + +#define pr_prefix "ns16x50" +#define pr_fmt(fmt) pr_prefix ": " fmt + +#ifdef CONFIG_VUART_NS16X50_DEBUG +#define guest_prefix "FROM GUEST " +#define ns16x50_log_level 2 +#else +#define guest_prefix "" +#define ns16x50_log_level 0 +#endif + +#include +#include +#include +#include +#include +#include + +#include + +#define ns16x50_log(n, lvl, vdev, fmt, args...) \ +do { \ + if ( ns16x50_log_level >=3D n ) \ + gprintk(lvl, pr_fmt("%s: " fmt), (vdev)->name, ## args); \ +} while (0) + +#define ns16x50_err(vdev, fmt, args...) \ + ns16x50_log(0, XENLOG_ERR, vdev, fmt, ## args) +#define ns16x50_warn(vdev, fmt, args...) \ + ns16x50_log(1, XENLOG_WARNING, vdev, fmt, ## args) +#define ns16x50_info(vdev, fmt, args...) \ + ns16x50_log(2, XENLOG_INFO, vdev, fmt, ## args) +#define ns16x50_debug(vdev, fmt, args...) \ + ns16x50_log(3, XENLOG_DEBUG, vdev, fmt, ## args) + +/* + * Number of supported registers in the UART. + */ +#define NS16X50_REGS_NUM (UART_SCR + 1) + +/* + * Number of emulated registers. + * + * - Emulated registers [0..NS16X50_REGS_NUM] are R/W registers for DLAB= =3D0. + * - DLAB=3D1, R/W, DLL =3D NS16X50_REGS_NUM + 0 + * - DLAB=3D1, R/W, DLM =3D NS16X50_REGS_NUM + 1 + * - R/O, IIR (IIR_THR) =3D NS16X50_REGS_NUM + 2 + */ +#define NS16X50_EMU_REGS_NUM (NS16X50_REGS_NUM + 3) + +/* + * Virtual ns16x50 device state. + */ +struct vuart_ns16x50 { + uint8_t regs[NS16X50_EMU_REGS_NUM]; /* Emulated registers */ + const struct vuart_info *info; /* UART description */ + struct domain *owner; /* Owner domain */ + const char *name; /* Device name */ + spinlock_t lock; /* Protection */ + struct xencons_interface cons; /* Emulated RX/TX FIFOs */ +}; + +static uint8_t ns16x50_dlab_get(const struct vuart_ns16x50 *vdev) +{ + return 0; +} + +/* + * Emulate 8-bit write access to ns16x50 register. + */ +static int ns16x50_io_write8( + struct vuart_ns16x50 *vdev, uint32_t reg, uint8_t *data) +{ + int rc =3D 0; + + return rc; +} + +/* + * Emulate 16-bit write access to ns16x50 register. + * NB: some guest OSes use outw() to access UART_DLL. + */ +static int ns16x50_io_write16( + struct vuart_ns16x50 *vdev, uint32_t reg, uint16_t *data) +{ + int rc =3D -EINVAL; + + return rc; +} + +/* + * Emulate write access to ns16x50 register. + */ +static int ns16x50_io_write( + struct vuart_ns16x50 *vdev, uint8_t reg, uint32_t size, uint32_t *data) +{ + int rc; + + switch ( size ) + { + case 1: + rc =3D ns16x50_io_write8(vdev, reg, (uint8_t *)data); + break; + + case 2: + rc =3D ns16x50_io_write16(vdev, reg, (uint16_t *)data); + break; + + default: + rc =3D -EINVAL; + break; + } + + return rc; +} + +/* + * Emulate 8-bit read access to ns16x50 register. + */ +static int ns16x50_io_read8( + struct vuart_ns16x50 *vdev, uint32_t reg, uint8_t *data) +{ + uint8_t val =3D 0xff; + int rc =3D 0; + + *data =3D val; + + return rc; +} + +/* + * Emulate 16-bit read access to ns16x50 register. + */ +static int ns16x50_io_read16( + struct vuart_ns16x50 *vdev, uint32_t reg, uint16_t *data) +{ + uint16_t val =3D 0xffff; + int rc =3D -EINVAL; + + *data =3D val; + + return rc; +} + +/* + * Emulate read access to ns16x50 register. + */ +static int ns16x50_io_read( + struct vuart_ns16x50 *vdev, uint8_t reg, uint32_t size, uint32_t *data) +{ + int rc; + + switch ( size ) + { + case 1: + rc =3D ns16x50_io_read8(vdev, reg, (uint8_t *)data); + break; + + case 2: + rc =3D ns16x50_io_read16(vdev, reg, (uint16_t *)data); + break; + + default: + *data =3D 0xffffffff; + rc =3D -EINVAL; + break; + } + + return rc; +} + +/* + * Emulate I/O access to ns16x50 register. + * Note, emulation always returns X86EMUL_OKAY, once I/O port trap is enab= led. + */ +static int cf_check ns16x50_io_handle( + int dir, unsigned int addr, unsigned int size, uint32_t *data) +{ +#define op(dir) (((dir) =3D=3D IOREQ_WRITE) ? 'W' : 'R') + struct domain *d =3D rcu_lock_current_domain(); + struct vuart *vuart =3D vuart_find_by_io_range(d, addr, size); + struct vuart_ns16x50 *vdev; + const struct domain *owner; + const struct vuart_info *info; + uint32_t reg; + unsigned dlab; + int rc; + + if ( !vuart || !vuart->vdev ) + { + printk(XENLOG_ERR "%c io 0x%04x %d: not initialized\n", + op(dir), addr, size); + + ASSERT_UNREACHABLE(); + goto out; + } + vdev =3D vuart->vdev; + + owner =3D vuart->owner; + ASSERT(owner); + if ( d !=3D owner ) + { + ns16x50_err(vdev, "%c io 0x%04x %d: does not match current domain = %pv\n", + op(dir), addr, size, d); + + ASSERT_UNREACHABLE(); + goto out; + } + + info =3D vuart->info; + ASSERT(info); + reg =3D addr - info->base_addr; + if ( !IS_ALIGNED(reg, size) ) + { + ns16x50_err(vdev, "%c 0x%04x %d: unaligned access\n", + op(dir), addr, size); + goto out; + } + + dlab =3D ns16x50_dlab_get(vdev); + if ( reg >=3D NS16X50_REGS_NUM ) + { + ns16x50_err(vdev, "%c io 0x%04x %d: DLAB=3D%d %02"PRIx32" 0x%08"PR= Ix32": not implemented\n", + op(dir), addr, size, dlab, reg, *data); + goto out; + } + + spin_lock(&vdev->lock); + + if ( dir =3D=3D IOREQ_WRITE ) + { + ns16x50_debug(vdev, "%c 0x%04x %d: DLAB=3D%d %02"PRIx32" 0x%08"PRI= x32"\n", + op(dir), addr, size, dlab, reg, *data); + rc =3D ns16x50_io_write(vdev, reg, size, data); + } + else + { + rc =3D ns16x50_io_read(vdev, reg, size, data); + ns16x50_debug(vdev, "%c 0x%04x %d: DLAB=3D%d %02"PRIx32" 0x%08"PRI= x32"\n", + op(dir), addr, size, dlab, reg, *data); + } + if ( rc < 0 ) + ns16x50_err(vdev, "%c 0x%04x %d: DLAB=3D%d %02"PRIx32" 0x%08"PRIx3= 2": unsupported access\n", + op(dir), addr, size, dlab, reg, *data); + + spin_unlock(&vdev->lock); + +out: + rcu_unlock_domain(d); + + return X86EMUL_OKAY; +#undef op +} + +static int ns16x50_init(void *arg) +{ + struct vuart_ns16x50 *vdev =3D arg; + const struct vuart_info *info =3D vdev->info; + struct domain *d =3D vdev->owner; + + ASSERT(vdev); + + register_portio_handler(d, info->base_addr, info->size, ns16x50_io_han= dle); + + return 0; +} + +static void cf_check ns16x50_deinit(void *arg) +{ + struct vuart_ns16x50 *vdev =3D arg; + + ASSERT(vdev); +} + +static void * cf_check ns16x50_alloc(struct domain *d, const struct vuart_= info *info) +{ + struct vuart_ns16x50 *vdev; + int rc; + + if ( !info ) + return ERR_PTR(-EINVAL); + + if ( vuart_find_by_io_range(d, info->base_addr, info->size) ) + { + ns16x50_err(info, "already registered\n"); + return ERR_PTR(-EBUSY); + } + + if ( !is_hvm_domain(d) ) + { + ns16x50_err(info, "not an HVM domain\n"); + return ERR_PTR(-ENOSYS); + } + + vdev =3D xvzalloc(typeof(*vdev)); + if ( !vdev ) + { + ns16x50_err(info, "failed to allocate memory\n"); + return ERR_PTR(-ENOMEM); + } + + spin_lock_init(&vdev->lock); + vdev->name =3D info->name; + vdev->owner =3D d; + vdev->info =3D info; + + rc =3D ns16x50_init(vdev); + if ( rc ) + return ERR_PTR(rc); + + return vdev; +} + +static void cf_check ns16x50_free(void *arg) +{ + if ( arg ) + ns16x50_deinit(arg); + + xvfree(arg); +} + +#define ns16x50_emulator \ +{ \ + .compatible =3D "ns16550", \ + .alloc =3D ns16x50_alloc, \ + .free =3D ns16x50_free, \ + .dump_state =3D NULL, \ + .put_rx =3D NULL, \ +} + +VUART_REGISTER(ns16x50, ns16x50_emulator); + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ --=20 2.51.0 From nobody Tue Sep 9 16:44:13 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1757114866; cv=none; d=zohomail.com; s=zohoarc; b=K6MtGqgdBE6lZJewL+IW4kv6MOW871Ukx28GrCTlt9PO1U9mg5ZMalZAmHjevLtHnJaE+cB5agmgfumjFzjslRgu3WoO42S+DUW2Jywqz7OtAmju53KrGnin1TqrzlLZkqLCNd6de2PRGWvMSbeLx9zKkILarPcoJznCb8AZUYU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757114866; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=euQ/8vNf5GpufgF2TZgbk8vUuC32iTlLIUaYRtS1M14=; b=nmnP2pD7HIp+OmYdPZez3U+TtG18Pu3Te2Z1dVfOc8Bn9yvA0dfTNcX3hDNjWzkuSvKCQo0hhi6xPnLBr34ixch1DtfJQ64CqRiN+XkT4jp/yKtFF04coKaLueSbUuGX4L93f3qO9kIRv9WULYzhT+o0+MrrfsU2NZJfUNADNbA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1757114866490960.4644437391105; Fri, 5 Sep 2025 16:27:46 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1112632.1460863 (Exim 4.92) (envelope-from ) id 1uufq1-00029o-O9; Fri, 05 Sep 2025 23:27:25 +0000 Received: by outflank-mailman (output) from mailman id 1112632.1460863; Fri, 05 Sep 2025 23:27:25 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufq1-00029Z-Jb; Fri, 05 Sep 2025 23:27:25 +0000 Received: by outflank-mailman (input) for mailman id 1112632; Fri, 05 Sep 2025 23:27:23 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufpz-0001hz-GU for xen-devel@lists.xenproject.org; Fri, 05 Sep 2025 23:27:23 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uufpy-008AAw-2t; Fri, 05 Sep 2025 23:27:23 +0000 Received: from [19.12.91.86] (helo=localhost) by xenbits.xenproject.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1uufpy-0005D2-2q; Fri, 05 Sep 2025 23:27:23 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org; s=20200302mail; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From; bh=euQ/8vNf5GpufgF2TZgbk8vUuC32iTlLIUaYRtS1M14=; b=boyOdTz8V0yH9S5Ab4iNInZzSA CvM6uB7BqGhXl6uRwbofX+8i5Abqh/O+kx3PDbg5zVMPYdI/w7SXC1OXkHUnN+h49RX9LlFtdLwzJ 6VCPJ5lmiF+XDvV7gOEc8zqLSEkQl5KLVeW9A8u/sR0Rq6wiPulswMuVKG/p3eikRi2A=; From: dmukhin@xen.org To: xen-devel@lists.xenproject.org Cc: andrew.cooper3@citrix.com, anthony.perard@vates.tech, jbeulich@suse.com, julien@xen.org, michal.orzel@amd.com, roger.pau@citrix.com, sstabellini@kernel.org, dmukhin@ford.com Subject: [PATCH v6 04/15] emul/ns16x50: implement DLL/DLM registers Date: Fri, 5 Sep 2025 16:27:03 -0700 Message-ID: <20250905232715.440758-5-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250905232715.440758-1-dmukhin@ford.com> References: <20250905232715.440758-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757114868334116600 Content-Type: text/plain; charset="utf-8" From: Denis Mukhin =20 Add DLL/DLM registers emulation. DLL/DLM registers report hardcoded 115200 baud rate to the guest OS. Add stub for ns16x50_dlab_get() helper. Signed-off-by: Denis Mukhin Reviewed-by: Stefano Stabellini --- Changes since v5: - dropped ns16x50_dlab_get() hunk (moved to emulator stub) - Link to v5: https://lore.kernel.org/xen-devel/20250828235409.2835815-5-dm= ukhin@ford.com/ --- xen/common/emul/vuart/ns16x50.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x5= 0.c index 0462a961e785..7f479a5be4a2 100644 --- a/xen/common/emul/vuart/ns16x50.c +++ b/xen/common/emul/vuart/ns16x50.c @@ -97,8 +97,13 @@ static uint8_t ns16x50_dlab_get(const struct vuart_ns16x= 50 *vdev) static int ns16x50_io_write8( struct vuart_ns16x50 *vdev, uint32_t reg, uint8_t *data) { + uint8_t *regs =3D vdev->regs; + uint8_t val =3D *data; int rc =3D 0; =20 + if ( ns16x50_dlab_get(vdev) && (reg =3D=3D UART_DLL || reg =3D=3D UART= _DLM) ) + regs[NS16X50_REGS_NUM + reg] =3D val; + return rc; } =20 @@ -109,8 +114,16 @@ static int ns16x50_io_write8( static int ns16x50_io_write16( struct vuart_ns16x50 *vdev, uint32_t reg, uint16_t *data) { + uint16_t val =3D *data; int rc =3D -EINVAL; =20 + if ( ns16x50_dlab_get(vdev) && reg =3D=3D UART_DLL ) + { + vdev->regs[NS16X50_REGS_NUM + UART_DLL] =3D val & 0xff; + vdev->regs[NS16X50_REGS_NUM + UART_DLM] =3D (val >> 8) & 0xff; + rc =3D 0; + } + return rc; } =20 @@ -146,9 +159,13 @@ static int ns16x50_io_write( static int ns16x50_io_read8( struct vuart_ns16x50 *vdev, uint32_t reg, uint8_t *data) { + uint8_t *regs =3D vdev->regs; uint8_t val =3D 0xff; int rc =3D 0; =20 + if ( ns16x50_dlab_get(vdev) && (reg =3D=3D UART_DLL || reg =3D=3D UART= _DLM) ) + val =3D regs[NS16X50_REGS_NUM + reg]; + *data =3D val; =20 return rc; @@ -163,6 +180,13 @@ static int ns16x50_io_read16( uint16_t val =3D 0xffff; int rc =3D -EINVAL; =20 + if ( ns16x50_dlab_get(vdev) && reg =3D=3D UART_DLL ) + { + val =3D vdev->regs[NS16X50_REGS_NUM + UART_DLM] << 8 | + vdev->regs[NS16X50_REGS_NUM + UART_DLL]; + rc =3D 0; + } + *data =3D val; =20 return rc; @@ -280,12 +304,17 @@ out: =20 static int ns16x50_init(void *arg) { + const uint16_t divisor =3D (UART_CLOCK_HZ / 115200) >> 4; struct vuart_ns16x50 *vdev =3D arg; const struct vuart_info *info =3D vdev->info; struct domain *d =3D vdev->owner; =20 ASSERT(vdev); =20 + /* NB: report 115200 baud rate. */ + vdev->regs[NS16X50_REGS_NUM + UART_DLL] =3D divisor & 0xff; + vdev->regs[NS16X50_REGS_NUM + UART_DLM] =3D (divisor >> 8) & 0xff; + register_portio_handler(d, info->base_addr, info->size, ns16x50_io_han= dle); =20 return 0; --=20 2.51.0 From nobody Tue Sep 9 16:44:13 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1757114875; cv=none; d=zohomail.com; s=zohoarc; b=K1/nIlgg2+1u9RrzFDLcNO64CFoICBpFPVAT+OZLKmUS31HiuUCbX6+3d3N/v2vMs/HPtYUxDHrHsXGRu5xFwD9VvzTwLHrnumjtrSqxhpyj8k1dEcUSMXwPeIu6Y2UdTG+8TIrmrwhrFRIYt2Uu7CRzZNwJyVqdx8CMJ2AHJ+I= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757114875; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=UmQzHfQSoeUK3EyjGre7Frz+a/7pj0V41RdQZawNalI=; b=JzbJ4txwIdvN50YV0Us++j/HSdhj+pEOsDzE2wbqwKcMqreS0ljCxGdOW/pSpDLkiabMkJ+gycWo+4bOPfn54sUzJXUZ90xcZ2mV79Iar+863O+L8vKjIOcwoye3/YVusAHyHbmCAqDpRtC0iRb/uwveRQxQyEbsCHzU75osz6k= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 17571148756263.223161562486098; Fri, 5 Sep 2025 16:27:55 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1112633.1460873 (Exim 4.92) (envelope-from ) id 1uufq3-0002P9-0T; Fri, 05 Sep 2025 23:27:27 +0000 Received: by outflank-mailman (output) from mailman id 1112633.1460873; Fri, 05 Sep 2025 23:27:26 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufq2-0002OF-Ss; Fri, 05 Sep 2025 23:27:26 +0000 Received: by outflank-mailman (input) for mailman id 1112633; Fri, 05 Sep 2025 23:27:24 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufq0-00020R-Ld for xen-devel@lists.xenproject.org; Fri, 05 Sep 2025 23:27:24 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uufpz-008AB8-3C; Fri, 05 Sep 2025 23:27:24 +0000 Received: from [19.12.91.86] (helo=localhost) by xenbits.xenproject.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1uufpz-0005D6-39; Fri, 05 Sep 2025 23:27:24 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org; s=20200302mail; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From; bh=UmQzHfQSoeUK3EyjGre7Frz+a/7pj0V41RdQZawNalI=; b=R2Ldlmao5TsX5jjH26E1hrRT+N fMqbNTrmUfZ9T+vahssMVk1I9wk0stagNbzZ6DCviCCfeZb4u0t6FBRdOt+tKqkYsqbbru/Llh7DP Fythg9UWdSIP0tz8R34kAsVn6P5yLMoP8nXHDHYMcs+NeC3A5HE/lCra8LrjRjR6T8EA=; From: dmukhin@xen.org To: xen-devel@lists.xenproject.org Cc: andrew.cooper3@citrix.com, anthony.perard@vates.tech, jbeulich@suse.com, julien@xen.org, michal.orzel@amd.com, roger.pau@citrix.com, sstabellini@kernel.org, dmukhin@ford.com Subject: [PATCH v6 05/15] emul/ns16x50: implement SCR register Date: Fri, 5 Sep 2025 16:27:04 -0700 Message-ID: <20250905232715.440758-6-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250905232715.440758-1-dmukhin@ford.com> References: <20250905232715.440758-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757114876429116600 Content-Type: text/plain; charset="utf-8" From: Denis Mukhin =20 Add SCR register emulation to the I/O port handler. Firmware (e.g. OVMF) may use SCR during the guest OS boot. Signed-off-by: Denis Mukhin Reviewed-by: Stefano Stabellini --- Changes since v5: - moved earlier in the series to simplify I/O handler population in the follow on patches - Link to v5: https://lore.kernel.org/xen-devel/20250828235409.2835815-11-d= mukhin@ford.com/ --- xen/common/emul/vuart/ns16x50.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x5= 0.c index 7f479a5be4a2..51ec85e57627 100644 --- a/xen/common/emul/vuart/ns16x50.c +++ b/xen/common/emul/vuart/ns16x50.c @@ -103,6 +103,20 @@ static int ns16x50_io_write8( =20 if ( ns16x50_dlab_get(vdev) && (reg =3D=3D UART_DLL || reg =3D=3D UART= _DLM) ) regs[NS16X50_REGS_NUM + reg] =3D val; + else + { + switch ( reg ) + { + /* NB: Firmware (e.g. OVMF) may rely on SCR presence. */ + case UART_SCR: + regs[UART_SCR] =3D val; + break; + + default: + rc =3D -EINVAL; + break; + } + } =20 return rc; } @@ -165,6 +179,19 @@ static int ns16x50_io_read8( =20 if ( ns16x50_dlab_get(vdev) && (reg =3D=3D UART_DLL || reg =3D=3D UART= _DLM) ) val =3D regs[NS16X50_REGS_NUM + reg]; + else + { + switch ( reg ) + { + case UART_SCR: + val =3D regs[UART_SCR]; + break; + + default: + rc =3D -EINVAL; + break; + } + } =20 *data =3D val; =20 --=20 2.51.0 From nobody Tue Sep 9 16:44:13 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1757114869; cv=none; d=zohomail.com; s=zohoarc; b=AJnTtczXulXBEY7ZMMU/FkuFXlcZxGPg4cd53GNm+2dDIIOnO9L71Ka0E4RpE5vQADYdhs/SRMJk6nXvbxnsTUaY0somsrZuys52eI91sSfq6sHu+i5eZZ+brQ9NUF7CqTAyIVqAWqwTFa3AcznsfPNeo1QiPMm7ATNZAr+BQfU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757114869; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=fu1wH8axdO9Xp+ceQdcC/+izkB5lgAddWuqh9BIqll0=; b=ZKy5NJ8IhgUd+ii2x4yykEz2mG4iU+TKMmv6ZonFzlDTEi6bbcHqvnAfLmcMMVd93LLCtXUY40K3i+ZGokL/HOdr3JjlkFE9CGOF01JWaMwh56KXPtYwNXSI4Kvxxio+zI/CZXSeiUpxc6K7QwNjXwn4/Fh0LluWl9Vjy8R3WcQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1757114869606480.3215956046479; Fri, 5 Sep 2025 16:27:49 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1112634.1460878 (Exim 4.92) (envelope-from ) id 1uufq3-0002Se-CD; Fri, 05 Sep 2025 23:27:27 +0000 Received: by outflank-mailman (output) from mailman id 1112634.1460878; Fri, 05 Sep 2025 23:27:27 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufq3-0002SL-6k; Fri, 05 Sep 2025 23:27:27 +0000 Received: by outflank-mailman (input) for mailman id 1112634; Fri, 05 Sep 2025 23:27:25 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufq1-00029m-Ky for xen-devel@lists.xenproject.org; Fri, 05 Sep 2025 23:27:25 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uufq1-008ABJ-0F; Fri, 05 Sep 2025 23:27:25 +0000 Received: from [19.12.91.86] (helo=localhost) by xenbits.xenproject.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1uufq1-0005DA-0C; Fri, 05 Sep 2025 23:27:25 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org; s=20200302mail; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From; bh=fu1wH8axdO9Xp+ceQdcC/+izkB5lgAddWuqh9BIqll0=; b=bwea3ctxQQOh7UunFyJLzy2ygL NZ3ytO+Gm1Ebm3oJW6QtcrdBqROvEq07jdQEg2/CKDbHwe0jxBFWr83CKzOYRO7rg3f9dpuf0Uq5T 6kn+al4qtzr/n7uypoKvae66fcAPaNgl8AJ0ARqhzz7yXna0R5Qk0t4m1JdGAM1dHFRA=; From: dmukhin@xen.org To: xen-devel@lists.xenproject.org Cc: andrew.cooper3@citrix.com, anthony.perard@vates.tech, jbeulich@suse.com, julien@xen.org, michal.orzel@amd.com, roger.pau@citrix.com, sstabellini@kernel.org, dmukhin@ford.com Subject: [PATCH v6 06/15] emul/ns16x50: implement IER/IIR registers Date: Fri, 5 Sep 2025 16:27:05 -0700 Message-ID: <20250905232715.440758-7-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250905232715.440758-1-dmukhin@ford.com> References: <20250905232715.440758-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757114870726116600 Content-Type: text/plain; charset="utf-8" From: Denis Mukhin =20 Add interrupt enable register emulation (IER) and interrupt identity reason (IIR) register emulation to the I/O port handler. Also add routines for asserting/deasserting the virtual ns16x50 interrupt line as a dependent on IIR code. Poke ns16x50_irq_check() on every I/O register access because the emulator does not have clock emulation anyway (e.g. for baud rate emulation). Signed-off-by: Denis Mukhin --- Changes since v5: - stubbed out ns16x50_iir_check_xxx() - dropped UART_IIR_THR handling (moved to THR register patch) - Link to v5: https://lore.kernel.org/xen-devel/20250828235409.2835815-6-dm= ukhin@ford.com/ --- xen/common/emul/vuart/ns16x50.c | 135 ++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x5= 0.c index 51ec85e57627..a7429c84c36e 100644 --- a/xen/common/emul/vuart/ns16x50.c +++ b/xen/common/emul/vuart/ns16x50.c @@ -91,6 +91,121 @@ static uint8_t ns16x50_dlab_get(const struct vuart_ns16= x50 *vdev) return 0; } =20 +static bool cf_check ns16x50_iir_check_lsi(const struct vuart_ns16x50 *vde= v) +{ + return false; +} + +static bool cf_check ns16x50_iir_check_rda(const struct vuart_ns16x50 *vde= v) +{ + return false; +} + +static bool cf_check ns16x50_iir_check_thr(const struct vuart_ns16x50 *vde= v) +{ + return false; +} + +static bool cf_check ns16x50_iir_check_msi(const struct vuart_ns16x50 *vde= v) +{ + return false; +} + +/* + * Get the interrupt identity reason. + * + * IIR is re-calculated once called, because ns16x50 always reports high + * priority events first. + * regs[NS16X50_REGS_NUM + UART_IIR] is used to store THR reason only. + */ +static uint8_t ns16x50_iir_get(const struct vuart_ns16x50 *vdev) +{ + /* + * Interrupt identity reasons by priority. + * NB: high priority are at lower indexes below. + */ + static const struct { + bool (*check)(const struct vuart_ns16x50 *vdev); + uint8_t ier; + uint8_t iir; + } iir_by_prio[] =3D { + [0] =3D { ns16x50_iir_check_lsi, UART_IER_ELSI, UART_IIR_LSI }, + [1] =3D { ns16x50_iir_check_rda, UART_IER_ERDAI, UART_IIR_RDA }, + [2] =3D { ns16x50_iir_check_thr, UART_IER_ETHREI, UART_IIR_THR }, + [3] =3D { ns16x50_iir_check_msi, UART_IER_EMSI, UART_IIR_MSI }, + }; + const uint8_t *regs =3D vdev->regs; + uint8_t iir =3D 0; + unsigned int i; + + /* + * NB: every interaction w/ ns16x50 registers (except DLAB=3D1) goes + * through that call. + */ + ASSERT(spin_is_locked(&vdev->lock)); + + for ( i =3D 0; i < ARRAY_SIZE(iir_by_prio); i++ ) + { + if ( (regs[UART_IER] & iir_by_prio[i].ier) && + iir_by_prio[i].check(vdev) ) + break; + + } + if ( i =3D=3D ARRAY_SIZE(iir_by_prio) ) + iir |=3D UART_IIR_NOINT; + else + iir |=3D iir_by_prio[i].iir; + + if ( regs[UART_FCR] & UART_FCR_ENABLE ) + iir |=3D UART_IIR_FE; + + return iir; +} + +static void ns16x50_irq_assert(const struct vuart_ns16x50 *vdev) +{ + struct domain *d =3D vdev->owner; + const struct vuart_info *info =3D vdev->info; + int vector; + + if ( has_vpic(d) ) + vector =3D hvm_isa_irq_assert(d, info->irq, vioapic_get_vector); + else + ASSERT_UNREACHABLE(); + + ns16x50_debug(vdev, "IRQ#%d vector %d assert\n", info->irq, vector); +} + +static void ns16x50_irq_deassert(const struct vuart_ns16x50 *vdev) +{ + struct domain *d =3D vdev->owner; + const struct vuart_info *info =3D vdev->info; + + if ( has_vpic(d) ) + hvm_isa_irq_deassert(d, info->irq); + else + ASSERT_UNREACHABLE(); + + ns16x50_debug(vdev, "IRQ#%d deassert\n", info->irq); +} + +/* + * Assert/deassert virtual ns16x50 interrupt line. + */ +static void ns16x50_irq_check(const struct vuart_ns16x50 *vdev) +{ + uint8_t iir =3D ns16x50_iir_get(vdev); + const struct vuart_info *info =3D vdev->info; + + if ( iir & UART_IIR_NOINT ) + ns16x50_irq_deassert(vdev); + else + ns16x50_irq_assert(vdev); + + ns16x50_debug(vdev, "IRQ#%d IIR 0x%02x %s\n", info->irq, iir, + (iir & UART_IIR_NOINT) ? "deassert" : "assert"); +} + /* * Emulate 8-bit write access to ns16x50 register. */ @@ -107,6 +222,10 @@ static int ns16x50_io_write8( { switch ( reg ) { + case UART_IER: + regs[UART_IER] =3D val & UART_IER_MASK; + break; + /* NB: Firmware (e.g. OVMF) may rely on SCR presence. */ case UART_SCR: regs[UART_SCR] =3D val; @@ -116,6 +235,8 @@ static int ns16x50_io_write8( rc =3D -EINVAL; break; } + + ns16x50_irq_check(vdev); } =20 return rc; @@ -183,6 +304,14 @@ static int ns16x50_io_read8( { switch ( reg ) { + case UART_IER: + val =3D regs[UART_IER]; + break; + + case UART_IIR: /* RO */ + val =3D ns16x50_iir_get(vdev); + break; + case UART_SCR: val =3D regs[UART_SCR]; break; @@ -191,6 +320,8 @@ static int ns16x50_io_read8( rc =3D -EINVAL; break; } + + ns16x50_irq_check(vdev); } =20 *data =3D val; @@ -344,6 +475,10 @@ static int ns16x50_init(void *arg) =20 register_portio_handler(d, info->base_addr, info->size, ns16x50_io_han= dle); =20 + spin_lock(&vdev->lock); + ns16x50_irq_check(vdev); + spin_unlock(&vdev->lock); + return 0; } =20 --=20 2.51.0 From nobody Tue Sep 9 16:44:13 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1757114866; cv=none; d=zohomail.com; s=zohoarc; b=RRIkEkrH2BOFr3jH6vOxvqfnxVtgw/erD774y9BzWYPY7vZ+oymUB0c+1omUgkknxtW8tUjwm/225JW1NRzZrfjjXYMFNnrYe5TO0KS4srkg8yLpO3p5hG2a5644UNoKwWupQkeSg7YE8bg3Bf/rFWUaObtvOHBZg5JMwdr667Y= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757114866; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=hb3mt55KoPzpt9PYPd0ysWNPG2aT/CyfcVL0JIYVlkQ=; b=UIBduQ0xIMfCVZ0cipStRQziOW5Vhbm56FznsRkHnwuYoSvPKBqNK1csCjGXSsQR/kn+ENK7l/CDaX/6ua1Trr8Ehj53M4T1Xfz3r3fKVv9juXsQTqxa38tw4ITurFdD3h8mRcQd73IG38LNckXRwuw2PTd7EIz80wQEbNbYzpg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1757114866887756.3323932435668; Fri, 5 Sep 2025 16:27:46 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1112635.1460882 (Exim 4.92) (envelope-from ) id 1uufq3-0002YK-NY; Fri, 05 Sep 2025 23:27:27 +0000 Received: by outflank-mailman (output) from mailman id 1112635.1460882; Fri, 05 Sep 2025 23:27:27 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufq3-0002Vy-F0; Fri, 05 Sep 2025 23:27:27 +0000 Received: by outflank-mailman (input) for mailman id 1112635; Fri, 05 Sep 2025 23:27:26 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufq2-0002Mw-Ml for xen-devel@lists.xenproject.org; Fri, 05 Sep 2025 23:27:26 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uufq2-008ABU-0T; Fri, 05 Sep 2025 23:27:26 +0000 Received: from [19.12.91.86] (helo=localhost) by xenbits.xenproject.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1uufq2-0005DE-0R; Fri, 05 Sep 2025 23:27:26 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org; s=20200302mail; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From; bh=hb3mt55KoPzpt9PYPd0ysWNPG2aT/CyfcVL0JIYVlkQ=; b=egcgATVzCVnVonFV7aSCnoEZUZ J1PTMh1fvax3B/REWv1D9Sl1wfCOW+oWa/WPlNCbORewzcS3nyiVhjLaR3OPH2cJoT1jhHFPIOE7m FFaI/DQuSOBCIk2kuwPOPYEvSkWXDBQe62ZzFHCcoVfymL3+vHqax06eNixTALW3GcFk=; From: dmukhin@xen.org To: xen-devel@lists.xenproject.org Cc: andrew.cooper3@citrix.com, anthony.perard@vates.tech, jbeulich@suse.com, julien@xen.org, michal.orzel@amd.com, roger.pau@citrix.com, sstabellini@kernel.org, dmukhin@ford.com Subject: [PATCH v6 07/15] emul/ns16x50: implement LCR/LSR registers Date: Fri, 5 Sep 2025 16:27:06 -0700 Message-ID: <20250905232715.440758-8-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250905232715.440758-1-dmukhin@ford.com> References: <20250905232715.440758-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757114868394116600 Content-Type: text/plain; charset="utf-8" From: Denis Mukhin =20 Add LCR/LSR registers implementation to the I/O port handler. Add implementation of ns16x50_dlab_get() and ns16x50_iir_check_lsi(). Signed-off-by: Denis Mukhin --- Changes since v5: - Moved earlier in the series so follow on patches (THR/RBR) could make use= of LSR bits more naturally - Link to v5: https://lore.kernel.org/xen-devel/20250828235409.2835815-9-dm= ukhin@ford.com/ --- xen/common/emul/vuart/ns16x50.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x5= 0.c index a7429c84c36e..9d1fe0284362 100644 --- a/xen/common/emul/vuart/ns16x50.c +++ b/xen/common/emul/vuart/ns16x50.c @@ -88,12 +88,12 @@ struct vuart_ns16x50 { =20 static uint8_t ns16x50_dlab_get(const struct vuart_ns16x50 *vdev) { - return 0; + return vdev->regs[UART_LCR] & UART_LCR_DLAB ? 1 : 0; } =20 static bool cf_check ns16x50_iir_check_lsi(const struct vuart_ns16x50 *vde= v) { - return false; + return vdev->regs[UART_LSR] & UART_LSR_MASK; } =20 static bool cf_check ns16x50_iir_check_rda(const struct vuart_ns16x50 *vde= v) @@ -226,11 +226,16 @@ static int ns16x50_io_write8( regs[UART_IER] =3D val & UART_IER_MASK; break; =20 + case UART_LCR: + regs[UART_LCR] =3D val; + break; + /* NB: Firmware (e.g. OVMF) may rely on SCR presence. */ case UART_SCR: regs[UART_SCR] =3D val; break; =20 + case UART_LSR: /* RO */ default: rc =3D -EINVAL; break; @@ -312,6 +317,15 @@ static int ns16x50_io_read8( val =3D ns16x50_iir_get(vdev); break; =20 + case UART_LCR: + val =3D regs[UART_LCR]; + break; + + case UART_LSR: + val =3D regs[UART_LSR] | UART_LSR_THRE | UART_LSR_TEMT; + regs[UART_LSR] =3D val & ~UART_LSR_MASK; + break; + case UART_SCR: val =3D regs[UART_SCR]; break; --=20 2.51.0 From nobody Tue Sep 9 16:44:13 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1757114864; cv=none; d=zohomail.com; s=zohoarc; b=P8wBAHEHUykjtHe36NgjvThD3aISZM0NCldEi9opG6PmdA9JBs1JmaHmDtk527imJpxsTvVaITZaMQ2ScNjfi4C4OPhmVlNTxQFcPdnhu3L+KnmPeqme2y5Wa1AMFSgJuwjSju0Kdmc4bUbwKeAHI6NkqpiI89ub7KHa44sIqdw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757114864; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=lacCZFGmXlDfnSAS6hfC6DHktgzcKHiHe+PObjndGXg=; b=mSvbbRvfQFb+2lNnm8l3JEOKAVIMb6Zb5r0hB/dWd9cdrX1ru7q8Gdr2Zd/LZrgOzUHGXq+zP7paFJlCPlaD/pIDYfkDsIZ8d++lnuQCVYQNrtWDeAcNsJKo1JTaalMOW/2LErJa8zJHSM5T9NnEq/yik9la2v4qRIlolw+xTWA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1757114864811219.39253639834465; Fri, 5 Sep 2025 16:27:44 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1112636.1460900 (Exim 4.92) (envelope-from ) id 1uufq5-00031B-Ar; Fri, 05 Sep 2025 23:27:29 +0000 Received: by outflank-mailman (output) from mailman id 1112636.1460900; Fri, 05 Sep 2025 23:27:29 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufq4-00030M-V4; Fri, 05 Sep 2025 23:27:28 +0000 Received: by outflank-mailman (input) for mailman id 1112636; Fri, 05 Sep 2025 23:27:27 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufq3-0002ZE-Lu for xen-devel@lists.xenproject.org; Fri, 05 Sep 2025 23:27:27 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uufq3-008ABf-0o; Fri, 05 Sep 2025 23:27:27 +0000 Received: from [19.12.91.86] (helo=localhost) by xenbits.xenproject.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1uufq3-0005DI-0m; Fri, 05 Sep 2025 23:27:27 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org; s=20200302mail; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From; bh=lacCZFGmXlDfnSAS6hfC6DHktgzcKHiHe+PObjndGXg=; b=G1pmnoo+ZEN+TcIqdFDsQKGgdJ /FWLeg0iGHix2iDuRi7baQP0ogmDPvUJRw4ImgEaZvvRGI0SXTSDeyylCrx4RcKqZzkKcxLudUQz4 x/4SLMrstkpsstf3VrTMp0lYGWCz8De8XFbMJgRCS1YCGifOYrBxBuFiwwkPXQOOIc2A=; From: dmukhin@xen.org To: xen-devel@lists.xenproject.org Cc: andrew.cooper3@citrix.com, anthony.perard@vates.tech, jbeulich@suse.com, julien@xen.org, michal.orzel@amd.com, roger.pau@citrix.com, sstabellini@kernel.org, dmukhin@ford.com Subject: [PATCH v6 08/15] emul/ns16x50: implement MCR/MSR registers Date: Fri, 5 Sep 2025 16:27:07 -0700 Message-ID: <20250905232715.440758-9-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250905232715.440758-1-dmukhin@ford.com> References: <20250905232715.440758-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757114866321116600 Content-Type: text/plain; charset="utf-8" From: Denis Mukhin =20 Add MCR/MSR registers emulation to the I/O port handler. Add implementation of ns16x50_iir_check_msi(). Signed-off-by: Denis Mukhin --- Changes in v5: - Moved earlier in the series - Link to v5: https://lore.kernel.org/xen-devel/20250828235409.2835815-10-d= mukhin@ford.com/ --- xen/common/emul/vuart/ns16x50.c | 62 ++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x5= 0.c index 9d1fe0284362..a8ec9f6c3a04 100644 --- a/xen/common/emul/vuart/ns16x50.c +++ b/xen/common/emul/vuart/ns16x50.c @@ -108,7 +108,7 @@ static bool cf_check ns16x50_iir_check_thr(const struct= vuart_ns16x50 *vdev) =20 static bool cf_check ns16x50_iir_check_msi(const struct vuart_ns16x50 *vde= v) { - return false; + return vdev->regs[UART_MSR] & UART_MSR_CHANGE; } =20 /* @@ -230,12 +230,63 @@ static int ns16x50_io_write8( regs[UART_LCR] =3D val; break; =20 + case UART_MCR: { + uint8_t msr_curr, msr_next, msr_delta; + + msr_curr =3D regs[UART_MSR]; + msr_next =3D 0; + msr_delta =3D 0; + + if ( val & UART_MCR_RESERVED0 ) + ns16x50_warn(vdev, "MCR: attempt to set reserved bit: %x\n= ", + UART_MCR_RESERVED0); + + if ( val & UART_MCR_TCRTLR ) + ns16x50_warn(vdev, "MCR: not supported: %x\n", + UART_MCR_TCRTLR); + + if ( val & UART_MCR_RESERVED1 ) + ns16x50_warn(vdev, "MCR: attempt to set reserved bit: %x\n= ", + UART_MCR_RESERVED1); + + /* Set modem status */ + if ( val & UART_MCR_LOOP ) + { + if ( val & UART_MCR_DTR ) + msr_next |=3D UART_MSR_DSR; + if ( val & UART_MCR_RTS ) + msr_next |=3D UART_MSR_CTS; + if ( val & UART_MCR_OUT1 ) + msr_next |=3D UART_MSR_RI; + if ( val & UART_MCR_OUT2 ) + msr_next |=3D UART_MSR_DCD; + } + else + msr_next |=3D UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS; + + /* Calculate changes in modem status */ + if ( (msr_curr & UART_MSR_CTS) ^ (msr_next & UART_MSR_CTS) ) + msr_delta |=3D UART_MSR_DCTS; + if ( (msr_curr & UART_MSR_DSR) ^ (msr_next & UART_MSR_DSR) ) + msr_delta |=3D UART_MSR_DDSR; + if ( (msr_curr & UART_MSR_RI) & (msr_next & UART_MSR_RI) ) + msr_delta |=3D UART_MSR_TERI; + if ( (msr_curr & UART_MSR_DCD) ^ (msr_next & UART_MSR_DCD) ) + msr_delta |=3D UART_MSR_DDCD; + + regs[UART_MCR] =3D val & UART_MCR_MASK; + regs[UART_MSR] =3D msr_next | msr_delta; + + break; + } + /* NB: Firmware (e.g. OVMF) may rely on SCR presence. */ case UART_SCR: regs[UART_SCR] =3D val; break; =20 case UART_LSR: /* RO */ + case UART_MSR: /* RO */ default: rc =3D -EINVAL; break; @@ -321,11 +372,20 @@ static int ns16x50_io_read8( val =3D regs[UART_LCR]; break; =20 + case UART_MCR: + val =3D regs[UART_MCR]; + break; + case UART_LSR: val =3D regs[UART_LSR] | UART_LSR_THRE | UART_LSR_TEMT; regs[UART_LSR] =3D val & ~UART_LSR_MASK; break; =20 + case UART_MSR: + val =3D regs[UART_MSR]; + regs[UART_MSR] &=3D ~UART_MSR_CHANGE; + break; + case UART_SCR: val =3D regs[UART_SCR]; break; --=20 2.51.0 From nobody Tue Sep 9 16:44:13 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1757114875; cv=none; d=zohomail.com; s=zohoarc; b=FaetcGqD7Ki3gYZ4Qd2XinskASVbwzYKsY+6SEmCIIbjp6J0pzZ8qqafv/qFvz24NfiaBumq9O5X9PSofctHoe2FKogw49roMWI2SqeEOJF7yxzT0USXrv/WV8HvQcVkI7gL6rxC3HJjCde9f+eByVpHRZa9FJ/26jY2zkZjhSM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757114875; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=WS5zJJrZC73EleKCg8ae2WORbb1w+LMvbUphJXaEKpA=; b=g5EV7dL3y+ozvak36jybuJKegkE6JeIGpCs3/PWW4PleLRQ1kBYeYFpoko7hz7zDe+e3pnNArLeDlA/0nNhuqa31Bomok/9JsVz1qhMkuYfaqAWNWJuZZqibug5g5kMxu2YaqbenpezrZe2BRrt2719nN7OQQRyECv56P0JEJns= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1757114875780636.5921319228328; Fri, 5 Sep 2025 16:27:55 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1112637.1460910 (Exim 4.92) (envelope-from ) id 1uufq6-0003P9-IY; Fri, 05 Sep 2025 23:27:30 +0000 Received: by outflank-mailman (output) from mailman id 1112637.1460910; Fri, 05 Sep 2025 23:27:30 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufq6-0003OG-Ca; Fri, 05 Sep 2025 23:27:30 +0000 Received: by outflank-mailman (input) for mailman id 1112637; Fri, 05 Sep 2025 23:27:28 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufq4-0002x4-PL for xen-devel@lists.xenproject.org; Fri, 05 Sep 2025 23:27:28 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uufq4-008ABr-15; Fri, 05 Sep 2025 23:27:28 +0000 Received: from [19.12.91.86] (helo=localhost) by xenbits.xenproject.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1uufq4-0005DM-12; Fri, 05 Sep 2025 23:27:28 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org; s=20200302mail; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From; bh=WS5zJJrZC73EleKCg8ae2WORbb1w+LMvbUphJXaEKpA=; b=jNWrRxuNVdg6IdrqX02mQgeaLh 9i2kbBLF2tQf/yS4UWx8xi4u02rnPFtwimxiMqeclPlnu7RhMTz1P7svgzN58dM/MuOZe4+MPdzs2 w5s83fTbNIwgKaYh5yBve9JnS2qw8d7UBL7De14jV80wtdZATPqkWS2gzjKv6GAnaGqA=; From: dmukhin@xen.org To: xen-devel@lists.xenproject.org Cc: andrew.cooper3@citrix.com, anthony.perard@vates.tech, jbeulich@suse.com, julien@xen.org, michal.orzel@amd.com, roger.pau@citrix.com, sstabellini@kernel.org, dmukhin@ford.com Subject: [PATCH v6 09/15] emul/ns16x50: implement RBR register Date: Fri, 5 Sep 2025 16:27:08 -0700 Message-ID: <20250905232715.440758-10-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250905232715.440758-1-dmukhin@ford.com> References: <20250905232715.440758-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757114876931124100 Content-Type: text/plain; charset="utf-8" From: Denis Mukhin =20 Add RBR register emulation to the I/O port handlder. Add RX FIFO management code since RBR depends on RX FIFO. RX FIFO is not emulated as per UART specs for simplicity (not need to emula= te baud rate). Emulator does not emulate NS8250 (no FIFO), NS16550a (16 bytes)= or NS16750 (64 bytes). RX FIFO is emulated by means of using xencons_interface which conveniently provides primitives for buffer management and later can be used for inter-domain communication similarly to vpl011. Add UART_LSR_DR handling since it depends on RBR register access. Finally, implement put_rx() vUART hook for placing a character into the emulated RX FIFO from console driver. That implements physical console forwarding to the guest OS over emulated NS16550. Signed-off-by: Denis Mukhin Reviewed-by: Stefano Stabellini --- Changes since v5: - new patch - Link to v5 (both THR/RBR): https://lore.kernel.org/xen-devel/202508282354= 09.2835815-7-dmukhin@ford.com/ - Link to v5 (rx_put): https://lore.kernel.org/xen-devel/20250828235409.283= 5815-12-dmukhin@ford.com/ --- xen/common/emul/vuart/ns16x50.c | 121 +++++++++++++++++++++++++++++++- 1 file changed, 119 insertions(+), 2 deletions(-) diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x5= 0.c index a8ec9f6c3a04..cac5128f0573 100644 --- a/xen/common/emul/vuart/ns16x50.c +++ b/xen/common/emul/vuart/ns16x50.c @@ -86,6 +86,68 @@ struct vuart_ns16x50 { struct xencons_interface cons; /* Emulated RX/TX FIFOs */ }; =20 +static bool ns16x50_fifo_rx_empty(const struct vuart_ns16x50 *vdev) +{ + const struct xencons_interface *cons =3D &vdev->cons; + + return cons->in_prod =3D=3D cons->in_cons; +} + +static bool ns16x50_fifo_rx_full(const struct vuart_ns16x50 *vdev) +{ + const struct xencons_interface *cons =3D &vdev->cons; + + return cons->in_prod - cons->in_cons =3D=3D ARRAY_SIZE(cons->in); +} + +static void ns16x50_fifo_rx_reset(struct vuart_ns16x50 *vdev) +{ + struct xencons_interface *cons =3D &vdev->cons; + + cons->in_cons =3D cons->in_prod; +} + +/* + * Transfer character from RX FIFO and return the RX FIFO status after the + * transfer. + */ +static int ns16x50_fifo_rx_getchar(struct vuart_ns16x50 *vdev, uint8_t *pt= r) +{ + struct xencons_interface *cons =3D &vdev->cons; + + if ( ns16x50_fifo_rx_empty(vdev) ) + return -ENODATA; + + *ptr =3D cons->in[MASK_XENCONS_IDX(cons->in_cons, cons->in)]; + cons->in_cons++; + + return ns16x50_fifo_rx_empty(vdev) ? -ENODATA : 0; +} + +static int ns16x50_fifo_rx_putchar(struct vuart_ns16x50 *vdev, char c) +{ + struct xencons_interface *cons =3D &vdev->cons; + int rc; + + /* + * FIFO-less 8250/16450 UARTs: newly arrived word overwrites the conte= nts + * of the THR. + */ + if ( ns16x50_fifo_rx_full(vdev) ) + { + ns16x50_debug(vdev, "RX FIFO full; resetting\n"); + ns16x50_fifo_rx_reset(vdev); + rc =3D -ENOSPC; + } + else + rc =3D 0; + + cons->in[MASK_XENCONS_IDX(cons->in_prod, cons->in)] =3D c; + cons->in_prod++; + + return rc; +} + static uint8_t ns16x50_dlab_get(const struct vuart_ns16x50 *vdev) { return vdev->regs[UART_LCR] & UART_LCR_DLAB ? 1 : 0; @@ -98,7 +160,7 @@ static bool cf_check ns16x50_iir_check_lsi(const struct = vuart_ns16x50 *vdev) =20 static bool cf_check ns16x50_iir_check_rda(const struct vuart_ns16x50 *vde= v) { - return false; + return !ns16x50_fifo_rx_empty(vdev); } =20 static bool cf_check ns16x50_iir_check_thr(const struct vuart_ns16x50 *vde= v) @@ -360,6 +422,17 @@ static int ns16x50_io_read8( { switch ( reg ) { + case UART_RBR: + /* NB: do not forget to clear overrun condition */ + regs[UART_LSR] &=3D ~UART_LSR_OE; + + if ( ns16x50_fifo_rx_getchar(vdev, &val) ) + regs[UART_LSR] &=3D ~UART_LSR_DR; + else + regs[UART_LSR] |=3D UART_LSR_DR; + + break; + case UART_IER: val =3D regs[UART_IER]; break; @@ -610,13 +683,57 @@ static void cf_check ns16x50_free(void *arg) xvfree(arg); } =20 +static int cf_check ns16x50_put_rx(void *arg, char ch) +{ + struct vuart_ns16x50 *vdev =3D arg; + uint8_t *regs; + uint8_t dlab; + int rc =3D -EBUSY; + + spin_lock(&vdev->lock); + + dlab =3D ns16x50_dlab_get(vdev); + regs =3D vdev->regs; + + if ( dlab ) + ns16x50_debug(vdev, "THR/RBR access disabled: DLAB=3D1\n"); + else if ( regs[UART_MCR] & UART_MCR_LOOP ) + ns16x50_debug(vdev, "THR/RBR access disabled: loopback mode\n"); + else + { + const struct domain *d =3D vdev->owner; + + /* + * Echo the user input on Xen console iff Xen console input is own= ed + * by ns16x50 domain. + * NB: use 'console_timestamps=3Dnone' to disable Xen timestamps. + */ + if ( is_console_printable(ch) ) + guest_printk(d, "%c", ch); + + if ( ns16x50_fifo_rx_putchar(vdev, ch) ) + regs[UART_LSR] |=3D UART_LSR_OE; + + regs[UART_LSR] |=3D UART_LSR_DR; + + /* TODO: check FCR when to fire an interrupt */ + ns16x50_irq_check(vdev); + + rc =3D 0; + } + + spin_unlock(&vdev->lock); + + return rc; +} + #define ns16x50_emulator \ { \ .compatible =3D "ns16550", \ .alloc =3D ns16x50_alloc, \ .free =3D ns16x50_free, \ .dump_state =3D NULL, \ - .put_rx =3D NULL, \ + .put_rx =3D ns16x50_put_rx, \ } =20 VUART_REGISTER(ns16x50, ns16x50_emulator); --=20 2.51.0 From nobody Tue Sep 9 16:44:13 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1757114865; cv=none; d=zohomail.com; s=zohoarc; b=EMi60PXqzvBc0XIS3NPw8BPJ46cP6FAec7cMKpn5zM0Bvw//uX3h5Ix/Yjo2ekcdTZonkfJIAn+OzqeavS8wI7rNk3YICJrZdieVaz6N2W7xyDelNhyWIC8bzzdQp6j6MPOQEdwQ17mqdme2U9NV4eEKghWhA1Ub1YnFyKerV1w= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757114865; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=H6Jsk6o0mPE6CkIqUYbOmKkRmoSPy4kytmL3+MJblb8=; b=DbR0dgia/EpXK1Xo1dEkrhLlOZKSyquwAiYoDYfmXFBwQwYt0mHVeAH2nYcY9RVYf9TIUsjwYYq8MCF2fIVogSYbsSNmNT6uL080/l8fcza8tnzCRYnbZG6Xn3tPQ52GtV7L62eyPnHjPVQ97pksiiG/MrShzrsZfF4+g9uNns4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1757114865421879.7417631457745; Fri, 5 Sep 2025 16:27:45 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1112638.1460919 (Exim 4.92) (envelope-from ) id 1uufq7-0003V3-Eh; Fri, 05 Sep 2025 23:27:31 +0000 Received: by outflank-mailman (output) from mailman id 1112638.1460919; Fri, 05 Sep 2025 23:27:31 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufq6-0003TV-Sy; Fri, 05 Sep 2025 23:27:30 +0000 Received: by outflank-mailman (input) for mailman id 1112638; Fri, 05 Sep 2025 23:27:29 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufq5-0003Gd-RP for xen-devel@lists.xenproject.org; Fri, 05 Sep 2025 23:27:29 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uufq5-008AC6-1Z; Fri, 05 Sep 2025 23:27:29 +0000 Received: from [19.12.91.86] (helo=localhost) by xenbits.xenproject.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1uufq5-0005DQ-1V; Fri, 05 Sep 2025 23:27:29 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org; s=20200302mail; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From; bh=H6Jsk6o0mPE6CkIqUYbOmKkRmoSPy4kytmL3+MJblb8=; b=hAKeWQc5fQbyKAWWfsxPT2V4il qo1Sw8jQGZOdOCoJAhbjlfTv2UVT4ZFG0zBVcVMWnml8M8C+/cO2nJzedz/iGBXKZctnTORvtZXII xr/LHyQCvERV0DRxNpfSl9NxEf3gZFm6CWow4pFQBOTb4Dq2nsrhO94bUsN4oPTcVCRM=; From: dmukhin@xen.org To: xen-devel@lists.xenproject.org Cc: andrew.cooper3@citrix.com, anthony.perard@vates.tech, jbeulich@suse.com, julien@xen.org, michal.orzel@amd.com, roger.pau@citrix.com, sstabellini@kernel.org, dmukhin@ford.com Subject: [PATCH v6 10/15] emul/ns16x50: implement THR register Date: Fri, 5 Sep 2025 16:27:09 -0700 Message-ID: <20250905232715.440758-11-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250905232715.440758-1-dmukhin@ford.com> References: <20250905232715.440758-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757114866852124100 Content-Type: text/plain; charset="utf-8" From: Denis Mukhin =20 Add THR register emulation to the I/O port handlder. Add TX FIFO management code since THR depends on TX FIFO. TX FIFOs is not emulated as per UART specs for simplicity (not need to emul= ate baud rate). Emulator does not emulate NS8250 (no FIFO), NS16550a (16 bytes)= or NS16750 (64 bytes). TX FIFOs is emulated by using xencons_interface which conveniently provides primitives for buffer management and later can be used for inter-domain communication similarly to vpl011. Add UART_IIR_THR interrupt reason handling since it depends on THR register access. Signed-off-by: Denis Mukhin --- Changes since v5: - new patch - Link to v5 (both THR/RBR): https://lore.kernel.org/xen-devel/202508282354= 09.2835815-7-dmukhin@ford.com/ --- xen/common/emul/vuart/ns16x50.c | 103 +++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x5= 0.c index cac5128f0573..987d4c06e23b 100644 --- a/xen/common/emul/vuart/ns16x50.c +++ b/xen/common/emul/vuart/ns16x50.c @@ -148,6 +148,66 @@ static int ns16x50_fifo_rx_putchar(struct vuart_ns16x5= 0 *vdev, char c) return rc; } =20 +static bool ns16x50_fifo_tx_full(const struct vuart_ns16x50 *vdev) +{ + const struct xencons_interface *cons =3D &vdev->cons; + + return cons->out_prod - cons->out_cons =3D=3D ARRAY_SIZE(cons->out); +} + +static void ns16x50_fifo_tx_reset(struct vuart_ns16x50 *vdev) +{ + struct xencons_interface *cons =3D &vdev->cons; + + cons->out_cons =3D cons->out_prod; +} + +/* + * Flush cached output to Xen console. + */ +static void ns16x50_fifo_tx_flush(struct vuart_ns16x50 *vdev) +{ + struct xencons_interface *cons =3D &vdev->cons; + struct domain *d =3D vdev->owner; + XENCONS_RING_IDX i, n, len =3D cons->out_prod - cons->out_cons; + + ASSERT(len <=3D ARRAY_SIZE(cons->out)); + if ( !len ) + return; + + i =3D MASK_XENCONS_IDX(cons->out_cons, cons->out); + n =3D min_t(XENCONS_RING_IDX, len, ARRAY_SIZE(cons->out) - i); + if ( n ) + guest_printk(d, guest_prefix "%.*s", n, &cons->out[i]); + + i =3D 0; + n =3D len - n; + if ( n ) + guest_printk(d, guest_prefix "%.*s", n, &cons->out[i]); + + cons->out_cons +=3D len; +} + +/* + * Accumulate guest OS output before sending to Xen console. + */ +static void ns16x50_fifo_tx_putchar(struct vuart_ns16x50 *vdev, char ch) +{ + struct xencons_interface *cons =3D &vdev->cons; + + if ( !is_console_printable(ch) ) + return; + + if ( !ns16x50_fifo_tx_full(vdev) ) + { + cons->out[MASK_XENCONS_IDX(cons->out_prod, cons->out)] =3D ch; + cons->out_prod++; + } + + if ( ch =3D=3D '\n' || ch =3D=3D '\0' || ns16x50_fifo_tx_full(vdev) ) + ns16x50_fifo_tx_flush(vdev); +} + static uint8_t ns16x50_dlab_get(const struct vuart_ns16x50 *vdev) { return vdev->regs[UART_LCR] & UART_LCR_DLAB ? 1 : 0; @@ -165,7 +225,7 @@ static bool cf_check ns16x50_iir_check_rda(const struct= vuart_ns16x50 *vdev) =20 static bool cf_check ns16x50_iir_check_thr(const struct vuart_ns16x50 *vde= v) { - return false; + return vdev->regs[NS16X50_REGS_NUM + UART_IIR] & UART_IIR_THR; } =20 static bool cf_check ns16x50_iir_check_msi(const struct vuart_ns16x50 *vde= v) @@ -284,7 +344,31 @@ static int ns16x50_io_write8( { switch ( reg ) { + case UART_THR: + if ( regs[UART_MCR] & UART_MCR_LOOP ) + { + if ( ns16x50_fifo_rx_putchar(vdev, val) ) + regs[UART_LSR] |=3D UART_LSR_OE; + + regs[UART_LSR] |=3D UART_LSR_DR; + } + else + { + ns16x50_fifo_tx_putchar(vdev, val); + regs[NS16X50_REGS_NUM + UART_IIR] |=3D UART_IIR_THR; + } + + break; + case UART_IER: + /* + * NB: Make sure THR interrupt is re-triggered once guest OS + * re-enables ETHREI in IER since all THR writes are immediate, + * there's no baud rate emulation. + */ + if ( val & regs[UART_IER] & UART_IER_ETHREI ) + regs[NS16X50_REGS_NUM + UART_IIR] |=3D UART_IIR_THR; + regs[UART_IER] =3D val & UART_IER_MASK; break; =20 @@ -439,6 +523,16 @@ static int ns16x50_io_read8( =20 case UART_IIR: /* RO */ val =3D ns16x50_iir_get(vdev); + + /* + * Since there's no baud rate emulation, transmits are immedia= te + * to the guest. Clear IIR scratch location to make sure there + * will be interrupt generated once guest re-enabled ETHREI in + * IER. + */ + if ( val & UART_IIR_THR ) + regs[NS16X50_REGS_NUM + UART_IIR] &=3D ~UART_IIR_THR; + break; =20 case UART_LCR: @@ -620,6 +714,9 @@ static int ns16x50_init(void *arg) vdev->regs[NS16X50_REGS_NUM + UART_DLL] =3D divisor & 0xff; vdev->regs[NS16X50_REGS_NUM + UART_DLM] =3D (divisor >> 8) & 0xff; =20 + /* Report UART is ready to transmit. */ + vdev->regs[NS16X50_REGS_NUM + UART_IIR] =3D UART_IIR_THR; + register_portio_handler(d, info->base_addr, info->size, ns16x50_io_han= dle); =20 spin_lock(&vdev->lock); @@ -634,6 +731,10 @@ static void cf_check ns16x50_deinit(void *arg) struct vuart_ns16x50 *vdev =3D arg; =20 ASSERT(vdev); + + spin_lock(&vdev->lock); + ns16x50_fifo_tx_flush(vdev); + spin_unlock(&vdev->lock); } =20 static void * cf_check ns16x50_alloc(struct domain *d, const struct vuart_= info *info) --=20 2.51.0 From nobody Tue Sep 9 16:44:13 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1757114871; cv=none; d=zohomail.com; s=zohoarc; b=jMLvnnBNdvQjHp1FmmydvzJfgjEHBfeHSU8V3tQT+hErs752MNRcDjCA5devcLwYXiu6in9L2JPYNkT7DwUrt7n4s4vJOfyN8HhOReyu1q7SlFcbMzBOSrA6zQrxQKnt+vXNiYlcAncudN6oXMB722sFcV4EmCd3M0sakaQF7UQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757114871; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=wv/+ypHhGLMV6T5qoOflVazYUaQF2ZGJkFc9G2aHE+8=; b=TCkD6jUII/iHOz+iw4KQWSVvsKGhjnvXsUNmhr/XgBexQMH2ld2F8Fe/f095cROnUb69ugOZN9qaRDpH7XBrKoPdw2yfuThY8kUjOlr8rTpTtiSL6hrcMTcFgiHyvhDUm3+uBT/oSLvWjdI7K4M1vexp5l2hn4bxylRcYHX43Iw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1757114871718757.2706108064232; Fri, 5 Sep 2025 16:27:51 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1112641.1460926 (Exim 4.92) (envelope-from ) id 1uufq8-0003th-S1; Fri, 05 Sep 2025 23:27:32 +0000 Received: by outflank-mailman (output) from mailman id 1112641.1460926; Fri, 05 Sep 2025 23:27:32 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufq8-0003rI-MI; Fri, 05 Sep 2025 23:27:32 +0000 Received: by outflank-mailman (input) for mailman id 1112641; Fri, 05 Sep 2025 23:27:31 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufq7-0003Va-3X for xen-devel@lists.xenproject.org; Fri, 05 Sep 2025 23:27:31 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uufq6-008ACK-1u; Fri, 05 Sep 2025 23:27:30 +0000 Received: from [19.12.91.86] (helo=localhost) by xenbits.xenproject.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1uufq6-0005DU-1r; Fri, 05 Sep 2025 23:27:30 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org; s=20200302mail; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From; bh=wv/+ypHhGLMV6T5qoOflVazYUaQF2ZGJkFc9G2aHE+8=; b=IBQMlSmOQUHnzX6idaVqBKZYxe vZZNoMMLUOSwVsBnngL4NfcWCTtHchJWcT2QaVJ+zkj0My5S2qV1GXu3BN1xobXT7dEqIeV6hH8+1 ZjsSzq1iZ/yUHCT5DSIt6G59tg70P3d4gF2pHZyJI5FF5fniix8kURhlOS+nnKTCGysU=; From: dmukhin@xen.org To: xen-devel@lists.xenproject.org Cc: andrew.cooper3@citrix.com, anthony.perard@vates.tech, jbeulich@suse.com, julien@xen.org, michal.orzel@amd.com, roger.pau@citrix.com, sstabellini@kernel.org, dmukhin@ford.com Subject: [PATCH v6 11/15] emul/ns16x50: implement FCR register (write-only) Date: Fri, 5 Sep 2025 16:27:10 -0700 Message-ID: <20250905232715.440758-12-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250905232715.440758-1-dmukhin@ford.com> References: <20250905232715.440758-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757114872471116600 Content-Type: text/plain; charset="utf-8" From: Denis Mukhin =20 Add emulation logic for FCR register. Note, that does not hook FIFO interrupt moderation to the FIFO management code for simplicity. Signed-off-by: Denis Mukhin Reviewed-by: Stefano Stabellini --- Changes since v5: - fixed UART_FCR_CLRX and UART_FCR_CLTX handling - Link to v5: https://lore.kernel.org/xen-devel/20250828235409.2835815-8-dm= ukhin@ford.com/ --- xen/common/emul/vuart/ns16x50.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x5= 0.c index 987d4c06e23b..3fc1112709df 100644 --- a/xen/common/emul/vuart/ns16x50.c +++ b/xen/common/emul/vuart/ns16x50.c @@ -372,6 +372,36 @@ static int ns16x50_io_write8( regs[UART_IER] =3D val & UART_IER_MASK; break; =20 + case UART_FCR: /* WO */ + if ( val & UART_FCR_RESERVED0 ) + ns16x50_warn(vdev, "FCR: attempt to set reserved bit: %x\n= ", + UART_FCR_RESERVED0); + + if ( val & UART_FCR_RESERVED1 ) + ns16x50_warn(vdev, "FCR: attempt to set reserved bit: %x\n= ", + UART_FCR_RESERVED1); + + if ( val & UART_FCR_CLRX ) + { + ns16x50_fifo_rx_reset(vdev); + regs[UART_LSR] &=3D ~UART_LSR_DR; + } + + if ( val & UART_FCR_CLTX ) + { + ns16x50_fifo_tx_reset(vdev); + regs[NS16X50_REGS_NUM + UART_IIR] |=3D UART_IIR_THR; + } + + if ( val & UART_FCR_ENABLE ) + val &=3D UART_FCR_ENABLE | UART_FCR_DMA | UART_FCR_TRG_MAS= K; + else + val =3D 0; + + regs[UART_FCR] =3D val; + + break; + case UART_LCR: regs[UART_LCR] =3D val; break; --=20 2.51.0 From nobody Tue Sep 9 16:44:13 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1757114874; cv=none; d=zohomail.com; s=zohoarc; b=bwX52st5shCZnAOHOcztmoS2bu8sSzqwnMtqubOIearwpSKCrje2UIp7Dlr2k4kTCZItrtohSrpCXqEzOH0bzp2WfvIq5HvB4uQjb6UAM07k12Ra0oy2jg0Xf417nzqz21VH5Vfl6WmuO+C6LTAGM+NidMZeyiVyiqV4CiSQmLI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757114874; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=u2jdc7rLZ93+UT0tmBIy3UeulgEZY7zZ1DBAZKI8/+g=; b=NIvP7EGRd4+643JupbHN24LCd2HhIN8jMvNhP0rhKY1ZZNq+QNHA3We6H0+nKN+Llnwd6+VJELjD3Smo2/+BjsEHe3P+EGJZd3riZABXqCkgk2d0duGZ26tE3nG5MnW+/6TGYszcE7I1X+fJ8k8be+0x7wcHt6pORRyhn6Fq7ig= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 175711487486314.555515625793532; Fri, 5 Sep 2025 16:27:54 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1112643.1460938 (Exim 4.92) (envelope-from ) id 1uufqA-0004Df-CT; Fri, 05 Sep 2025 23:27:34 +0000 Received: by outflank-mailman (output) from mailman id 1112643.1460938; Fri, 05 Sep 2025 23:27:34 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufqA-0004C5-1A; Fri, 05 Sep 2025 23:27:34 +0000 Received: by outflank-mailman (input) for mailman id 1112643; Fri, 05 Sep 2025 23:27:32 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufq8-0003lL-82 for xen-devel@lists.xenproject.org; Fri, 05 Sep 2025 23:27:32 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uufq7-008ACU-2B; Fri, 05 Sep 2025 23:27:31 +0000 Received: from [19.12.91.86] (helo=localhost) by xenbits.xenproject.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1uufq7-0005DY-2A; Fri, 05 Sep 2025 23:27:31 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org; s=20200302mail; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From; bh=u2jdc7rLZ93+UT0tmBIy3UeulgEZY7zZ1DBAZKI8/+g=; b=us44G4mHhQkzqi+a5rTigbberW DnTiESUfEPrrt/+dqdcPnY+djyikMBzPjhNUgfvQefLwkIwxvgNpdQmHu2ijFn0KXgidlXHwroc7i Yu1ryjQ5U6MP2GTTDbd9gnou7KFoFOJxghmL3ozDz77Jtx/swpPAQ7kBW39sIordgTXo=; From: dmukhin@xen.org To: xen-devel@lists.xenproject.org Cc: andrew.cooper3@citrix.com, anthony.perard@vates.tech, jbeulich@suse.com, julien@xen.org, michal.orzel@amd.com, roger.pau@citrix.com, sstabellini@kernel.org, dmukhin@ford.com Subject: [PATCH v6 12/15] emul/ns16550: implement dump_state() hook Date: Fri, 5 Sep 2025 16:27:11 -0700 Message-ID: <20250905232715.440758-13-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250905232715.440758-1-dmukhin@ford.com> References: <20250905232715.440758-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757114876824124100 Content-Type: text/plain; charset="utf-8" From: Denis Mukhin =20 Implement dump_state() vUART hook for debugging UART state machine over Xen console. dump_state() prints state of all emulated registers (including state-less IIR) and state of RX/TX FIFOs. Signed-off-by: Denis Mukhin --- Changes since v5: - Fixed printouts formatters - Link to v5: https://lore.kernel.org/xen-devel/20250828235409.2835815-13-d= mukhin@ford.com/ --- xen/common/emul/vuart/ns16x50.c | 59 ++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x5= 0.c index 3fc1112709df..a4fa3a9be713 100644 --- a/xen/common/emul/vuart/ns16x50.c +++ b/xen/common/emul/vuart/ns16x50.c @@ -648,6 +648,58 @@ static int ns16x50_io_read( return rc; } =20 +static void cf_check ns16x50_dump_state(void *arg) +{ +#ifdef CONFIG_VUART_NS16X50_DEBUG + struct vuart_ns16x50 *vdev =3D arg; + const struct domain *d =3D vdev->owner; + const struct vuart_info *info =3D vdev->info; + const struct xencons_interface *cons; + const uint8_t *regs; + + if ( !vdev ) + return; + + /* Allow printing state in case of a deadlock. */ + if ( !spin_trylock(&vdev->lock) ) + return; + + cons =3D &vdev->cons; + regs =3D &vdev->regs[0]; + + printk("Virtual " pr_prefix " (%s) I/O port 0x%04x IRQ#%d owner %pd\n", + vdev->name, info->base_addr, info->irq, d); + + printk(" RX FIFO size %ld in_prod %d in_cons %d used %d\n", + ARRAY_SIZE(cons->in), cons->in_prod, cons->in_cons, + cons->in_prod - cons->in_cons); + + printk(" TX FIFO size %ld out_prod %d out_cons %d used %d\n", + ARRAY_SIZE(cons->out), cons->out_prod, cons->out_cons, + cons->out_prod - cons->out_cons); + + printk(" %02"PRIx8" RBR %02"PRIx8" THR %02"PRIx8" DLL %02"PRIx8" DLM = %02"PRIx8"\n", + UART_RBR, + cons->in[MASK_XENCONS_IDX(cons->in_prod, cons)], + cons->out[MASK_XENCONS_IDX(cons->out_prod, cons)], + regs[NS16X50_REGS_NUM + UART_DLL], + regs[NS16X50_REGS_NUM + UART_DLM]); + + printk(" %02"PRIx8" IER %02"PRIx8"\n", UART_IER, regs[UART_IER]); + + printk(" %02"PRIx8" FCR %02"PRIx8" IIR %02"PRIx8"\n", + UART_FCR, regs[UART_FCR], ns16x50_iir_get(vdev)); + + printk(" %02"PRIx8" LCR %02"PRIx8"\n", UART_LCR, regs[UART_LCR]); + printk(" %02"PRIx8" MCR %02"PRIx8"\n", UART_MCR, regs[UART_MCR]); + printk(" %02"PRIx8" LSR %02"PRIx8"\n", UART_LSR, regs[UART_LSR]); + printk(" %02"PRIx8" MSR %02"PRIx8"\n", UART_MSR, regs[UART_MSR]); + printk(" %02"PRIx8" SCR %02"PRIx8"\n", UART_SCR, regs[UART_SCR]); + + spin_unlock(&vdev->lock); +#endif /* CONFIG_VUART_NS16X50_DEBUG */ +} + /* * Emulate I/O access to ns16x50 register. * Note, emulation always returns X86EMUL_OKAY, once I/O port trap is enab= led. @@ -724,6 +776,9 @@ static int cf_check ns16x50_io_handle( =20 spin_unlock(&vdev->lock); =20 + if ( ns16x50_log_level >=3D 3 ) + ns16x50_dump_state(vdev); + out: rcu_unlock_domain(d); =20 @@ -854,6 +909,8 @@ static int cf_check ns16x50_put_rx(void *arg, char ch) } =20 spin_unlock(&vdev->lock); + if ( ns16x50_log_level >=3D 3 ) + ns16x50_dump_state(vdev); =20 return rc; } @@ -863,7 +920,7 @@ static int cf_check ns16x50_put_rx(void *arg, char ch) .compatible =3D "ns16550", \ .alloc =3D ns16x50_alloc, \ .free =3D ns16x50_free, \ - .dump_state =3D NULL, \ + .dump_state =3D ns16x50_dump_state, \ .put_rx =3D ns16x50_put_rx, \ } =20 --=20 2.51.0 From nobody Tue Sep 9 16:44:13 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1757114878; cv=none; d=zohomail.com; s=zohoarc; b=Cxyj1k04yTbgsB2vEPZjCeKC9DVm89LT0S35DVLABapK7EWL8xtIxlKMbu4kdVAYczYex23zl0satfm3HJQa7dyy72B37xLoftTv7+YK22mFx4VvP6gaZHO0mQGZY1WZMCrT2Q/4JMM1PWA3YMwPrZLkWzTOac4IeX+yAYcpuBA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757114878; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=sRCoyJrQXJ7kAPK0GzF+5VS6TdNQm9twBbzHI7FmCnI=; b=RZruuBVUbzg9ySJD4kLHW803QKzrUC6Q5IbHi9b5TTG3iTS5rBc8WexnvCIZEoH8IpeF2mkddfqv6APwx1KDEu8zEIxsevTpGN5Xb6tahuksNfqE3K7kEKiVrpBiq+ggz9hZa8whjzJgac22Wt6OwKCkl9NLacEt81QRAATE4ZA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 175711487834359.515816220694774; Fri, 5 Sep 2025 16:27:58 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1112645.1460947 (Exim 4.92) (envelope-from ) id 1uufqC-0004do-PP; Fri, 05 Sep 2025 23:27:36 +0000 Received: by outflank-mailman (output) from mailman id 1112645.1460947; Fri, 05 Sep 2025 23:27:36 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufqC-0004br-5t; Fri, 05 Sep 2025 23:27:36 +0000 Received: by outflank-mailman (input) for mailman id 1112645; Fri, 05 Sep 2025 23:27:33 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufq9-00046l-Ft for xen-devel@lists.xenproject.org; Fri, 05 Sep 2025 23:27:33 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uufq8-008ACh-30; Fri, 05 Sep 2025 23:27:33 +0000 Received: from [19.12.91.86] (helo=localhost) by xenbits.xenproject.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1uufq8-0005Dc-2d; Fri, 05 Sep 2025 23:27:33 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org; s=20200302mail; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From; bh=sRCoyJrQXJ7kAPK0GzF+5VS6TdNQm9twBbzHI7FmCnI=; b=GA9Mna5+ZgkBUKCB1+gPFUFdmH vynHYi5zImLsAS9xjU9hycKmGDBlMVWNxM6NiBmuxN+LxchDjk+Pz5YE+k79hDvIXezdLXPXg2mWI c23bf5LIgukj0oLTdoz8aqxlWgLkEPpKhqX7tp1ogcVD5E/jAmpfPfeqrKVtog9+RpMw=; From: dmukhin@xen.org To: xen-devel@lists.xenproject.org Cc: andrew.cooper3@citrix.com, anthony.perard@vates.tech, jbeulich@suse.com, julien@xen.org, michal.orzel@amd.com, roger.pau@citrix.com, sstabellini@kernel.org, dmukhin@ford.com Subject: [PATCH v6 13/15] x86/domain: enable per-domain I/O port bitmaps Date: Fri, 5 Sep 2025 16:27:12 -0700 Message-ID: <20250905232715.440758-14-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250905232715.440758-1-dmukhin@ford.com> References: <20250905232715.440758-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757114880923116600 Content-Type: text/plain; charset="utf-8" From: Denis Mukhin =20 Current design enables all HVM domains share the same I/O port bitmap. It is necessary for domains crafting its own I/O port address space dependi= ng on the user configuration. Ensure NS16550 emulator does not share I/O ports with the physical I/O port= s, which is essential for emulation in PVH hwdom case (dom0). Not a functional change. Signed-off-by: Denis Mukhin --- Changes since v5: - fixed printout formatters in ns16x50_init() - Link to v5: https://lore.kernel.org/xen-devel/20250828235409.2835815-14-d= mukhin@ford.com/ --- xen/arch/x86/Makefile | 1 + xen/arch/x86/dom0_build.c | 111 +-------------- xen/arch/x86/hvm/hvm.c | 35 +---- xen/arch/x86/hvm/nestedhvm.c | 8 +- xen/arch/x86/hvm/quirks.c | 3 - xen/arch/x86/hvm/svm/nestedsvm.c | 2 +- xen/arch/x86/hvm/vmx/vvmx.c | 4 +- xen/arch/x86/include/asm/hvm/nestedhvm.h | 3 +- xen/arch/x86/include/asm/hvm/support.h | 2 - xen/arch/x86/include/asm/iocap.h | 2 + xen/arch/x86/ioport.c | 163 +++++++++++++++++++++++ xen/arch/x86/pv/dom0_build.c | 4 + xen/common/emul/vuart/ns16x50.c | 11 ++ 13 files changed, 200 insertions(+), 149 deletions(-) create mode 100644 xen/arch/x86/ioport.c diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index d7aed7d92c15..85a8475e126c 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -44,6 +44,7 @@ obj-y +=3D msi.o obj-y +=3D msr.o obj-$(CONFIG_INDIRECT_THUNK) +=3D indirect-thunk.o obj-$(CONFIG_RETURN_THUNK) +=3D indirect-thunk.o +obj-y +=3D ioport.o obj-$(CONFIG_PV) +=3D ioport_emulate.o obj-y +=3D irq.o obj-$(CONFIG_KEXEC) +=3D machine_kexec.o diff --git a/xen/arch/x86/dom0_build.c b/xen/arch/x86/dom0_build.c index 0b467fd4a4fc..26202b33345c 100644 --- a/xen/arch/x86/dom0_build.c +++ b/xen/arch/x86/dom0_build.c @@ -298,9 +298,6 @@ int __init parse_arch_dom0_param(const char *s, const c= har *e) return 0; } =20 -static char __initdata opt_dom0_ioports_disable[200] =3D ""; -string_param("dom0_ioports_disable", opt_dom0_ioports_disable); - static bool __initdata ro_hpet =3D true; boolean_param("ro-hpet", ro_hpet); =20 @@ -433,122 +430,20 @@ unsigned long __init dom0_compute_nr_pages( return nr_pages; } =20 -static void __init process_dom0_ioports_disable(struct domain *dom0) -{ - unsigned long io_from, io_to; - char *t, *s =3D opt_dom0_ioports_disable; - const char *u; - - if ( *s =3D=3D '\0' ) - return; - - while ( (t =3D strsep(&s, ",")) !=3D NULL ) - { - io_from =3D simple_strtoul(t, &u, 16); - if ( u =3D=3D t ) - { - parse_error: - printk("Invalid ioport range <%s> " - "in dom0_ioports_disable, skipping\n", t); - continue; - } - - if ( *u =3D=3D '\0' ) - io_to =3D io_from; - else if ( *u =3D=3D '-' ) - io_to =3D simple_strtoul(u + 1, &u, 16); - else - goto parse_error; - - if ( (*u !=3D '\0') || (io_to < io_from) || (io_to >=3D 65536) ) - goto parse_error; - - printk("Disabling dom0 access to ioport range %04lx-%04lx\n", - io_from, io_to); - - if ( ioports_deny_access(dom0, io_from, io_to) !=3D 0 ) - BUG(); - } -} - +/* Modify I/O memory access permissions. */ int __init dom0_setup_permissions(struct domain *d) { unsigned long mfn; - unsigned int i, offs; - int rc; + unsigned int i; + int rc =3D 0; =20 if ( pv_shim ) return 0; =20 - /* The hardware domain is initially permitted full I/O capabilities. */ - rc =3D ioports_permit_access(d, 0, 0xFFFF); rc |=3D iomem_permit_access(d, 0UL, PFN_DOWN(1UL << domain_max_paddr_bits(d)) - = 1); rc |=3D irqs_permit_access(d, 1, nr_irqs_gsi - 1); =20 - /* Modify I/O port access permissions. */ - - for ( offs =3D 0, i =3D ISOLATE_LSB(i8259A_alias_mask) ?: 2; - offs <=3D i8259A_alias_mask; offs +=3D i ) - { - if ( offs & ~i8259A_alias_mask ) - continue; - /* Master Interrupt Controller (PIC). */ - rc |=3D ioports_deny_access(d, 0x20 + offs, 0x21 + offs); - /* Slave Interrupt Controller (PIC). */ - rc |=3D ioports_deny_access(d, 0xA0 + offs, 0xA1 + offs); - } - - /* ELCR of both PICs. */ - rc |=3D ioports_deny_access(d, 0x4D0, 0x4D1); - - /* Interval Timer (PIT). */ - for ( offs =3D 0, i =3D ISOLATE_LSB(pit_alias_mask) ?: 4; - offs <=3D pit_alias_mask; offs +=3D i ) - if ( !(offs & ~pit_alias_mask) ) - rc |=3D ioports_deny_access(d, PIT_CH0 + offs, PIT_MODE + offs= ); - - /* PIT Channel 2 / PC Speaker Control. */ - rc |=3D ioports_deny_access(d, 0x61, 0x61); - - /* INIT# and alternative A20M# control. */ - rc |=3D ioports_deny_access(d, 0x92, 0x92); - - /* IGNNE# control. */ - rc |=3D ioports_deny_access(d, 0xF0, 0xF0); - - /* ACPI PM Timer. */ - if ( pmtmr_ioport ) - rc |=3D ioports_deny_access(d, pmtmr_ioport, pmtmr_ioport + 3); - - /* Reset control. */ - rc |=3D ioports_deny_access(d, 0xCF9, 0xCF9); - - /* PCI configuration space (NB. 0xCF8 has special treatment). */ - rc |=3D ioports_deny_access(d, 0xCFC, 0xCFF); - -#ifdef CONFIG_HVM - if ( is_hvm_domain(d) ) - { - /* ISA DMA controller, channels 0-3 (incl possible aliases). */ - rc |=3D ioports_deny_access(d, 0x00, 0x1F); - /* ISA DMA controller, page registers (incl various reserved ones)= . */ - rc |=3D ioports_deny_access(d, 0x80 + !!hvm_port80_allowed, 0x8F); - /* ISA DMA controller, channels 4-7 (incl usual aliases). */ - rc |=3D ioports_deny_access(d, 0xC0, 0xDF); - - /* HVM debug console IO port. */ - rc |=3D ioports_deny_access(d, XEN_HVM_DEBUGCONS_IOPORT, - XEN_HVM_DEBUGCONS_IOPORT); - if ( amd_acpi_c1e_quirk ) - rc |=3D ioports_deny_access(d, acpi_smi_cmd, acpi_smi_cmd); - } -#endif - /* Command-line I/O ranges. */ - process_dom0_ioports_disable(d); - - /* Modify I/O memory access permissions. */ - /* Local APIC. */ if ( mp_lapic_addr !=3D 0 ) { diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 91c971f11e14..93109db77283 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -81,14 +82,6 @@ integer_param("hvm_debug", opt_hvm_debug_level); =20 struct hvm_function_table __ro_after_init hvm_funcs; =20 -/* - * The I/O permission bitmap is globally shared by all HVM guests except - * the hardware domain which needs a more permissive one. - */ -#define HVM_IOBITMAP_SIZE (3 * PAGE_SIZE) -unsigned long __section(".bss.page_aligned") __aligned(PAGE_SIZE) - hvm_io_bitmap[HVM_IOBITMAP_SIZE / BYTES_PER_LONG]; - /* Xen command-line option to enable HAP */ static bool __initdata opt_hap_enabled =3D true; boolean_param("hap", opt_hap_enabled); @@ -205,15 +198,6 @@ static int __init cf_check hvm_enable(void) if ( opt_hvm_fep ) warning_add(warning_hvm_fep); =20 - /* - * Allow direct access to the PC debug ports 0x80 and 0xed (they are - * often used for I/O delays, but the vmexits simply slow things down). - */ - memset(hvm_io_bitmap, ~0, sizeof(hvm_io_bitmap)); - if ( hvm_port80_allowed ) - __clear_bit(0x80, hvm_io_bitmap); - __clear_bit(0xed, hvm_io_bitmap); - register_cpu_notifier(&cpu_nfb); =20 return 0; @@ -645,19 +629,12 @@ int hvm_domain_initialise(struct domain *d, =20 rwlock_init(&d->arch.hvm.pl_time->pt_migrate); =20 - /* Set the default IO Bitmap. */ - if ( is_hardware_domain(d) ) + rc =3D ioports_setup_access(d); + if ( rc ) { - d->arch.hvm.io_bitmap =3D _xmalloc(HVM_IOBITMAP_SIZE, PAGE_SIZE); - if ( d->arch.hvm.io_bitmap =3D=3D NULL ) - { - rc =3D -ENOMEM; - goto fail1; - } - memset(d->arch.hvm.io_bitmap, ~0, HVM_IOBITMAP_SIZE); + printk("%pd failed to setup I/O bitmap: %d\n", d, rc); + goto fail1; } - else - d->arch.hvm.io_bitmap =3D hvm_io_bitmap; =20 register_g2m_portio_handler(d); register_vpci_portio_handler(d); @@ -684,6 +661,8 @@ int hvm_domain_initialise(struct domain *d, break; } =20 + BUG_ON(!d->arch.ioport_caps); + vpic_init(d); =20 rc =3D vioapic_init(d); diff --git a/xen/arch/x86/hvm/nestedhvm.c b/xen/arch/x86/hvm/nestedhvm.c index bddd77d8109b..d4e03123d910 100644 --- a/xen/arch/x86/hvm/nestedhvm.c +++ b/xen/arch/x86/hvm/nestedhvm.c @@ -107,7 +107,7 @@ nestedhvm_vmcx_flushtlb(struct p2m_domain *p2m) * The users of the bitmap patterns are in SVM/VMX specific code. * * bitmap port 0x80 port 0xed - * hvm_io_bitmap cleared cleared + * hvm.io_bitmap cleared cleared * iomap[0] cleared set * iomap[1] set cleared * iomap[2] set set @@ -115,7 +115,7 @@ nestedhvm_vmcx_flushtlb(struct p2m_domain *p2m) =20 static int __init cf_check nestedhvm_setup(void) { - /* Same format and size as hvm_io_bitmap (Intel needs only 2 pages). */ + /* Same format and size as hvm.io_bitmap (Intel needs only 2 pages). */ unsigned nr =3D cpu_has_vmx ? 2 : 3; unsigned int i, order =3D get_order_from_pages(nr); =20 @@ -165,7 +165,7 @@ static int __init cf_check nestedhvm_setup(void) __initcall(nestedhvm_setup); =20 unsigned long * -nestedhvm_vcpu_iomap_get(bool ioport_80, bool ioport_ed) +nestedhvm_vcpu_iomap_get(struct vcpu *v, bool ioport_80, bool ioport_ed) { int i; =20 @@ -174,7 +174,7 @@ nestedhvm_vcpu_iomap_get(bool ioport_80, bool ioport_ed) =20 if (ioport_80 =3D=3D 0) { if (ioport_ed =3D=3D 0) - return hvm_io_bitmap; + return v->domain->arch.hvm.io_bitmap; i =3D 0; } else { if (ioport_ed =3D=3D 0) diff --git a/xen/arch/x86/hvm/quirks.c b/xen/arch/x86/hvm/quirks.c index 9202f5a47fe9..f4d95441fcff 100644 --- a/xen/arch/x86/hvm/quirks.c +++ b/xen/arch/x86/hvm/quirks.c @@ -73,9 +73,6 @@ static int __init cf_check check_port80(void) =20 dmi_check_system(hvm_no_port80_dmi_table); =20 - if ( !hvm_port80_allowed ) - __set_bit(0x80, hvm_io_bitmap); - return 0; } __initcall(check_port80); diff --git a/xen/arch/x86/hvm/svm/nestedsvm.c b/xen/arch/x86/hvm/svm/nested= svm.c index dc2b6a42534a..cc8500b61665 100644 --- a/xen/arch/x86/hvm/svm/nestedsvm.c +++ b/xen/arch/x86/hvm/svm/nestedsvm.c @@ -381,7 +381,7 @@ static int nsvm_vmrun_permissionmap(struct vcpu *v, boo= l viopm) hvm_unmap_guest_frame(ns_viomap, 0); } =20 - svm->ns_iomap =3D nestedhvm_vcpu_iomap_get(ioport_80, ioport_ed); + svm->ns_iomap =3D nestedhvm_vcpu_iomap_get(v, ioport_80, ioport_ed); =20 nv->nv_ioport80 =3D ioport_80; nv->nv_ioportED =3D ioport_ed; diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c index e4f3a5fe4c71..4da3e6e90e6c 100644 --- a/xen/arch/x86/hvm/vmx/vvmx.c +++ b/xen/arch/x86/hvm/vmx/vvmx.c @@ -554,7 +554,7 @@ unsigned long *_shadow_io_bitmap(struct vcpu *v) port80 =3D bitmap[0x80 >> 3] & (1 << (0x80 & 0x7)) ? 1 : 0; portED =3D bitmap[0xed >> 3] & (1 << (0xed & 0x7)) ? 1 : 0; =20 - return nestedhvm_vcpu_iomap_get(port80, portED); + return nestedhvm_vcpu_iomap_get(v, port80, portED); } =20 static void update_msrbitmap(struct vcpu *v, uint32_t shadow_ctrl) @@ -622,7 +622,7 @@ void nvmx_update_exec_control(struct vcpu *v, u32 host_= cntrl) * L1 VMM doesn't intercept IO instruction. * Use host configuration and reset IO_BITMAP */ - bitmap =3D hvm_io_bitmap; + bitmap =3D v->domain->arch.hvm.io_bitmap; } else { /* use IO bitmap */ diff --git a/xen/arch/x86/include/asm/hvm/nestedhvm.h b/xen/arch/x86/includ= e/asm/hvm/nestedhvm.h index ea2c1bc328c7..d691ccb07dd6 100644 --- a/xen/arch/x86/include/asm/hvm/nestedhvm.h +++ b/xen/arch/x86/include/asm/hvm/nestedhvm.h @@ -50,7 +50,8 @@ int nestedhvm_hap_nested_page_fault(struct vcpu *v, paddr= _t *L2_gpa, struct npfec npfec); =20 /* IO permission map */ -unsigned long *nestedhvm_vcpu_iomap_get(bool ioport_80, bool ioport_ed); +unsigned long *nestedhvm_vcpu_iomap_get(struct vcpu *v, + bool ioport_80, bool ioport_ed); =20 /* Misc */ #define nestedhvm_paging_mode_hap(v) (!!nhvm_vmcx_hap_enabled(v)) diff --git a/xen/arch/x86/include/asm/hvm/support.h b/xen/arch/x86/include/= asm/hvm/support.h index 2a7ba36af06f..7e36d00cc188 100644 --- a/xen/arch/x86/include/asm/hvm/support.h +++ b/xen/arch/x86/include/asm/hvm/support.h @@ -41,8 +41,6 @@ extern unsigned int opt_hvm_debug_level; #define HVM_DBG_LOG(level, _f, _a...) do {} while (0) #endif =20 -extern unsigned long hvm_io_bitmap[]; - enum hvm_translation_result { HVMTRANS_okay, HVMTRANS_bad_linear_to_gfn, diff --git a/xen/arch/x86/include/asm/iocap.h b/xen/arch/x86/include/asm/io= cap.h index f948b7186e95..1083f6171cf7 100644 --- a/xen/arch/x86/include/asm/iocap.h +++ b/xen/arch/x86/include/asm/iocap.h @@ -22,6 +22,8 @@ #define cache_flush_permitted(d) \ (has_arch_io_resources(d) || has_arch_pdevs(d)) =20 +int ioports_setup_access(struct domain *d); + static inline int ioports_permit_access(struct domain *d, unsigned long s, unsigned long e) { diff --git a/xen/arch/x86/ioport.c b/xen/arch/x86/ioport.c new file mode 100644 index 000000000000..dbcd52d37a4f --- /dev/null +++ b/xen/arch/x86/ioport.c @@ -0,0 +1,163 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Guest I/O port address space configuration. + * + * Copyright 2025 Ford Motor Company + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +static char __initdata opt_dom0_ioports_disable[200] =3D ""; +string_param("dom0_ioports_disable", opt_dom0_ioports_disable); + +/* + * The I/O permission bitmap size. + * See: comment in nestedhvm_setup() + */ +#define HVM_IOBITMAP_SIZE (3 * PAGE_SIZE) + +/* Hide user-defined I/O ports from the guest OS. */ +static void process_dom0_ioports_disable(struct domain *dom0) +{ + unsigned long io_from, io_to; + char *t, *s =3D opt_dom0_ioports_disable; + const char *u; + + if ( *s =3D=3D '\0' ) + return; + + while ( (t =3D strsep(&s, ",")) !=3D NULL ) + { + io_from =3D simple_strtoul(t, &u, 16); + if ( u =3D=3D t ) + { + parse_error: + printk("Invalid ioport range <%s> " + "in dom0_ioports_disable, skipping\n", t); + continue; + } + + if ( *u =3D=3D '\0' ) + io_to =3D io_from; + else if ( *u =3D=3D '-' ) + io_to =3D simple_strtoul(u + 1, &u, 16); + else + goto parse_error; + + if ( (*u !=3D '\0') || (io_to < io_from) || (io_to >=3D 65536) ) + goto parse_error; + + printk("Disabling dom0 access to ioport range %04lx-%04lx\n", + io_from, io_to); + + if ( ioports_deny_access(dom0, io_from, io_to) !=3D 0 ) + BUG(); + } +} + +/* Set the default IO Bitmap. */ +int ioports_setup_access(struct domain *d) +{ + unsigned int i, offs; + int rc; + + if ( pv_shim ) + return 0; + +#ifdef CONFIG_HVM + d->arch.hvm.io_bitmap =3D _xmalloc(HVM_IOBITMAP_SIZE, PAGE_SIZE); + if ( d->arch.hvm.io_bitmap =3D=3D NULL ) + return -ENOMEM; + + memset(d->arch.hvm.io_bitmap, ~0, HVM_IOBITMAP_SIZE); + + if ( !is_hardware_domain(d) ) + { + /* + * Allow direct access to the PC debug ports 0x80 and 0xed (they a= re + * often used for I/O delays, but the vmexits simply slow things d= own). + */ + if ( hvm_port80_allowed ) + __clear_bit(0x80, d->arch.hvm.io_bitmap); + + __clear_bit(0xed, d->arch.hvm.io_bitmap); + + return 0; + } +#endif + + /* The hardware domain is initially permitted full I/O capabilities. */ + rc =3D ioports_permit_access(d, 0, 0xFFFF); + + /* Modify I/O port access permissions. */ + + for ( offs =3D 0, i =3D ISOLATE_LSB(i8259A_alias_mask) ?: 2; + offs <=3D i8259A_alias_mask; offs +=3D i ) + { + if ( offs & ~i8259A_alias_mask ) + continue; + /* Master Interrupt Controller (PIC). */ + rc |=3D ioports_deny_access(d, 0x20 + offs, 0x21 + offs); + /* Slave Interrupt Controller (PIC). */ + rc |=3D ioports_deny_access(d, 0xA0 + offs, 0xA1 + offs); + } + + /* ELCR of both PICs. */ + rc |=3D ioports_deny_access(d, 0x4D0, 0x4D1); + + /* Interval Timer (PIT). */ + for ( offs =3D 0, i =3D ISOLATE_LSB(pit_alias_mask) ?: 4; + offs <=3D pit_alias_mask; offs +=3D i ) + if ( !(offs & ~pit_alias_mask) ) + rc |=3D ioports_deny_access(d, PIT_CH0 + offs, PIT_MODE + offs= ); + + /* PIT Channel 2 / PC Speaker Control. */ + rc |=3D ioports_deny_access(d, 0x61, 0x61); + + /* INIT# and alternative A20M# control. */ + rc |=3D ioports_deny_access(d, 0x92, 0x92); + + /* IGNNE# control. */ + rc |=3D ioports_deny_access(d, 0xF0, 0xF0); + + /* ACPI PM Timer. */ + if ( pmtmr_ioport ) + rc |=3D ioports_deny_access(d, pmtmr_ioport, pmtmr_ioport + 3); + + /* Reset control. */ + rc |=3D ioports_deny_access(d, 0xCF9, 0xCF9); + + /* PCI configuration space (NB. 0xCF8 has special treatment). */ + rc |=3D ioports_deny_access(d, 0xCFC, 0xCFF); + +#ifdef CONFIG_HVM + if ( is_hvm_domain(d) ) + { + /* ISA DMA controller, channels 0-3 (incl possible aliases). */ + rc |=3D ioports_deny_access(d, 0x00, 0x1F); + /* ISA DMA controller, page registers (incl various reserved ones)= . */ + rc |=3D ioports_deny_access(d, 0x80 + !!hvm_port80_allowed, 0x8F); + /* ISA DMA controller, channels 4-7 (incl usual aliases). */ + rc |=3D ioports_deny_access(d, 0xC0, 0xDF); + + /* HVM debug console IO port. */ + rc |=3D ioports_deny_access(d, XEN_HVM_DEBUGCONS_IOPORT, + XEN_HVM_DEBUGCONS_IOPORT); + if ( amd_acpi_c1e_quirk ) + rc |=3D ioports_deny_access(d, acpi_smi_cmd, acpi_smi_cmd); + } +#endif + + /* Command-line I/O ranges. */ + process_dom0_ioports_disable(d); + + return rc; +} diff --git a/xen/arch/x86/pv/dom0_build.c b/xen/arch/x86/pv/dom0_build.c index 21158ce1812e..2b8b4d869ee7 100644 --- a/xen/arch/x86/pv/dom0_build.c +++ b/xen/arch/x86/pv/dom0_build.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -1033,6 +1034,9 @@ static int __init dom0_construct(const struct boot_do= main *bd) if ( test_bit(XENFEAT_supervisor_mode_kernel, parms.f_required) ) panic("Dom0 requires supervisor-mode execution\n"); =20 + rc =3D ioports_setup_access(d); + BUG_ON(rc !=3D 0); + rc =3D dom0_setup_permissions(d); BUG_ON(rc !=3D 0); =20 diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x5= 0.c index a4fa3a9be713..7c4affe98533 100644 --- a/xen/common/emul/vuart/ns16x50.c +++ b/xen/common/emul/vuart/ns16x50.c @@ -792,9 +792,20 @@ static int ns16x50_init(void *arg) struct vuart_ns16x50 *vdev =3D arg; const struct vuart_info *info =3D vdev->info; struct domain *d =3D vdev->owner; + int rc; =20 ASSERT(vdev); =20 + /* Disallow sharing physical I/O port */ + rc =3D ioports_deny_access(d, info->base_addr, + info->base_addr + info->size - 1); + if ( rc ) + { + ns16x50_err(info, " virtual I/O port range [0x%04lx..0x%04lx]: con= flict w/ physical range\n", + info->base_addr, info->base_addr + info->size - 1); + return rc; + } + /* NB: report 115200 baud rate. */ vdev->regs[NS16X50_REGS_NUM + UART_DLL] =3D divisor & 0xff; vdev->regs[NS16X50_REGS_NUM + UART_DLM] =3D (divisor >> 8) & 0xff; --=20 2.51.0 From nobody Tue Sep 9 16:44:13 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1757114870; cv=none; d=zohomail.com; s=zohoarc; b=lXVuNSj1yAz4MVbAQ47yDSwVBUZLIICp5uHe7H0hL/UOrEs+d0982PS+263qWJYUREND8whtOAwZ3Jx501e5y/oiXxNMN2UGib5AS8Z3IQhukE85iAPn8nA/TNDPe5OCJ3R4Cg8a4WbrAt2OwWqrPuQd/uw4z8kyWNft7BLBUhI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757114870; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=kdR4+D2HTw7sqqj0HNahqkkhzpwH2jMWlfFIDzxZevA=; b=eYsXzzgoMm0MXMF5p088Y8hHP2SqXnrLU1Kv168iCiDlMhedBDy31nMHj0CCjahnpYwCrWVRgRBiCyrtDbffvdpnL97hzcUYWYEaPEkrhi9GuP+9BHRPWk9UZ0+7HW+KOkQgNKwD+S9YAQpxbKfcQogcH9SLzDqOb2PLj8Xf/Aw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1757114870249838.0299457165974; Fri, 5 Sep 2025 16:27:50 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1112647.1460954 (Exim 4.92) (envelope-from ) id 1uufqD-0004kK-T1; Fri, 05 Sep 2025 23:27:37 +0000 Received: by outflank-mailman (output) from mailman id 1112647.1460954; Fri, 05 Sep 2025 23:27:37 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufqC-0004j6-Uv; Fri, 05 Sep 2025 23:27:36 +0000 Received: by outflank-mailman (input) for mailman id 1112647; Fri, 05 Sep 2025 23:27:34 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufqA-0004HV-De for xen-devel@lists.xenproject.org; Fri, 05 Sep 2025 23:27:34 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uufqA-008ACs-05; Fri, 05 Sep 2025 23:27:34 +0000 Received: from [19.12.91.86] (helo=localhost) by xenbits.xenproject.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1uufqA-0005Dg-04; Fri, 05 Sep 2025 23:27:34 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org; s=20200302mail; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From; bh=kdR4+D2HTw7sqqj0HNahqkkhzpwH2jMWlfFIDzxZevA=; b=VME4w8rPFIRkvrv6atSbQYGNhs 0kMQUp/RAjELNTLais/tj1W5WJZWZQnzQSq+78Yaje5xgmSr7H7U4fPs04obNgvxgO1RS+tMTb0Oa dn+3nmvjMo883tmFIFqSjO5ZRFCNEkB879c9VE9P9Alv+T81gwynHnnLkol1N+L+UCBM=; From: dmukhin@xen.org To: xen-devel@lists.xenproject.org Cc: andrew.cooper3@citrix.com, anthony.perard@vates.tech, jbeulich@suse.com, julien@xen.org, michal.orzel@amd.com, roger.pau@citrix.com, sstabellini@kernel.org, dmukhin@ford.com Subject: [PATCH v6 14/15] xen/domain: allocate d->irq_caps before arch-specific initialization Date: Fri, 5 Sep 2025 16:27:13 -0700 Message-ID: <20250905232715.440758-15-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250905232715.440758-1-dmukhin@ford.com> References: <20250905232715.440758-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757114872852124100 Content-Type: text/plain; charset="utf-8" From: Denis Mukhin =20 Make sure that NS16550 emulator does not share virtual device IRQ with the physical one. This is needed for enabling NS16550 emulator for PVH hwdom (dom0). To do that, move per-domain interrupt rangeset allocation before arch-speci= fic code. Add irqs_setup_access() to setup the initial rangeset. Signed-off-by: Denis Mukhin --- Changes since v5: - n/a - Link to v5: https://lore.kernel.org/xen-devel/20250828235409.2835815-15-d= mukhin@ford.com/ --- xen/arch/x86/dom0_build.c | 1 - xen/arch/x86/hvm/dom0_build.c | 7 +++++++ xen/arch/x86/include/asm/irq.h | 2 ++ xen/arch/x86/irq.c | 8 ++++++++ xen/arch/x86/pv/dom0_build.c | 3 +++ xen/common/domain.c | 8 ++++++-- xen/common/emul/vuart/ns16x50.c | 9 +++++++++ 7 files changed, 35 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/dom0_build.c b/xen/arch/x86/dom0_build.c index 26202b33345c..9dc87efbf3e8 100644 --- a/xen/arch/x86/dom0_build.c +++ b/xen/arch/x86/dom0_build.c @@ -442,7 +442,6 @@ int __init dom0_setup_permissions(struct domain *d) =20 rc |=3D iomem_permit_access(d, 0UL, PFN_DOWN(1UL << domain_max_paddr_bits(d)) - = 1); - rc |=3D irqs_permit_access(d, 1, nr_irqs_gsi - 1); =20 /* Local APIC. */ if ( mp_lapic_addr !=3D 0 ) diff --git a/xen/arch/x86/hvm/dom0_build.c b/xen/arch/x86/hvm/dom0_build.c index 5551f9044836..245a42dec9aa 100644 --- a/xen/arch/x86/hvm/dom0_build.c +++ b/xen/arch/x86/hvm/dom0_build.c @@ -1348,6 +1348,13 @@ int __init dom0_construct_pvh(const struct boot_doma= in *bd) */ pvh_setup_mmcfg(d); =20 + rc =3D irqs_setup_access(d); + if ( rc ) + { + printk("%pd unable to setup IRQ rangeset: %d\n", d, rc); + return rc; + } + /* * Setup permissions early so that calls to add MMIO regions to the * p2m as part of vPCI setup don't fail due to permission checks. diff --git a/xen/arch/x86/include/asm/irq.h b/xen/arch/x86/include/asm/irq.h index 8c81f66434a8..8bffec3bbfee 100644 --- a/xen/arch/x86/include/asm/irq.h +++ b/xen/arch/x86/include/asm/irq.h @@ -231,4 +231,6 @@ int allocate_and_map_gsi_pirq(struct domain *d, int ind= ex, int *pirq_p); int allocate_and_map_msi_pirq(struct domain *d, int index, int *pirq_p, int type, struct msi_info *msi); =20 +int irqs_setup_access(struct domain *d); + #endif /* _ASM_HW_IRQ_H */ diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index 556134f85aa0..079277be719d 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -3046,3 +3046,11 @@ int allocate_and_map_msi_pirq(struct domain *d, int = index, int *pirq_p, =20 return ret; } + +int irqs_setup_access(struct domain *d) +{ + if ( is_hardware_domain(d) ) + return irqs_permit_access(d, 1, nr_irqs_gsi - 1); + + return 0; +} diff --git a/xen/arch/x86/pv/dom0_build.c b/xen/arch/x86/pv/dom0_build.c index 2b8b4d869ee7..1a092b802833 100644 --- a/xen/arch/x86/pv/dom0_build.c +++ b/xen/arch/x86/pv/dom0_build.c @@ -1037,6 +1037,9 @@ static int __init dom0_construct(const struct boot_do= main *bd) rc =3D ioports_setup_access(d); BUG_ON(rc !=3D 0); =20 + rc =3D irqs_setup_access(d); + BUG_ON(rc !=3D 0); + rc =3D dom0_setup_permissions(d); BUG_ON(rc !=3D 0); =20 diff --git a/xen/common/domain.c b/xen/common/domain.c index 775c33928585..edf76b02e1a1 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -952,6 +952,11 @@ struct domain *domain_create(domid_t domid, radix_tree_init(&d->pirq_tree); #endif =20 + err =3D -ENOMEM; + d->irq_caps =3D rangeset_new(d, "Interrupts", 0); + if ( !d->irq_caps ) + goto fail; + if ( (err =3D arch_domain_create(d, config, flags)) !=3D 0 ) goto fail; init_status |=3D INIT_arch; @@ -961,8 +966,7 @@ struct domain *domain_create(domid_t domid, =20 err =3D -ENOMEM; d->iomem_caps =3D rangeset_new(d, "I/O Memory", RANGESETF_prettyprint_= hex); - d->irq_caps =3D rangeset_new(d, "Interrupts", 0); - if ( !d->iomem_caps || !d->irq_caps ) + if ( !d->iomem_caps ) goto fail; =20 if ( (err =3D xsm_domain_create(XSM_HOOK, d, config->ssidref)) !=3D 0 ) diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x5= 0.c index 7c4affe98533..bcbd765b815d 100644 --- a/xen/common/emul/vuart/ns16x50.c +++ b/xen/common/emul/vuart/ns16x50.c @@ -806,6 +806,15 @@ static int ns16x50_init(void *arg) return rc; } =20 + /* Disallow sharing physical IRQ */ + rc =3D irq_deny_access(d, info->irq); + if ( rc ) + { + ns16x50_err(info, "virtual IRQ#%d: conflict w/ physical IRQ: %d\n", + info->irq, rc); + return rc; + } + /* NB: report 115200 baud rate. */ vdev->regs[NS16X50_REGS_NUM + UART_DLL] =3D divisor & 0xff; vdev->regs[NS16X50_REGS_NUM + UART_DLM] =3D (divisor >> 8) & 0xff; --=20 2.51.0 From nobody Tue Sep 9 16:44:13 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1757114881; cv=none; d=zohomail.com; s=zohoarc; b=LQtZIMglr2N6ui1rxJqy19rBc5l9ptk4jUIuPI1UQ99ahZVRjsQY5dFoCAZGhq3tkHE0c9Vjiy0LIFxyFVmpZOHvzTtBc/RTpmd6zP+N4Dh0PJcBdFD0g0WihiGeEBqKW1T5p2R/v8kZ4l78KT5522E+ke8h824bj4di6HkCmgY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757114881; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=3mwBazL9kANwQ3BnZxsZTOwFxpPGlCvixHJoTT4Lu2c=; b=GtcATLkD7JF0kDa+M2KRxyonIz0MSUO7dcHZ4g6HaeebvxqWQQPZd5ef7OKn0AloLk1j8bdPHcTeMSglR5brYT1YB5WpC/IRYHOiap2BT9oz4A189Gh/aebna5IjxfGwzYW66btOeRqxmuv2ikIT1N/mqN94iKdgnJDsUOr5+I0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1757114880997901.9234884952042; Fri, 5 Sep 2025 16:28:00 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1112649.1460961 (Exim 4.92) (envelope-from ) id 1uufqF-0005Fj-Vr; Fri, 05 Sep 2025 23:27:39 +0000 Received: by outflank-mailman (output) from mailman id 1112649.1460961; Fri, 05 Sep 2025 23:27:39 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufqF-0005CQ-AU; Fri, 05 Sep 2025 23:27:39 +0000 Received: by outflank-mailman (input) for mailman id 1112649; Fri, 05 Sep 2025 23:27:35 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufqB-0004Ts-IH for xen-devel@lists.xenproject.org; Fri, 05 Sep 2025 23:27:35 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uufqB-008AD3-0N; Fri, 05 Sep 2025 23:27:35 +0000 Received: from [19.12.91.86] (helo=localhost) by xenbits.xenproject.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1uufqB-0005Dk-0M; Fri, 05 Sep 2025 23:27:35 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org; s=20200302mail; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From; bh=3mwBazL9kANwQ3BnZxsZTOwFxpPGlCvixHJoTT4Lu2c=; b=YlcGtW3+chCoHlxxDwnt0y8l13 sIv7ttz6hYQ0OurpgLhVhQQ95/EEVfqYbKSPaCNFXpLDqoRK9x4EhwXNcY1QoefMyQGYtiDIBbkwn PP+ivJWyufaoLcSB930NB9DcAHQbiKxUbejx0DWCnT0ZsYP6pZw8hLqWWjd144N3aIJc=; From: dmukhin@xen.org To: xen-devel@lists.xenproject.org Cc: andrew.cooper3@citrix.com, anthony.perard@vates.tech, jbeulich@suse.com, julien@xen.org, michal.orzel@amd.com, roger.pau@citrix.com, sstabellini@kernel.org, dmukhin@ford.com Subject: [PATCH v6 15/15] emul/ns16x50: implement IRQ emulation via vIOAPIC Date: Fri, 5 Sep 2025 16:27:14 -0700 Message-ID: <20250905232715.440758-16-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250905232715.440758-1-dmukhin@ford.com> References: <20250905232715.440758-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757114882928124101 Content-Type: text/plain; charset="utf-8" From: Denis Mukhin =20 PVH domains use vIOAPIC, not vPIC and NS16550 emulates ISA IRQs which cannot be asserted on vIOAPIC. {map,unmap}_domain_pirq_emuirq() infrastructure is modified by adding new type of interrupt resources 'IRQ_EMU' which means 'emulated device IRQ' (similarly to IRQ_MSI_EMU). This is necessary to for IOAPIC emulation code to skip IRQ->PIRQ mapping (vioapic_hwdom_map_gsi()) when guest OS unmasks vIOAPIC pin corresponding to virtual device's IRQ. Also, hvm_gsi_eoi() is modified to trigger assertion in hvm_gsi_deassert() path for ISA IRQs. Signed-off-by: Denis Mukhin --- Changes since v5: - did cosmetic renaming and dropped unneeded changes - fixed ns16x50_irq_assert() and ns16x50_irq_deassert() as per Jan's suggestion in v4 (missed to address in v5) - fixed __hvm_dpci_eoi() - Link to v5: https://lore.kernel.org/xen-devel/20250828235409.2835815-16-d= mukhin@ford.com/ --- xen/arch/x86/hvm/vioapic.c | 10 ++++++++++ xen/arch/x86/include/asm/irq.h | 6 ++++++ xen/common/emul/vuart/ns16x50.c | 28 ++++++++++++++++++++++++++++ xen/drivers/passthrough/x86/hvm.c | 11 ++++++++++- 4 files changed, 54 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c index 7c725f9e471f..6314874b64f7 100644 --- a/xen/arch/x86/hvm/vioapic.c +++ b/xen/arch/x86/hvm/vioapic.c @@ -177,6 +177,16 @@ static int vioapic_hwdom_map_gsi(unsigned int gsi, uns= igned int trig, =20 ASSERT(is_hardware_domain(currd)); =20 + /* + * Interrupt is claimed by one of the platform virtual devices (e.g. + * NS16550); do nothing. + */ + write_lock(&currd->event_lock); + ret =3D is_domain_emuirq_claimed(currd, gsi); + write_unlock(&currd->event_lock); + if ( ret ) + return 0; + /* Interrupt has been unmasked, bind it now. */ ret =3D mp_register_gsi(gsi, trig, pol); if ( ret =3D=3D -EEXIST ) diff --git a/xen/arch/x86/include/asm/irq.h b/xen/arch/x86/include/asm/irq.h index 8bffec3bbfee..bdbe700274e9 100644 --- a/xen/arch/x86/include/asm/irq.h +++ b/xen/arch/x86/include/asm/irq.h @@ -168,6 +168,11 @@ void free_domain_pirqs(struct domain *d); int map_domain_emuirq_pirq(struct domain *d, int pirq, int emuirq); int unmap_domain_pirq_emuirq(struct domain *d, int pirq); =20 +#define domain_emuirq_claim(d, irq) map_domain_emuirq_pirq(d, irq, IRQ= _EMU) +#define domain_emuirq_unclaim(d, irq) unmap_domain_pirq_emuirq(d, irq) +#define is_domain_emuirq_claimed(d, irq) \ + (domain_pirq_to_emuirq(d, irq) !=3D IRQ_UNBOUND) + /* Evacuate interrupts assigned to CPUs not present in the CPU online map.= */ void fixup_irqs(void); void fixup_eoi(void); @@ -221,6 +226,7 @@ void cleanup_domain_irq_mapping(struct domain *d); #define IRQ_UNBOUND (-1) #define IRQ_PT (-2) #define IRQ_MSI_EMU (-3) +#define IRQ_EMU (-4) =20 bool cpu_has_pending_apic_eoi(void); =20 diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x5= 0.c index bcbd765b815d..723b1b0bb55d 100644 --- a/xen/common/emul/vuart/ns16x50.c +++ b/xen/common/emul/vuart/ns16x50.c @@ -292,6 +292,8 @@ static void ns16x50_irq_assert(const struct vuart_ns16x= 50 *vdev) =20 if ( has_vpic(d) ) vector =3D hvm_isa_irq_assert(d, info->irq, vioapic_get_vector); + else if ( has_vioapic(d) ) + vector =3D hvm_ioapic_assert(d, info->irq, false); else ASSERT_UNREACHABLE(); =20 @@ -305,6 +307,8 @@ static void ns16x50_irq_deassert(const struct vuart_ns1= 6x50 *vdev) =20 if ( has_vpic(d) ) hvm_isa_irq_deassert(d, info->irq); + else if ( has_vioapic(d) ) + hvm_ioapic_deassert(d, info->irq); else ASSERT_UNREACHABLE(); =20 @@ -815,6 +819,17 @@ static int ns16x50_init(void *arg) return rc; } =20 + /* Claim virtual IRQ */ + write_lock(&d->event_lock); + rc =3D domain_emuirq_claim(d, info->irq); + write_unlock(&d->event_lock); + if ( rc ) + { + ns16x50_err(info, "virtual IRQ#%d: cannot claim: %d\n", + info->irq, rc); + return rc; + } + /* NB: report 115200 baud rate. */ vdev->regs[NS16X50_REGS_NUM + UART_DLL] =3D divisor & 0xff; vdev->regs[NS16X50_REGS_NUM + UART_DLM] =3D (divisor >> 8) & 0xff; @@ -834,9 +849,22 @@ static int ns16x50_init(void *arg) static void cf_check ns16x50_deinit(void *arg) { struct vuart_ns16x50 *vdev =3D arg; + const struct vuart_info *info; + struct domain *d; + int rc; =20 ASSERT(vdev); =20 + d =3D vdev->owner; + info =3D vdev->info; + + write_lock(&d->event_lock); + rc =3D domain_emuirq_unclaim(d, info->irq); + write_unlock(&d->event_lock); + if ( rc ) + ns16x50_err(vdev, "virtual IRQ#%d: cannot unclaim: %d\n", + info->irq, rc); + spin_lock(&vdev->lock); ns16x50_fifo_tx_flush(vdev); spin_unlock(&vdev->lock); diff --git a/xen/drivers/passthrough/x86/hvm.c b/xen/drivers/passthrough/x8= 6/hvm.c index a2ca7e0e570c..20641194561f 100644 --- a/xen/drivers/passthrough/x86/hvm.c +++ b/xen/drivers/passthrough/x86/hvm.c @@ -922,7 +922,16 @@ static void __hvm_dpci_eoi(struct domain *d, =20 static void hvm_gsi_eoi(struct domain *d, unsigned int gsi) { - struct pirq *pirq =3D pirq_info(d, gsi); + struct pirq *pirq; + + /* Check if GSI is claimed by one of the virtual devices. */ + if ( is_domain_emuirq_claimed(d, gsi) ) + { + hvm_gsi_deassert(d, gsi); + return; + } + + pirq =3D pirq_info(d, gsi); =20 /* Check if GSI is actually mapped. */ if ( !pirq_dpci(pirq) ) --=20 2.51.0