From patchwork Tue Jun 7 14:30:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= X-Patchwork-Id: 12872009 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id AAB38CCA484 for ; Tue, 7 Jun 2022 14:31:35 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.343347.568685 (Exim 4.92) (envelope-from ) id 1nyaEo-0006Xj-3V; Tue, 07 Jun 2022 14:31:18 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 343347.568685; Tue, 07 Jun 2022 14:31:18 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1nyaEn-0006Xa-VG; Tue, 07 Jun 2022 14:31:17 +0000 Received: by outflank-mailman (input) for mailman id 343347; Tue, 07 Jun 2022 14:31:16 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1nyaEm-00061K-Er for xen-devel@lists.xenproject.org; Tue, 07 Jun 2022 14:31:16 +0000 Received: from out1-smtp.messagingengine.com (out1-smtp.messagingengine.com [66.111.4.25]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 7ac4aee9-e66e-11ec-b605-df0040e90b76; Tue, 07 Jun 2022 16:31:12 +0200 (CEST) Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailout.nyi.internal (Postfix) with ESMTP id 115835C01B2; Tue, 7 Jun 2022 10:31:12 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute1.internal (MEProxy); Tue, 07 Jun 2022 10:31:12 -0400 Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 7 Jun 2022 10:31:10 -0400 (EDT) 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" X-Inumbo-ID: 7ac4aee9-e66e-11ec-b605-df0040e90b76 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= invisiblethingslab.com; h=cc:cc:content-transfer-encoding :content-type:date:date:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to; s=fm1; t=1654612272; x=1654698672; bh=Z7Lr0j0M2K aSvcNr1cRj7+FQLB0GDunqIgj6YEaiVuo=; b=QMbE85kSJ2KvhvxcyHDARQoyz7 ss3tdAXA6hhXhNY5rR01dfLXxLe8d0c4cdWskt5OrXN8KswNxKKwijkv+32BtP84 nNv64e+cu8rBlsOg3PjNH2UvfxK//wGv3fCXdvvr01m93bcS4UEUEDhchdaCib7N XWhSe6EhBfMYJnOycAp33d24H3v67YUA4ti3w5RHvMME7Th9DGmXJmpZiqBW714H J/MawPI1Wl63DpSnmcyhUPlEelgnK+EWRykBSEK4eqEhcdVDD5wWetOusgDZhBh8 SeS9mc+1Owm9/DAceXupmUoDJLPntN/d5SJoGXIsF1NPZ8skU7OCSUm5kp5Q== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm2; t=1654612272; x= 1654698672; bh=Z7Lr0j0M2KaSvcNr1cRj7+FQLB0GDunqIgj6YEaiVuo=; b=W cnEKzUcDZSkoZc7lWP7fzxcKOMq8LLrQxv/gz5SVITEkBIcKcLrEp49bgAi9U7QC JEDyFC4/HS7K83/OZJyU/viGV2+w4oqCaX5WnKfqiimSvpcf1AlDfmdhRu3Idou9 zxRgeoPsYTcVP3M/VUIIutFVivaWHWzHDnEIhGY6vWnLNOFYoPtuu6DfLvuRrQKy XlrP6UcmqLlgx16YvRsfY7WXQOaTE6V6aNdCIIQ3vmY2DP1DJakEgQh1dNT9qR8+ n3jQkwOJGi9nVFk6KQIVQuDhsYAgckXcuvhTHNWQ5DIitXGzRqpOJOFIJXxxlKs6 OAxYwWr+kObgJqW8BgxFg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvfedruddthedgjeeiucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhephffvvefufffkofgjfhggtgfgsehtkeertdertdejnecuhfhrohhmpeforghr vghkucforghrtgiihihkohifshhkihdqifpkrhgvtghkihcuoehmrghrmhgrrhgvkhesih hnvhhishhisghlvghthhhinhhgshhlrggsrdgtohhmqeenucggtffrrghtthgvrhhnpeek udejueeuudetudffffdtheetteeileekkeefjeeljefhkeelffevueffkeelfeenucffoh hmrghinhepghhithhhuhgsrdgtohhmpdhgnhhurdhorhhgnecuvehluhhsthgvrhfuihii vgeptdenucfrrghrrghmpehmrghilhhfrhhomhepmhgrrhhmrghrvghksehinhhvihhsih gslhgvthhhihhnghhslhgrsgdrtghomh X-ME-Proxy: Feedback-ID: i1568416f:Fastmail From: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= To: xen-devel@lists.xenproject.org Cc: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= , Connor Davis , Jan Beulich , Andrew Cooper , =?utf-8?q?Roger_Pau_Monn=C3=A9?= , Wei Liu , George Dunlap , Julien Grall , Stefano Stabellini Subject: [PATCH v1 01/10] drivers/char: Add support for Xue USB3 debugger Date: Tue, 7 Jun 2022 16:30:07 +0200 Message-Id: <87c73737fe8ec6d9fe31c844b72b6c979b90c25d.1654612169.git-series.marmarek@invisiblethingslab.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: References: MIME-Version: 1.0 From: Connor Davis [Connor] Xue is a cross-platform USB 3 debugger that drives the Debug Capability (DbC) of xHCI-compliant host controllers. This patch implements the operations needed for xue to initialize the host controller's DbC and communicate with it. It also implements a struct uart_driver that uses xue as a backend. Note that only target -> host communication is supported for now. To use Xue as a console, add 'console=dbgp dbgp=xue' to the command line. [Marek] The Xue driver is taken from https://github.com/connojd/xue and heavily refactored to fit into Xen code base. Major changes include: - drop support for non-Xen systems - drop xue_ops abstraction - use Xen's native helper functions for PCI access - move all the code to xue.c, drop "inline" - build for x86 only - annotate functions with cf_check - adjust for Xen's code style Signed-off-by: Connor Davis Signed-off-by: Marek Marczykowski-Górecki --- xen/arch/x86/Kconfig | 1 +- xen/arch/x86/include/asm/fixmap.h | 4 +- xen/arch/x86/setup.c | 1 +- xen/drivers/char/Kconfig | 7 +- xen/drivers/char/Makefile | 1 +- xen/drivers/char/xue.c | 957 +++++++++++++++++++++++++++++++- xen/include/xen/serial.h | 1 +- 7 files changed, 972 insertions(+) create mode 100644 xen/drivers/char/xue.c diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig index 06d6fbc86478..9260f464d478 100644 --- a/xen/arch/x86/Kconfig +++ b/xen/arch/x86/Kconfig @@ -13,6 +13,7 @@ config X86 select HAS_COMPAT select HAS_CPUFREQ select HAS_EHCI + select HAS_XHCI select HAS_EX_TABLE select HAS_FAST_MULTIPLY select HAS_IOPORTS diff --git a/xen/arch/x86/include/asm/fixmap.h b/xen/arch/x86/include/asm/fixmap.h index 20746afd0a2a..bc39ffe896b1 100644 --- a/xen/arch/x86/include/asm/fixmap.h +++ b/xen/arch/x86/include/asm/fixmap.h @@ -25,6 +25,8 @@ #include #include +#define MAX_XHCI_PAGES 16 + /* * Here we define all the compile-time 'special' virtual * addresses. The point is to have a constant address at @@ -43,6 +45,8 @@ enum fixed_addresses { FIX_COM_BEGIN, FIX_COM_END, FIX_EHCI_DBGP, + FIX_XHCI_BEGIN, + FIX_XHCI_END = FIX_XHCI_BEGIN + MAX_XHCI_PAGES - 1, #ifdef CONFIG_XEN_GUEST FIX_PV_CONSOLE, FIX_XEN_SHARED_INFO, diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 53a73010e029..801081befa78 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -946,6 +946,7 @@ void __init noreturn __start_xen(unsigned long mbi_p) ns16550.irq = 3; ns16550_init(1, &ns16550); ehci_dbgp_init(); + xue_uart_init(); console_init_preirq(); if ( pvh_boot ) diff --git a/xen/drivers/char/Kconfig b/xen/drivers/char/Kconfig index e5f7b1d8eb8a..55d35af960e5 100644 --- a/xen/drivers/char/Kconfig +++ b/xen/drivers/char/Kconfig @@ -74,3 +74,10 @@ config HAS_EHCI help This selects the USB based EHCI debug port to be used as a UART. If you have an x86 based system with USB, say Y. + +config HAS_XHCI + bool + depends on X86 + help + This selects the USB based XHCI debug capability to be used as a UART. If + you have an x86 based system with USB3, say Y. diff --git a/xen/drivers/char/Makefile b/xen/drivers/char/Makefile index 14e67cf072d7..bda1e44d3f39 100644 --- a/xen/drivers/char/Makefile +++ b/xen/drivers/char/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_HAS_MVEBU) += mvebu-uart.o obj-$(CONFIG_HAS_OMAP) += omap-uart.o obj-$(CONFIG_HAS_SCIF) += scif-uart.o obj-$(CONFIG_HAS_EHCI) += ehci-dbgp.o +obj-$(CONFIG_HAS_XHCI) += xue.o obj-$(CONFIG_HAS_IMX_LPUART) += imx-lpuart.o obj-$(CONFIG_ARM) += arm-uart.o obj-y += serial.o diff --git a/xen/drivers/char/xue.c b/xen/drivers/char/xue.c new file mode 100644 index 000000000000..e95dd09d39a8 --- /dev/null +++ b/xen/drivers/char/xue.c @@ -0,0 +1,957 @@ +/* + * drivers/char/xue.c + * + * Xen port for the xue debugger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; If not, see . + * + * Copyright (c) 2019 Assured Information Security. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define XUE_POLL_INTERVAL 100 /* us */ + +#define XUE_PAGE_SIZE 4096ULL + +/* Supported xHC PCI configurations */ +#define XUE_XHC_CLASSC 0xC0330ULL + +/* DbC idVendor and idProduct */ +#define XUE_DBC_VENDOR 0x1D6B +#define XUE_DBC_PRODUCT 0x0010 +#define XUE_DBC_PROTOCOL 0x0000 + +/* DCCTRL fields */ +#define XUE_CTRL_DCR 0 +#define XUE_CTRL_HOT 2 +#define XUE_CTRL_HIT 3 +#define XUE_CTRL_DRC 4 +#define XUE_CTRL_DCE 31 + +/* DCPORTSC fields */ +#define XUE_PSC_PED 1 +#define XUE_PSC_CSC 17 +#define XUE_PSC_PRC 21 +#define XUE_PSC_PLC 22 +#define XUE_PSC_CEC 23 + +#define XUE_PSC_ACK_MASK \ + ((1UL << XUE_PSC_CSC) | (1UL << XUE_PSC_PRC) | (1UL << XUE_PSC_PLC) | \ + (1UL << XUE_PSC_CEC)) + +#define xue_debug(...) printk("xue debug: " __VA_ARGS__) +#define xue_alert(...) printk("xue alert: " __VA_ARGS__) +#define xue_error(...) printk("xue error: " __VA_ARGS__) + +/****************************************************************************** + * TRB ring (summarized from the manual): + * + * TRB rings are circular queues of TRBs shared between the xHC and the driver. + * Each ring has one producer and one consumer. The DbC has one event + * ring and two transfer rings; one IN and one OUT. + * + * The DbC hardware is the producer on the event ring, and + * xue is the consumer. This means that event TRBs are read-only from + * the xue. + * + * OTOH, xue is the producer of transfer TRBs on the two transfer + * rings, so xue enqueues transfers, and the hardware dequeues + * them. The dequeue pointer of a transfer ring is read by + * xue by examining the latest transfer event TRB on the event ring. The + * transfer event TRB contains the address of the transfer TRB that generated + * the event. + * + * To make each transfer ring circular, the last TRB must be a link TRB, which + * points to the beginning of the next queue. Note that this implementation + * does not support multiple segments, so each link TRB points back to the + * beginning of its own segment. + ******************************************************************************/ + +/* TRB types */ +enum { + xue_trb_norm = 1, + xue_trb_link = 6, + xue_trb_tfre = 32, + xue_trb_psce = 34 +}; + +/* TRB completion codes */ +enum { xue_trb_cc_success = 1, xue_trb_cc_trb_err = 5 }; + +/* DbC endpoint types */ +enum { xue_ep_bulk_out = 2, xue_ep_bulk_in = 6 }; + +/* DMA/MMIO structures */ +#pragma pack(push, 1) +struct xue_trb { + uint64_t params; + uint32_t status; + uint32_t ctrl; +}; + +struct xue_erst_segment { + uint64_t base; + uint16_t size; + uint8_t rsvdz[6]; +}; + +#define XUE_CTX_SIZE 16 +#define XUE_CTX_BYTES (XUE_CTX_SIZE * 4) + +struct xue_dbc_ctx { + uint32_t info[XUE_CTX_SIZE]; + uint32_t ep_out[XUE_CTX_SIZE]; + uint32_t ep_in[XUE_CTX_SIZE]; +}; + +struct xue_dbc_reg { + uint32_t id; + uint32_t db; + uint32_t erstsz; + uint32_t rsvdz; + uint64_t erstba; + uint64_t erdp; + uint32_t ctrl; + uint32_t st; + uint32_t portsc; + uint32_t rsvdp; + uint64_t cp; + uint32_t ddi1; + uint32_t ddi2; +}; +#pragma pack(pop) + +#define XUE_TRB_MAX_TFR (XUE_PAGE_SIZE << 4) +#define XUE_TRB_PER_PAGE (XUE_PAGE_SIZE / sizeof(struct xue_trb)) + +/* Defines the size in bytes of TRB rings as 2^XUE_TRB_RING_ORDER * 4096 */ +#ifndef XUE_TRB_RING_ORDER +#define XUE_TRB_RING_ORDER 4 +#endif +#define XUE_TRB_RING_CAP (XUE_TRB_PER_PAGE * (1ULL << XUE_TRB_RING_ORDER)) +#define XUE_TRB_RING_BYTES (XUE_TRB_RING_CAP * sizeof(struct xue_trb)) +#define XUE_TRB_RING_MASK (XUE_TRB_RING_BYTES - 1U) + +struct xue_trb_ring { + struct xue_trb *trb; /* Array of TRBs */ + uint32_t enq; /* The offset of the enqueue ptr */ + uint32_t deq; /* The offset of the dequeue ptr */ + uint8_t cyc; /* Cycle state toggled on each wrap-around */ + uint8_t db; /* Doorbell target */ +}; + +#define XUE_DB_OUT 0x0 +#define XUE_DB_IN 0x1 +#define XUE_DB_INVAL 0xFF + +/* Defines the size in bytes of work rings as 2^XUE_WORK_RING_ORDER * 4096 */ +#ifndef XUE_WORK_RING_ORDER +#define XUE_WORK_RING_ORDER 3 +#endif +#define XUE_WORK_RING_CAP (XUE_PAGE_SIZE * (1ULL << XUE_WORK_RING_ORDER)) +#define XUE_WORK_RING_BYTES XUE_WORK_RING_CAP + +#if XUE_WORK_RING_CAP > XUE_TRB_MAX_TFR +#error "XUE_WORK_RING_ORDER must be at most 4" +#endif + +struct xue_work_ring { + uint8_t *buf; + uint32_t enq; + uint32_t deq; + uint64_t dma; +}; + +struct xue { + struct xue_dbc_reg *dbc_reg; + struct xue_dbc_ctx *dbc_ctx; + struct xue_erst_segment *dbc_erst; + struct xue_trb_ring dbc_ering; + struct xue_trb_ring dbc_oring; + struct xue_trb_ring dbc_iring; + struct xue_work_ring dbc_owork; + char *dbc_str; + + pci_sbdf_t sbdf; + uint64_t xhc_mmio_phys; + uint64_t xhc_mmio_size; + uint64_t xhc_dbc_offset; + void *xhc_mmio; + + int open; +}; + +static void xue_sys_pause(void) +{ + __asm volatile("pause" ::: "memory"); +} + +static void *xue_sys_map_xhc(uint64_t phys, uint64_t size) +{ + size_t i; + + if ( size != MAX_XHCI_PAGES * XUE_PAGE_SIZE ) + return NULL; + + for ( i = FIX_XHCI_END; i >= FIX_XHCI_BEGIN; i-- ) + { + set_fixmap_nocache(i, phys); + phys += XUE_PAGE_SIZE; + } + + /* + * The fixmap grows downward, so the lowest virt is + * at the highest index + */ + return fix_to_virt(FIX_XHCI_END); +} + +static void xue_flush_range(struct xue *xue, void *ptr, uint32_t bytes) +{ + uint32_t i; + + const uint32_t clshft = 6; + const uint32_t clsize = (1UL << clshft); + const uint32_t clmask = clsize - 1; + + uint32_t lines = (bytes >> clshft); + lines += (bytes & clmask) != 0; + + for ( i = 0; i < lines; i++ ) + clflush((void *)((uint64_t)ptr + (i * clsize))); +} + +static int xue_init_xhc(struct xue *xue) +{ + uint32_t bar0; + uint64_t bar1; + uint64_t devfn; + + /* + * Search PCI bus 0 for the xHC. All the host controllers supported so far + * are part of the chipset and are on bus 0. + */ + for ( devfn = 0; devfn < 256; devfn++ ) { + uint32_t dev = (devfn & 0xF8) >> 3; + uint32_t fun = devfn & 0x07; + pci_sbdf_t sbdf = PCI_SBDF(0, dev, fun); + uint32_t hdr = pci_conf_read8(sbdf, PCI_HEADER_TYPE); + + if ( hdr == 0 || hdr == 0x80 ) + { + if ( (pci_conf_read32(sbdf, PCI_CLASS_REVISION) >> 8) == XUE_XHC_CLASSC ) + { + xue->sbdf = sbdf; + break; + } + } + } + + if ( !xue->sbdf.sbdf ) + { + xue_error("Compatible xHC not found on bus 0\n"); + return 0; + } + + /* ...we found it, so parse the BAR and map the registers */ + bar0 = pci_conf_read32(xue->sbdf, PCI_BASE_ADDRESS_0); + bar1 = pci_conf_read32(xue->sbdf, PCI_BASE_ADDRESS_1); + + /* IO BARs not allowed; BAR must be 64-bit */ + if ( (bar0 & 0x1) != 0 || ((bar0 & 0x6) >> 1) != 2 ) + return 0; + + pci_conf_write32(xue->sbdf, PCI_BASE_ADDRESS_0, 0xFFFFFFFF); + xue->xhc_mmio_size = ~(pci_conf_read32(xue->sbdf, PCI_BASE_ADDRESS_0) & 0xFFFFFFF0) + 1; + pci_conf_write32(xue->sbdf, PCI_BASE_ADDRESS_0, bar0); + + xue->xhc_mmio_phys = (bar0 & 0xFFFFFFF0) | (bar1 << 32); + xue->xhc_mmio = xue_sys_map_xhc(xue->xhc_mmio_phys, xue->xhc_mmio_size); + + return xue->xhc_mmio != NULL; +} + +/** + * The first register of the debug capability is found by traversing the + * host controller's capability list (xcap) until a capability + * with ID = 0xA is found. The xHCI capability list begins at address + * mmio + (HCCPARAMS1[31:16] << 2) + */ +static struct xue_dbc_reg *xue_find_dbc(struct xue *xue) +{ + uint32_t *xcap; + uint32_t next; + uint32_t id; + uint8_t *mmio = (uint8_t *)xue->xhc_mmio; + uint32_t *hccp1 = (uint32_t *)(mmio + 0x10); + const uint32_t DBC_ID = 0xA; + + /** + * Paranoid check against a zero value. The spec mandates that + * at least one "supported protocol" capability must be implemented, + * so this should always be false. + */ + if ( (*hccp1 & 0xFFFF0000) == 0 ) + return NULL; + + xcap = (uint32_t *)(mmio + (((*hccp1 & 0xFFFF0000) >> 16) << 2)); + next = (*xcap & 0xFF00) >> 8; + id = *xcap & 0xFF; + + /** + * Table 7-1 states that 'next' is relative to + * the current value of xcap and is a dword offset. + */ + while ( id != DBC_ID && next ) { + xcap += next; + id = *xcap & 0xFF; + next = (*xcap & 0xFF00) >> 8; + } + + if ( id != DBC_ID ) + return NULL; + + xue->xhc_dbc_offset = (uint64_t)xcap - (uint64_t)mmio; + return (struct xue_dbc_reg *)xcap; +} + +/** + * Fields with the same interpretation for every TRB type (section 4.11.1). + * These are the fields defined in the TRB template, minus the ENT bit. That + * bit is the toggle cycle bit in link TRBs, so it shouldn't be in the + * template. + */ +static uint32_t xue_trb_cyc(const struct xue_trb *trb) +{ + return trb->ctrl & 0x1; +} + +static uint32_t xue_trb_type(const struct xue_trb *trb) +{ + return (trb->ctrl & 0xFC00) >> 10; +} + +static void xue_trb_set_cyc(struct xue_trb *trb, uint32_t c) +{ + trb->ctrl &= ~0x1UL; + trb->ctrl |= c; +} + +static void xue_trb_set_type(struct xue_trb *trb, uint32_t t) +{ + trb->ctrl &= ~0xFC00UL; + trb->ctrl |= (t << 10); +} + +/* Fields for normal TRBs */ +static void xue_trb_norm_set_buf(struct xue_trb *trb, uint64_t addr) +{ + trb->params = addr; +} + +static void xue_trb_norm_set_len(struct xue_trb *trb, uint32_t len) +{ + trb->status &= ~0x1FFFFUL; + trb->status |= len; +} + +static void xue_trb_norm_set_ioc(struct xue_trb *trb) +{ + trb->ctrl |= 0x20; +} + +/** + * Fields for Transfer Event TRBs (see section 6.4.2.1). Note that event + * TRBs are read-only from software + */ +static uint64_t xue_trb_tfre_ptr(const struct xue_trb *trb) +{ + return trb->params; +} + +static uint32_t xue_trb_tfre_cc(const struct xue_trb *trb) +{ + return trb->status >> 24; +} + +/* Fields for link TRBs (section 6.4.4.1) */ +static void xue_trb_link_set_rsp(struct xue_trb *trb, uint64_t rsp) +{ + trb->params = rsp; +} + +static void xue_trb_link_set_tc(struct xue_trb *trb) +{ + trb->ctrl |= 0x2; +} + +static void xue_trb_ring_init(const struct xue *xue, + struct xue_trb_ring *ring, int producer, + int doorbell) +{ + memset(ring->trb, 0, XUE_TRB_RING_CAP * sizeof(ring->trb[0])); + + ring->enq = 0; + ring->deq = 0; + ring->cyc = 1; + ring->db = (uint8_t)doorbell; + + /* + * Producer implies transfer ring, so we have to place a + * link TRB at the end that points back to trb[0] + */ + if ( producer ) + { + struct xue_trb *trb = &ring->trb[XUE_TRB_RING_CAP - 1]; + xue_trb_set_type(trb, xue_trb_link); + xue_trb_link_set_tc(trb); + xue_trb_link_set_rsp(trb, virt_to_maddr(ring->trb)); + } +} + +static int xue_trb_ring_full(const struct xue_trb_ring *ring) +{ + return ((ring->enq + 1) & (XUE_TRB_RING_CAP - 1)) == ring->deq; +} + +static int xue_work_ring_full(const struct xue_work_ring *ring) +{ + return ((ring->enq + 1) & (XUE_WORK_RING_CAP - 1)) == ring->deq; +} + +static uint64_t xue_work_ring_size(const struct xue_work_ring *ring) +{ + if ( ring->enq >= ring->deq ) + return ring->enq - ring->deq; + + return XUE_WORK_RING_CAP - ring->deq + ring->enq; +} + +static void xue_push_trb(struct xue *xue, struct xue_trb_ring *ring, + uint64_t dma, uint64_t len) +{ + struct xue_trb trb; + + if ( ring->enq == XUE_TRB_RING_CAP - 1 ) + { + /* + * We have to make sure the xHC processes the link TRB in order + * for wrap-around to work properly. We do this by marking the + * xHC as owner of the link TRB by setting the TRB's cycle bit + * (just like with normal TRBs). + */ + struct xue_trb *link = &ring->trb[ring->enq]; + xue_trb_set_cyc(link, ring->cyc); + + ring->enq = 0; + ring->cyc ^= 1; + } + + trb.params = 0; + trb.status = 0; + trb.ctrl = 0; + + xue_trb_set_type(&trb, xue_trb_norm); + xue_trb_set_cyc(&trb, ring->cyc); + + xue_trb_norm_set_buf(&trb, dma); + xue_trb_norm_set_len(&trb, (uint32_t)len); + xue_trb_norm_set_ioc(&trb); + + ring->trb[ring->enq++] = trb; + xue_flush_range(xue, &ring->trb[ring->enq - 1], sizeof(trb)); +} + +static int64_t xue_push_work(struct xue *xue, struct xue_work_ring *ring, + const char *buf, int64_t len) +{ + int64_t i = 0; + uint32_t start = ring->enq; + uint32_t end = 0; + + while ( !xue_work_ring_full(ring) && i < len ) + { + ring->buf[ring->enq] = buf[i++]; + ring->enq = (ring->enq + 1) & (XUE_WORK_RING_CAP - 1); + } + + end = ring->enq; + + if ( end > start ) + xue_flush_range(xue, &ring->buf[start], end - start); + else if ( i > 0 ) + { + xue_flush_range(xue, &ring->buf[start], XUE_WORK_RING_CAP - start); + xue_flush_range(xue, &ring->buf[0], end); + } + + return i; +} + +/* + * Note that if IN transfer support is added, then this + * will need to be changed; it assumes an OUT transfer ring only + */ +static void xue_pop_events(struct xue *xue) +{ + const int trb_shift = 4; + + struct xue_dbc_reg *reg = xue->dbc_reg; + struct xue_trb_ring *er = &xue->dbc_ering; + struct xue_trb_ring *tr = &xue->dbc_oring; + struct xue_trb *event = &er->trb[er->deq]; + uint64_t erdp = reg->erdp; + + rmb(); + + while ( xue_trb_cyc(event) == er->cyc ) { + switch (xue_trb_type(event)) { + case xue_trb_tfre: + if ( xue_trb_tfre_cc(event) != xue_trb_cc_success ) + { + xue_alert("tfre error cc: %u\n", xue_trb_tfre_cc(event)); + break; + } + tr->deq = + (xue_trb_tfre_ptr(event) & XUE_TRB_RING_MASK) >> trb_shift; + break; + case xue_trb_psce: + reg->portsc |= (XUE_PSC_ACK_MASK & reg->portsc); + break; + default: + break; + } + + er->cyc = (er->deq == XUE_TRB_RING_CAP - 1) ? er->cyc ^ 1 : er->cyc; + er->deq = (er->deq + 1) & (XUE_TRB_RING_CAP - 1); + event = &er->trb[er->deq]; + } + + erdp &= ~XUE_TRB_RING_MASK; + erdp |= (er->deq << trb_shift); + wmb(); + reg->erdp = erdp; +} + +/** + * xue_init_ep + * + * Initializes the endpoint as specified in sections 7.6.3.2 and 7.6.9.2. + * Each endpoint is Bulk, so the MaxPStreams, LSA, HID, CErr, FE, + * Interval, Mult, and Max ESIT Payload fields are all 0. + * + * Max packet size: 1024 + * Max burst size: debug mbs (from dbc_reg->ctrl register) + * EP type: 2 for OUT bulk, 6 for IN bulk + * TR dequeue ptr: physical base address of transfer ring + * Avg TRB length: software defined (see 4.14.1.1 for suggested defaults) + */ +static void xue_init_ep(uint32_t *ep, uint64_t mbs, uint32_t type, + uint64_t ring_dma) +{ + memset(ep, 0, XUE_CTX_BYTES); + + ep[1] = (1024 << 16) | ((uint32_t)mbs << 8) | (type << 3); + ep[2] = (ring_dma & 0xFFFFFFFF) | 1; + ep[3] = ring_dma >> 32; + ep[4] = 3 * 1024; +} + +/* Initialize the DbC info with USB string descriptor addresses */ +static void xue_init_strings(struct xue *xue, uint32_t *info) +{ + uint64_t *sda; + + /* clang-format off */ + const char strings[] = { + 6, 3, 9, 0, 4, 0, + 8, 3, 'A', 0, 'I', 0, 'S', 0, + 30, 3, 'X', 0, 'u', 0, 'e', 0, ' ', 0, + 'D', 0, 'b', 0, 'C', 0, ' ', 0, + 'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0, 'e', 0, + 4, 3, '0', 0 + }; + /* clang-format on */ + + memcpy(xue->dbc_str, strings, sizeof(strings)); + + sda = (uint64_t *)&info[0]; + sda[0] = virt_to_maddr(xue->dbc_str); + sda[1] = sda[0] + 6; + sda[2] = sda[0] + 6 + 8; + sda[3] = sda[0] + 6 + 8 + 30; + info[8] = (4 << 24) | (30 << 16) | (8 << 8) | 6; +} + +static void xue_dump(struct xue *xue) +{ + struct xue_dbc_reg *r = xue->dbc_reg; + + xue_debug("XUE DUMP:\n"); + xue_debug(" ctrl: 0x%x stat: 0x%x psc: 0x%x\n", r->ctrl, r->st, + r->portsc); + xue_debug(" id: 0x%x, db: 0x%x\n", r->id, r->db); +#if defined(__XEN__) || defined(VMM) + xue_debug(" erstsz: %u, erstba: 0x%lx\n", r->erstsz, r->erstba); + xue_debug(" erdp: 0x%lx, cp: 0x%lx\n", r->erdp, r->cp); +#else + xue_debug(" erstsz: %u, erstba: 0x%llx\n", r->erstsz, r->erstba); + xue_debug(" erdp: 0x%llx, cp: 0x%llx\n", r->erdp, r->cp); +#endif + xue_debug(" ddi1: 0x%x, ddi2: 0x%x\n", r->ddi1, r->ddi2); + xue_debug(" erstba == virt_to_dma(erst): %d\n", + r->erstba == virt_to_maddr(xue->dbc_erst)); + xue_debug(" erdp == virt_to_dma(erst[0].base): %d\n", + r->erdp == xue->dbc_erst[0].base); + xue_debug(" cp == virt_to_dma(ctx): %d\n", + r->cp == virt_to_maddr(xue->dbc_ctx)); +} + +static void xue_enable_dbc(struct xue *xue) +{ + struct xue_dbc_reg *reg = xue->dbc_reg; + + wmb(); + reg->ctrl |= (1UL << XUE_CTRL_DCE); + wmb(); + + while ( (reg->ctrl & (1UL << XUE_CTRL_DCE)) == 0 ) + xue_sys_pause(); + + wmb(); + reg->portsc |= (1UL << XUE_PSC_PED); + wmb(); + + while ( (reg->ctrl & (1UL << XUE_CTRL_DCR)) == 0 ) + xue_sys_pause(); +} + +static void xue_disable_dbc(struct xue *xue) +{ + struct xue_dbc_reg *reg = xue->dbc_reg; + + reg->portsc &= ~(1UL << XUE_PSC_PED); + wmb(); + reg->ctrl &= ~(1UL << XUE_CTRL_DCE); + + while ( reg->ctrl & (1UL << XUE_CTRL_DCE) ) + xue_sys_pause(); +} + +static int xue_init_dbc(struct xue *xue) +{ + uint64_t erdp = 0; + uint64_t out = 0; + uint64_t in = 0; + uint64_t mbs = 0; + struct xue_dbc_reg *reg = xue_find_dbc(xue); + + if ( !reg ) + return 0; + + xue->dbc_reg = reg; + xue_disable_dbc(xue); + + xue_trb_ring_init(xue, &xue->dbc_ering, 0, XUE_DB_INVAL); + xue_trb_ring_init(xue, &xue->dbc_oring, 1, XUE_DB_OUT); + xue_trb_ring_init(xue, &xue->dbc_iring, 1, XUE_DB_IN); + + erdp = virt_to_maddr(xue->dbc_ering.trb); + if ( !erdp ) + return 0; + + memset(xue->dbc_erst, 0, sizeof(*xue->dbc_erst)); + xue->dbc_erst->base = erdp; + xue->dbc_erst->size = XUE_TRB_RING_CAP; + + mbs = (reg->ctrl & 0xFF0000) >> 16; + out = virt_to_maddr(xue->dbc_oring.trb); + in = virt_to_maddr(xue->dbc_iring.trb); + + memset(xue->dbc_ctx, 0, sizeof(*xue->dbc_ctx)); + xue_init_strings(xue, xue->dbc_ctx->info); + xue_init_ep(xue->dbc_ctx->ep_out, mbs, xue_ep_bulk_out, out); + xue_init_ep(xue->dbc_ctx->ep_in, mbs, xue_ep_bulk_in, in); + + reg->erstsz = 1; + reg->erstba = virt_to_maddr(xue->dbc_erst); + reg->erdp = erdp; + reg->cp = virt_to_maddr(xue->dbc_ctx); + reg->ddi1 = (XUE_DBC_VENDOR << 16) | XUE_DBC_PROTOCOL; + reg->ddi2 = XUE_DBC_PRODUCT; + + xue_flush_range(xue, xue->dbc_ctx, sizeof(*xue->dbc_ctx)); + xue_flush_range(xue, xue->dbc_erst, sizeof(*xue->dbc_erst)); + xue_flush_range(xue, xue->dbc_ering.trb, XUE_TRB_RING_BYTES); + xue_flush_range(xue, xue->dbc_oring.trb, XUE_TRB_RING_BYTES); + xue_flush_range(xue, xue->dbc_iring.trb, XUE_TRB_RING_BYTES); + xue_flush_range(xue, xue->dbc_owork.buf, XUE_WORK_RING_BYTES); + + return 1; +} + +static void xue_init_work_ring(struct xue *xue, + struct xue_work_ring *wrk) +{ + wrk->enq = 0; + wrk->deq = 0; + wrk->dma = virt_to_maddr(wrk->buf); +} + +/* @endcond */ + +/** + * Initialize the DbC and enable it for transfers. First map in the DbC + * registers from the host controller's MMIO region. Then allocate and map + * DMA for the event and transfer rings. Finally, enable the DbC for + * the host to enumerate. On success, the DbC is ready to send packets. + * + * @param xue the xue to open (!= NULL) + * @param ops the xue ops to use (!= NULL) + * @param sys the system-specific data (may be NULL) + * @return 1 iff xue_open succeeded + */ +static int64_t xue_open(struct xue *xue) +{ + if ( !xue ) + return 0; + + if ( !xue_init_xhc(xue) ) + return 0; + + if ( !xue_init_dbc(xue) ) + return 0; + + xue_init_work_ring(xue, &xue->dbc_owork); + xue_enable_dbc(xue); + xue->open = 1; + + return 1; +} + +/** + * Commit the pending transfer TRBs to the DbC. This notifies + * the DbC of any previously-queued data on the work ring and + * rings the doorbell. + * + * @param xue the xue to flush + * @param trb the ring containing the TRBs to transfer + * @param wrk the work ring containing data to be flushed + */ +static void xue_flush(struct xue *xue, struct xue_trb_ring *trb, + struct xue_work_ring *wrk) +{ + struct xue_dbc_reg *reg = xue->dbc_reg; + uint32_t db = (reg->db & 0xFFFF00FF) | (trb->db << 8); + + if ( xue->open && !(reg->ctrl & (1UL << XUE_CTRL_DCE)) ) + { + if ( !xue_init_dbc(xue) ) + return; + + xue_init_work_ring(xue, &xue->dbc_owork); + xue_enable_dbc(xue); + } + + xue_pop_events(xue); + + if ( !(reg->ctrl & (1UL << XUE_CTRL_DCR)) ) + { + xue_error("DbC not configured"); + return; + } + + if ( reg->ctrl & (1UL << XUE_CTRL_DRC) ) + { + reg->ctrl |= (1UL << XUE_CTRL_DRC); + reg->portsc |= (1UL << XUE_PSC_PED); + wmb(); + } + + if ( xue_trb_ring_full(trb) ) + return; + + if ( wrk->enq == wrk->deq ) + return; + else if ( wrk->enq > wrk->deq ) + { + xue_push_trb(xue, trb, wrk->dma + wrk->deq, wrk->enq - wrk->deq); + wrk->deq = wrk->enq; + } + else + { + xue_push_trb(xue, trb, wrk->dma + wrk->deq, + XUE_WORK_RING_CAP - wrk->deq); + wrk->deq = 0; + if ( wrk->enq > 0 && !xue_trb_ring_full(trb) ) + { + xue_push_trb(xue, trb, wrk->dma, wrk->enq); + wrk->deq = wrk->enq; + } + } + + wmb(); + reg->db = db; +} + +/** + * Queue a single character to the DbC. A transfer TRB will be created + * if the character is a newline and the DbC will be notified that data is + * available for writing to the debug host. + * + * @param xue the xue to write to + * @param c the character to write + * @return the number of bytes written + */ +static int64_t xue_putc(struct xue *xue, char c) +{ + if ( !xue_push_work(xue, &xue->dbc_owork, &c, 1) ) + return 0; + + if ( c == '\n' ) + xue_flush(xue, &xue->dbc_oring, &xue->dbc_owork); + + return 1; +} + +struct xue_uart { + struct xue xue; + struct timer timer; + spinlock_t *lock; +}; + +static struct xue_uart xue_uart; + +static void cf_check xue_uart_poll(void *data) +{ + struct serial_port *port = data; + struct xue_uart *uart = port->uart; + struct xue *xue = &uart->xue; + unsigned long flags = 0; + + if ( spin_trylock_irqsave(&port->tx_lock, flags) ) + { + xue_flush(xue, &xue->dbc_oring, &xue->dbc_owork); + spin_unlock_irqrestore(&port->tx_lock, flags); + } + + serial_tx_interrupt(port, guest_cpu_user_regs()); + set_timer(&uart->timer, NOW() + MICROSECS(XUE_POLL_INTERVAL)); +} + +static void __init cf_check xue_uart_init_preirq(struct serial_port *port) +{ + struct xue_uart *uart = port->uart; + uart->lock = &port->tx_lock; +} + +static void __init cf_check xue_uart_init_postirq(struct serial_port *port) +{ + struct xue_uart *uart = port->uart; + + serial_async_transmit(port); + init_timer(&uart->timer, xue_uart_poll, port, 0); + set_timer(&uart->timer, NOW() + MILLISECS(1)); +} + +static int cf_check xue_uart_tx_ready(struct serial_port *port) +{ + struct xue_uart *uart = port->uart; + struct xue *xue = &uart->xue; + + return XUE_WORK_RING_CAP - xue_work_ring_size(&xue->dbc_owork); +} + +static void cf_check xue_uart_putc(struct serial_port *port, char c) +{ + struct xue_uart *uart = port->uart; + xue_putc(&uart->xue, c); +} + +static void cf_check xue_uart_flush(struct serial_port *port) +{ + s_time_t goal; + struct xue_uart *uart = port->uart; + struct xue *xue = &uart->xue; + + xue_flush(xue, &xue->dbc_oring, &xue->dbc_owork); + + goal = NOW() + MICROSECS(XUE_POLL_INTERVAL); + if ( uart->timer.expires > goal ) + set_timer(&uart->timer, goal); +} + +static struct uart_driver xue_uart_driver = { + .init_preirq = xue_uart_init_preirq, + .init_postirq = xue_uart_init_postirq, + .endboot = NULL, + .suspend = NULL, + .resume = NULL, + .tx_ready = xue_uart_tx_ready, + .putc = xue_uart_putc, + .flush = xue_uart_flush, + .getc = NULL +}; + +static struct xue_trb evt_trb[XUE_TRB_RING_CAP] __aligned(XUE_PAGE_SIZE); +static struct xue_trb out_trb[XUE_TRB_RING_CAP] __aligned(XUE_PAGE_SIZE); +static struct xue_trb in_trb[XUE_TRB_RING_CAP] __aligned(XUE_PAGE_SIZE); +static struct xue_erst_segment erst __aligned(64); +static struct xue_dbc_ctx ctx __aligned(64); +static uint8_t wrk_buf[XUE_WORK_RING_CAP] __aligned(XUE_PAGE_SIZE); +static char str_buf[XUE_PAGE_SIZE] __aligned(64); +static char __initdata opt_dbgp[30]; + +string_param("dbgp", opt_dbgp); + +void __init xue_uart_init(void) +{ + struct xue_uart *uart = &xue_uart; + struct xue *xue = &uart->xue; + + if ( strncmp(opt_dbgp, "xue", 3) ) + return; + + memset(xue, 0, sizeof(*xue)); + + xue->dbc_ctx = &ctx; + xue->dbc_erst = &erst; + xue->dbc_ering.trb = evt_trb; + xue->dbc_oring.trb = out_trb; + xue->dbc_iring.trb = in_trb; + xue->dbc_owork.buf = wrk_buf; + xue->dbc_str = str_buf; + + xue_open(xue); + + serial_register_uart(SERHND_DBGP, &xue_uart_driver, &xue_uart); +} + +void xue_uart_dump(void) +{ + struct xue_uart *uart = &xue_uart; + struct xue *xue = &uart->xue; + + xue_dump(xue); +} diff --git a/xen/include/xen/serial.h b/xen/include/xen/serial.h index 6548f0b0a9cf..803e24cda0b6 100644 --- a/xen/include/xen/serial.h +++ b/xen/include/xen/serial.h @@ -171,6 +171,7 @@ struct ns16550_defaults { }; void ns16550_init(int index, struct ns16550_defaults *defaults); void ehci_dbgp_init(void); +void xue_uart_init(void); void arm_uart_init(void); From patchwork Tue Jun 7 14:30:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= X-Patchwork-Id: 12872008 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A91D2CCA47E for ; Tue, 7 Jun 2022 14:31:35 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.343346.568669 (Exim 4.92) (envelope-from ) id 1nyaEm-00064z-Jw; Tue, 07 Jun 2022 14:31:16 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 343346.568669; Tue, 07 Jun 2022 14:31:16 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1nyaEm-00064p-FV; Tue, 07 Jun 2022 14:31:16 +0000 Received: by outflank-mailman (input) for mailman id 343346; Tue, 07 Jun 2022 14:31:15 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1nyaEl-000619-Nd for xen-devel@lists.xenproject.org; Tue, 07 Jun 2022 14:31:15 +0000 Received: from out1-smtp.messagingengine.com (out1-smtp.messagingengine.com [66.111.4.25]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 7bcb5aaa-e66e-11ec-bd2c-47488cf2e6aa; Tue, 07 Jun 2022 16:31:14 +0200 (CEST) Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.nyi.internal (Postfix) with ESMTP id 1A2265C01E3; Tue, 7 Jun 2022 10:31:14 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute5.internal (MEProxy); Tue, 07 Jun 2022 10:31:14 -0400 Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 7 Jun 2022 10:31:12 -0400 (EDT) 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" X-Inumbo-ID: 7bcb5aaa-e66e-11ec-bd2c-47488cf2e6aa DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= invisiblethingslab.com; h=cc:cc:content-transfer-encoding :content-type:date:date:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to; s=fm1; t=1654612274; x=1654698674; bh=hjjCyL93xP zVhTjBxPMqGX4BQBGEIc0Cak0bF/sHaPE=; b=VyGiUkOtBFMTxv7ZoHNmIbNOsd AB177RNXxwaSJWtagThnKSrkUjb5VNbsMLrTPv9n+jApy9ASVbcNMK2OVcfLUmhz 0BIUbAeV4t8IEQLZHQK6zBWHVikGpjc1PvKqhpVadoazrvobSkNmdrkm+tn6bTex NrVXxUxZPDjXWf752c20zj0LowKRi6aTmSVWCkIzdAy4+VUEo3EYZ0BafpBjZzjh HhPhRZDycba/TePH6up79LLmHE3xzqyAoxoEBe55jw8vf6grHr9pf6NVi9xSalVV VweqCoKiEcoAPUhqqjvRGA9H/r7qCkmeWcCbgQiF+rKuAXI9gyk3r04vfFAQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm2; t=1654612274; x= 1654698674; bh=hjjCyL93xPzVhTjBxPMqGX4BQBGEIc0Cak0bF/sHaPE=; b=b G/zZt35M7Z/JIcwnFutal3cTjRw5VWuiwzM9heDUnGkkNsnyMHNrNfU8VRjFGIf8 DWlQWykXOiBW/F0kJtQqzsjE6abvaW++gl9EPEfyJXQETnxFB+k/ZPwPud3gT/Yl WGXbI1GG8Lt29FOm35DA40JoKHsOZknAuMy4Axny/2jYktjbsfEqg5DSU8u1UKe4 I8y5oxDn7w5uAoB3G4Q5e17S1p/uf9j/G9ZIEwito3XY6zCXfc+Imd9DDQ8MOCeI D4Z8+TyMroYRiQrYJW/SEDT5L5k7OkzZmpm4ebaM9A0ijQx0tcKe7yrmXXsqOBwE bdeWxAxb+xrCGA5heT+2g== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvfedruddthedgjeeiucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhephffvvefufffkofgjfhggtgfgsehtkeertdertdejnecuhfhrohhmpeforghr vghkucforghrtgiihihkohifshhkihdqifpkrhgvtghkihcuoehmrghrmhgrrhgvkhesih hnvhhishhisghlvghthhhinhhgshhlrggsrdgtohhmqeenucggtffrrghtthgvrhhnpefg ueduhefgvdefheehudejheefudevueeghfekhfehleegveduteeuiedugffgffenucevlh hushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehmrghrmhgrrhgv khesihhnvhhishhisghlvghthhhinhhgshhlrggsrdgtohhm X-ME-Proxy: Feedback-ID: i1568416f:Fastmail From: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= To: xen-devel@lists.xenproject.org Cc: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= , Andrew Cooper , George Dunlap , Jan Beulich , Julien Grall , Stefano Stabellini , Wei Liu Subject: [PATCH v1 02/10] xue: reset XHCI ports when initializing dbc Date: Tue, 7 Jun 2022 16:30:08 +0200 Message-Id: X-Mailer: git-send-email 2.35.3 In-Reply-To: References: MIME-Version: 1.0 Reset ports, to force host system to re-enumerate devices. Otheriwse it will require the cable to be re-plugged, or will wait in the "configuring" state indefinitely. Trick and code copied from Linux: drivers/usb/early/xhci-dbc.c:xdbc_start()->xdbc_reset_debug_port() Signed-off-by: Marek Marczykowski-Górecki --- xen/drivers/char/xue.c | 70 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+) diff --git a/xen/drivers/char/xue.c b/xen/drivers/char/xue.c index e95dd09d39a8..a9ba25d9d07e 100644 --- a/xen/drivers/char/xue.c +++ b/xen/drivers/char/xue.c @@ -60,6 +60,10 @@ ((1UL << XUE_PSC_CSC) | (1UL << XUE_PSC_PRC) | (1UL << XUE_PSC_PLC) | \ (1UL << XUE_PSC_CEC)) +#define XUE_XHC_EXT_PORT_MAJOR(x) (((x) >> 24) & 0xff) +#define PORT_RESET (1 << 4) +#define PORT_CONNECT (1 << 0) + #define xue_debug(...) printk("xue debug: " __VA_ARGS__) #define xue_alert(...) printk("xue alert: " __VA_ARGS__) #define xue_error(...) printk("xue error: " __VA_ARGS__) @@ -604,6 +608,68 @@ static void xue_init_strings(struct xue *xue, uint32_t *info) info[8] = (4 << 24) | (30 << 16) | (8 << 8) | 6; } +static void xue_do_reset_debug_port(struct xue *xue, u32 id, u32 count) +{ + uint32_t *ops_reg; + uint32_t *portsc; + u32 val, cap_length; + int i; + + cap_length = (*(uint32_t*)xue->xhc_mmio) & 0xff; + ops_reg = xue->xhc_mmio + cap_length; + + id--; + for ( i = id; i < (id + count); i++ ) + { + portsc = ops_reg + 0x100 + i * 0x4; + val = *portsc; + if ( !(val & PORT_CONNECT) ) + *portsc = val | PORT_RESET; + } +} + + +static void xue_reset_debug_port(struct xue *xue) +{ + u32 val, port_offset, port_count; + uint32_t *xcap; + uint32_t next; + uint32_t id; + uint8_t *mmio = (uint8_t *)xue->xhc_mmio; + uint32_t *hccp1 = (uint32_t *)(mmio + 0x10); + const uint32_t PROTOCOL_ID = 0x2; + + /** + * Paranoid check against a zero value. The spec mandates that + * at least one "supported protocol" capability must be implemented, + * so this should always be false. + */ + if ( (*hccp1 & 0xFFFF0000) == 0 ) + return; + + xcap = (uint32_t *)(mmio + (((*hccp1 & 0xFFFF0000) >> 16) << 2)); + next = (*xcap & 0xFF00) >> 8; + id = *xcap & 0xFF; + + /* Look for "supported protocol" capability, major revision 3 */ + for ( ; next; xcap += next, id = *xcap & 0xFF, next = (*xcap & 0xFF00) >> 8) + { + if ( id != PROTOCOL_ID && next ) + continue; + + if ( XUE_XHC_EXT_PORT_MAJOR(*xcap) != 0x3 ) + continue; + + /* extract ports offset and count from the capability structure */ + val = *(xcap + 2); + port_offset = val & 0xff; + port_count = (val >> 8) & 0xff; + + /* and reset them all */ + xue_do_reset_debug_port(xue, port_offset, port_count); + } +} + static void xue_dump(struct xue *xue) { struct xue_dbc_reg *r = xue->dbc_reg; @@ -639,6 +705,10 @@ static void xue_enable_dbc(struct xue *xue) while ( (reg->ctrl & (1UL << XUE_CTRL_DCE)) == 0 ) xue_sys_pause(); + /* reset ports on initial open, to force re-enumerating by the host */ + if ( !xue->open ) + xue_reset_debug_port(xue); + wmb(); reg->portsc |= (1UL << XUE_PSC_PED); wmb(); From patchwork Tue Jun 7 14:30:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= X-Patchwork-Id: 12872007 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id BBC91C43334 for ; Tue, 7 Jun 2022 14:31:34 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.343348.568696 (Exim 4.92) (envelope-from ) id 1nyaEp-0006pV-N6; Tue, 07 Jun 2022 14:31:19 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 343348.568696; Tue, 07 Jun 2022 14:31:19 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1nyaEp-0006pJ-Hr; Tue, 07 Jun 2022 14:31:19 +0000 Received: by outflank-mailman (input) for mailman id 343348; Tue, 07 Jun 2022 14:31:17 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1nyaEn-00061K-GP for xen-devel@lists.xenproject.org; Tue, 07 Jun 2022 14:31:17 +0000 Received: from out1-smtp.messagingengine.com (out1-smtp.messagingengine.com [66.111.4.25]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 7cfeae9f-e66e-11ec-b605-df0040e90b76; Tue, 07 Jun 2022 16:31:16 +0200 (CEST) Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.nyi.internal (Postfix) with ESMTP id C13F55C01E9; Tue, 7 Jun 2022 10:31:15 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute5.internal (MEProxy); Tue, 07 Jun 2022 10:31:15 -0400 Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 7 Jun 2022 10:31:14 -0400 (EDT) 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" X-Inumbo-ID: 7cfeae9f-e66e-11ec-b605-df0040e90b76 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= invisiblethingslab.com; h=cc:cc:content-transfer-encoding :content-type:date:date:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to; s=fm1; t=1654612275; x=1654698675; bh=Q5My+tX/Z1 yRUUbiyXNglzpIQl2V/2Tz8JD1D74I3cc=; b=nbw599YaKL8ReHa6gbyVi9XSSv ItmURASUNmvTOp7lDLCLDrL7exendz2RW064vfjKNe+XEEyDSOe7taLHiIk/EWX+ N2Xu5o3rAFowCxKcmq5ZQMo70VEs/Lzaw1DmK934uZjoyUzxF+kyrNFw7vao86Lo XY4ga85nMJ4YikbBWAgBNurGAxvofsvTmpWwrHg8DgjqsT31QqKVx0mbF9SG0QOd /Sj6JbIBlqoBVcMLFYGFp4UpeSoauhkSA45EyOXEQrChzWjT6wH7r5kfgHvOqzLx VwildrMwXDgstNL422TTIbZtdYwmTBMV5s28k744Th+BClQjgx9JIqkKogpQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm2; t=1654612275; x= 1654698675; bh=Q5My+tX/Z1yRUUbiyXNglzpIQl2V/2Tz8JD1D74I3cc=; b=g vHbtrRLLsyncnXqdlZ2ywdzEvXx2p7iDewMG2ktXdlzIHRPJjP14GE4/ZNZ7d1JF meGrWecXZ0dVYqs8hdYMPi7ALfmqrkpsExXspysTeo+BTxVGuZiyre74yV4M4rUx dMwPZrMYPG1Tmqmnkpe0LYVRFpggDBz4AOKqz/utRl1kfjyuNYT/6L4elk91KkEl fqk6FqMeY1qqzTIDwZ3en6fU1IKwlFrAL7PZq7lAn5eKHtuen/Bjsku695qXh4wY N3JKeufGTrho5vWe5858kcaKCbgcfFSyhi1XlrFo5ApqWV94WiCJ2ROjc+WrzETn OorJ4Z24NI9fspxAjIy4Q== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvfedruddthedgjeeiucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhephffvvefufffkofgjfhggtgfgsehtkeertdertdejnecuhfhrohhmpeforghr vghkucforghrtgiihihkohifshhkihdqifpkrhgvtghkihcuoehmrghrmhgrrhgvkhesih hnvhhishhisghlvghthhhinhhgshhlrggsrdgtohhmqeenucggtffrrghtthgvrhhnpefg ueduhefgvdefheehudejheefudevueeghfekhfehleegveduteeuiedugffgffenucevlh hushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehmrghrmhgrrhgv khesihhnvhhishhisghlvghthhhinhhgshhlrggsrdgtohhm X-ME-Proxy: Feedback-ID: i1568416f:Fastmail From: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= To: xen-devel@lists.xenproject.org Cc: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= , Andrew Cooper , George Dunlap , Jan Beulich , Julien Grall , Stefano Stabellini , Wei Liu Subject: [PATCH v1 03/10] xue: add support for selecting specific xhci Date: Tue, 7 Jun 2022 16:30:09 +0200 Message-Id: X-Mailer: git-send-email 2.35.3 In-Reply-To: References: MIME-Version: 1.0 Handle parameters similar to dbgp=ehci. Implement this by not resettting xhc_cf8 again in xue_init_xhc(), but using a value found there if non-zero. Additionally, add xue->xhc_num to select n-th controller. Signed-off-by: Marek Marczykowski-Górecki --- docs/misc/xen-command-line.pandoc | 5 +++- xen/drivers/char/xue.c | 56 ++++++++++++++++++++++++-------- 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line.pandoc index 881fe409ac76..37a564c2386f 100644 --- a/docs/misc/xen-command-line.pandoc +++ b/docs/misc/xen-command-line.pandoc @@ -721,10 +721,15 @@ Available alternatives, with their meaning, are: ### dbgp > `= ehci[ | @pci:. ]` +> `= xue[ | @pci:. ]` Specify the USB controller to use, either by instance number (when going over the PCI busses sequentially) or by PCI device (must be on segment 0). +Use `ehci` for EHCI debug port, use `xue` for XHCI debug capability. +Xue driver will wait indefinitely for the debug host to connect - make sure the +cable is connected. + ### debug_stack_lines > `= ` diff --git a/xen/drivers/char/xue.c b/xen/drivers/char/xue.c index a9ba25d9d07e..b253426a95f8 100644 --- a/xen/drivers/char/xue.c +++ b/xen/drivers/char/xue.c @@ -204,6 +204,7 @@ struct xue { void *xhc_mmio; int open; + int xhc_num; /* look for n-th xhc */ }; static void xue_sys_pause(void) @@ -252,24 +253,34 @@ static int xue_init_xhc(struct xue *xue) uint64_t bar1; uint64_t devfn; - /* - * Search PCI bus 0 for the xHC. All the host controllers supported so far - * are part of the chipset and are on bus 0. - */ - for ( devfn = 0; devfn < 256; devfn++ ) { - uint32_t dev = (devfn & 0xF8) >> 3; - uint32_t fun = devfn & 0x07; - pci_sbdf_t sbdf = PCI_SBDF(0, dev, fun); - uint32_t hdr = pci_conf_read8(sbdf, PCI_HEADER_TYPE); - - if ( hdr == 0 || hdr == 0x80 ) + if ( xue->sbdf.sbdf == 0 ) + { + /* + * Search PCI bus 0 for the xHC. All the host controllers supported so far + * are part of the chipset and are on bus 0. + */ + for ( devfn = 0; devfn < 256; devfn++ ) { - if ( (pci_conf_read32(sbdf, PCI_CLASS_REVISION) >> 8) == XUE_XHC_CLASSC ) + uint32_t dev = (devfn & 0xF8) >> 3; + uint32_t fun = devfn & 0x07; + pci_sbdf_t sbdf = PCI_SBDF(0, dev, fun); + uint32_t hdr = pci_conf_read8(sbdf, PCI_HEADER_TYPE); + + if ( hdr == 0 || hdr == 0x80 ) { - xue->sbdf = sbdf; - break; + if ( (pci_conf_read32(sbdf, PCI_CLASS_REVISION) >> 8) == XUE_XHC_CLASSC ) + { + if ( xue->xhc_num-- ) + continue; + xue->sbdf = sbdf; + break; + } } } + } else { + /* Verify if selected device is really xHC */ + if ( (pci_conf_read32(xue->sbdf, PCI_CLASS_REVISION) >> 8) != XUE_XHC_CLASSC ) + xue->sbdf.sbdf = 0; } if ( !xue->sbdf.sbdf ) @@ -999,12 +1010,29 @@ void __init xue_uart_init(void) { struct xue_uart *uart = &xue_uart; struct xue *xue = &uart->xue; + const char *e; if ( strncmp(opt_dbgp, "xue", 3) ) return; memset(xue, 0, sizeof(*xue)); + if ( isdigit(opt_dbgp[3]) || !opt_dbgp[3] ) + { + if ( opt_dbgp[3] ) + xue->xhc_num = simple_strtoul(opt_dbgp + 3, &e, 10); + } + else if ( strncmp(opt_dbgp + 3, "@pci", 4) == 0 ) + { + unsigned int bus, slot, func; + + e = parse_pci(opt_dbgp + 7, NULL, &bus, &slot, &func); + if ( !e || *e ) + return; + + xue->sbdf = PCI_SBDF(0, bus, slot, func); + } + xue->dbc_ctx = &ctx; xue->dbc_erst = &erst; xue->dbc_ering.trb = evt_trb; From patchwork Tue Jun 7 14:30:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= X-Patchwork-Id: 12872012 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 260F4C433EF for ; Tue, 7 Jun 2022 14:31:38 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.343349.568702 (Exim 4.92) (envelope-from ) id 1nyaEq-0006u3-8d; Tue, 07 Jun 2022 14:31:20 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 343349.568702; Tue, 07 Jun 2022 14:31:20 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1nyaEp-0006sV-U8; Tue, 07 Jun 2022 14:31:19 +0000 Received: by outflank-mailman (input) for mailman id 343349; Tue, 07 Jun 2022 14:31:19 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1nyaEp-00061K-7m for xen-devel@lists.xenproject.org; Tue, 07 Jun 2022 14:31:19 +0000 Received: from out1-smtp.messagingengine.com (out1-smtp.messagingengine.com [66.111.4.25]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 7e216186-e66e-11ec-b605-df0040e90b76; Tue, 07 Jun 2022 16:31:18 +0200 (CEST) Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailout.nyi.internal (Postfix) with ESMTP id AAAFD5C01CA; Tue, 7 Jun 2022 10:31:17 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute3.internal (MEProxy); Tue, 07 Jun 2022 10:31:17 -0400 Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 7 Jun 2022 10:31:15 -0400 (EDT) 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" X-Inumbo-ID: 7e216186-e66e-11ec-b605-df0040e90b76 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= invisiblethingslab.com; h=cc:cc:content-transfer-encoding :content-type:date:date:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to; s=fm1; t=1654612277; x=1654698677; bh=U8kU4goNfn hejF90xv/RWehAvQ7mOrYaRxEFIubWjr0=; b=R19Zk3lTBIeggp7H1+bRpEHI/N X/7qNFFQex0MnoJYaqhZ0tdxCiKI+vgtcLLVUcnwQ5vgmCEUzzr6bAak9WqLMm4s Bcinoc7WAgQ68OM5AruE6spN6iUCPA+FjAIcsO7zO7cAjqpsEhFV5hTffWzQfJKq jFAlt7LBoCG8zLmlNZHrzG3sRYE8As+LhOVzNREn5RbbM1yVt3+LaR6IwXPqxiGh S4o+oqKJ0fbUW7hAS5LHOJGWR6GvXUy3M0ljr/4N5Q6dEgymDBbytT5xgBED1s9S XBnQVufCI0z+9ucFYcVocoNWPytS32v+FQcL0SSvAHtIVwNWJi7vnQtzjkkA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm2; t=1654612277; x= 1654698677; bh=U8kU4goNfnhejF90xv/RWehAvQ7mOrYaRxEFIubWjr0=; b=H uXIBu3wUbTKPSN1QekhmnIa/VHUUcWwk2OAM3jg34KB+lNkS8cmGyTxu2SF8kn+5 vdWcHXPqxJeTOfKDx7goJDx/d5eQEGLZ0Yoj2gCowra/cXabkzjjvkjyr0VDH2ST C/E32RFFif/xxQHKqUgfVnvqNBFJu3DRQyscNYdsjDpf+LeF85uorh52FoKMSd8V ybuROokVnpRuaU6QRU071ogi1mCZnCHW3m8kRbHIwvl54sEhmvtQa8LmoMnSd4jd EtK0GukwDJeA4i/7CPyvs8C+xjkP/nyq1j01L93TxuOtz0GRlaC6IJinVR8+/8vy Ym9kiltCtPkkR0vjkyCvQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvfedruddthedgjeeiucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhephffvvefufffkofgjfhggtgfgsehtkeertdertdejnecuhfhrohhmpeforghr vghkucforghrtgiihihkohifshhkihdqifpkrhgvtghkihcuoehmrghrmhgrrhgvkhesih hnvhhishhisghlvghthhhinhhgshhlrggsrdgtohhmqeenucggtffrrghtthgvrhhnpefg ueduhefgvdefheehudejheefudevueeghfekhfehleegveduteeuiedugffgffenucevlh hushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehmrghrmhgrrhgv khesihhnvhhishhisghlvghthhhinhhgshhlrggsrdgtohhm X-ME-Proxy: Feedback-ID: i1568416f:Fastmail From: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= To: xen-devel@lists.xenproject.org Cc: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= , Andrew Cooper , George Dunlap , Jan Beulich , Julien Grall , Stefano Stabellini , Wei Liu Subject: [PATCH v1 04/10] ehci-dbgp: fix selecting n-th ehci controller Date: Tue, 7 Jun 2022 16:30:10 +0200 Message-Id: X-Mailer: git-send-email 2.35.3 In-Reply-To: References: MIME-Version: 1.0 The ehci number was parsed but ignored. Signed-off-by: Marek Marczykowski-Górecki Reviewed-by: Jan Beulich --- xen/drivers/char/ehci-dbgp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xen/drivers/char/ehci-dbgp.c b/xen/drivers/char/ehci-dbgp.c index 16c8ff394d5c..92c588ec0aa3 100644 --- a/xen/drivers/char/ehci-dbgp.c +++ b/xen/drivers/char/ehci-dbgp.c @@ -1480,7 +1480,7 @@ void __init ehci_dbgp_init(void) unsigned int num = 0; if ( opt_dbgp[4] ) - simple_strtoul(opt_dbgp + 4, &e, 10); + num = simple_strtoul(opt_dbgp + 4, &e, 10); dbgp->cap = find_dbgp(dbgp, num); if ( !dbgp->cap ) From patchwork Tue Jun 7 14:30:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= X-Patchwork-Id: 12872006 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 21F0ACCA481 for ; Tue, 7 Jun 2022 14:31:35 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.343350.568718 (Exim 4.92) (envelope-from ) id 1nyaEs-0007Pu-FU; Tue, 07 Jun 2022 14:31:22 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 343350.568718; Tue, 07 Jun 2022 14:31:22 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1nyaEs-0007Pg-Bj; Tue, 07 Jun 2022 14:31:22 +0000 Received: by outflank-mailman (input) for mailman id 343350; Tue, 07 Jun 2022 14:31:21 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1nyaEr-000619-3Z for xen-devel@lists.xenproject.org; Tue, 07 Jun 2022 14:31:21 +0000 Received: from out1-smtp.messagingengine.com (out1-smtp.messagingengine.com [66.111.4.25]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 7ee3f402-e66e-11ec-bd2c-47488cf2e6aa; Tue, 07 Jun 2022 16:31:19 +0200 (CEST) Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.nyi.internal (Postfix) with ESMTP id 48AAD5C01ED; Tue, 7 Jun 2022 10:31:19 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute5.internal (MEProxy); Tue, 07 Jun 2022 10:31:19 -0400 Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 7 Jun 2022 10:31:17 -0400 (EDT) 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" X-Inumbo-ID: 7ee3f402-e66e-11ec-bd2c-47488cf2e6aa DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= invisiblethingslab.com; h=cc:cc:content-transfer-encoding :content-type:date:date:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to; s=fm1; t=1654612279; x=1654698679; bh=/FmM9IRoHk jrJvz5SecKZ+9vnPpot8BHqRtqlD2wsdk=; b=nRmoMLokKnoTQxNYHIVIw6fE1F 177uy3Ek8M3bRPAGocRhUA91JiD6McUjah+DxUKG2X7wCEDpEIMNJ32lZKHPS4Vt sAWqYtZlee9SCdgWHD95BmrNoTfJIxPbm2MEkDAB7jpp1COWYEEqXqoa9oaNpEgx XmBvcm5kny8NuTpzHCVYx8xWjyYr8W5f+FyfrijW5gl54Og4K+tQNxCuL51fJEmD ELtKV5Q1ZN+p1oLuBNHIWqrDi14khV1cRlGvOk4wu3IOSMhdLVZBzeyBH+BuwzyO PX0m30cGtNFk09D/6t9jOlt6Ux7Yod8Bhsd/xBR4ZOcD46A8ks6zdnGXbVYA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm2; t=1654612279; x= 1654698679; bh=/FmM9IRoHkjrJvz5SecKZ+9vnPpot8BHqRtqlD2wsdk=; b=h E4byz8dzkMVIukdL40jB1/bCncvD2WvJLvYOfo6DohGP60RT3ZHzKb6kuGVh0OnA N81od+R+NH8Kh2A/nO09OFE8Epb/QC1ZdSGxDxgKYRL+tPPXUY5gBbNE+m869MtK jZwF9NHZY9Fob/b8MnHjol7yjNnkyUR2RdGtLk85L5z+VSEiJYZwLNSyh3Ois5P+ RiJOSnk6CWj6/dkL9EmF02IqiloxEvd6DVWkNRcWtjX99yCqyDMXcllrhaNq9gs5 bYC+SX5uZ+w0vD1ri8brr+eur/JS0RY/OAexZfMvLrf6lL8jhjoC1iw+ZiTLaQoc J2uAvzmXGTjs2j28NQvmQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvfedruddthedgjeeiucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhephffvvefufffkofgjfhggtgfgsehtkeertdertdejnecuhfhrohhmpeforghr vghkucforghrtgiihihkohifshhkihdqifpkrhgvtghkihcuoehmrghrmhgrrhgvkhesih hnvhhishhisghlvghthhhinhhgshhlrggsrdgtohhmqeenucggtffrrghtthgvrhhnpefg ueduhefgvdefheehudejheefudevueeghfekhfehleegveduteeuiedugffgffenucevlh hushhtvghrufhiiigvpedvnecurfgrrhgrmhepmhgrihhlfhhrohhmpehmrghrmhgrrhgv khesihhnvhhishhisghlvghthhhinhhgshhlrggsrdgtohhm X-ME-Proxy: Feedback-ID: i1568416f:Fastmail From: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= To: xen-devel@lists.xenproject.org Cc: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= , Andrew Cooper , George Dunlap , Jan Beulich , Julien Grall , Stefano Stabellini , Wei Liu Subject: [PATCH v1 05/10] console: support multiple serial console simultaneously Date: Tue, 7 Jun 2022 16:30:11 +0200 Message-Id: X-Mailer: git-send-email 2.35.3 In-Reply-To: References: MIME-Version: 1.0 Previously only one serial console was supported at the same time. Using console=com1,dbgp,vga silently ignored all but last serial console (in this case: only dbgp and vga were active). Fix this by storing not a single sercon_handle, but an array of them, up to MAX_SERCONS entries. The value of MAX_SERCONS (4) is arbitrary, inspired by the number of SERHND_IDX values. Signed-off-by: Marek Marczykowski-Górecki --- xen/drivers/char/console.c | 58 ++++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c index f9937c5134c0..44b703296487 100644 --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -113,7 +113,9 @@ static char *__read_mostly conring = _conring; static uint32_t __read_mostly conring_size = _CONRING_SIZE; static uint32_t conringc, conringp; -static int __read_mostly sercon_handle = -1; +#define MAX_SERCONS 4 +static int __read_mostly sercon_handle[MAX_SERCONS]; +static int __read_mostly nr_sercon_handle = 0; #ifdef CONFIG_X86 /* Tristate: 0 disabled, 1 user enabled, -1 default enabled */ @@ -395,9 +397,17 @@ static unsigned int serial_rx_cons, serial_rx_prod; static void (*serial_steal_fn)(const char *, size_t nr) = early_puts; +/* Redirect any console output to *fn*, if *handle* is configured as a console. */ int console_steal(int handle, void (*fn)(const char *, size_t nr)) { - if ( (handle == -1) || (handle != sercon_handle) ) + int i; + + if ( handle == -1 ) + return 0; + for ( i = 0; i < nr_sercon_handle; i++ ) + if ( handle == sercon_handle[i] ) + break; + if ( nr_sercon_handle && i == nr_sercon_handle ) return 0; if ( serial_steal_fn != NULL ) @@ -415,10 +425,13 @@ void console_giveback(int id) void console_serial_puts(const char *s, size_t nr) { + int i; + if ( serial_steal_fn != NULL ) serial_steal_fn(s, nr); else - serial_puts(sercon_handle, s, nr); + for ( i = 0; i < nr_sercon_handle; i++ ) + serial_puts(sercon_handle[i], s, nr); /* Copy all serial output into PV console */ pv_console_puts(s, nr); @@ -956,7 +969,7 @@ void guest_printk(const struct domain *d, const char *fmt, ...) void __init console_init_preirq(void) { char *p; - int sh; + int sh, i; serial_init_preirq(); @@ -977,7 +990,8 @@ void __init console_init_preirq(void) continue; else if ( (sh = serial_parse_handle(p)) >= 0 ) { - sercon_handle = sh; + if ( nr_sercon_handle < MAX_SERCONS ) + sercon_handle[nr_sercon_handle++] = sh; serial_steal_fn = NULL; } else @@ -996,7 +1010,8 @@ void __init console_init_preirq(void) opt_console_xen = 0; #endif - serial_set_rx_handler(sercon_handle, serial_rx); + for ( i = 0; i < nr_sercon_handle; i++ ) + serial_set_rx_handler(sercon_handle[i], serial_rx); pv_console_set_rx_handler(serial_rx); /* HELLO WORLD --- start-of-day banner text. */ @@ -1014,7 +1029,8 @@ void __init console_init_preirq(void) if ( opt_sync_console ) { - serial_start_sync(sercon_handle); + for ( i = 0; i < nr_sercon_handle; i++ ) + serial_start_sync(sercon_handle[i]); add_taint(TAINT_SYNC_CONSOLE); printk("Console output is synchronous.\n"); warning_add(warning_sync_console); @@ -1121,13 +1137,19 @@ int __init console_has(const char *device) void console_start_log_everything(void) { - serial_start_log_everything(sercon_handle); + int i; + + for ( i = 0; i < nr_sercon_handle; i++ ) + serial_start_log_everything(sercon_handle[i]); atomic_inc(&print_everything); } void console_end_log_everything(void) { - serial_end_log_everything(sercon_handle); + int i; + + for ( i = 0; i < nr_sercon_handle; i++ ) + serial_end_log_everything(sercon_handle[i]); atomic_dec(&print_everything); } @@ -1149,23 +1171,32 @@ void console_unlock_recursive_irqrestore(unsigned long flags) void console_force_unlock(void) { + int i; + watchdog_disable(); spin_debug_disable(); spin_lock_init(&console_lock); - serial_force_unlock(sercon_handle); + for ( i = 0 ; i < nr_sercon_handle ; i++ ) + serial_force_unlock(sercon_handle[i]); console_locks_busted = 1; console_start_sync(); } void console_start_sync(void) { + int i; + atomic_inc(&print_everything); - serial_start_sync(sercon_handle); + for ( i = 0 ; i < nr_sercon_handle ; i++ ) + serial_start_sync(sercon_handle[i]); } void console_end_sync(void) { - serial_end_sync(sercon_handle); + int i; + + for ( i = 0; i < nr_sercon_handle; i++ ) + serial_end_sync(sercon_handle[i]); atomic_dec(&print_everything); } @@ -1291,7 +1322,8 @@ static int suspend_steal_id; int console_suspend(void) { - suspend_steal_id = console_steal(sercon_handle, suspend_steal_fn); + if ( nr_sercon_handle ) + suspend_steal_id = console_steal(sercon_handle[0], suspend_steal_fn); serial_suspend(); return 0; } From patchwork Tue Jun 7 14:30:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= X-Patchwork-Id: 12872010 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 01FDACCA485 for ; Tue, 7 Jun 2022 14:31:36 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.343351.568729 (Exim 4.92) (envelope-from ) id 1nyaEu-0007l7-UN; Tue, 07 Jun 2022 14:31:24 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 343351.568729; Tue, 07 Jun 2022 14:31:24 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1nyaEu-0007kc-Ng; Tue, 07 Jun 2022 14:31:24 +0000 Received: by outflank-mailman (input) for mailman id 343351; Tue, 07 Jun 2022 14:31:22 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1nyaEs-00061K-Ln for xen-devel@lists.xenproject.org; Tue, 07 Jun 2022 14:31:22 +0000 Received: from out1-smtp.messagingengine.com (out1-smtp.messagingengine.com [66.111.4.25]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 8016fee5-e66e-11ec-b605-df0040e90b76; Tue, 07 Jun 2022 16:31:21 +0200 (CEST) Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id E625E5C01DB; Tue, 7 Jun 2022 10:31:20 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute4.internal (MEProxy); Tue, 07 Jun 2022 10:31:20 -0400 Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 7 Jun 2022 10:31:19 -0400 (EDT) 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" X-Inumbo-ID: 8016fee5-e66e-11ec-b605-df0040e90b76 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= invisiblethingslab.com; h=cc:cc:content-transfer-encoding :content-type:date:date:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to; s=fm1; t=1654612280; x=1654698680; bh=9Z09zPwAMV UfGBsTlLDLpiIwvOBt3luu8w7C4olNcaY=; b=KwbseHJmSVm51Z4o4plrUu7Ohp WVSyTi0N9mwuNZ5H4GKcEGFy99iQyEg3SqnjTjmz+HXBqcmZrLBh9bdsVIAbd3mM jqiGXk+YgoY1X999yxsd10+7zuAMz+nygATXfwDxn22y8YetIo0WSxKrdnQiJU0F GuTfm5Kr8xbjSq9HfoUWsm27UjPOs4vtkXVD1WmASb7240SNJWME6kRvJlupuVJR 1hVkN22/N3rGtwX/leE4OyTS7x9jDAvXU9OXBzaKzu7E8mHb0bqyMCi3Kgq60ivX paFC194VSGV3S9oQmdNsV3yKRBfHb2ukJ3hr1RHX81Bk8yet27T8vGsmNlZA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm2; t=1654612280; x= 1654698680; bh=9Z09zPwAMVUfGBsTlLDLpiIwvOBt3luu8w7C4olNcaY=; b=Y OhGYlkT512yD3GpdI3c0a8g3LpUsSWdrGUyjXKpl92I+gf2PypmHCAaIOPyOXZ5k esJ+pnxpMC6Rjgedvb/0ej8yZw4eUfu8fFxyEmylfElmqrN3VHOnB13RycpbnCz9 wzqSxIK1LI4TWHQ8UUbgJnAJgzO6jbgaRx5FqQcA06Pyd9BZS/abQlZWUzXS27Yv xqMRhhyQ0+Q6hZG/CUR8bn8hspxbTJAS7Dg+4g4fCrMqcl5dxWt63Uzlt8cgnM7h FtXmlqvXtD9SULnuPbuB9FljoKLpuH6uZr0N4cg3g/Rl5EZ3o54JQML6R4PWLm4O HQgP5LNfJS6/5ONAcDR9w== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvfedruddthedgjeeiucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhephffvvefufffkofgjfhggtgfgsehtkeertdertdejnecuhfhrohhmpeforghr vghkucforghrtgiihihkohifshhkihdqifpkrhgvtghkihcuoehmrghrmhgrrhgvkhesih hnvhhishhisghlvghthhhinhhgshhlrggsrdgtohhmqeenucggtffrrghtthgvrhhnpefg ueduhefgvdefheehudejheefudevueeghfekhfehleegveduteeuiedugffgffenucevlh hushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehmrghrmhgrrhgv khesihhnvhhishhisghlvghthhhinhhgshhlrggsrdgtohhm X-ME-Proxy: Feedback-ID: i1568416f:Fastmail From: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= To: xen-devel@lists.xenproject.org Cc: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= , Jan Beulich , Paul Durrant , =?utf-8?q?Roger_Pau_Monn=C3=A9?= Subject: [PATCH v1 06/10] IOMMU: add common API for device reserved memory Date: Tue, 7 Jun 2022 16:30:12 +0200 Message-Id: <9a5b2f380244c0932b3c2c9ada7346a4d6a0433d.1654612169.git-series.marmarek@invisiblethingslab.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: References: MIME-Version: 1.0 Add API similar to rmrr= and ivmd= arguments, but in a common code. This will allow drivers to register reserved memory regardless of the IOMMU vendor. The direct reason for this API is xhci-dbc console driver (aka xue), that needs to use DMA. But future change may unify command line arguments for user-supplied reserved memory, and it may be useful for other drivers in the future too. This commit just introduces an API, subsequent patches will plug it in appropriate places. The reserved memory ranges needs to be saved locally, because at the point when they are collected, Xen doesn't know yet which IOMMU driver will be used. Signed-off-by: Marek Marczykowski-Górecki --- xen/drivers/passthrough/iommu.c | 40 ++++++++++++++++++++++++++++++++++- xen/include/xen/iommu.h | 11 +++++++++- 2 files changed, 51 insertions(+) diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c index 9393d987c788..5c4162912359 100644 --- a/xen/drivers/passthrough/iommu.c +++ b/xen/drivers/passthrough/iommu.c @@ -654,6 +654,46 @@ bool_t iommu_has_feature(struct domain *d, enum iommu_feature feature) return is_iommu_enabled(d) && test_bit(feature, dom_iommu(d)->features); } +#define MAX_EXTRA_RESERVED_RANGES 20 +struct extra_reserved_range { + xen_pfn_t start; + xen_ulong_t nr; + u32 sbdf; +}; +static unsigned int __initdata nr_extra_reserved_ranges; +static struct extra_reserved_range __initdata extra_reserved_ranges[MAX_EXTRA_RESERVED_RANGES]; + +int iommu_add_extra_reserved_device_memory(xen_pfn_t start, xen_ulong_t nr, u32 sbdf) +{ + unsigned int idx; + + if ( nr_extra_reserved_ranges >= MAX_EXTRA_RESERVED_RANGES ) + return -ENOMEM; + + idx = nr_extra_reserved_ranges++; + extra_reserved_ranges[idx].start = start; + extra_reserved_ranges[idx].nr = nr; + extra_reserved_ranges[idx].sbdf = sbdf; + return 0; +} + +int iommu_get_extra_reserved_device_memory(iommu_grdm_t *func, void *ctxt) +{ + unsigned int idx; + int ret; + + for ( idx = 0; idx < nr_extra_reserved_ranges; idx++ ) + { + ret = func(extra_reserved_ranges[idx].start, + extra_reserved_ranges[idx].nr, + extra_reserved_ranges[idx].sbdf, + ctxt); + if ( ret < 0 ) + return ret; + } + return 0; +} + /* * Local variables: * mode: C diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h index e0f82712ed73..97424130247c 100644 --- a/xen/include/xen/iommu.h +++ b/xen/include/xen/iommu.h @@ -296,6 +296,17 @@ struct iommu_ops { #endif }; +/* + * To be called by Xen internally, to register extra RMRR/IVMD ranges. + * Needs to be called before IOMMU initialization. + */ +extern int iommu_add_extra_reserved_device_memory(xen_pfn_t start, xen_ulong_t nr, u32 sbdf); +/* + * To be called by specific IOMMU driver during initialization, + * to fetch ranges registered with iommu_add_extra_reserved_device_memory(). + */ +extern int iommu_get_extra_reserved_device_memory(iommu_grdm_t *func, void *ctxt); + #include #ifndef iommu_call From patchwork Tue Jun 7 14:30:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= X-Patchwork-Id: 12872011 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id AFEFCCCA486 for ; Tue, 7 Jun 2022 14:31:35 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.343352.568735 (Exim 4.92) (envelope-from ) id 1nyaEv-0007rT-K2; Tue, 07 Jun 2022 14:31:25 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 343352.568735; Tue, 07 Jun 2022 14:31:25 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1nyaEv-0007qU-BL; Tue, 07 Jun 2022 14:31:25 +0000 Received: by outflank-mailman (input) for mailman id 343352; Tue, 07 Jun 2022 14:31:24 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1nyaEt-00061K-QX for xen-devel@lists.xenproject.org; Tue, 07 Jun 2022 14:31:24 +0000 Received: from out1-smtp.messagingengine.com (out1-smtp.messagingengine.com [66.111.4.25]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 80a6abbd-e66e-11ec-b605-df0040e90b76; Tue, 07 Jun 2022 16:31:22 +0200 (CEST) Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailout.nyi.internal (Postfix) with ESMTP id E60835C01ED; Tue, 7 Jun 2022 10:31:21 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute3.internal (MEProxy); Tue, 07 Jun 2022 10:31:21 -0400 Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 7 Jun 2022 10:31:21 -0400 (EDT) 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" X-Inumbo-ID: 80a6abbd-e66e-11ec-b605-df0040e90b76 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= invisiblethingslab.com; h=cc:cc:content-transfer-encoding :content-type:date:date:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to; s=fm1; t=1654612281; x=1654698681; bh=evEV0WFYEo SI8Y7yrgXC8kLje73u4yjd3P/XL+ndlpo=; b=ZxYqhXY/YIi8dTivWNGloIFnBH 2MHNOBgTxoURpbsF7RR5y2q7U90JZLBqvdcqh4O3teqCu9y1LSwrut6//Huny2m+ 9jPve5Gqo4yq2Q5m5hNX0Q00BtdQ3bQfxDt668kykyxywRZNypqO+881n1Wwyib6 ibCEr2yvOEYq92KZl00SBQ7jmRPAJ6Y3be61toBD9TQHK7sY81UsqlKDFWub4Cbq p6Kei2XDSdDa4cKcPZEgRW0NevnP2+VYEbxSzXF4wHgco3Mdp3pSKjtcQaciiD5E D9CT3g1J5B4x+UKH0gEY3kBcCl9xnOHnwS72LdC7Yl0axx/U/jrmHHUhB3dA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm2; t=1654612281; x= 1654698681; bh=evEV0WFYEoSI8Y7yrgXC8kLje73u4yjd3P/XL+ndlpo=; b=A Daxk6mZF3PB/WoZhtKAkeciH3EcZpYg8ujSfcM7SkjxHgwvH45LpAdqkF0D/b0vm oC+xq3nCSPe266xWIab7jHelDnQM1Bq/m6Ep5uyyk2wviH3BVpGNQSKBM3w0/09n 7fK6A9kAnoQCuoCT+itsps73hUkbyd0n3jvQkd5ld53SnMGI5GNE6RFbxrjw9hCn oULQFugauGb9PEssT9Uxf5iwRvrbovere3iVQu6omZmJLJokesA8ifWsYZWEmKiN 60j4My0Ihe+nKOvxUff6Vnl54TS9TLwQH9ILEi0f2zUHZQxLr+VPu9/ztxvhaKRj OTwLpBV09ogcsfxiQ8Xfw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvfedruddthedgjeeiucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhephffvvefufffkofgjfhggtgfgsehtkeertdertdejnecuhfhrohhmpeforghr vghkucforghrtgiihihkohifshhkihdqifpkrhgvtghkihcuoehmrghrmhgrrhgvkhesih hnvhhishhisghlvghthhhinhhgshhlrggsrdgtohhmqeenucggtffrrghtthgvrhhnpefg ueduhefgvdefheehudejheefudevueeghfekhfehleegveduteeuiedugffgffenucevlh hushhtvghrufhiiigvpedunecurfgrrhgrmhepmhgrihhlfhhrohhmpehmrghrmhgrrhgv khesihhnvhhishhisghlvghthhhinhhgshhlrggsrdgtohhm X-ME-Proxy: Feedback-ID: i1568416f:Fastmail From: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= To: xen-devel@lists.xenproject.org Cc: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= , Kevin Tian Subject: [PATCH v1 07/10] IOMMU/VT-d: wire common device reserved memory API Date: Tue, 7 Jun 2022 16:30:13 +0200 Message-Id: <80a37be8a8fd6ba2f401a45b5e073939ceaca2cf.1654612169.git-series.marmarek@invisiblethingslab.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: References: MIME-Version: 1.0 Re-use rmrr= parameter handling code to handle common device reserved memory. Signed-off-by: Marek Marczykowski-Górecki --- xen/drivers/passthrough/vtd/dmar.c | 201 +++++++++++++++++------------- 1 file changed, 119 insertions(+), 82 deletions(-) diff --git a/xen/drivers/passthrough/vtd/dmar.c b/xen/drivers/passthrough/vtd/dmar.c index 367304c8739c..661a182b08d9 100644 --- a/xen/drivers/passthrough/vtd/dmar.c +++ b/xen/drivers/passthrough/vtd/dmar.c @@ -861,111 +861,148 @@ static struct user_rmrr __initdata user_rmrrs[MAX_USER_RMRR]; /* Macro for RMRR inclusive range formatting. */ #define ERMRRU_FMT "[%lx-%lx]" -#define ERMRRU_ARG(eru) eru.base_pfn, eru.end_pfn +#define ERMRRU_ARG base_pfn, end_pfn + +static int __init add_one_user_rmrr(unsigned long base_pfn, + unsigned long end_pfn, + unsigned int dev_count, + u32 *sbdf); static int __init add_user_rmrr(void) { + unsigned int i; + int ret; + + for ( i = 0; i < nr_rmrr; i++ ) + { + ret = add_one_user_rmrr(user_rmrrs[i].base_pfn, + user_rmrrs[i].end_pfn, + user_rmrrs[i].dev_count, + user_rmrrs[i].sbdf); + if ( ret < 0 ) + return ret; + } + return 0; +} + +/* Returns 1 on success, 0 when ignoring and < 0 on error. */ +static int __init add_one_user_rmrr(unsigned long base_pfn, + unsigned long end_pfn, + unsigned int dev_count, + u32 *sbdf) +{ struct acpi_rmrr_unit *rmrr, *rmrru; - unsigned int idx, seg, i; - unsigned long base, end; + unsigned int idx, seg; + unsigned long base_iter; bool overlap; - for ( i = 0; i < nr_rmrr; i++ ) + if ( iommu_verbose ) + printk(XENLOG_DEBUG VTDPREFIX + "Adding RMRR for %d device ([0]: %#x) range "ERMRRU_FMT"\n", + dev_count, sbdf[0], ERMRRU_ARG); + + if ( base_pfn > end_pfn ) + { + printk(XENLOG_ERR VTDPREFIX + "Invalid RMRR Range "ERMRRU_FMT"\n", + ERMRRU_ARG); + return 0; + } + + if ( (end_pfn - base_pfn) >= MAX_USER_RMRR_PAGES ) { - base = user_rmrrs[i].base_pfn; - end = user_rmrrs[i].end_pfn; + printk(XENLOG_ERR VTDPREFIX + "RMRR range "ERMRRU_FMT" exceeds "\ + __stringify(MAX_USER_RMRR_PAGES)" pages\n", + ERMRRU_ARG); + return 0; + } - if ( base > end ) + overlap = false; + list_for_each_entry(rmrru, &acpi_rmrr_units, list) + { + if ( pfn_to_paddr(base_pfn) <= rmrru->end_address && + rmrru->base_address <= pfn_to_paddr(end_pfn) ) { printk(XENLOG_ERR VTDPREFIX - "Invalid RMRR Range "ERMRRU_FMT"\n", - ERMRRU_ARG(user_rmrrs[i])); - continue; + "Overlapping RMRRs: "ERMRRU_FMT" and [%lx-%lx]\n", + ERMRRU_ARG, + paddr_to_pfn(rmrru->base_address), + paddr_to_pfn(rmrru->end_address)); + overlap = true; + break; } + } + /* Don't add overlapping RMRR. */ + if ( overlap ) + return 0; - if ( (end - base) >= MAX_USER_RMRR_PAGES ) + base_iter = base_pfn; + do + { + if ( !mfn_valid(_mfn(base_iter)) ) { printk(XENLOG_ERR VTDPREFIX - "RMRR range "ERMRRU_FMT" exceeds "\ - __stringify(MAX_USER_RMRR_PAGES)" pages\n", - ERMRRU_ARG(user_rmrrs[i])); - continue; + "Invalid pfn in RMRR range "ERMRRU_FMT"\n", + ERMRRU_ARG); + break; } + } while ( base_iter++ < end_pfn ); - overlap = false; - list_for_each_entry(rmrru, &acpi_rmrr_units, list) - { - if ( pfn_to_paddr(base) <= rmrru->end_address && - rmrru->base_address <= pfn_to_paddr(end) ) - { - printk(XENLOG_ERR VTDPREFIX - "Overlapping RMRRs: "ERMRRU_FMT" and [%lx-%lx]\n", - ERMRRU_ARG(user_rmrrs[i]), - paddr_to_pfn(rmrru->base_address), - paddr_to_pfn(rmrru->end_address)); - overlap = true; - break; - } - } - /* Don't add overlapping RMRR. */ - if ( overlap ) - continue; + /* Invalid pfn in range as the loop ended before end_pfn was reached. */ + if ( base_iter <= end_pfn ) + return 0; - do - { - if ( !mfn_valid(_mfn(base)) ) - { - printk(XENLOG_ERR VTDPREFIX - "Invalid pfn in RMRR range "ERMRRU_FMT"\n", - ERMRRU_ARG(user_rmrrs[i])); - break; - } - } while ( base++ < end ); + rmrr = xzalloc(struct acpi_rmrr_unit); + if ( !rmrr ) + return -ENOMEM; - /* Invalid pfn in range as the loop ended before end_pfn was reached. */ - if ( base <= end ) - continue; + rmrr->scope.devices = xmalloc_array(u16, dev_count); + if ( !rmrr->scope.devices ) + { + xfree(rmrr); + return -ENOMEM; + } - rmrr = xzalloc(struct acpi_rmrr_unit); - if ( !rmrr ) - return -ENOMEM; + seg = 0; + for ( idx = 0; idx < dev_count; idx++ ) + { + rmrr->scope.devices[idx] = sbdf[idx]; + seg |= PCI_SEG(sbdf[idx]); + } + if ( seg != PCI_SEG(sbdf[0]) ) + { + printk(XENLOG_ERR VTDPREFIX + "Segments are not equal for RMRR range "ERMRRU_FMT"\n", + ERMRRU_ARG); + scope_devices_free(&rmrr->scope); + xfree(rmrr); + return 0; + } - rmrr->scope.devices = xmalloc_array(u16, user_rmrrs[i].dev_count); - if ( !rmrr->scope.devices ) - { - xfree(rmrr); - return -ENOMEM; - } + rmrr->segment = seg; + rmrr->base_address = pfn_to_paddr(base_pfn); + /* Align the end_address to the end of the page */ + rmrr->end_address = pfn_to_paddr(end_pfn) | ~PAGE_MASK; + rmrr->scope.devices_cnt = dev_count; - seg = 0; - for ( idx = 0; idx < user_rmrrs[i].dev_count; idx++ ) - { - rmrr->scope.devices[idx] = user_rmrrs[i].sbdf[idx]; - seg |= PCI_SEG(user_rmrrs[i].sbdf[idx]); - } - if ( seg != PCI_SEG(user_rmrrs[i].sbdf[0]) ) - { - printk(XENLOG_ERR VTDPREFIX - "Segments are not equal for RMRR range "ERMRRU_FMT"\n", - ERMRRU_ARG(user_rmrrs[i])); - scope_devices_free(&rmrr->scope); - xfree(rmrr); - continue; - } + if ( register_one_rmrr(rmrr) ) + printk(XENLOG_ERR VTDPREFIX + "Could not register RMMR range "ERMRRU_FMT"\n", + ERMRRU_ARG); - rmrr->segment = seg; - rmrr->base_address = pfn_to_paddr(user_rmrrs[i].base_pfn); - /* Align the end_address to the end of the page */ - rmrr->end_address = pfn_to_paddr(user_rmrrs[i].end_pfn) | ~PAGE_MASK; - rmrr->scope.devices_cnt = user_rmrrs[i].dev_count; + return 1; +} - if ( register_one_rmrr(rmrr) ) - printk(XENLOG_ERR VTDPREFIX - "Could not register RMMR range "ERMRRU_FMT"\n", - ERMRRU_ARG(user_rmrrs[i])); - } +static int __init cf_check add_one_extra_rmrr(xen_pfn_t start, xen_ulong_t nr, u32 id, void *ctxt) +{ + u32 sbdf_array[] = { id }; + return add_one_user_rmrr(start, start+nr, 1, sbdf_array); +} - return 0; +static int __init add_extra_rmrr(void) +{ + return iommu_get_extra_reserved_device_memory(add_one_extra_rmrr, NULL); } #include @@ -1010,7 +1047,7 @@ int __init acpi_dmar_init(void) { iommu_init_ops = &intel_iommu_init_ops; - return add_user_rmrr(); + return add_user_rmrr() || add_extra_rmrr(); } return ret; From patchwork Tue Jun 7 14:30:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= X-Patchwork-Id: 12872015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id F1C80C433EF for ; Tue, 7 Jun 2022 14:31:43 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.343353.568749 (Exim 4.92) (envelope-from ) id 1nyaEx-0008EJ-6b; Tue, 07 Jun 2022 14:31:27 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 343353.568749; Tue, 07 Jun 2022 14:31:27 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1nyaEw-0008DY-OQ; Tue, 07 Jun 2022 14:31:26 +0000 Received: by outflank-mailman (input) for mailman id 343353; Tue, 07 Jun 2022 14:31:24 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1nyaEu-00061K-MG for xen-devel@lists.xenproject.org; Tue, 07 Jun 2022 14:31:24 +0000 Received: from out1-smtp.messagingengine.com (out1-smtp.messagingengine.com [66.111.4.25]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 81604b6c-e66e-11ec-b605-df0040e90b76; Tue, 07 Jun 2022 16:31:23 +0200 (CEST) Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.nyi.internal (Postfix) with ESMTP id 26C525C00E3; Tue, 7 Jun 2022 10:31:23 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute5.internal (MEProxy); Tue, 07 Jun 2022 10:31:23 -0400 Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 7 Jun 2022 10:31:22 -0400 (EDT) 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" X-Inumbo-ID: 81604b6c-e66e-11ec-b605-df0040e90b76 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= invisiblethingslab.com; h=cc:cc:content-transfer-encoding :content-type:date:date:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to; s=fm1; t=1654612283; x=1654698683; bh=A6IUb5PhcA I6HvRB0V+hA466Exyej9hEMYg/SSDCyCk=; b=kvLeIvF/rub3mbujq80JZ6rqh8 xFM+jPqRlvU2zoq6eFhJP10jWYcqRebmHXjkUeb5cV0cLtZjr0SxKhyCoceU/c+/ gCS+YBjMc/39D+Ab0Swy87DAeQcSVuVg+Vd5fknFmvFT+87x6ocyDF9pGsaHGr9N Fo3c8EOilP8kSCULmALBid6fS57MDKnC3GwHUSRyDgR/1EsjItYCaDZeqbEM3asD gTsP6dJjgIYMceDf+wiSTmnf7w/HulDgWtNFFRw/7UNyHlkR1f6D/vojpt6pQOxX ux7iG+5dVwcYPlFuI6c8b42fIxh6vo65jGdARhpG9gf3XyYtQhdSU4apSJIg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm2; t=1654612283; x= 1654698683; bh=A6IUb5PhcAI6HvRB0V+hA466Exyej9hEMYg/SSDCyCk=; b=P EZAkeVuZqW40QfZ+2Iw50ElZFKjh0SaSOZSTxddgnhHWS0WID4RthSk687b1APWq WAl+zFBx/wgbljGAl4SHS6lE+EoXogSbVtJjSoLRnZjEz6DMrwEUDquSFgSk3ZCK XjR5dcbvcMAmaxk52yKgSr3LQjlGB0kNRR9hWqvzqzfMvRqUQuV8QwN0Ee4q1qJs YbC5jjPzbMOsYv9gwedWnaVlbmLRK9c9GuNTciOGdZ6yIp0K7707tkeZekkKTrYL lUcXDLyLzlRI2LjIMlJpHQLLA70eDpWT1GbWK/C4cjTiu8rMA9dmh5DDQ692tVWr hAQuUZ6RHAdAnvpsyckjQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvfedruddthedgjeeiucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhephffvvefufffkofgjfhggtgfgsehtkeertdertdejnecuhfhrohhmpeforghr vghkucforghrtgiihihkohifshhkihdqifpkrhgvtghkihcuoehmrghrmhgrrhgvkhesih hnvhhishhisghlvghthhhinhhgshhlrggsrdgtohhmqeenucggtffrrghtthgvrhhnpefg ueduhefgvdefheehudejheefudevueeghfekhfehleegveduteeuiedugffgffenucevlh hushhtvghrufhiiigvpeefnecurfgrrhgrmhepmhgrihhlfhhrohhmpehmrghrmhgrrhgv khesihhnvhhishhisghlvghthhhinhhgshhlrggsrdgtohhm X-ME-Proxy: Feedback-ID: i1568416f:Fastmail From: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= To: xen-devel@lists.xenproject.org Cc: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= , Jan Beulich , Andrew Cooper Subject: [PATCH v1 08/10] IOMMU/AMD: wire common device reserved memory API Date: Tue, 7 Jun 2022 16:30:14 +0200 Message-Id: X-Mailer: git-send-email 2.35.3 In-Reply-To: References: MIME-Version: 1.0 Register common device reserved memory similar to how ivmd= parameter is handled. Signed-off-by: Marek Marczykowski-Górecki --- xen/drivers/passthrough/amd/iommu_acpi.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/xen/drivers/passthrough/amd/iommu_acpi.c b/xen/drivers/passthrough/amd/iommu_acpi.c index ac6835225bae..2a4896c05442 100644 --- a/xen/drivers/passthrough/amd/iommu_acpi.c +++ b/xen/drivers/passthrough/amd/iommu_acpi.c @@ -1078,6 +1078,20 @@ static inline bool_t is_ivmd_block(u8 type) type == ACPI_IVRS_TYPE_MEMORY_IOMMU); } +static int __init cf_check add_one_extra_ivmd(xen_pfn_t start, xen_ulong_t nr, u32 id, void *ctxt) +{ + struct acpi_ivrs_memory ivmd; + + ivmd.start_address = start << PAGE_SHIFT; + ivmd.memory_length = nr << PAGE_SHIFT; + ivmd.header.flags = ACPI_IVMD_UNITY | + ACPI_IVMD_READ | ACPI_IVMD_WRITE; + ivmd.header.length = sizeof(ivmd); + ivmd.header.device_id = id; + ivmd.header.type = ACPI_IVRS_TYPE_MEMORY_ONE; + return parse_ivmd_block(&ivmd); +} + static int __init cf_check parse_ivrs_table(struct acpi_table_header *table) { const struct acpi_ivrs_header *ivrs_block; @@ -1121,6 +1135,8 @@ static int __init cf_check parse_ivrs_table(struct acpi_table_header *table) AMD_IOMMU_DEBUG("IVMD: %u command line provided entries\n", nr_ivmd); for ( i = 0; !error && i < nr_ivmd; ++i ) error = parse_ivmd_block(user_ivmds + i); + if ( !error ) + error = iommu_get_extra_reserved_device_memory(add_one_extra_ivmd, NULL); /* Each IO-APIC must have been mentioned in the table. */ for ( apic = 0; !error && iommu_intremap && apic < nr_ioapics; ++apic ) From patchwork Tue Jun 7 14:30:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= X-Patchwork-Id: 12872013 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0F9CFCCA47E for ; Tue, 7 Jun 2022 14:31:40 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.343354.568760 (Exim 4.92) (envelope-from ) id 1nyaEy-0000C5-N0; Tue, 07 Jun 2022 14:31:28 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 343354.568760; Tue, 07 Jun 2022 14:31:28 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1nyaEy-0000B4-EX; Tue, 07 Jun 2022 14:31:28 +0000 Received: by outflank-mailman (input) for mailman id 343354; Tue, 07 Jun 2022 14:31:26 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1nyaEw-000619-K1 for xen-devel@lists.xenproject.org; Tue, 07 Jun 2022 14:31:26 +0000 Received: from out1-smtp.messagingengine.com (out1-smtp.messagingengine.com [66.111.4.25]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 823b965b-e66e-11ec-bd2c-47488cf2e6aa; Tue, 07 Jun 2022 16:31:25 +0200 (CEST) Received: from compute2.internal (compute2.nyi.internal [10.202.2.46]) by mailout.nyi.internal (Postfix) with ESMTP id D8C015C01A9; Tue, 7 Jun 2022 10:31:24 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute2.internal (MEProxy); Tue, 07 Jun 2022 10:31:24 -0400 Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 7 Jun 2022 10:31:23 -0400 (EDT) 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" X-Inumbo-ID: 823b965b-e66e-11ec-bd2c-47488cf2e6aa DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= invisiblethingslab.com; h=cc:cc:content-transfer-encoding :content-type:date:date:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to; s=fm1; t=1654612284; x=1654698684; bh=bVSELf5uLQ 6uKc/B+4q8TUi8lxYysoFD6qxpJaiy/dU=; b=XVGLR8gbDGDMJ01qLDdQa2s0RW bwVjQzaCsTdHatp1qUKzzjlbTwJBKXg25OCF8wYvZoSvKl2f0VECtYye3DpnBRPu bwqERkdJ/khzDWLbSUPfEgy99MlYjf2jxwzfvzx7h3FquGFG2jhHjRF70K6vtGag ayYkckmyyfCZHRWYSi4EXr0Wiq7h38KIV6kapI6wxAqwCTeVm3B6jUdfKHPMpiWu bVhxKOctQKzqe7gnWHNE97EeRaHp5DMtQCO/hxvP2N8B56SDWLV/fGtMALZLjUQZ LdDK9KL+XOSGIRbglmwISUMKXVsrglYW4cK8nHHudh7voVstTI80rKYKDYHQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm2; t=1654612284; x= 1654698684; bh=bVSELf5uLQ6uKc/B+4q8TUi8lxYysoFD6qxpJaiy/dU=; b=S 29bcsaAtrem1xMhKQHKkXzBYB57nkIGxGhCiFTiin1F7h/K0pUe6G8mMH62j1zuC kON8mTJN0pcJPMODq6oAaPudqfOeWpc02sNX9vpBFD5qGlwlI+X3wCNYR+scmnhA l6FC3IBFIrz3g9/j3l7vrZ+YvRF7g1Nj39yiLG/iYe45ymogY0ZFplYnQw/23Rej m8MbDF40qsRSCYR4LScwt+2YX0oYfSO617v7EwUgegQER+t8wbH3tLyaL5VRDpuF hX6OzsaTnNrpp/FXe4dQzBSeirp6mPZos/WvDk+kxq/8pcfNqLk+vR2YGiU5gGvT xWL8L684T7FmSsLoRdjog== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvfedruddthedgjeeiucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhephffvvefufffkofgjfhggtgfgsehtkeertdertdejnecuhfhrohhmpeforghr vghkucforghrtgiihihkohifshhkihdqifpkrhgvtghkihcuoehmrghrmhgrrhgvkhesih hnvhhishhisghlvghthhhinhhgshhlrggsrdgtohhmqeenucggtffrrghtthgvrhhnpefg ueduhefgvdefheehudejheefudevueeghfekhfehleegveduteeuiedugffgffenucevlh hushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehmrghrmhgrrhgv khesihhnvhhishhisghlvghthhhinhhgshhlrggsrdgtohhm X-ME-Proxy: Feedback-ID: i1568416f:Fastmail From: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= To: xen-devel@lists.xenproject.org Cc: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= , Andrew Cooper , George Dunlap , Jan Beulich , Julien Grall , Stefano Stabellini , Wei Liu , Kevin Tian Subject: [PATCH v1 09/10] xue: mark DMA buffers as reserved for the device Date: Tue, 7 Jun 2022 16:30:15 +0200 Message-Id: X-Mailer: git-send-email 2.35.3 In-Reply-To: References: MIME-Version: 1.0 The important part is to include those buffers in IOMMU page table relevant for the USB controller. Otherwise, DbC will stop working as soon as IOMMU is enabled, regardless of to which domain device assigned (be it xen or dom0). If the device is passed through to dom0 or other domain (see later patches), that domain will effectively have access to those buffers too. It does give such domain yet another way to DoS the system (as is the case when having PCI device assigned already), but also possibly steal the console ring content. Thus, such domain should be a trusted one. In any case, prevent anything else being placed on those pages by adding artificial padding. Using this API for DbC pages requires raising MAX_USER_RMRR_PAGES. Signed-off-by: Marek Marczykowski-Górecki --- xen/drivers/char/xue.c | 45 ++++++++++++++++++++----------- xen/drivers/passthrough/vtd/dmar.c | 2 +- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/xen/drivers/char/xue.c b/xen/drivers/char/xue.c index b253426a95f8..6fd26c3d38a8 100644 --- a/xen/drivers/char/xue.c +++ b/xen/drivers/char/xue.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -995,13 +996,21 @@ static struct uart_driver xue_uart_driver = { .getc = NULL }; -static struct xue_trb evt_trb[XUE_TRB_RING_CAP] __aligned(XUE_PAGE_SIZE); -static struct xue_trb out_trb[XUE_TRB_RING_CAP] __aligned(XUE_PAGE_SIZE); -static struct xue_trb in_trb[XUE_TRB_RING_CAP] __aligned(XUE_PAGE_SIZE); -static struct xue_erst_segment erst __aligned(64); -static struct xue_dbc_ctx ctx __aligned(64); -static uint8_t wrk_buf[XUE_WORK_RING_CAP] __aligned(XUE_PAGE_SIZE); -static char str_buf[XUE_PAGE_SIZE] __aligned(64); +struct xue_dma_bufs { + struct xue_trb evt_trb[XUE_TRB_RING_CAP] __aligned(XUE_PAGE_SIZE); + struct xue_trb out_trb[XUE_TRB_RING_CAP] __aligned(XUE_PAGE_SIZE); + struct xue_trb in_trb[XUE_TRB_RING_CAP] __aligned(XUE_PAGE_SIZE); + struct xue_erst_segment erst __aligned(64); + struct xue_dbc_ctx ctx __aligned(64); + uint8_t wrk_buf[XUE_WORK_RING_CAP] __aligned(XUE_PAGE_SIZE); + char str_buf[XUE_PAGE_SIZE] __aligned(64); + /* + * Don't place anything else on this page - it will be + * DMA-reachable by the USB controller. + */ + char _pad[0] __aligned(XUE_PAGE_SIZE); +}; +static struct xue_dma_bufs xue_dma_bufs __aligned(XUE_PAGE_SIZE); static char __initdata opt_dbgp[30]; string_param("dbgp", opt_dbgp); @@ -1033,15 +1042,21 @@ void __init xue_uart_init(void) xue->sbdf = PCI_SBDF(0, bus, slot, func); } - xue->dbc_ctx = &ctx; - xue->dbc_erst = &erst; - xue->dbc_ering.trb = evt_trb; - xue->dbc_oring.trb = out_trb; - xue->dbc_iring.trb = in_trb; - xue->dbc_owork.buf = wrk_buf; - xue->dbc_str = str_buf; + xue->dbc_ctx = &xue_dma_bufs.ctx; + xue->dbc_erst = &xue_dma_bufs.erst; + xue->dbc_ering.trb = xue_dma_bufs.evt_trb; + xue->dbc_oring.trb = xue_dma_bufs.out_trb; + xue->dbc_iring.trb = xue_dma_bufs.in_trb; + xue->dbc_owork.buf = xue_dma_bufs.wrk_buf; + xue->dbc_str = xue_dma_bufs.str_buf; - xue_open(xue); + if ( xue_open(xue) ) + { + iommu_add_extra_reserved_device_memory( + PFN_DOWN(virt_to_maddr(&xue_dma_bufs)), + PFN_UP(sizeof(xue_dma_bufs)), + uart->xue.sbdf.sbdf); + } serial_register_uart(SERHND_DBGP, &xue_uart_driver, &xue_uart); } diff --git a/xen/drivers/passthrough/vtd/dmar.c b/xen/drivers/passthrough/vtd/dmar.c index 661a182b08d9..2caa3e9ad1b0 100644 --- a/xen/drivers/passthrough/vtd/dmar.c +++ b/xen/drivers/passthrough/vtd/dmar.c @@ -845,7 +845,7 @@ out: return ret; } -#define MAX_USER_RMRR_PAGES 16 +#define MAX_USER_RMRR_PAGES 64 #define MAX_USER_RMRR 10 /* RMRR units derived from command line rmrr option. */ From patchwork Tue Jun 7 14:30:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= X-Patchwork-Id: 12872014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A350FCCA47C for ; Tue, 7 Jun 2022 14:31:40 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.343355.568770 (Exim 4.92) (envelope-from ) id 1nyaF0-0000Wh-Fv; Tue, 07 Jun 2022 14:31:30 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 343355.568770; Tue, 07 Jun 2022 14:31:30 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1nyaF0-0000U8-15; Tue, 07 Jun 2022 14:31:30 +0000 Received: by outflank-mailman (input) for mailman id 343355; Tue, 07 Jun 2022 14:31:28 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1nyaEy-000619-2q for xen-devel@lists.xenproject.org; Tue, 07 Jun 2022 14:31:28 +0000 Received: from out1-smtp.messagingengine.com (out1-smtp.messagingengine.com [66.111.4.25]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 8319eddd-e66e-11ec-bd2c-47488cf2e6aa; Tue, 07 Jun 2022 16:31:26 +0200 (CEST) Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.nyi.internal (Postfix) with ESMTP id 546365C01BE; Tue, 7 Jun 2022 10:31:26 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute5.internal (MEProxy); Tue, 07 Jun 2022 10:31:26 -0400 Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 7 Jun 2022 10:31:25 -0400 (EDT) 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" X-Inumbo-ID: 8319eddd-e66e-11ec-bd2c-47488cf2e6aa DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= invisiblethingslab.com; h=cc:cc:content-transfer-encoding :content-type:date:date:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to; s=fm1; t=1654612286; x=1654698686; bh=sGlhYvcRcQ 5DJkbewOsNiwax4QikybgKWGNbHy1b/To=; b=XGPSWXvQbtm+CS+eaOfrElY0ut zgiez65mQYYyvwyfMyrXmcXC9yY4jonAu8A6H07J+cLVqAMNKgp14DHkLbOIn7uS xQPhUhVE2rR02HvD5esvwfM6/Zed6GgmgtGsLeboi4GOzMkHwL/OEoQ5H93EfUrx 2+4Xio2CVonGty74H3TOdnKDmrFTfsXpp0Ew+V/ewSusMoCbXopF2R6eorFhRBdx r89oAfQbFNc7Vjq4FuUlw5fX1CfYkVcotG/Ya4yFX+blwIJaLXisKC9SgkIiuP08 z+oxVyKDPKBjJy7Qsh97WwCpIMtMes+DDcLJ2tpQ7OvHhd5Mg31kSGGmT4yg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm2; t=1654612286; x= 1654698686; bh=sGlhYvcRcQ5DJkbewOsNiwax4QikybgKWGNbHy1b/To=; b=h 8K3dtAM37ho2kR1GuCG0lGqQezLmA9O5PF6EhvBk3e75yilPIQo7CqQ06r6WivfL aZFXj9hDqUxkBUJFZ8G6s2qaEloZ3LKpLH3GhjuKNtN5h38BGqe739R0huqj+fSm aNSD+GMOFdRYp82kpomLwDrZSNIjL59WzjsQQeN4PUv58SeSkiWG/W8Cm3qNmnmR zzbZQw1hhdaXq5YK5u5qcOHcX4h2gqLUO1lx5TLVP3dLLuuHMk+3nMFreLMxe55F 8kAPia2ck5TzlxbYEbAgxoCgqQBQE7h7ubE1x/J0Sv8w4nUWcRlf5yiY9PSX6H+b O/x7daW3163aBDgr8jSWA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvfedruddthedgjeeiucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhephffvvefufffkofgjfhggtgfgsehtkeertdertdejnecuhfhrohhmpeforghr vghkucforghrtgiihihkohifshhkihdqifpkrhgvtghkihcuoehmrghrmhgrrhgvkhesih hnvhhishhisghlvghthhhinhhgshhlrggsrdgtohhmqeenucggtffrrghtthgvrhhnpefg ueduhefgvdefheehudejheefudevueeghfekhfehleegveduteeuiedugffgffenucevlh hushhtvghrufhiiigvpeefnecurfgrrhgrmhepmhgrihhlfhhrohhmpehmrghrmhgrrhgv khesihhnvhhishhisghlvghthhhinhhgshhlrggsrdgtohhm X-ME-Proxy: Feedback-ID: i1568416f:Fastmail From: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= To: xen-devel@lists.xenproject.org Cc: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= , Andrew Cooper , George Dunlap , Jan Beulich , Julien Grall , Stefano Stabellini , Wei Liu Subject: [PATCH v1 10/10] xue: allow driving the rest of XHCI by a domain while Xen uses DbC Date: Tue, 7 Jun 2022 16:30:16 +0200 Message-Id: <9c35e0e4ac14a273ed59fab22034fa11a264e394.1654612169.git-series.marmarek@invisiblethingslab.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: References: MIME-Version: 1.0 That's possible, because the capability was designed specifically to allow separate driver handle it, in parallel to unmodified xhci driver (separate set of registers, pretending the port is "disconnected" for the main xhci driver etc). It works with Linux dom0, although requires an awful hack - re-enabling bus mastering behind dom0's backs. Linux driver does similar thing - see drivers/usb/early/xhci-dbc.c:xdbc_handle_events(). To avoid Linux messing with the DbC, mark this MMIO area as read-only. Signed-off-by: Marek Marczykowski-Górecki --- xen/drivers/char/xue.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/xen/drivers/char/xue.c b/xen/drivers/char/xue.c index 6fd26c3d38a8..85aed0bccbbf 100644 --- a/xen/drivers/char/xue.c +++ b/xen/drivers/char/xue.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -846,6 +847,7 @@ static void xue_flush(struct xue *xue, struct xue_trb_ring *trb, { struct xue_dbc_reg *reg = xue->dbc_reg; uint32_t db = (reg->db & 0xFFFF00FF) | (trb->db << 8); + uint32_t cmd; if ( xue->open && !(reg->ctrl & (1UL << XUE_CTRL_DCE)) ) { @@ -856,6 +858,16 @@ static void xue_flush(struct xue *xue, struct xue_trb_ring *trb, xue_enable_dbc(xue); } + /* Re-enable bus mastering, if dom0 (or other) disabled it in the meantime. */ + cmd = pci_conf_read16(xue->sbdf, PCI_COMMAND); +#define XUE_XHCI_CMD_REQUIRED (PCI_COMMAND_MEMORY|PCI_COMMAND_MASTER) + if ( (cmd & XUE_XHCI_CMD_REQUIRED) != XUE_XHCI_CMD_REQUIRED ) + { + cmd |= XUE_XHCI_CMD_REQUIRED; + pci_conf_write16(xue->sbdf, PCI_COMMAND, cmd); + } +#undef XUE_XHCI_CMD_REQUIRED + xue_pop_events(xue); if ( !(reg->ctrl & (1UL << XUE_CTRL_DCR)) ) @@ -955,6 +967,13 @@ static void __init cf_check xue_uart_init_postirq(struct serial_port *port) serial_async_transmit(port); init_timer(&uart->timer, xue_uart_poll, port, 0); set_timer(&uart->timer, NOW() + MILLISECS(1)); + +#ifdef CONFIG_X86 + if ( rangeset_add_range(mmio_ro_ranges, + PFN_DOWN(uart->xue.xhc_mmio_phys + uart->xue.xhc_dbc_offset), + PFN_UP(uart->xue.xhc_mmio_phys + uart->xue.xhc_dbc_offset + sizeof(*uart->xue.dbc_reg)) - 1) ) + printk(XENLOG_INFO "Error while adding MMIO range of device to mmio_ro_ranges\n"); +#endif } static int cf_check xue_uart_tx_ready(struct serial_port *port)