From nobody Wed Sep 10 02:05:52 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=1757365942; cv=none; d=zohomail.com; s=zohoarc; b=jYpuS39feu5TbSM5+rkgVm/6vTk+BL3aUZGw+g0/e8xMJznrXW/hvexksJtpmnO6zOc2lvP7ucaWCi8mURCjBrNip83LqlRjXcePR+Rp87CCBatmgtZD28mKSO4CVp+rJFszrH9YVAYkmnWHSLvRwlP+JKZoU8JGT85+kaCYMnA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757365942; 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=qtj1opA8VkUAwTTzkkLeUXZOZ7qNdbdQYOa9K1xcC1Q=; b=RMDicVGu5PhrebeB4AuJLwrfkYAYMD+N838Gtu/afVzSpVJG3oGeSyRHSn7dHPEdwygHrs2aTbLrht7NmLsKnL57R/nksMBhx/i/PDqmnJpT5nj3kYSAAny3bhZGcztal1Qk7SDNiD9QuecwgnGlJhddWGD243qlFQV0Qr2/s0s= 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 1757365942772596.4481450415818; Mon, 8 Sep 2025 14:12:22 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1115534.1462084 (Exim 4.92) (envelope-from ) id 1uvj9X-0007jx-5K; Mon, 08 Sep 2025 21:11:55 +0000 Received: by outflank-mailman (output) from mailman id 1115534.1462084; Mon, 08 Sep 2025 21:11:55 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9X-0007jq-2J; Mon, 08 Sep 2025 21:11:55 +0000 Received: by outflank-mailman (input) for mailman id 1115534; Mon, 08 Sep 2025 21:11:53 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9V-0007WA-Az for xen-devel@lists.xenproject.org; Mon, 08 Sep 2025 21:11:53 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uvj9U-000FSB-2w; Mon, 08 Sep 2025 21:11:52 +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 1uvj9U-000gJy-35; Mon, 08 Sep 2025 21:11:52 +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=qtj1opA8VkUAwTTzkkLeUXZOZ7qNdbdQYOa9K1xcC1Q=; b=tMspcYbtuIWeGzDIyTx++hdG1K UbyBmS8gKQrHrsLo/rG2JULC1rKMVOvb1I3c5QCK+GMdRU1KShCIxW9OzhM7Uz/0Qj42ZUS0es81u 0h5crhOHhQ8nsq12QUSbFtLtRMURXylaz0E7NJiNepKL2ZftI4V0JIE+s4HLxeZgBXdc=; 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 v7 01/16] emul/vuart: introduce framework for UART emulators Date: Mon, 8 Sep 2025 14:11:34 -0700 Message-ID: <20250908211149.279143-2-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250908211149.279143-1-dmukhin@ford.com> References: <20250908211149.279143-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757365945460124101 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 --- Changes since v6: - addresses Mykola's feedback - some renaming (vuart_find_by_flags()) - added extra checks to put_rx and dump_state - fixed vuart_init() error path - simplified some checks during vUART state 'search' --- 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 | 165 +++++++++++++++++++++++++++++++++ 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 | 115 +++++++++++++++++++++++ xen/include/xen/xen.lds.h | 10 ++ 17 files changed, 326 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..ba89d608aeb2 --- /dev/null +++ b/xen/common/emul/vuart/vuart.c @@ -0,0 +1,165 @@ +/* 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_flags(const struct domain *d, unsigned int flags) +{ + const struct vuart *vuart =3D d->console.vuart; + + if ( vuart && (vuart->flags & flags) ) + return vuart; + + return NULL; +} + +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 && + 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, const 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(*vuart->info)); + if ( !vuart->info ) + { + rc =3D -ENOMEM; + goto err_out1; + } + 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_out2; + } + + 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_out2: + xvfree(vuart->info); + err_out1: + xvfree(vuart); + + return rc; +} + +/* + * Release any resources taken by UART emulators. + * + * NB: no flags are cleared, since currently exit() is called only during + * domain destroy. + */ +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); +} + +/* + * Print emulated UART state on the console. + * + * Must be called under rcu_lock_domain(). + */ +void vuart_dump_state(const struct domain *d) +{ + struct vuart *vuart =3D d->console.vuart; + + if ( vuart && vuart->emulator->dump_state ) + vuart->emulator->dump_state(vuart->vdev); +} + +/* + * Put character to the first emulated UART's FIFO with the physical conso= le + * forwarding enabled. + * + * Must be called under rcu_lock_domain(). + */ +int vuart_put_rx(struct domain *d, char c) +{ + const struct vuart *vuart =3D vuart_find_by_flags(d, VUART_CONSOLE_INP= UT); + + if ( vuart && vuart->emulator->put_rx ) + return vuart->emulator->put_rx(vuart->vdev, c); + + return -ENODEV; +} + +bool domain_has_vuart(const struct domain *d) +{ + return vuart_find_by_flags(d, VUART_CONSOLE_INPUT); +} + +/* + * 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..55828f8498ce --- /dev/null +++ b/xen/include/xen/vuart.h @@ -0,0 +1,115 @@ +/* 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; + unsigned int 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, const 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, const struct vuart_info *in= fo) +{ + 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 Wed Sep 10 02:05:52 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=1757365939; cv=none; d=zohomail.com; s=zohoarc; b=OBl1mry1I/xFaenoE/vjs3ozPFwulbQNABjdwM1kD7wtdmo2zojiEHSU8seBitByFd7LxIYzSMaLEj6mURtBqitwcFMFitppLl+yHMRW2xYn/hG2H/yXKHpj2kCjTcYAd4Y/luItvYdNg4k6/5z2CbKc4PNjf9E+jcuzESNQSec= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757365939; 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=ScRE3g8jVmbQQYHS5u6EzEGBByXpDzH+16MqZDTV2QA=; b=aQBWv79fCvMIc21MIL1g8RkOYku8E+8VdWEa5zNepT9b5zZQ6hiVMxxFuOxhkcjTJ+FTHC8LA9cxE5BjsqJGevnlKAphU7v5g/PbA+1ksSUTwsak7idl7bFnJWp0vFwL2OkI953VmmYY1nRN4hLZhdwz60iV1awYwjacUp7DsSo= 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 1757365939024267.90410062041735; Mon, 8 Sep 2025 14:12:19 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1115535.1462091 (Exim 4.92) (envelope-from ) id 1uvj9X-0007qp-K2; Mon, 08 Sep 2025 21:11:55 +0000 Received: by outflank-mailman (output) from mailman id 1115535.1462091; Mon, 08 Sep 2025 21:11:55 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9X-0007pP-Ed; Mon, 08 Sep 2025 21:11:55 +0000 Received: by outflank-mailman (input) for mailman id 1115535; Mon, 08 Sep 2025 21:11:54 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9W-0007g9-Hb for xen-devel@lists.xenproject.org; Mon, 08 Sep 2025 21:11:54 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uvj9W-000FSM-0J; Mon, 08 Sep 2025 21:11:54 +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 1uvj9W-000gK2-0U; Mon, 08 Sep 2025 21:11:54 +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=ScRE3g8jVmbQQYHS5u6EzEGBByXpDzH+16MqZDTV2QA=; b=SHNIZw8PuWMOdsmDTnYETDo1QS klbIfNDdyd+svI1DElYh8m7wO2zafd0+hnHN+ivmRyfphzI5KoDyTumkeIVue0muN6BuTNHLQf5mj 0tJ6p3QPKnAbVVqqvYCA7BqNSyI1/fRkOKjOQ+Xw9HykDa6PhfJMk1U56Cfil547TY+w=; 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 v7 02/16] xen/8250-uart: update definitions Date: Mon, 8 Sep 2025 14:11:35 -0700 Message-ID: <20250908211149.279143-3-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250908211149.279143-1-dmukhin@ford.com> References: <20250908211149.279143-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757365941519124100 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 --- Changes since v6: - used raw bitmasks instead of BIT() for consistency --- xen/drivers/char/ns16550.c | 16 ++++++++-------- xen/include/xen/8250-uart.h | 36 ++++++++++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 10 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..a8a26b64689e 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_DMA 0x08 /* enter DMA mode */ +#define UART_FCR_RSRVD0 0x10 /* reserved; always 0 */ +#define UART_FCR_RSRVD1 0x20 /* reserved; always 0 */ +#define UART_FCR_RTB0 0x40 /* receiver trigger bit #0 */ +#define UART_FCR_RTB1 0x80 /* 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 */ @@ -98,9 +108,30 @@ /* 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_OUT1 0x04 /* Output #1 */ +#define UART_MCR_OUT2 0x08 /* Output #2 */ #define UART_MCR_LOOP 0x10 /* Enable loopback test mode */ +#define UART_MCR_RSRVD0 0x20 /* Reserved #0 */ #define UART_MCR_TCRTLR 0x40 /* Access TCR/TLR (TI16C752, EFR[4]=3D1)= */ +#define UART_MCR_RSRVD1 0x80 /* 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 0x01 /* Change in CTS */ +#define UART_MSR_DDSR 0x02 /* Change in DSR */ +#define UART_MSR_TERI 0x04 /* Change in RI */ +#define UART_MSR_DDCD 0x08 /* Change in DCD */ +#define UART_MSR_CTS 0x10 +#define UART_MSR_DSR 0x20 +#define UART_MSR_RI 0x40 +#define UART_MSR_DCD 0x80 +#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 Wed Sep 10 02:05:52 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=1757365953; cv=none; d=zohomail.com; s=zohoarc; b=UtVkhMUP4WXSGksMBA7KpuhBSIqTrxfm8I71MIZi7F8EtfldKU2cUwwv6kmpoKYt0im/ZpNCsgmR6VssjUvhQZukorV/d4m0hvDzU5c1VnqvkionMkU8jOaLTaMN9KHpd1SB6Fm/T9z2g/htC/6lJOik+LQCaVxnzxpdZsYD7o0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757365953; 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=1FdFTRNsjH5U9rDP4kQAUpXOlwuD271Mac2A8wU+UVw=; b=kDoJyqBEzzckTVFzL3DNPVhJVePHtNtFYJO5zeJKHItDxZB736Z0wVTB4xqQ2yU6BeOIrRBjOjknPgpVlB07kOBHewj2NNTo+GKGpCGZUxfC5t5yOKAANTvYrgPdjA1WRBqjE7wej9VdrrPe7C7qAsQH+j9D/LRLExdVyPG/DR4= 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 1757365953417188.45138461628562; Mon, 8 Sep 2025 14:12:33 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1115536.1462104 (Exim 4.92) (envelope-from ) id 1uvj9Y-0008Bl-Ou; Mon, 08 Sep 2025 21:11:56 +0000 Received: by outflank-mailman (output) from mailman id 1115536.1462104; Mon, 08 Sep 2025 21:11:56 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9Y-0008Bc-Lf; Mon, 08 Sep 2025 21:11:56 +0000 Received: by outflank-mailman (input) for mailman id 1115536; Mon, 08 Sep 2025 21:11:55 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9X-0007uw-Nj for xen-devel@lists.xenproject.org; Mon, 08 Sep 2025 21:11:55 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uvj9X-000FSc-18; Mon, 08 Sep 2025 21:11:55 +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 1uvj9X-000gKq-1K; Mon, 08 Sep 2025 21:11:55 +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=1FdFTRNsjH5U9rDP4kQAUpXOlwuD271Mac2A8wU+UVw=; b=5ZzkpER2wQKhBha22yOLu1C5DQ l4XWikl2jK8dKsP+A860LeeFf9qmsNy1wElQuGGM9LzAjAbWq7zwWzHM67+qEqNQmmLcZprJ9v6kf eHQ+Cs4IEh1eJzrvA3SbyDpjMfZB2cKxgI6HD4GyAsC6Yee+IEG8VsBqQVXj5aPwPq0s=; 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 v7 03/16] emul/ns16x50: implement emulator stub Date: Mon, 8 Sep 2025 14:11:36 -0700 Message-ID: <20250908211149.279143-4-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250908211149.279143-1-dmukhin@ford.com> References: <20250908211149.279143-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757365955646124100 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. Only one domain, defined via 'vuart=3D' parameter, will have UART emulator initially. The command line option is not documented yet because of the plan to adjust this code for vUART configuration via xl. 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 v6: - feedback from Mykola - added temporary 'vuart=3D' run-time option to enable emulator for certain domain for ease of testing --- xen/arch/x86/hvm/hvm.c | 75 +++++++ xen/common/emul/vuart/Makefile | 1 + xen/common/emul/vuart/ns16x50.c | 364 ++++++++++++++++++++++++++++++++ 3 files changed, 440 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..363c010f8dcc 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include =20 @@ -107,6 +108,67 @@ static const char __initconst warning_hvm_fep[] =3D static bool __initdata opt_altp2m_enabled; boolean_param("altp2m", opt_altp2m_enabled); =20 +/* Enable NS16550 emulator for certain domain only. */ +static int __read_mostly opt_vuart_domid =3D -1; + +#ifdef CONFIG_VUART_NS16X50 +static int __read_mostly opt_vuart_id; +static int __init cf_check parse_vuart_param(const char *s) +{ + if ( !isdigit(*s) ) + return -EINVAL; + + opt_vuart_domid =3D simple_strtoul(s, &s, 0); + + if ( *s !=3D ':' ) + return 0; + + if ( strncmp(s, "com", 3) ) + return -EINVAL; + + opt_vuart_id =3D *(s + 3) - '1'; + if ( opt_vuart_id < 0 || opt_vuart_id > 3 ) + return -EINVAL; + + return 0; +} +custom_param("vuart", parse_vuart_param); + +static const struct vuart_info *get_vuart_info(struct domain *d) +{ +#define PC_UART(n,p,i) { \ + .name =3D n, \ + .compatible =3D "ns16550", \ + .base_addr =3D p, \ + .size =3D 8, \ + .irq =3D i, \ +} + static const struct vuart_info pc_uarts[4] =3D + { + PC_UART("com1", 0x3f8, 4), + PC_UART("com2", 0x2f8, 3), + PC_UART("com3", 0x3fe, 4), + PC_UART("com4", 0x2fe, 3), + }; + unsigned i; + + for ( i =3D 0; i < ARRAY_SIZE(pc_uarts); i++ ) + if ( i =3D=3D opt_vuart_id ) + break; + + if ( i !=3D ARRAY_SIZE(pc_uarts) ) + return &pc_uarts[i]; + + return NULL; +#undef PC_UART +} +#else +static const struct vuart_info *get_vuart_info(struct domain *d) +{ + return NULL; +} +#endif /* CONFIG_VUART_NS16X50 */ + static int cf_check cpu_callback( struct notifier_block *nfb, unsigned long action, void *hcpu) { @@ -689,6 +751,15 @@ int hvm_domain_initialise(struct domain *d, if ( rc !=3D 0 ) goto fail1; =20 + if ( IS_ENABLED(CONFIG_VUART_NS16X50) && d->domain_id =3D=3D opt_vuart= _domid ) + { + const struct vuart_info *info =3D get_vuart_info(d); + + rc =3D vuart_init(d, info); + if ( rc ) + goto out_vioapic_deinit; + } + stdvga_init(d); =20 rtc_init(d); @@ -712,6 +783,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 +847,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/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..a3bdf9f415ca --- /dev/null +++ b/xen/common/emul/vuart/ns16x50.c @@ -0,0 +1,364 @@ +/* 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) + */ +#define NS16X50_EMU_REGS_NUM (NS16X50_REGS_NUM + 2) + +/* + * 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 UINT8_MAX; + 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 UINT16_MAX; + 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 UINT32_MAX; + 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) +{ + const char op =3D (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 ) + { + printk(XENLOG_ERR "%c io 0x%04x %d: not initialized\n", + op, addr, size); + + ASSERT_UNREACHABLE(); + goto out; + } + + vdev =3D vuart->vdev; + ASSERT(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, 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, 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, addr, size, dlab, reg, *data); + goto out; + } + + spin_lock(&vdev->lock); + + if ( dir =3D=3D IOREQ_WRITE ) + rc =3D ns16x50_io_write(vdev, reg, size, data); + else + rc =3D ns16x50_io_read(vdev, reg, size, data); + + spin_unlock(&vdev->lock); + + if ( rc =3D=3D 0 ) + ns16x50_debug(vdev, "%c 0x%04x %d: DLAB=3D%d %02"PRIx32" 0x%08"PRI= x32"\n", + op, addr, size, dlab, reg, *data); + else + ns16x50_err(vdev, "%c 0x%04x %d: DLAB=3D%d %02"PRIx32" 0x%08"PRIx3= 2": unsupported access\n", + op, addr, size, dlab, reg, *data); + +out: + rcu_unlock_domain(d); + + return X86EMUL_OKAY; +} + +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 ( !is_hvm_domain(d) ) + { + ns16x50_err(info, "not an HVM domain\n"); + return ERR_PTR(-ENOSYS); + } + + if ( vuart_find_by_io_range(d, info->base_addr, info->size) ) + { + ns16x50_err(info, "already registered\n"); + return ERR_PTR(-EBUSY); + } + + 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 ) + { + xvfree(vdev); + 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 Wed Sep 10 02:05:52 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=1757365938; cv=none; d=zohomail.com; s=zohoarc; b=erbBS4KbvY7br2sm73u0M8CZiJVbuyaUxxGQyqRe9MrTXyQjmnO1oXQaCK/M8OZaoDqPN0+5vDUuPX1VA4LfVXrKL9MuYVQY9HoklIex8aTNW3rENh1/6tHO08Pr0xycpewcQGKk1aR8T3R2OI1gJYoHT/u9bO454+odQDVjgLI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757365938; 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=NWRpmqJhOTOIY3zhSnhQ9LFHXgJeUqzoWYVvV58DwuQ=; b=nRK7asdR2ENAX7KfcNRz3AaQ22DcFzPd56WxTG7CkuhKn4y/1Ce5CuS2jSKusCVWcHruqjX3fXEtmoIQ/v/Vo9xapvbEk0/hOY3aWbY02w9ozMS4sjZGpL1uHUs137FC0F0PZUFHWuCy0w4XSowETZ77vLhsYWRnq8xJj93NOFk= 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 1757365938603396.38456889655004; Mon, 8 Sep 2025 14:12:18 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1115537.1462115 (Exim 4.92) (envelope-from ) id 1uvj9a-0008QR-3e; Mon, 08 Sep 2025 21:11:58 +0000 Received: by outflank-mailman (output) from mailman id 1115537.1462115; Mon, 08 Sep 2025 21:11:58 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9Z-0008QI-To; Mon, 08 Sep 2025 21:11:57 +0000 Received: by outflank-mailman (input) for mailman id 1115537; Mon, 08 Sep 2025 21:11:56 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9Y-0008DO-Su for xen-devel@lists.xenproject.org; Mon, 08 Sep 2025 21:11:56 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uvj9Y-000FSp-1Q; Mon, 08 Sep 2025 21:11:56 +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 1uvj9Y-000gKu-1d; Mon, 08 Sep 2025 21:11:56 +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=NWRpmqJhOTOIY3zhSnhQ9LFHXgJeUqzoWYVvV58DwuQ=; b=QfQCzboiEv5kPwQ8hac1qgJUSu WVT/GvMWfIpHz9k78XZcH5ZjiWa0/w3fE0w+ifdBNX1vYlvmkYN8zxvgnmrnS2TiEmvpU/jAlGYK/ b9CiyvuZljKoLIOkOO2Gpspcp9y58R1u42i8fEpj4L12/LRDZvmH5oK4A7FCJrLVpx8Q=; 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 v7 04/16] emul/ns16x50: implement DLL/DLM registers Date: Mon, 8 Sep 2025 14:11:37 -0700 Message-ID: <20250908211149.279143-5-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250908211149.279143-1-dmukhin@ford.com> References: <20250908211149.279143-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757365941386124100 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 --- Changes since v6: - added default registers handling for non-DLL/DLM accesses - used UINT8_MAX --- xen/common/emul/vuart/ns16x50.c | 47 +++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x5= 0.c index a3bdf9f415ca..da8583a1dc93 100644 --- a/xen/common/emul/vuart/ns16x50.c +++ b/xen/common/emul/vuart/ns16x50.c @@ -96,8 +96,22 @@ 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; + else + { + switch ( reg ) + { + default: + rc =3D -EINVAL; + break; + } + } + return rc; } =20 @@ -108,8 +122,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 & UINT8_MAX; + vdev->regs[NS16X50_REGS_NUM + UART_DLM] =3D (val >> 8) & UINT8_MAX; + rc =3D 0; + } + return rc; } =20 @@ -145,9 +167,22 @@ 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 UINT8_MAX; 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]; + else + { + switch ( reg ) + { + default: + rc =3D -EINVAL; + break; + } + } + *data =3D val; =20 return rc; @@ -162,6 +197,13 @@ static int ns16x50_io_read16( uint16_t val =3D UINT16_MAX; 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; @@ -278,12 +320,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 & UINT8_MAX; + vdev->regs[NS16X50_REGS_NUM + UART_DLM] =3D (divisor >> 8) & UINT8_MAX; + register_portio_handler(d, info->base_addr, info->size, ns16x50_io_han= dle); =20 return 0; --=20 2.51.0 From nobody Wed Sep 10 02:05:52 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=1757365940; cv=none; d=zohomail.com; s=zohoarc; b=DSOvxmDQvGR2TRJigx3SaFHQf8UXa/xUXp9133LthhQq3N378jwNo/tHULB20hnGJ+74/yNNONaNSrQqT4iwma11zcB+F4K7MZsa6dr48wgmrDOSzrmyjFPFEIRIqTii5w5XtJ08fx7j1Jqd8oX130RIst30m281OBx5qPLu+kM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757365940; 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=TefMi+8qYWJ3sWp2Jmhd2ppEtx/E0etNYFj1pW73ooo=; b=K7Q4qS0cG4sAyU98Bj7MIsDcPwK0oL0i80G+BohrxdvKxUlwsn1bBH0mwP5vYgo1A2dJ6Hs6vm02yDEr8UOAXClEZNrHuSAI8Wz47Yhaf983LYy1PVWcCBk/UBB7MiEPuACMSz0dj5AQrmOyvW0x2OTcmDwH2CNQGtSTt3dwXZA= 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 175736593996377.85490452289196; Mon, 8 Sep 2025 14:12:19 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1115538.1462124 (Exim 4.92) (envelope-from ) id 1uvj9b-0000FT-AL; Mon, 08 Sep 2025 21:11:59 +0000 Received: by outflank-mailman (output) from mailman id 1115538.1462124; Mon, 08 Sep 2025 21:11:59 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9b-0000FG-5Z; Mon, 08 Sep 2025 21:11:59 +0000 Received: by outflank-mailman (input) for mailman id 1115538; Mon, 08 Sep 2025 21:11:58 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9Z-0008QT-Um for xen-devel@lists.xenproject.org; Mon, 08 Sep 2025 21:11:57 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uvj9Z-000FT2-1m; Mon, 08 Sep 2025 21:11:57 +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 1uvj9Z-000gMD-1x; Mon, 08 Sep 2025 21:11:57 +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=TefMi+8qYWJ3sWp2Jmhd2ppEtx/E0etNYFj1pW73ooo=; b=RMrlGjVZwWJhwisdIpfyGQezh/ j8FyprAHyc3RVkYgK75iO9XUlEb0qzIUafCBitw5W9uK7ove5z4B8g4I+/xloaXFZRIK3umNtUu+E +yxga2J46i5Km9ti7PzcwdCiKZq84Az/cyKeO9LM4mSWQid53qBKYoNulhHaA1gR4vSI=; 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 v7 05/16] emul/ns16x50: implement SCR register Date: Mon, 8 Sep 2025 14:11:38 -0700 Message-ID: <20250908211149.279143-6-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250908211149.279143-1-dmukhin@ford.com> References: <20250908211149.279143-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757365941411124100 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 --- Changes since v6: - default handling of non-DLL/DLM registers moved to the previous patch --- xen/common/emul/vuart/ns16x50.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x5= 0.c index da8583a1dc93..5643ef4cc01e 100644 --- a/xen/common/emul/vuart/ns16x50.c +++ b/xen/common/emul/vuart/ns16x50.c @@ -106,6 +106,11 @@ static int ns16x50_io_write8( { 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; @@ -177,6 +182,10 @@ static int ns16x50_io_read8( { switch ( reg ) { + case UART_SCR: + val =3D regs[UART_SCR]; + break; + default: rc =3D -EINVAL; break; --=20 2.51.0 From nobody Wed Sep 10 02:05:52 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=1757365949; cv=none; d=zohomail.com; s=zohoarc; b=g8K1mZeneRyhga3ryIgOD2BQuxqWwKXoa/MudK9Hpc5HRwAEifF2WBeCXvNXVpOxhmF9zgboekNMoZXVmSaJGJVXS91FYbuqaW4zceSVSsC2kl+MMaeXbAeGdz+0LdJYTod6XBnH9bgLpjhqxWn1xdV1k7TuBUjKGr0iD8UKORA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757365949; 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=UpqDmrURqhicTlP+xGJnrT1Wd61lJrVuEW9MZuV9LUw=; b=HL2Pn+QDJLiddYw5gZOIwYSz4MMigL/67sQboD7T0pxkxezCsZ+niiy5J4HeFONd+Z3pxbTp5HLa79qImLu8fRbWrXfovmmk2woAi2nnrfX9dY8SLGd2QTTea9VbUFrav4Ee+l84BdEtgFWz3Io/4P09/CTYPFGmyfb7vx+fQ9c= 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 1757365949301653.739543520829; Mon, 8 Sep 2025 14:12:29 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1115539.1462131 (Exim 4.92) (envelope-from ) id 1uvj9b-0000Mq-Sq; Mon, 08 Sep 2025 21:11:59 +0000 Received: by outflank-mailman (output) from mailman id 1115539.1462131; Mon, 08 Sep 2025 21:11:59 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9b-0000Kl-Mq; Mon, 08 Sep 2025 21:11:59 +0000 Received: by outflank-mailman (input) for mailman id 1115539; Mon, 08 Sep 2025 21:11:59 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9a-0000E8-Vi for xen-devel@lists.xenproject.org; Mon, 08 Sep 2025 21:11:58 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uvj9a-000FTE-26; Mon, 08 Sep 2025 21:11:58 +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 1uvj9a-000gMH-2K; Mon, 08 Sep 2025 21:11:58 +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=UpqDmrURqhicTlP+xGJnrT1Wd61lJrVuEW9MZuV9LUw=; b=QJ+W5RoOargplJeMWgu+XCccUz wZJBB6qyLmwA6PakBbMOh8500+D+mgMfVMPDgHPZa+OZ+1SGo2fo3OIGrZuQUuI5j7qmTXKN26yCk 91RDoRYIJxLN6G66S7CZlRJkXeYy3HRRx+GeUjjYcAXXbOLUFQ8ld2hXjiPr35WrAJP8=; 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 v7 06/16] emul/ns16x50: implement IER/IIR registers Date: Mon, 8 Sep 2025 14:11:39 -0700 Message-ID: <20250908211149.279143-7-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250908211149.279143-1-dmukhin@ford.com> References: <20250908211149.279143-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757365950138116600 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. vPIC case is implemented (HVM), vIOAPIC case is stubbed out (for follow on PVH). 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 v6: - removed asserts for !has_vpic() paths --- xen/common/emul/vuart/ns16x50.c | 138 ++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x5= 0.c index 5643ef4cc01e..664d799ddaee 100644 --- a/xen/common/emul/vuart/ns16x50.c +++ b/xen/common/emul/vuart/ns16x50.c @@ -90,6 +90,124 @@ 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. + */ +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 if ( has_vioapic(d) ) + /* TODO */ + 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 if ( has_vioapic(d) ) + /* TODO */ + 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. */ @@ -106,6 +224,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; @@ -115,6 +237,8 @@ static int ns16x50_io_write8( rc =3D -EINVAL; break; } + + ns16x50_irq_check(vdev); } =20 return rc; @@ -182,6 +306,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; @@ -190,6 +322,8 @@ static int ns16x50_io_read8( rc =3D -EINVAL; break; } + + ns16x50_irq_check(vdev); } =20 *data =3D val; @@ -342,6 +476,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 Wed Sep 10 02:05:52 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=1757365940; cv=none; d=zohomail.com; s=zohoarc; b=MiaQKQKqOeGvHKl5QWRJ86zvoETY2ufy9tiirJF6ga9U3mC8NnRunsw6c5viZgtcmGkR8boSWNpaKUNViPl5xSzjMmC+LKYzPiFzyvymUjpXJSwX8KDqYwTBwIEOuf60VbB5bzofimPyGeYev1YreeLBVzKNa60oTqF+oa5k+Io= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757365940; 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=zvzWLhOV/JuCu2mvge1tqyEd27KupA6wAEV4H8Ytz2o=; b=dYGV9dDVK0idhFFq4SUEQMXvE2p01GV9REeByaRxi4MmCC8ow1gC03FRRPnkmedqWVrBeLQu8uArGdxj+xM7zfIVCnquQCwXrkSXlpxH4P1pG3SQzY8+HmZw66HNIyzlPtrMteuA8rrjcQqRuDlvP4rkeR2YarKdZz9T6Fs9xMo= 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 1757365940341901.5320368355286; Mon, 8 Sep 2025 14:12:20 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1115540.1462145 (Exim 4.92) (envelope-from ) id 1uvj9d-0000jW-7J; Mon, 08 Sep 2025 21:12:01 +0000 Received: by outflank-mailman (output) from mailman id 1115540.1462145; Mon, 08 Sep 2025 21:12:01 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9d-0000ik-0y; Mon, 08 Sep 2025 21:12:01 +0000 Received: by outflank-mailman (input) for mailman id 1115540; Mon, 08 Sep 2025 21:12:00 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9c-0000Sw-23 for xen-devel@lists.xenproject.org; Mon, 08 Sep 2025 21:12:00 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uvj9b-000FTS-2Q; Mon, 08 Sep 2025 21:11:59 +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 1uvj9b-000gML-2e; Mon, 08 Sep 2025 21:11:59 +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=zvzWLhOV/JuCu2mvge1tqyEd27KupA6wAEV4H8Ytz2o=; b=RC3FU9fvNVrQUef+qZ8kprTEBT hcpe1q7LW4fQYlQnGo+yjlbxuADdqEJrUYMEur6/Mng/Ic4GC7ZwJqULvMiQcfLqFPUIG4cYk7dfH 3/9/uwNi57vf5TUGOA4M1s2iw0JHdsxn+ZeSA906NFtmb2/7B4/qnau6m/of+Q71YyOk=; 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 v7 07/16] emul/ns16x50: implement LCR/LSR registers Date: Mon, 8 Sep 2025 14:11:40 -0700 Message-ID: <20250908211149.279143-8-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250908211149.279143-1-dmukhin@ford.com> References: <20250908211149.279143-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757365942168116600 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 v6: - n/a --- 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 664d799ddaee..0831a576cd9e 100644 --- a/xen/common/emul/vuart/ns16x50.c +++ b/xen/common/emul/vuart/ns16x50.c @@ -87,12 +87,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) @@ -228,11 +228,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; @@ -314,6 +319,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 Wed Sep 10 02:05:52 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=1757365940; cv=none; d=zohomail.com; s=zohoarc; b=JMmkG2f4Ftu0VtUVc7sqJew9//drmHXtT2CftRNjhkzO6WF4bnfrl9dpTtFSl/tc6hW3Km7j9PGpuqezG/RX/bd9eIfm3Nbi2sIKMIvXWjcLiE9jS5pFNAEj8CN4KB+EJg9L/IsmRSDyALaYIDdsYtUqE3Snpj9WUxKCi3VLEmE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757365940; 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=mgBIXJuIz84mlcqZHiPSZTYiEqMID1sT7aaSFn+Fx+Y=; b=HDDPgm/v0fRVUm/wPSsQhlGGYX75UkjWsBKA9fjT0JIg8LNaVhK8y+6Ov/Xxh8uT5EL9n3Jspsg9TXVBfM7D8TJd7tw27gPgQpHjsFWJvlh8j/F7Bz0XDtl2LWgWyDgB7Ht86N4syWObnGaAP8hcHYtRhkd8reH3TYAIKKXFWI8= 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 1757365940665877.6076786772447; Mon, 8 Sep 2025 14:12:20 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1115541.1462154 (Exim 4.92) (envelope-from ) id 1uvj9f-00016g-FO; Mon, 08 Sep 2025 21:12:03 +0000 Received: by outflank-mailman (output) from mailman id 1115541.1462154; Mon, 08 Sep 2025 21:12:03 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9f-00016P-AW; Mon, 08 Sep 2025 21:12:03 +0000 Received: by outflank-mailman (input) for mailman id 1115541; Mon, 08 Sep 2025 21:12:01 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9d-0000kF-4U for xen-devel@lists.xenproject.org; Mon, 08 Sep 2025 21:12:01 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uvj9c-000FTf-2g; Mon, 08 Sep 2025 21:12:00 +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 1uvj9c-000gMQ-2t; Mon, 08 Sep 2025 21:12:00 +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=mgBIXJuIz84mlcqZHiPSZTYiEqMID1sT7aaSFn+Fx+Y=; b=63xdtqy6k03JSFof0Lbgh4XeuR ULTNEZGFh9DRKh7kf/CV7uOWmckNLYqbfkwDzXbCazUMUk42eF6sj6K5LvvtVvUwlHiCQgQDNsQnR hnW1ip1rPrqyA/aH4vExgy6ojzr9wcL6kWpLurWwYJpmyfPVbstN+o1QGdFHZftj+NWE=; 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 v7 08/16] emul/ns16x50: implement MCR/MSR registers Date: Mon, 8 Sep 2025 14:11:41 -0700 Message-ID: <20250908211149.279143-9-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250908211149.279143-1-dmukhin@ford.com> References: <20250908211149.279143-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757365942105116600 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 since v6: - fixed UART_MSR_TERI handling --- 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 0831a576cd9e..fdc20124d4c9 100644 --- a/xen/common/emul/vuart/ns16x50.c +++ b/xen/common/emul/vuart/ns16x50.c @@ -107,7 +107,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 /* @@ -232,12 +232,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_RSRVD0 ) + ns16x50_warn(vdev, "MCR: attempt to set reserved bit: %x\n= ", + UART_MCR_RSRVD0); + + if ( val & UART_MCR_TCRTLR ) + ns16x50_warn(vdev, "MCR: not supported: %x\n", + UART_MCR_TCRTLR); + + if ( val & UART_MCR_RSRVD1 ) + ns16x50_warn(vdev, "MCR: attempt to set reserved bit: %x\n= ", + UART_MCR_RSRVD1); + + /* 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; @@ -323,11 +374,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 Wed Sep 10 02:05:52 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=1757365945; cv=none; d=zohomail.com; s=zohoarc; b=gzpnzf94UTQaUy+Q31xMpEQpmf6fzOvvoaLmVr/15ZIw83mOpUy/IQ/c3Tny9HZbGnqCZ94zMB/4vo5S2gkBFFL9DF5bfuc1YDXpUFFOv+GqN8ZfAi6wkKM3wtD6tb7ONL/ZGIxXMjt4Z4k8805cP1wXIs4i9swGkSu7ZU/0jFU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757365945; 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=sJw6viqpsDfMS5MRma9QK/++3SeyoW0ownBjjeYeZKo=; b=cNBgWmQLUT9DjMwobIoNfe9Os7wNisHc61jQ55+8KE9UYXTt1lygquxBbagy9p+6W5KZR8rLRxDwxhDv4f9lhnzWevcbxI3lwG6B3n8DowdFculf5DbkmD/kK7HVgJqvqclGKuEHFPhglkbmyGYBr5/SLA92O9LvWtPAm4RA2mE= 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 1757365945280648.9815905421576; Mon, 8 Sep 2025 14:12:25 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1115542.1462159 (Exim 4.92) (envelope-from ) id 1uvj9g-0001BX-10; Mon, 08 Sep 2025 21:12:04 +0000 Received: by outflank-mailman (output) from mailman id 1115542.1462159; Mon, 08 Sep 2025 21:12:03 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9f-0001AG-Nw; Mon, 08 Sep 2025 21:12:03 +0000 Received: by outflank-mailman (input) for mailman id 1115542; Mon, 08 Sep 2025 21:12:02 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9e-0000zQ-53 for xen-devel@lists.xenproject.org; Mon, 08 Sep 2025 21:12:02 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uvj9d-000FU1-2x; Mon, 08 Sep 2025 21:12:01 +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 1uvj9d-000gMV-3B; Mon, 08 Sep 2025 21:12:01 +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=sJw6viqpsDfMS5MRma9QK/++3SeyoW0ownBjjeYeZKo=; b=Zqr8zJltVqZnjQMSoCh8s/n1nd +xuQYSproeuFQMambh3zctjtcQW64xcEIRma5q/s4hI7FmFGIYPU+XtPnX9Nxuu+rGZ/1NkXYzHew YsVmI/C5mtSEsEd8Z/256c+5QN0GkArjOCIlBP9tJ+ohtvhAumN64SR3dFQb+99ZeCt0=; 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 v7 09/16] emul/ns16x50: implement RBR register Date: Mon, 8 Sep 2025 14:11:42 -0700 Message-ID: <20250908211149.279143-10-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250908211149.279143-1-dmukhin@ford.com> References: <20250908211149.279143-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757365947609124100 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. Account for DLL =3D=3D 0: in this case, disable receiver. 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 --- Changes since v6: - added DLL =3D=3D 0 case handling as per Mykola's suggestion --- xen/common/emul/vuart/ns16x50.c | 134 +++++++++++++++++++++++++++++++- 1 file changed, 132 insertions(+), 2 deletions(-) diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x5= 0.c index fdc20124d4c9..250411e0a7d8 100644 --- a/xen/common/emul/vuart/ns16x50.c +++ b/xen/common/emul/vuart/ns16x50.c @@ -9,6 +9,8 @@ * https://www.ti.com/lit/ds/symlink/tl16c550c.pdf * - UART w/ 64 byte FIFO: * https://www.ti.com/lit/ds/symlink/tl16c750.pdf + * - DesignWare DW_apb_uart Databook, v4.02a: + * https://iccircle.com/static/upload/img20240313113905.pdf * * Limitations: * - Only x86; @@ -85,6 +87,74 @@ 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 bool ns16x50_is_running(const struct vuart_ns16x50 *vdev) +{ + /* DLL set to 0 disables serial communication. */ + return vdev->regs[NS16X50_REGS_NUM + UART_DLL]; +} + static uint8_t ns16x50_dlab_get(const struct vuart_ns16x50 *vdev) { return vdev->regs[UART_LCR] & UART_LCR_DLAB ? 1 : 0; @@ -97,7 +167,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) @@ -362,6 +432,20 @@ static int ns16x50_io_read8( { switch ( reg ) { + case UART_RBR: + if ( !ns16x50_is_running(vdev) ) + break; + + /* 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; @@ -611,13 +695,59 @@ 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 ( !ns16x50_is_running(vdev) ) + ns16x50_debug(vdev, "THR/RBR access disabled: DLL =3D=3D 0\n"); + else 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 Wed Sep 10 02:05:52 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=1757365941; cv=none; d=zohomail.com; s=zohoarc; b=VGu05M9B7cR/vhw14q6iiYl92MY9E3/oU7G73q+APmFGexSq7QutqUQZCg8FjwWcUYcHen6S98yFntCgpu5cu9EPjdAEA+pzbuNo9+MiYF4ij45bciKojRclIHVzlmluOjTzjkxcubNzOmKMs9vK9WqQ6f6TVN2gI8DaMwvrefc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757365941; 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=b4hUxqYghrvWW5yLlDTNdgPS7IjF5GT2QqKNV0EctlI=; b=h7UK+OVWuNlOdvN4cREnxhL/8DpFGCUyv6rpg12CfuVjwZmEe99XRAtg46JQC2X6n7CTbzAwg1xtAU6Zpv8ZVr43sE2gxdZJ4l5gMYDBiaI7UmiobXKPQ0NGejIKzSHdhwmub9c6/pazMi37TIggMNL+jhkHzMZLK9epk+jN99A= 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 1757365941582236.9532960347184; Mon, 8 Sep 2025 14:12:21 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1115543.1462166 (Exim 4.92) (envelope-from ) id 1uvj9g-0001Iy-Rh; Mon, 08 Sep 2025 21:12:04 +0000 Received: by outflank-mailman (output) from mailman id 1115543.1462166; Mon, 08 Sep 2025 21:12:04 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9g-0001Fi-8N; Mon, 08 Sep 2025 21:12:04 +0000 Received: by outflank-mailman (input) for mailman id 1115543; Mon, 08 Sep 2025 21:12:03 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9f-000164-7u for xen-devel@lists.xenproject.org; Mon, 08 Sep 2025 21:12:03 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uvj9f-000FUE-01; Mon, 08 Sep 2025 21:12:03 +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 1uvj9f-000gN1-0G; Mon, 08 Sep 2025 21:12:02 +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=b4hUxqYghrvWW5yLlDTNdgPS7IjF5GT2QqKNV0EctlI=; b=JkzGM+cpJE/hIL99ZEjDEJcHoH vkoNQIP/dyxrYsu5nhCithcAwxfUYQLUS7gngL77ITVYpL0r+M1SqzjE6QnVVZIQp29ciVAqT7iTp QMgUIJvFNj8p0PQBzJIiBeCA44D8O/i8+r2E15UUxTxNIp0am0JLwQ0DTYvO2mWJ5W1Q=; 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 v7 10/16] emul/ns16x50: implement THR register Date: Mon, 8 Sep 2025 14:11:43 -0700 Message-ID: <20250908211149.279143-11-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250908211149.279143-1-dmukhin@ford.com> References: <20250908211149.279143-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757365942244116600 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. Account for DLL =3D=3D 0: in this case, disable transmitter. Add UART_IIR_THR interrupt reason handling since it depends on THR register access. Signed-off-by: Denis Mukhin --- Changes since v6: - added DLL =3D=3D 0 case handling as per Mykola's suggestion - dropped UART_IIR_THR clearing in UART_IIR register emulation in ns16x50_i= o_write8() - simplified UART_IIR_THR handling - updated ns16x50_iir_check_thr() --- xen/common/emul/vuart/ns16x50.c | 82 ++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x5= 0.c index 250411e0a7d8..137ce08f4e1d 100644 --- a/xen/common/emul/vuart/ns16x50.c +++ b/xen/common/emul/vuart/ns16x50.c @@ -149,6 +149,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 bool ns16x50_is_running(const struct vuart_ns16x50 *vdev) { /* DLL set to 0 disables serial communication. */ @@ -172,7 +232,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 !ns16x50_fifo_tx_full(vdev); } =20 static bool cf_check ns16x50_iir_check_msi(const struct vuart_ns16x50 *vde= v) @@ -294,6 +354,22 @@ static int ns16x50_io_write8( { switch ( reg ) { + case UART_THR: + if ( !ns16x50_is_running(vdev) ) + break; + + 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); + + break; + case UART_IER: regs[UART_IER] =3D val & UART_IER_MASK; break; @@ -646,6 +722,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 Wed Sep 10 02:05:52 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=1757365948; cv=none; d=zohomail.com; s=zohoarc; b=TNYQgj+UYpjh5SG3Cjjq98LxwX2RSvnbne4pvn5aY6XyWKK7SFz6vQBAkZGGDrTR9eQ3EOWAaq5QlvB1hck1Xzce4hNOdt80TsPz0ZwK7IFLctEhjeaQ5sVCiz6nRUTWaHk1CLPPCZIn7rQ4nDOMCA2V+CWa+foVNB97G7qRxMA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757365948; 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=jOrpkPK6Y2sHbIx1Zg9cP39ItjKVIpi7DD14BHDTv7c=; b=GsrA88uQkvUvU+Fl4SVkW/csCrtGOntYsWTLOSCd430dGSkE0lT27s63h39yQ8MBXKRrTyxrXe07ssWcaqH5hTjcV1ljP/bliigsLMlRcHy8ar6JXtACI6oOp9wGn+dfbRsVdBZPGf2VOUXYHPuGZcDGwUdVf8pBOw3MDnBxWWI= 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 1757365948204775.8063720140517; Mon, 8 Sep 2025 14:12:28 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1115545.1462180 (Exim 4.92) (envelope-from ) id 1uvj9i-0001mh-FE; Mon, 08 Sep 2025 21:12:06 +0000 Received: by outflank-mailman (output) from mailman id 1115545.1462180; Mon, 08 Sep 2025 21:12:06 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9i-0001ke-4k; Mon, 08 Sep 2025 21:12:06 +0000 Received: by outflank-mailman (input) for mailman id 1115545; Mon, 08 Sep 2025 21:12:04 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9g-0001J0-Dc for xen-devel@lists.xenproject.org; Mon, 08 Sep 2025 21:12:04 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uvj9g-000FUS-0K; Mon, 08 Sep 2025 21:12:04 +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 1uvj9g-000gNA-0Y; Mon, 08 Sep 2025 21:12:04 +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=jOrpkPK6Y2sHbIx1Zg9cP39ItjKVIpi7DD14BHDTv7c=; b=Lfpk1ztSq/H6d4MF6OefdVvZPK w0S23FSr2I7VTRlJ3WqXyhnrHSQi6Wi0Y/eYi7ID25udDhzcaU1A1ii4O4KYNs1HreBVQL10atV0S RVOISIqsZ1fyb1yANVnZij9IYm/AxoGDn1JaMyvOvMfocfx3+pwVU04CBFB9HkNw0QBQ=; 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 v7 11/16] emul/ns16x50: implement FCR register (write-only) Date: Mon, 8 Sep 2025 14:11:44 -0700 Message-ID: <20250908211149.279143-12-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250908211149.279143-1-dmukhin@ford.com> References: <20250908211149.279143-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757365950013116600 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 --- Changes since v6: - dropped UART_IIR_THR handling from UART_FCR_CLTX case --- 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 137ce08f4e1d..a92df6923aa5 100644 --- a/xen/common/emul/vuart/ns16x50.c +++ b/xen/common/emul/vuart/ns16x50.c @@ -374,6 +374,33 @@ static int ns16x50_io_write8( regs[UART_IER] =3D val & UART_IER_MASK; break; =20 + case UART_FCR: /* WO */ + if ( val & UART_FCR_RSRVD0 ) + ns16x50_warn(vdev, "FCR: attempt to set reserved bit: %x\n= ", + UART_FCR_RSRVD0); + + if ( val & UART_FCR_RSRVD1 ) + ns16x50_warn(vdev, "FCR: attempt to set reserved bit: %x\n= ", + UART_FCR_RSRVD1); + + 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); + + 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 Wed Sep 10 02:05:52 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=1757365947; cv=none; d=zohomail.com; s=zohoarc; b=UQ9Vn0fDNTZP4Os9Q1k1aNaupVGJexrJx01rnDus0wlrZ622t2hy709qcYZKtJN8CD1pDodLR/ZxtiAyRAWq9zHd9MBGviXJ0zFTQ4FKinwBP+gJ9alVz9GoDQtpvaEGcOyKOEmDdNqK+ptFKH6zNQLPIuSzFD7/Q2t2UWKtI5s= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757365947; 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=QW9I8ZuXBd/H3nKRB+tcF6FvOZaI6qXJPw/5aA/9wEw=; b=intUtiugMLkC0y5ZBUh+iB7lSQ5IYg9QfeXpcLGLqcdJVr+1Qa9fQKuNZg7RnWnIcl87X6tuo7tzUtCt64SwVmJfXG3hOyUQJJiJazw4kvTE2LZhtCIKVpWy2lXbYovOamf1YYhP/3n38XP1cMUZm/ggvnE2HZOUd8g4/8q3XMU= 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 1757365947350798.2189234829318; Mon, 8 Sep 2025 14:12:27 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1115548.1462186 (Exim 4.92) (envelope-from ) id 1uvj9j-0001w4-DY; Mon, 08 Sep 2025 21:12:07 +0000 Received: by outflank-mailman (output) from mailman id 1115548.1462186; Mon, 08 Sep 2025 21:12:07 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9i-0001u1-R9; Mon, 08 Sep 2025 21:12:06 +0000 Received: by outflank-mailman (input) for mailman id 1115548; Mon, 08 Sep 2025 21:12:05 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9h-0001ZP-Eu for xen-devel@lists.xenproject.org; Mon, 08 Sep 2025 21:12:05 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uvj9h-000FUh-0d; Mon, 08 Sep 2025 21:12:05 +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 1uvj9h-000gNK-0r; Mon, 08 Sep 2025 21:12:05 +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=QW9I8ZuXBd/H3nKRB+tcF6FvOZaI6qXJPw/5aA/9wEw=; b=IJaIKbhghKRi/SM12NScR/FphI s/Rly6SBlOFXqgntn1c8D5VaEMrgqlSxjqF6UixnMd4Y2mt+ybpVS+vI7Qy0NJ2PMX5odVIlUUjES yNIZQQehjJoDscx1Jv3fuKaGu6reRySzIVv7T/QgjjY1wDgZuwzQ8NMnlhh6eA1/y+P8=; 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 v7 12/16] emul/ns16550: implement dump_state() hook Date: Mon, 8 Sep 2025 14:11:45 -0700 Message-ID: <20250908211149.279143-13-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250908211149.279143-1-dmukhin@ford.com> References: <20250908211149.279143-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757365948007116600 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 v6: - n/a --- 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 a92df6923aa5..c341f012d005 100644 --- a/xen/common/emul/vuart/ns16x50.c +++ b/xen/common/emul/vuart/ns16x50.c @@ -640,6 +640,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. @@ -709,6 +761,9 @@ static int cf_check ns16x50_io_handle( =20 spin_unlock(&vdev->lock); =20 + if ( ns16x50_log_level >=3D 3 ) + ns16x50_dump_state(vdev); + if ( rc =3D=3D 0 ) ns16x50_debug(vdev, "%c 0x%04x %d: DLAB=3D%d %02"PRIx32" 0x%08"PRI= x32"\n", op, addr, size, dlab, reg, *data); @@ -844,6 +899,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; } @@ -853,7 +910,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 Wed Sep 10 02:05:52 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=1757365956; cv=none; d=zohomail.com; s=zohoarc; b=duy7BsrNC8OIJWSzCgw8B3J8bc4W1UGjHNWuF3RTaIcdRJuJjtfhdNF6bvKTgGBgTnwJZItHfmU9nPTMMO8OZGrvoPtxPjSfVmM60wewOsSGjC6tE56ZThtFR18J+Qj2iiEirgaH4LpMhUQO1pH52SFfTplzjnLmUfkBzYzQQOo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757365956; 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=KkUN0OllhKW27ZmsCBHTtMD+F/9dKnn+1KTiUiwT17c=; b=GfHGYGwriKF9Tl7p0E1+vV9z6aTfBUIeglvTEgCmQa0MjA0BqQioRyTDj/8SobFsM2h6dnne1F754INN4xHf56YzT/1unHyAXqB0xTok8S+fI8lYr3meOLKL88krz+4nTg4xA4KL6FOnJskzJUr3u0DW3z2QFtHNauZN3FfIbwg= 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 1757365956615844.1165601324109; Mon, 8 Sep 2025 14:12:36 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1115549.1462196 (Exim 4.92) (envelope-from ) id 1uvj9k-0002Kn-Qs; Mon, 08 Sep 2025 21:12:08 +0000 Received: by outflank-mailman (output) from mailman id 1115549.1462196; Mon, 08 Sep 2025 21:12:08 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9k-0002Io-LB; Mon, 08 Sep 2025 21:12:08 +0000 Received: by outflank-mailman (input) for mailman id 1115549; Mon, 08 Sep 2025 21:12:06 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9i-0001qT-Hl for xen-devel@lists.xenproject.org; Mon, 08 Sep 2025 21:12:06 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uvj9i-000FUt-0w; Mon, 08 Sep 2025 21:12:06 +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 1uvj9i-000gNQ-1A; Mon, 08 Sep 2025 21:12:06 +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=KkUN0OllhKW27ZmsCBHTtMD+F/9dKnn+1KTiUiwT17c=; b=GbGd+yPlZZoKbzzS07p93lgEKd /XZqka49ao5ewWmTypg9sYU4phrlCfNqN+m1E/I6ATWtAkUxLj73rA7X57HPCylyyr9Q9vb4PkpWo 2PbzxoE11vg7Quxvny1g5Fn3hvcYiiFttggU2fx6GUYMhvyFlbejQLc3Qz3JyREeIsV8=; 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 v7 13/16] emul/ns16x50: add Kconfig options Date: Mon, 8 Sep 2025 14:11:46 -0700 Message-ID: <20250908211149.279143-14-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250908211149.279143-1-dmukhin@ford.com> References: <20250908211149.279143-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757365958237116600 Content-Type: text/plain; charset="utf-8" From: Denis Mukhin =20 Add initial Kconfig options configure NS16550-capable emulator. Signed-off-by: Denis Mukhin --- Changes since v6: - new patch --- xen/common/emul/vuart/Kconfig | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/xen/common/emul/vuart/Kconfig b/xen/common/emul/vuart/Kconfig index ce1b976b7da7..9a49a6528b5a 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 + help + In-hypervisor NS16550-compatible UART emulation. + + Only one legacy PC COM port is emulated for domain with a certain ID + (set via 'vuart-domid=3D' command line setting). + + This is strictly for testing purposes (such as early HVM guest console), + and not appropriate for use in production. + +config VUART_NS16X50_DEBUG + bool "Development: NS16550-compatible UART Emulator Debugging" + depends on VUART_NS16X50 && DEBUG + help + Enable development debugging. + endmenu --=20 2.51.0 From nobody Wed Sep 10 02:05:52 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=1757365946; cv=none; d=zohomail.com; s=zohoarc; b=OxG9WMFFcpuOWzjtofWaqnlSKeUBOgfLXTP7cM4qJfAg17tW5QmYUImKC+Q2SXxkfCOy8C2h83dFl71cUm5rBzpMlxMDEf/JcLbC2Tqxb2jhwBGf5RmwIIcw201BylwD9e7DGmuM3H+/1UjupQ7iVUTd00tT52AZGhBiK+YP2lI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757365946; 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=bDnknz7r88crgl/cPA1cLrvLlvrN6IJa2LZ7XeWLxFY=; b=c5qHegU405OSAZn2Pg6WwcO5oXAtYCg/RmEo1BDqXJqbW6WA/Z9aAGfoWyMp2DGgH6SvkcYer/NJnqKCEelYT0UgCyhUgJ3kbfUvSZggkDiqY9iI+NWkh3E98ik92bDYofjL768zkLkYWHFNBtZUw/35gDxKpFz9s+5OYd5/PXQ= 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 1757365946913839.9955091598061; Mon, 8 Sep 2025 14:12:26 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1115553.1462208 (Exim 4.92) (envelope-from ) id 1uvj9m-0002km-Om; Mon, 08 Sep 2025 21:12:10 +0000 Received: by outflank-mailman (output) from mailman id 1115553.1462208; Mon, 08 Sep 2025 21:12:10 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9m-0002i6-AN; Mon, 08 Sep 2025 21:12:10 +0000 Received: by outflank-mailman (input) for mailman id 1115553; Mon, 08 Sep 2025 21:12:08 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9j-00023q-MO for xen-devel@lists.xenproject.org; Mon, 08 Sep 2025 21:12:07 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uvj9j-000FV9-1X; Mon, 08 Sep 2025 21:12:07 +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 1uvj9j-000gNW-1U; Mon, 08 Sep 2025 21:12:07 +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=bDnknz7r88crgl/cPA1cLrvLlvrN6IJa2LZ7XeWLxFY=; b=5R2c/NewHRd1WLlL/YZ719Dfzg s+zc/RpjjywnrIRSJ0Tu5WlRb4JNFYPB2rJ4XCg5rRka1yqh5vNuW/8tp/V9lRmpmBdHxYUhwFAnu +mPjSskJkNDpPHD4Wf+9oPpUWnodUVntU+MgBxoIROSUiKABfRPPd4JLyfGw7aQhRPyc=; 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 v7 14/16] x86/domain: enable per-domain I/O port bitmaps Date: Mon, 8 Sep 2025 14:11:47 -0700 Message-ID: <20250908211149.279143-15-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250908211149.279143-1-dmukhin@ford.com> References: <20250908211149.279143-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757365948382116600 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 v6: - n/a --- 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 363c010f8dcc..1fc16a22e157 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); @@ -266,15 +259,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; @@ -706,19 +690,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); @@ -745,6 +722,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 c341f012d005..ea34c3ae598a 100644 --- a/xen/common/emul/vuart/ns16x50.c +++ b/xen/common/emul/vuart/ns16x50.c @@ -783,9 +783,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 & UINT8_MAX; vdev->regs[NS16X50_REGS_NUM + UART_DLM] =3D (divisor >> 8) & UINT8_MAX; --=20 2.51.0 From nobody Wed Sep 10 02:05:52 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=1757365954; cv=none; d=zohomail.com; s=zohoarc; b=nc1Y0s/MHoNgaz8asTxNNpv1W34Kou/CoyYq9ZHH9orOMkIOhl6TXk2wrxdSRsre9jCHn7to/qnhfEboRsJ203rgm2UeWNFpMkKdl2HijjKERv7cifvV+VsBQVUUg4/D1+Nqm4K9CQbCpcRn4ZnX4IUUzGmsWlfxjIoNq/1XVlU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757365954; 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=2EIgKUJ6qf0RiPOYjpi3onfm0JU2Yq54wzXSyn3SuHQ=; b=MAIErjigEEfLIfWY8ywNxZZuGMt/kBDb7dAUOLuXhbQG8Q5JZQ0XCQAbDE43z4GkszV/KMG+PufeQmT6BVJFnD4CWB/0H6oq0JlovLja/e9PRie5ffrAMXS21UVOjFOaMAvxHLuavJalpsZDjtoNkVaXKarn5zdAuYCmVQFjVrU= 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 1757365954662838.7170382781081; Mon, 8 Sep 2025 14:12:34 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1115554.1462214 (Exim 4.92) (envelope-from ) id 1uvj9o-00033Z-Jd; Mon, 08 Sep 2025 21:12:12 +0000 Received: by outflank-mailman (output) from mailman id 1115554.1462214; Mon, 08 Sep 2025 21:12:12 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9n-00030o-No; Mon, 08 Sep 2025 21:12:11 +0000 Received: by outflank-mailman (input) for mailman id 1115554; Mon, 08 Sep 2025 21:12:09 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9k-0002L2-Ng for xen-devel@lists.xenproject.org; Mon, 08 Sep 2025 21:12:08 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uvj9k-000FVM-1s; Mon, 08 Sep 2025 21:12:08 +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 1uvj9k-000gNe-27; Mon, 08 Sep 2025 21:12:08 +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=2EIgKUJ6qf0RiPOYjpi3onfm0JU2Yq54wzXSyn3SuHQ=; b=pT7tt06uHlD/3fRZmHZr8/lEaY srf21/NDSqLw48HMOMSwwra/+LUhoZr+aPDqKD/SyDl0W3l+sg8mynD7jKEVCoIyZ78vUyditFcwx YQ3w1tZXpHzrQyZRMfbZjlpUXzb1p3mk4THrznmJuE2+ESWTwoi0giJk08ZrJFDNjZsw=; 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 v7 15/16] xen/domain: allocate d->irq_caps before arch-specific initialization Date: Mon, 8 Sep 2025 14:11:48 -0700 Message-ID: <20250908211149.279143-16-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250908211149.279143-1-dmukhin@ford.com> References: <20250908211149.279143-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757365956496116601 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 v6: - n/a --- 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 ea34c3ae598a..6bd58ba5540b 100644 --- a/xen/common/emul/vuart/ns16x50.c +++ b/xen/common/emul/vuart/ns16x50.c @@ -797,6 +797,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 & UINT8_MAX; vdev->regs[NS16X50_REGS_NUM + UART_DLM] =3D (divisor >> 8) & UINT8_MAX; --=20 2.51.0 From nobody Wed Sep 10 02:05:52 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=1757365948; cv=none; d=zohomail.com; s=zohoarc; b=NZuj++wkaeiXGirc1sx1r9chqJj2yB32WtH4kJedKZVGShIO7bTpkYkdiQL5DTd/0rpSbWf+KYdw3L6fOTZ6djz+Qsk8dRRXRnBIaANVoTkEya396oyKiTDGXpVsXyuIydeanrN0mUlS5O9gdRevhHXEidqci6ZQ9qs/5IKJ67c= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757365948; 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=QgoMqHbu0tUc+lVtvyYl2w5a013VrqpmgCwPwd2nRFw=; b=A7VnJgRzByOF/akD9CD49ZCgIuajlPz1KqT8YdmslPh9bLrZOJ9FtlrpaiGR8gTb2lGwkzNvvezFwklYEcqjLaLSGzvdWHJlVrclVQlMnMD+zFtSyV+VmjebEBJy1lhX0Gj+78gBJganXswKLMs5DMkATUMOHjvFgvOd/dZ+85k= 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 17573659487281010.4203410554849; Mon, 8 Sep 2025 14:12:28 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1115556.1462223 (Exim 4.92) (envelope-from ) id 1uvj9q-0003IR-1W; Mon, 08 Sep 2025 21:12:14 +0000 Received: by outflank-mailman (output) from mailman id 1115556.1462223; Mon, 08 Sep 2025 21:12:13 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9o-0003Ct-Pk; Mon, 08 Sep 2025 21:12:12 +0000 Received: by outflank-mailman (input) for mailman id 1115556; Mon, 08 Sep 2025 21:12:09 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uvj9l-0002aN-RZ for xen-devel@lists.xenproject.org; Mon, 08 Sep 2025 21:12:09 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uvj9l-000FVX-2F; Mon, 08 Sep 2025 21:12:09 +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 1uvj9l-000gNi-2T; Mon, 08 Sep 2025 21:12:09 +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=QgoMqHbu0tUc+lVtvyYl2w5a013VrqpmgCwPwd2nRFw=; b=sOqZXpCXdQNe+SfB8ANsxd7Vn4 ZxrzEB4O/VMXSs0Fr3nr5FmWbheVLjFkqlmzUFrSF1+D0tmWM43cGV0CSvKydOw7dY9AbSw45y7M6 FsI9G9nOelJVlrFjztHRmbcjYGVEGob1snavNNwQppzgnhaWoUNvvV0i+b7LRE+TMm6E=; 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 v7 16/16] emul/ns16x50: implement IRQ emulation via vIOAPIC Date: Mon, 8 Sep 2025 14:11:49 -0700 Message-ID: <20250908211149.279143-17-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250908211149.279143-1-dmukhin@ford.com> References: <20250908211149.279143-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757365951384124100 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 v6: - n/a --- 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, 52 insertions(+), 3 deletions(-) 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 6bd58ba5540b..081d2639aa7a 100644 --- a/xen/common/emul/vuart/ns16x50.c +++ b/xen/common/emul/vuart/ns16x50.c @@ -299,7 +299,7 @@ static void ns16x50_irq_assert(const struct vuart_ns16x= 50 *vdev) if ( has_vpic(d) ) vector =3D hvm_isa_irq_assert(d, info->irq, vioapic_get_vector); else if ( has_vioapic(d) ) - /* TODO */ + vector =3D hvm_ioapic_assert(d, info->irq, false); else ASSERT_UNREACHABLE(); =20 @@ -314,7 +314,7 @@ static void ns16x50_irq_deassert(const struct vuart_ns1= 6x50 *vdev) if ( has_vpic(d) ) hvm_isa_irq_deassert(d, info->irq); else if ( has_vioapic(d) ) - /* TODO */ + hvm_ioapic_deassert(d, info->irq); else ASSERT_UNREACHABLE(); =20 @@ -806,6 +806,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 & UINT8_MAX; vdev->regs[NS16X50_REGS_NUM + UART_DLM] =3D (divisor >> 8) & UINT8_MAX; @@ -822,9 +833,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