From 0359ff3565b40f8692c9a986d6d04a61b03e6d4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= Date: Mon, 20 Apr 2026 12:34:52 +0200 Subject: [PATCH] xen/uart: be more careful with changes to the PCI command register MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Read the existing PCI command register and only add the required bits to it, as to avoid clearing bits that might be possibly set by the firmware already, which might put the device into a non-working state. Xen being the owner of the PCI device it's legitimately allowed to change command registers bits. Be careful however in case buggy devices require certain command register bits to be enabled, while not strictly required from Xen's usage. Fixes: f2ff5d6628b3 ("ns16550: enable PCI serial card usage") Signed-off-by: Roger Pau Monné Reviewed-by: Jan Beulich master commit: ebf543972560e45b838def3a54859331cc92c970 master date: 2026-03-30 16:43:14 +0200 --- xen/drivers/char/ns16550.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c index 1dce415cb2..9507af299f 100644 --- a/xen/drivers/char/ns16550.c +++ b/xen/drivers/char/ns16550.c @@ -273,14 +273,19 @@ static int cf_check ns16550_getc(struct serial_port *port, char *pc) static void pci_serial_early_init(struct ns16550 *uart) { #ifdef NS16550_PCI + uint16_t cmd; + if ( !uart->ps_bdf_enable ) return; + cmd = pci_conf_read16(PCI_SBDF(0, uart->ps_bdf[0], uart->ps_bdf[1], + uart->ps_bdf[2]), PCI_COMMAND); + if ( uart->io_base >= 0x10000 ) { pci_conf_write16(PCI_SBDF(0, uart->ps_bdf[0], uart->ps_bdf[1], uart->ps_bdf[2]), - PCI_COMMAND, PCI_COMMAND_MEMORY); + PCI_COMMAND, cmd | PCI_COMMAND_MEMORY); return; } @@ -297,7 +302,7 @@ static void pci_serial_early_init(struct ns16550 *uart) uart->io_base | PCI_BASE_ADDRESS_SPACE_IO); pci_conf_write16(PCI_SBDF(0, uart->ps_bdf[0], uart->ps_bdf[1], uart->ps_bdf[2]), - PCI_COMMAND, PCI_COMMAND_IO); + PCI_COMMAND, cmd | PCI_COMMAND_IO); #endif }