From patchwork Fri Aug 21 13:15:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 1349237 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=linux-pci-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=NpM+QAeA; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4BY28n3jjdz9sPB for ; Fri, 21 Aug 2020 23:16:25 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728759AbgHUNQT (ORCPT ); Fri, 21 Aug 2020 09:16:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32924 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727976AbgHUNQM (ORCPT ); Fri, 21 Aug 2020 09:16:12 -0400 Received: from mail-ed1-x541.google.com (mail-ed1-x541.google.com [IPv6:2a00:1450:4864:20::541]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7050BC061385 for ; Fri, 21 Aug 2020 06:16:12 -0700 (PDT) Received: by mail-ed1-x541.google.com with SMTP id c10so1383513edk.6 for ; Fri, 21 Aug 2020 06:16:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=CGfR6v3AK9RiKFWmVUt4OX8zldgtD7R209TqBrFRf6A=; b=NpM+QAeAtDS+vuHr/qsAxLGz0RzOZbBpb7eNNFUK3Kan9Wha3FSnGrRgODlSfxTHji jqPHivHK0RsfnSvZINhMJVXV5ePliRbvAny/XW+puDQKC9eSaVAT90nZ237E34X+jPYz kqcNeVfjnEsJ8Zd/HJrDBnyrln9AFE9kVmyfgvbVnVxLMTT6NChJuydDWP2g8r/bs627 o/8F+GSTZ5LbFww31m11upQpAqghI7vnm3FSwkHTJlg1f7RR+pI4bBJ3Zi1Je66cAb+E K1wzyw+hhAwliNdzhiHjWsJXWyJbMOjB6LnZIj4Kyg9JvalM3Q+LR0JUdr19byex8jUC RJ7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=CGfR6v3AK9RiKFWmVUt4OX8zldgtD7R209TqBrFRf6A=; b=E988IGIHEUsIOcHMvyByBHgtrbn8NrPA2SAVku5oN1nltq9jKGvajzaaBtgAgYaPol 67HDldfD6aJLykKXhKfE0mY37AdZPV2Ck0fA5NeqMXakQ8eBwo1RVLHNJEZixrzpuZe+ SM/V0xj9MhN6q+ge+jqVmu+ZOG6xWtEN8onOOltvrDyRhMs+qxJyysnYVH06ngXAaU7r Xx5zNE7Hy1qw30+srW9CMOvdy4PMr+vDOvfRGT/VlJ8Yuoj1L6bcQMorC3h2ZKwiGNDH ubazVmZTM3wgUHBh4cVmrQxX+ho1eyL8nba141+3FIY5EyRHlI1qEC2q9B2bQh/RiULn C8Gw== X-Gm-Message-State: AOAM5320ibHgofNUg9bDM/PjnDuhtDqZZMM/5G6e+AEP0KqSW2gTgnGh irA1RcbRMfdO71bqnoJ+0XwlrQ== X-Google-Smtp-Source: ABdhPJxokcQ0IuXysG4c3tg0Qxks3XmbNzQjbGHqNkBr899EEr9X26aBW5gNkvYxSfGRWPA0z+/VaA== X-Received: by 2002:a05:6402:b1c:: with SMTP id bm28mr2790782edb.116.1598015768219; Fri, 21 Aug 2020 06:16:08 -0700 (PDT) Received: from localhost.localdomain ([2001:1715:4e26:a7e0:116c:c27a:3e7f:5eaf]) by smtp.gmail.com with ESMTPSA id v4sm1299748eje.39.2020.08.21.06.16.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Aug 2020 06:16:07 -0700 (PDT) From: Jean-Philippe Brucker To: iommu@lists.linux-foundation.org, virtualization@lists.linux-foundation.org, virtio-dev@lists.oasis-open.org, linux-pci@vger.kernel.org Cc: joro@8bytes.org, bhelgaas@google.com, mst@redhat.com, jasowang@redhat.com, kevin.tian@intel.com, sebastien.boeuf@intel.com, eric.auger@redhat.com, lorenzo.pieralisi@arm.com, Jean-Philippe Brucker Subject: [PATCH v3 1/6] iommu/virtio: Move to drivers/iommu/virtio/ Date: Fri, 21 Aug 2020 15:15:35 +0200 Message-Id: <20200821131540.2801801-2-jean-philippe@linaro.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200821131540.2801801-1-jean-philippe@linaro.org> References: <20200821131540.2801801-1-jean-philippe@linaro.org> MIME-Version: 1.0 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Before adding new files to the virtio-iommu driver, move it to its own subfolder, similarly to other IOMMU drivers. Signed-off-by: Jean-Philippe Brucker Reviewed-by: Eric Auger --- drivers/iommu/Makefile | 3 +-- drivers/iommu/virtio/Makefile | 2 ++ drivers/iommu/{ => virtio}/virtio-iommu.c | 0 MAINTAINERS | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 drivers/iommu/virtio/Makefile rename drivers/iommu/{ => virtio}/virtio-iommu.c (100%) diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 11f1771104f3..fc7523042512 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -obj-y += amd/ intel/ arm/ +obj-y += amd/ intel/ arm/ virtio/ obj-$(CONFIG_IOMMU_API) += iommu.o obj-$(CONFIG_IOMMU_API) += iommu-traces.o obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o @@ -26,4 +26,3 @@ obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o obj-$(CONFIG_S390_IOMMU) += s390-iommu.o obj-$(CONFIG_HYPERV_IOMMU) += hyperv-iommu.o -obj-$(CONFIG_VIRTIO_IOMMU) += virtio-iommu.o diff --git a/drivers/iommu/virtio/Makefile b/drivers/iommu/virtio/Makefile new file mode 100644 index 000000000000..279368fcc074 --- /dev/null +++ b/drivers/iommu/virtio/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_VIRTIO_IOMMU) += virtio-iommu.o diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio/virtio-iommu.c similarity index 100% rename from drivers/iommu/virtio-iommu.c rename to drivers/iommu/virtio/virtio-iommu.c diff --git a/MAINTAINERS b/MAINTAINERS index deaafb617361..3602b223c9b2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -18451,7 +18451,7 @@ VIRTIO IOMMU DRIVER M: Jean-Philippe Brucker L: virtualization@lists.linux-foundation.org S: Maintained -F: drivers/iommu/virtio-iommu.c +F: drivers/iommu/virtio/ F: include/uapi/linux/virtio_iommu.h VIRTIO MEM DRIVER From patchwork Fri Aug 21 13:15:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 1349238 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=linux-pci-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=lJXaHRti; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4BY28p3xKnz9sPB for ; Fri, 21 Aug 2020 23:16:26 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727976AbgHUNQY (ORCPT ); Fri, 21 Aug 2020 09:16:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32936 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728739AbgHUNQP (ORCPT ); Fri, 21 Aug 2020 09:16:15 -0400 Received: from mail-ed1-x542.google.com (mail-ed1-x542.google.com [IPv6:2a00:1450:4864:20::542]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EC08BC061386 for ; Fri, 21 Aug 2020 06:16:13 -0700 (PDT) Received: by mail-ed1-x542.google.com with SMTP id w14so889231eds.0 for ; Fri, 21 Aug 2020 06:16:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=qIWN2A9Pg6dkinmsu+W9xC580ElUmiDl+mJTFgDdlfk=; b=lJXaHRtihKmQ0Z2fAhiSdOZT5NzKnzoSxLejvf96zLb4lOwQTV2Mth4JS8ym05KJfj hbZuRDp8ARmG/8/q30QH/hSDRmtTGGlcAihsxtc72ByHW7yYNak+CEcwcMEL71gQ2sJm DHN6LUUhbybZNvBQeMbghUQKNhDFO/9WxcYazlqTb7ApD0jzGbGI0b4yvUJpXE+fF6bN 69U2Fw1Qrm94pB44JFwSqFPgMODwH43iIYsIO0i0faBkkZ1i+TxwuoQIuXkHN0VuU7E3 IH0FlmWpLAOeeRpFjqrbDLBLyAssqLX6ZOTkwS72nMckwOMlG81tV46gVG/P6PC40tNf alrQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=qIWN2A9Pg6dkinmsu+W9xC580ElUmiDl+mJTFgDdlfk=; b=YKGA4j6AW9C7uYFbLpzPkVHbAjkjJTGeRBuzJZETWjC4qk/wNc3g/C0U+HU2LCBQ1Z Re3JSfOy2aDhFZ+r4tzAXMo33UfwGNdpR1OtGoDrC+ZL3+TIjVahnVeD1Fx9eS5MNFbb j32z88aCCFqvILzDtVkXTPEt67iIvsFEEYVtf5+83YrRvYfU0M1kbY5t9IuP50YQQNtA XK1Gkx1mcLxClAMP40CsT7DH/SdzL6dkvcu69rY9FiC8ozQYoTBReVSvCWLEEr0hCIk0 sC3o1tPG/eDwhp5l6NJLcD1WXdJ7Bw9FCd95US5RVF/A2hQY9ZXWwTNzF5s0Yg5ZQaAK KASw== X-Gm-Message-State: AOAM533bdyd2XyzygI4r2uFDWliBQdyzkTH24lGlrCC8gVhWS9zcKrVK AFqtUFvb/2Y4LOkEQcZPyqwoYA== X-Google-Smtp-Source: ABdhPJzxq1c9JigDVrS42THmZTWZeFAgfMyVfSNwCK+EUYesa8zCQaunBd0jytbwhye3B13DjvZOhA== X-Received: by 2002:a05:6402:1d92:: with SMTP id dk18mr2705911edb.206.1598015769483; Fri, 21 Aug 2020 06:16:09 -0700 (PDT) Received: from localhost.localdomain ([2001:1715:4e26:a7e0:116c:c27a:3e7f:5eaf]) by smtp.gmail.com with ESMTPSA id v4sm1299748eje.39.2020.08.21.06.16.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Aug 2020 06:16:08 -0700 (PDT) From: Jean-Philippe Brucker To: iommu@lists.linux-foundation.org, virtualization@lists.linux-foundation.org, virtio-dev@lists.oasis-open.org, linux-pci@vger.kernel.org Cc: joro@8bytes.org, bhelgaas@google.com, mst@redhat.com, jasowang@redhat.com, kevin.tian@intel.com, sebastien.boeuf@intel.com, eric.auger@redhat.com, lorenzo.pieralisi@arm.com, Jean-Philippe Brucker Subject: [PATCH v3 2/6] iommu/virtio: Add topology helpers Date: Fri, 21 Aug 2020 15:15:36 +0200 Message-Id: <20200821131540.2801801-3-jean-philippe@linaro.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200821131540.2801801-1-jean-philippe@linaro.org> References: <20200821131540.2801801-1-jean-philippe@linaro.org> MIME-Version: 1.0 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org To support topology description from ACPI and from the builtin description, add helpers to keep track of I/O topology descriptors. To ease re-use of the helpers by other drivers and future ACPI extensions, use the "virt_" prefix rather than "virtio_" when naming structs and functions. Signed-off-by: Jean-Philippe Brucker Reviewed-by: Eric Auger --- drivers/iommu/Kconfig | 3 + drivers/iommu/virtio/Makefile | 1 + drivers/iommu/virtio/topology-helpers.h | 50 ++++++ include/linux/virt_iommu.h | 15 ++ drivers/iommu/virtio/topology-helpers.c | 196 ++++++++++++++++++++++++ drivers/iommu/virtio/virtio-iommu.c | 4 + MAINTAINERS | 1 + 7 files changed, 270 insertions(+) create mode 100644 drivers/iommu/virtio/topology-helpers.h create mode 100644 include/linux/virt_iommu.h create mode 100644 drivers/iommu/virtio/topology-helpers.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index bef5d75e306b..e29ae50f7100 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -391,4 +391,7 @@ config VIRTIO_IOMMU Say Y here if you intend to run this kernel as a guest. +config VIRTIO_IOMMU_TOPOLOGY_HELPERS + bool + endif # IOMMU_SUPPORT diff --git a/drivers/iommu/virtio/Makefile b/drivers/iommu/virtio/Makefile index 279368fcc074..b42ad47eac7e 100644 --- a/drivers/iommu/virtio/Makefile +++ b/drivers/iommu/virtio/Makefile @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_VIRTIO_IOMMU) += virtio-iommu.o +obj-$(CONFIG_VIRTIO_IOMMU_TOPOLOGY_HELPERS) += topology-helpers.o diff --git a/drivers/iommu/virtio/topology-helpers.h b/drivers/iommu/virtio/topology-helpers.h new file mode 100644 index 000000000000..436ca6a900c5 --- /dev/null +++ b/drivers/iommu/virtio/topology-helpers.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef TOPOLOGY_HELPERS_H_ +#define TOPOLOGY_HELPERS_H_ + +#ifdef CONFIG_VIRTIO_IOMMU_TOPOLOGY_HELPERS + +/* Identify a device node in the topology */ +struct virt_topo_dev_id { + unsigned int type; +#define VIRT_TOPO_DEV_TYPE_PCI 1 +#define VIRT_TOPO_DEV_TYPE_MMIO 2 + union { + /* PCI endpoint or range */ + struct { + u16 segment; + u16 bdf_start; + u16 bdf_end; + }; + /* MMIO region */ + u64 base; + }; +}; + +/* Specification of an IOMMU */ +struct virt_topo_iommu { + struct virt_topo_dev_id dev_id; + struct device *dev; /* transport device */ + struct fwnode_handle *fwnode; + struct iommu_ops *ops; + struct list_head list; +}; + +/* Specification of an endpoint */ +struct virt_topo_endpoint { + struct virt_topo_dev_id dev_id; + u32 endpoint_id; + struct virt_topo_iommu *viommu; + struct list_head list; +}; + +void virt_topo_add_endpoint(struct virt_topo_endpoint *ep); +void virt_topo_add_iommu(struct virt_topo_iommu *viommu); + +void virt_topo_set_iommu_ops(struct device *dev, struct iommu_ops *ops); + +#else /* !CONFIG_VIRTIO_IOMMU_TOPOLOGY_HELPERS */ +static inline void virt_topo_set_iommu_ops(struct device *dev, struct iommu_ops *ops) +{ } +#endif /* !CONFIG_VIRTIO_IOMMU_TOPOLOGY_HELPERS */ +#endif /* TOPOLOGY_HELPERS_H_ */ diff --git a/include/linux/virt_iommu.h b/include/linux/virt_iommu.h new file mode 100644 index 000000000000..17d2bd4732e0 --- /dev/null +++ b/include/linux/virt_iommu.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef VIRT_IOMMU_H_ +#define VIRT_IOMMU_H_ + +#ifdef CONFIG_VIRTIO_IOMMU_TOPOLOGY_HELPERS +int virt_dma_configure(struct device *dev); + +#else /* !CONFIG_VIRTIO_IOMMU_TOPOLOGY_HELPERS */ +static inline int virt_dma_configure(struct device *dev) +{ + /* Don't disturb the normal DMA configuration methods */ + return 0; +} +#endif /* !CONFIG_VIRTIO_IOMMU_TOPOLOGY_HELPERS */ +#endif /* VIRT_IOMMU_H_ */ diff --git a/drivers/iommu/virtio/topology-helpers.c b/drivers/iommu/virtio/topology-helpers.c new file mode 100644 index 000000000000..8815e3a5d431 --- /dev/null +++ b/drivers/iommu/virtio/topology-helpers.c @@ -0,0 +1,196 @@ +// SPDX-License-Identifier: GPL-2.0 +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include + +#include "topology-helpers.h" + +static LIST_HEAD(viommus); +static LIST_HEAD(pci_endpoints); +static LIST_HEAD(mmio_endpoints); +static DEFINE_MUTEX(viommus_lock); + +static bool virt_topo_device_match(struct device *dev, + struct virt_topo_dev_id *id) +{ + if (id->type == VIRT_TOPO_DEV_TYPE_PCI && dev_is_pci(dev)) { + struct pci_dev *pdev = to_pci_dev(dev); + u16 dev_id = pci_dev_id(pdev); + + return pci_domain_nr(pdev->bus) == id->segment && + dev_id >= id->bdf_start && + dev_id <= id->bdf_end; + } else if (id->type == VIRT_TOPO_DEV_TYPE_MMIO && + dev_is_platform(dev)) { + struct platform_device *plat_dev = to_platform_device(dev); + struct resource *mem; + + mem = platform_get_resource(plat_dev, IORESOURCE_MEM, 0); + if (!mem) + return false; + return mem->start == id->base; + } + return false; +} + +static const struct iommu_ops *virt_iommu_setup(struct device *dev) +{ + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); + struct virt_topo_iommu *viommu = NULL; + struct virt_topo_endpoint *ep; + struct pci_dev *pci_dev = NULL; + u32 epid; + int ret; + + /* Already translated? */ + if (fwspec && fwspec->ops) + return NULL; + + mutex_lock(&viommus_lock); + if (dev_is_pci(dev)) { + pci_dev = to_pci_dev(dev); + list_for_each_entry(ep, &pci_endpoints, list) { + if (virt_topo_device_match(dev, &ep->dev_id)) { + epid = pci_dev_id(pci_dev) - + ep->dev_id.bdf_start + + ep->endpoint_id; + viommu = ep->viommu; + break; + } + } + } else if (dev_is_platform(dev)) { + list_for_each_entry(ep, &mmio_endpoints, list) { + if (virt_topo_device_match(dev, &ep->dev_id)) { + epid = ep->endpoint_id; + viommu = ep->viommu; + break; + } + } + } + mutex_unlock(&viommus_lock); + if (!viommu) + return NULL; + + /* We're not translating ourselves. */ + if (virt_topo_device_match(dev, &viommu->dev_id) || + dev == viommu->dev) + return NULL; + + /* + * If we found a PCI range managed by the viommu, we're the one that has + * to request ACS. + */ + if (pci_dev) + pci_request_acs(); + + if (!viommu->ops) + return ERR_PTR(-EPROBE_DEFER); + + ret = iommu_fwspec_init(dev, viommu->fwnode, viommu->ops); + if (ret) + return ERR_PTR(ret); + + iommu_fwspec_add_ids(dev, &epid, 1); + + return viommu->ops; +} + +/** + * virt_topo_add_endpoint - Register endpoint specification + * @ep: the endpoint specification + */ +void virt_topo_add_endpoint(struct virt_topo_endpoint *ep) +{ + mutex_lock(&viommus_lock); + list_add(&ep->list, + ep->dev_id.type == VIRT_TOPO_DEV_TYPE_MMIO ? + &mmio_endpoints : &pci_endpoints); + mutex_unlock(&viommus_lock); +} + +/** + * virt_topo_add_iommu - Register IOMMU specification + * @viommu: the IOMMU specification + */ +void virt_topo_add_iommu(struct virt_topo_iommu *viommu) +{ + mutex_lock(&viommus_lock); + list_add(&viommu->list, &viommus); + mutex_unlock(&viommus_lock); +} + +/** + * virt_dma_configure - Configure DMA of virtualized devices + * @dev: the endpoint + * + * Setup the DMA and IOMMU ops of a virtual device, for platforms without DT or + * ACPI. + * + * Return: -EPROBE_DEFER if the device is managed by an IOMMU that hasn't been + * probed yet, 0 otherwise + */ +int virt_dma_configure(struct device *dev) +{ + const struct iommu_ops *iommu_ops; + + iommu_ops = virt_iommu_setup(dev); + if (IS_ERR_OR_NULL(iommu_ops)) { + int ret = PTR_ERR(iommu_ops); + + if (ret == -EPROBE_DEFER || ret == 0) + return ret; + dev_err(dev, "error %d while setting up virt IOMMU\n", ret); + return 0; + } + + /* + * If we have reason to believe the IOMMU driver missed the initial + * add_device callback for dev, replay it to get things in order. + */ + if (dev->bus && !device_iommu_mapped(dev)) + iommu_probe_device(dev); + + /* Assume coherent, as well as full 64-bit addresses. */ +#ifdef CONFIG_ARCH_HAS_SETUP_DMA_OPS + arch_setup_dma_ops(dev, 0, ~0ULL, iommu_ops, true); +#else + iommu_setup_dma_ops(dev, 0, ~0ULL); +#endif + return 0; +} + +/** + * virt_topo_set_iommu_ops - Set the IOMMU ops of a virtual IOMMU device + * @dev: the IOMMU device (transport) + * @ops: the new IOMMU ops or NULL + * + * Setup the iommu_ops associated to an IOMMU, once the driver is loaded + * and the device probed. + */ +void virt_topo_set_iommu_ops(struct device *dev, struct iommu_ops *ops) +{ + struct virt_topo_iommu *viommu; + + mutex_lock(&viommus_lock); + list_for_each_entry(viommu, &viommus, list) { + /* + * In case the topology driver didn't have a dev handle when + * registering the topology, add it now. + */ + if (!viommu->dev && + virt_topo_device_match(dev, &viommu->dev_id)) + viommu->dev = dev; + + if (viommu->dev == dev) { + viommu->ops = ops; + viommu->fwnode = ops ? dev->fwnode : NULL; + break; + } + } + mutex_unlock(&viommus_lock); +} +EXPORT_SYMBOL_GPL(virt_topo_set_iommu_ops); diff --git a/drivers/iommu/virtio/virtio-iommu.c b/drivers/iommu/virtio/virtio-iommu.c index b4da396cce60..b371d15f837f 100644 --- a/drivers/iommu/virtio/virtio-iommu.c +++ b/drivers/iommu/virtio/virtio-iommu.c @@ -25,6 +25,8 @@ #include +#include "topology-helpers.h" + #define MSI_IOVA_BASE 0x8000000 #define MSI_IOVA_LENGTH 0x100000 @@ -1065,6 +1067,7 @@ static int viommu_probe(struct virtio_device *vdev) if (ret) goto err_free_vqs; + virt_topo_set_iommu_ops(dev->parent, &viommu_ops); iommu_device_set_ops(&viommu->iommu, &viommu_ops); iommu_device_set_fwnode(&viommu->iommu, parent_dev->fwnode); @@ -1111,6 +1114,7 @@ static void viommu_remove(struct virtio_device *vdev) { struct viommu_dev *viommu = vdev->priv; + virt_topo_set_iommu_ops(vdev->dev.parent, NULL); iommu_device_sysfs_remove(&viommu->iommu); iommu_device_unregister(&viommu->iommu); diff --git a/MAINTAINERS b/MAINTAINERS index 3602b223c9b2..8fd53c22a0ab 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -18452,6 +18452,7 @@ M: Jean-Philippe Brucker L: virtualization@lists.linux-foundation.org S: Maintained F: drivers/iommu/virtio/ +F: include/linux/virt_iommu.h F: include/uapi/linux/virtio_iommu.h VIRTIO MEM DRIVER From patchwork Fri Aug 21 13:15:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 1349239 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=linux-pci-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=Evc7JHiQ; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4BY28q1kg1z9sR4 for ; Fri, 21 Aug 2020 23:16:27 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728739AbgHUNQZ (ORCPT ); Fri, 21 Aug 2020 09:16:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32938 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728746AbgHUNQQ (ORCPT ); Fri, 21 Aug 2020 09:16:16 -0400 Received: from mail-ed1-x541.google.com (mail-ed1-x541.google.com [IPv6:2a00:1450:4864:20::541]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 14CE6C061387 for ; Fri, 21 Aug 2020 06:16:13 -0700 (PDT) Received: by mail-ed1-x541.google.com with SMTP id l23so1369466edv.11 for ; Fri, 21 Aug 2020 06:16:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=AnnlDaJISLBh3tlC6QY64TitbeK2bzvjOXLypqqoQOw=; b=Evc7JHiQsscTCCzRJuF4RGxVPF/TfJEQoNFtq/F7l4VJCPfkB8ZnzeHE1jSsjrZ5r7 5C5idkHzraOBGbOnKZ34LNp9EprEIaOlttQSmNnVriYiMTyEn0rEcuYChBq7/TbDjIa9 h9y8+WSyeAHbE/U5TdEhnhnBK3VaWQsOiKiNRvRwvjKBbSoZrDHgc/ZU3yHnRDYGsqwM dcz4chm8cEyq8yr22YRPHjEUeukQaL7QYjLiVubrUsFr+Z3R6l5PdO1A8jIMu+4qOmwq DC8C2F+j/g3CwmANZ24gMXCH2L7IB0mQp2b8fBSq4UKvRyEOgAylfTesVJgJHr38GfK+ JKGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=AnnlDaJISLBh3tlC6QY64TitbeK2bzvjOXLypqqoQOw=; b=LqxzW4oEMI+zwnVUaan/Ufgw5OX8DjWL7TqePmxIH9mE91StDDGb1ySDXSWMq4br5C VpymzQKfFLP7s7mSkrJxO+jBLkOfBmGW64Sox5JFldpHafKKfOiIrZyxycS0RQ4N+ZNj B9KPmijJPyZf9dtWlCuzMDnTw3RMdRbH8TfaQ3jTcvTQI8zSTZVj1i6zWrf+UhvopYdf hH6fPy89ebmK0/YjIptLsMxFXRh1+CNX8VImGWRGqCj6AUW7sr69DRmDGW7svQXiUgfM Gv71Al+QcloaV1QMmrIuetH9jRO+DilJ84FugIJvxqfS+QUZZ7u0SOWYp6Bmk9vnsFgH tqfQ== X-Gm-Message-State: AOAM531qJFrLPe8Thn2mkWPbEx76Eu4tkwe4moMzJdfHk0OrcNKvnkfb 7F/b5G9Z+q8zGrebrLfe2s/gUA== X-Google-Smtp-Source: ABdhPJxLTyEDp1sdq7LgF1huRP9DNgLTxWOLZlImVJP3z0/PYSRni9H4ifVAEYm5/PMqx1CpjBujwg== X-Received: by 2002:aa7:c353:: with SMTP id j19mr2827173edr.128.1598015770571; Fri, 21 Aug 2020 06:16:10 -0700 (PDT) Received: from localhost.localdomain ([2001:1715:4e26:a7e0:116c:c27a:3e7f:5eaf]) by smtp.gmail.com with ESMTPSA id v4sm1299748eje.39.2020.08.21.06.16.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Aug 2020 06:16:10 -0700 (PDT) From: Jean-Philippe Brucker To: iommu@lists.linux-foundation.org, virtualization@lists.linux-foundation.org, virtio-dev@lists.oasis-open.org, linux-pci@vger.kernel.org Cc: joro@8bytes.org, bhelgaas@google.com, mst@redhat.com, jasowang@redhat.com, kevin.tian@intel.com, sebastien.boeuf@intel.com, eric.auger@redhat.com, lorenzo.pieralisi@arm.com, Jean-Philippe Brucker Subject: [PATCH v3 3/6] PCI: Add DMA configuration for virtual platforms Date: Fri, 21 Aug 2020 15:15:37 +0200 Message-Id: <20200821131540.2801801-4-jean-philippe@linaro.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200821131540.2801801-1-jean-philippe@linaro.org> References: <20200821131540.2801801-1-jean-philippe@linaro.org> MIME-Version: 1.0 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Hardware platforms usually describe the IOMMU topology using either device-tree pointers or vendor-specific ACPI tables. For virtual platforms that don't provide a device-tree, the virtio-iommu device contains a description of the endpoints it manages. That information allows us to probe endpoints after the IOMMU is probed (possibly as late as userspace modprobe), provided it is discovered early enough. Add a hook to pci_dma_configure(), which returns -EPROBE_DEFER if the endpoint is managed by a vIOMMU that will be loaded later, or 0 in any other case to avoid disturbing the normal DMA configuration methods. When CONFIG_VIRTIO_IOMMU_TOPOLOGY_HELPERS isn't selected, the call to virt_dma_configure() is compiled out. As long as the information is consistent, platforms can provide both a device-tree and a built-in topology, and the IOMMU infrastructure is able to deal with multiple DMA configuration methods. Acked-by: Bjorn Helgaas Signed-off-by: Jean-Philippe Brucker --- drivers/pci/pci-driver.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 449466f71040..dbe9d33606b0 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "pci.h" #include "pcie/portdrv.h" @@ -1605,6 +1606,10 @@ static int pci_dma_configure(struct device *dev) struct device *bridge; int ret = 0; + ret = virt_dma_configure(dev); + if (ret) + return ret; + bridge = pci_get_host_bridge_device(to_pci_dev(dev)); if (IS_ENABLED(CONFIG_OF) && bridge->parent && From patchwork Fri Aug 21 13:15:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 1349240 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=linux-pci-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=F7qrOUgT; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4BY28q4MmDz9sTF for ; Fri, 21 Aug 2020 23:16:27 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728746AbgHUNQ0 (ORCPT ); Fri, 21 Aug 2020 09:16:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32940 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728750AbgHUNQQ (ORCPT ); Fri, 21 Aug 2020 09:16:16 -0400 Received: from mail-ed1-x542.google.com (mail-ed1-x542.google.com [IPv6:2a00:1450:4864:20::542]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1BF26C061388 for ; Fri, 21 Aug 2020 06:16:13 -0700 (PDT) Received: by mail-ed1-x542.google.com with SMTP id ba10so1392042edb.3 for ; Fri, 21 Aug 2020 06:16:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=mFxcuowFu0Jv3evIc1dad6n3ZhAX6nITskxpnaVl5+I=; b=F7qrOUgTT3E74XyC9jWEuKSCWozpJkqtVAUNfrVyQYb7KuFQaRifAbrV29U+QTgdO7 svaPN2mULjuJmM9GzglZwFzOSgvsCjum3Skmnma0ZxZOa0TjXvzHG00pItNlS0o+yHHb DHKfdTgv1Vsra0RFLIHnHM3PWZPg1i4t79wJcD/ye7C4kl6emXJwM47EZ2fqK9NjHU8Z 7l+LTNCupWNFida4Mq7tKvQSx5gdmvST6bW+kSiDnNAhy1j/RRW6vu0KYRZKH8ouJXsm 8/+XKVKeZNzd+4C8Jbsu4oNNebPMyjg8aTlotZFno4GFpdtboKUIpaIYzxudSgt9xQLD ZQhA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=mFxcuowFu0Jv3evIc1dad6n3ZhAX6nITskxpnaVl5+I=; b=tWCT16PqVtCn2wM0aHhMbb0EIckJTY1+4/RYk+RsnhhD2aN+8Rk1DLrs2sSGHpkzdB naGXbSFQXWzwWLL5eUL1yTaTmTVekhNhOHxKADiXbfWGwaZVr+MI0n0ea6s1zV4/rEJW oHCdCVgsIKPrwMEBUcPsIBHNYnAb1S3VrJnwXJb1QmlgnFIu2qT+uL41OqEqFJQ5BZ0I 22pfeurS/r6mE8zlnTl4p30LWyfbBIc6YG47NfxRFNP9w+z8xcr7hNgFf4fJbNE3+eCI +YH2Ee3jxpJsBA0unSTkXhYEosa1VOZRKy/BEH2vEBIIGl7AYjdRutjsHRqltK3VilaC 4Bew== X-Gm-Message-State: AOAM531SB7gW4YEFEPllC5WJsiNJqqyug6yUBYJ7Gx5xDFnrT0ckcd5k u3bgkuvC3hXMue0VcwN1yCu9gw== X-Google-Smtp-Source: ABdhPJxSuluZjkQxfsXp9THILY+NXbkzKwWS5DVjT4ygD1u7SdXIMGmAG5nqsAUF8rJME9RMD8pSxg== X-Received: by 2002:a50:a2e6:: with SMTP id 93mr2650226edm.147.1598015771724; Fri, 21 Aug 2020 06:16:11 -0700 (PDT) Received: from localhost.localdomain ([2001:1715:4e26:a7e0:116c:c27a:3e7f:5eaf]) by smtp.gmail.com with ESMTPSA id v4sm1299748eje.39.2020.08.21.06.16.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Aug 2020 06:16:11 -0700 (PDT) From: Jean-Philippe Brucker To: iommu@lists.linux-foundation.org, virtualization@lists.linux-foundation.org, virtio-dev@lists.oasis-open.org, linux-pci@vger.kernel.org Cc: joro@8bytes.org, bhelgaas@google.com, mst@redhat.com, jasowang@redhat.com, kevin.tian@intel.com, sebastien.boeuf@intel.com, eric.auger@redhat.com, lorenzo.pieralisi@arm.com, Jean-Philippe Brucker Subject: [PATCH v3 4/6] iommu/virtio: Add topology definitions Date: Fri, 21 Aug 2020 15:15:38 +0200 Message-Id: <20200821131540.2801801-5-jean-philippe@linaro.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200821131540.2801801-1-jean-philippe@linaro.org> References: <20200821131540.2801801-1-jean-philippe@linaro.org> MIME-Version: 1.0 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Add struct definitions for describing endpoints managed by the virtio-iommu. When VIRTIO_IOMMU_F_TOPOLOGY is offered, an array of virtio_iommu_topo_* structures in config space describes the endpoints, identified either by their PCI BDF or their physical MMIO address. Signed-off-by: Jean-Philippe Brucker Reviewed-by: Eric Auger --- include/uapi/linux/virtio_iommu.h | 44 +++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/include/uapi/linux/virtio_iommu.h b/include/uapi/linux/virtio_iommu.h index 237e36a280cb..70cba30644d5 100644 --- a/include/uapi/linux/virtio_iommu.h +++ b/include/uapi/linux/virtio_iommu.h @@ -16,6 +16,7 @@ #define VIRTIO_IOMMU_F_BYPASS 3 #define VIRTIO_IOMMU_F_PROBE 4 #define VIRTIO_IOMMU_F_MMIO 5 +#define VIRTIO_IOMMU_F_TOPOLOGY 6 struct virtio_iommu_range_64 { __le64 start; @@ -27,6 +28,17 @@ struct virtio_iommu_range_32 { __le32 end; }; +struct virtio_iommu_topo_config { + /* Number of topology description structures */ + __le16 count; + /* + * Offset to the first topology description structure + * (virtio_iommu_topo_*) from the start of the virtio_iommu config + * space. Aligned on 8 bytes. + */ + __le16 offset; +}; + struct virtio_iommu_config { /* Supported page sizes */ __le64 page_size_mask; @@ -36,6 +48,38 @@ struct virtio_iommu_config { struct virtio_iommu_range_32 domain_range; /* Probe buffer size */ __le32 probe_size; + struct virtio_iommu_topo_config topo_config; +}; + +#define VIRTIO_IOMMU_TOPO_PCI_RANGE 0x1 +#define VIRTIO_IOMMU_TOPO_MMIO 0x2 + +struct virtio_iommu_topo_pci_range { + /* VIRTIO_IOMMU_TOPO_PCI_RANGE */ + __u8 type; + __u8 reserved; + /* Length of this structure */ + __le16 length; + /* First endpoint ID in the range */ + __le32 endpoint_start; + /* PCI domain number */ + __le16 segment; + /* PCI Bus:Device.Function range */ + __le16 bdf_start; + __le16 bdf_end; + __le16 padding; +}; + +struct virtio_iommu_topo_mmio { + /* VIRTIO_IOMMU_TOPO_MMIO */ + __u8 type; + __u8 reserved; + /* Length of this structure */ + __le16 length; + /* Endpoint ID */ + __le32 endpoint; + /* Address of the first MMIO region */ + __le64 address; }; /* Request types */ From patchwork Fri Aug 21 13:15:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 1349241 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=linux-pci-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=N+lXLh4H; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4BY28r1sRDz9sPB for ; Fri, 21 Aug 2020 23:16:28 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728750AbgHUNQ1 (ORCPT ); Fri, 21 Aug 2020 09:16:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32942 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728755AbgHUNQQ (ORCPT ); Fri, 21 Aug 2020 09:16:16 -0400 Received: from mail-ed1-x542.google.com (mail-ed1-x542.google.com [IPv6:2a00:1450:4864:20::542]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 64F21C06138B for ; Fri, 21 Aug 2020 06:16:14 -0700 (PDT) Received: by mail-ed1-x542.google.com with SMTP id w14so889388eds.0 for ; Fri, 21 Aug 2020 06:16:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=NxlhAJ1KOAer/ks+xcHyw//iJAXespq5AefJ6dSktes=; b=N+lXLh4HfaQ0PykHmJWAY0wIFAYXmf/kkyLxM6n+tR4lng3Wep0f01oGUHkb3cVCKf gFYq/d+EjZ+hkllmQv9OYJ4Rf39hAngnL69AsRS5PXRNowVzwZ7PLFDUw0C/0W89lqgA BCIm4CBQFIEAxT5+ERAEH6aCBuytNmJtF1ppIsUMzlQZs0XJ0IZpiduM9cW3MT9h5oUC ZmvnjVz4bUwMBR9lKVv5+QrmR9q/q2yMOGYf1NTWWZhWCbU6T7Ln0iMpaG/luqAZE2Fk 6TTvwj1S+mcCYqM9wYawQ3inV9lJ1qqimzG9Po1gngxKQYiECEmXLXQctrXj+WSTwDPK eVfA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=NxlhAJ1KOAer/ks+xcHyw//iJAXespq5AefJ6dSktes=; b=kNHacgQ2TOCv1aFl3j5V1Oal7eMzTOcOdz34cXcN2auWp4jppOj7x5J5cT9FpY30Po VtODrD77Xor5WNtGfkBA8y9JP7KDOW7sDXZXNOrBx42pU3oXdTBkLtyLf0Zs6SvRUNrP PcUXP/0gBrZye4IPcDWbCUyzmP2srtM859eX4P6qDR1HUrEfgEejSl8FzIFtfMvP6970 qevTVQyRit5zVsEjOP9ET1k4O0UAQY/VG3zfXu+0OdwPKGZT8AvNZo5vtGup/Fh8kqFm 5l4Op+Cr16/UPJ3Q0RenkOngirY6Tjhg82lX/d/dh8MEMc6joRUBs6JaToIjj/Og3tAG Guow== X-Gm-Message-State: AOAM533VOrrcna2Emoy7VYmkEUoUE8IL1kJBRBxpapTwSDflXV7LmccP +77n+bz/QZNYZrSNCyWf6hvQQA== X-Google-Smtp-Source: ABdhPJyZPNka7zmqI+7SgdHXEjXp0y2ZbjsHxMhgluktwq4n/jUSPkWoqJlR0OsXxAp22OOeuv0G3A== X-Received: by 2002:aa7:c1ca:: with SMTP id d10mr2750322edp.261.1598015772958; Fri, 21 Aug 2020 06:16:12 -0700 (PDT) Received: from localhost.localdomain ([2001:1715:4e26:a7e0:116c:c27a:3e7f:5eaf]) by smtp.gmail.com with ESMTPSA id v4sm1299748eje.39.2020.08.21.06.16.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Aug 2020 06:16:12 -0700 (PDT) From: Jean-Philippe Brucker To: iommu@lists.linux-foundation.org, virtualization@lists.linux-foundation.org, virtio-dev@lists.oasis-open.org, linux-pci@vger.kernel.org Cc: joro@8bytes.org, bhelgaas@google.com, mst@redhat.com, jasowang@redhat.com, kevin.tian@intel.com, sebastien.boeuf@intel.com, eric.auger@redhat.com, lorenzo.pieralisi@arm.com, Jean-Philippe Brucker Subject: [PATCH v3 5/6] iommu/virtio: Support topology description in config space Date: Fri, 21 Aug 2020 15:15:39 +0200 Message-Id: <20200821131540.2801801-6-jean-philippe@linaro.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200821131540.2801801-1-jean-philippe@linaro.org> References: <20200821131540.2801801-1-jean-philippe@linaro.org> MIME-Version: 1.0 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Platforms without device-tree nor ACPI can provide a topology description embedded into the virtio config space. Parse it. Use PCI FIXUP to probe the config space early, because we need to discover the topology before any DMA configuration takes place, and the virtio driver may be loaded much later. Since we discover the topology description when probing the PCI hierarchy, the virtual IOMMU cannot manage other platform devices discovered earlier. Signed-off-by: Jean-Philippe Brucker Reviewed-by: Eric Auger --- drivers/iommu/Kconfig | 12 ++ drivers/iommu/virtio/Makefile | 1 + drivers/iommu/virtio/topology.c | 259 ++++++++++++++++++++++++++++++++ 3 files changed, 272 insertions(+) create mode 100644 drivers/iommu/virtio/topology.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index e29ae50f7100..98d28fdbc19a 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -394,4 +394,16 @@ config VIRTIO_IOMMU config VIRTIO_IOMMU_TOPOLOGY_HELPERS bool +config VIRTIO_IOMMU_TOPOLOGY + bool "Handle topology properties from the virtio-iommu" + depends on VIRTIO_IOMMU + depends on PCI + default y + select VIRTIO_IOMMU_TOPOLOGY_HELPERS + help + Enable early probing of virtio-iommu devices to detect the built-in + topology description. + + Say Y here if you intend to run this kernel as a guest. + endif # IOMMU_SUPPORT diff --git a/drivers/iommu/virtio/Makefile b/drivers/iommu/virtio/Makefile index b42ad47eac7e..1eda8ca1cbbf 100644 --- a/drivers/iommu/virtio/Makefile +++ b/drivers/iommu/virtio/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_VIRTIO_IOMMU) += virtio-iommu.o +obj-$(CONFIG_VIRTIO_IOMMU_TOPOLOGY) += topology.o obj-$(CONFIG_VIRTIO_IOMMU_TOPOLOGY_HELPERS) += topology-helpers.o diff --git a/drivers/iommu/virtio/topology.c b/drivers/iommu/virtio/topology.c new file mode 100644 index 000000000000..4923eec618b9 --- /dev/null +++ b/drivers/iommu/virtio/topology.c @@ -0,0 +1,259 @@ +// SPDX-License-Identifier: GPL-2.0 +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "topology-helpers.h" + +struct viommu_cap_config { + u8 bar; + u32 length; /* structure size */ + u32 offset; /* structure offset within the bar */ +}; + +struct viommu_topo_header { + u8 type; + u8 reserved; + u16 length; +}; + +static struct virt_topo_endpoint * +viommu_parse_node(void __iomem *buf, size_t len) +{ + int ret = -EINVAL; + union { + struct viommu_topo_header hdr; + struct virtio_iommu_topo_pci_range pci; + struct virtio_iommu_topo_mmio mmio; + } __iomem *cfg = buf; + struct virt_topo_endpoint *spec; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (!spec) + return ERR_PTR(-ENOMEM); + + switch (ioread8(&cfg->hdr.type)) { + case VIRTIO_IOMMU_TOPO_PCI_RANGE: + if (len < sizeof(cfg->pci)) + goto err_free; + + spec->dev_id.type = VIRT_TOPO_DEV_TYPE_PCI; + spec->dev_id.segment = ioread16(&cfg->pci.segment); + spec->dev_id.bdf_start = ioread16(&cfg->pci.bdf_start); + spec->dev_id.bdf_end = ioread16(&cfg->pci.bdf_end); + spec->endpoint_id = ioread32(&cfg->pci.endpoint_start); + break; + case VIRTIO_IOMMU_TOPO_MMIO: + if (len < sizeof(cfg->mmio)) + goto err_free; + + spec->dev_id.type = VIRT_TOPO_DEV_TYPE_MMIO; + spec->dev_id.base = ioread64(&cfg->mmio.address); + spec->endpoint_id = ioread32(&cfg->mmio.endpoint); + break; + default: + pr_warn("unhandled format 0x%x\n", ioread8(&cfg->hdr.type)); + ret = 0; + goto err_free; + } + return spec; + +err_free: + kfree(spec); + return ERR_PTR(ret); +} + +static int viommu_parse_topology(struct device *dev, + struct virtio_iommu_config __iomem *cfg, + size_t max_len) +{ + int ret; + u16 len; + size_t i; + LIST_HEAD(endpoints); + size_t offset, count; + struct virt_topo_iommu *viommu; + struct virt_topo_endpoint *ep, *next; + struct viommu_topo_header __iomem *cur; + + offset = ioread16(&cfg->topo_config.offset); + count = ioread16(&cfg->topo_config.count); + if (!offset || !count) + return 0; + + viommu = kzalloc(sizeof(*viommu), GFP_KERNEL); + if (!viommu) + return -ENOMEM; + + viommu->dev = dev; + + for (i = 0; i < count; i++, offset += len) { + if (offset + sizeof(*cur) > max_len) { + ret = -EOVERFLOW; + goto err_free; + } + + cur = (void __iomem *)cfg + offset; + len = ioread16(&cur->length); + if (offset + len > max_len) { + ret = -EOVERFLOW; + goto err_free; + } + + ep = viommu_parse_node((void __iomem *)cur, len); + if (!ep) { + continue; + } else if (IS_ERR(ep)) { + ret = PTR_ERR(ep); + goto err_free; + } + + ep->viommu = viommu; + list_add(&ep->list, &endpoints); + } + + list_for_each_entry_safe(ep, next, &endpoints, list) + /* Moves ep to the helpers list */ + virt_topo_add_endpoint(ep); + virt_topo_add_iommu(viommu); + + return 0; +err_free: + list_for_each_entry_safe(ep, next, &endpoints, list) + kfree(ep); + kfree(viommu); + return ret; +} + +#define VPCI_FIELD(field) offsetof(struct virtio_pci_cap, field) + +static inline int viommu_pci_find_capability(struct pci_dev *dev, u8 cfg_type, + struct viommu_cap_config *cap) +{ + int pos; + u8 bar; + + for (pos = pci_find_capability(dev, PCI_CAP_ID_VNDR); + pos > 0; + pos = pci_find_next_capability(dev, pos, PCI_CAP_ID_VNDR)) { + u8 type; + + pci_read_config_byte(dev, pos + VPCI_FIELD(cfg_type), &type); + if (type != cfg_type) + continue; + + pci_read_config_byte(dev, pos + VPCI_FIELD(bar), &bar); + + /* Ignore structures with reserved BAR values */ + if (type != VIRTIO_PCI_CAP_PCI_CFG && bar > 0x5) + continue; + + cap->bar = bar; + pci_read_config_dword(dev, pos + VPCI_FIELD(length), + &cap->length); + pci_read_config_dword(dev, pos + VPCI_FIELD(offset), + &cap->offset); + + return pos; + } + return 0; +} + +static int viommu_pci_reset(struct virtio_pci_common_cfg __iomem *cfg) +{ + u8 status; + ktime_t timeout = ktime_add_ms(ktime_get(), 100); + + iowrite8(0, &cfg->device_status); + while ((status = ioread8(&cfg->device_status)) != 0 && + ktime_before(ktime_get(), timeout)) + msleep(1); + + return status ? -ETIMEDOUT : 0; +} + +static void viommu_pci_parse_topology(struct pci_dev *dev) +{ + int ret; + u32 features; + void __iomem *regs, *common_regs; + struct viommu_cap_config cap = {0}; + struct virtio_pci_common_cfg __iomem *common_cfg; + + /* + * The virtio infrastructure might not be loaded at this point. We need + * to access the BARs ourselves. + */ + ret = viommu_pci_find_capability(dev, VIRTIO_PCI_CAP_COMMON_CFG, &cap); + if (!ret) { + pci_warn(dev, "common capability not found\n"); + return; + } + + if (pci_enable_device_mem(dev)) + return; + + common_regs = pci_iomap(dev, cap.bar, 0); + if (!common_regs) + return; + + common_cfg = common_regs + cap.offset; + + /* Perform the init sequence before we can read the config */ + ret = viommu_pci_reset(common_cfg); + if (ret < 0) { + pci_warn(dev, "unable to reset device\n"); + goto out_unmap_common; + } + + iowrite8(VIRTIO_CONFIG_S_ACKNOWLEDGE, &common_cfg->device_status); + iowrite8(VIRTIO_CONFIG_S_ACKNOWLEDGE | VIRTIO_CONFIG_S_DRIVER, + &common_cfg->device_status); + + /* Find out if the device supports topology description */ + iowrite32(0, &common_cfg->device_feature_select); + features = ioread32(&common_cfg->device_feature); + + if (!(features & BIT(VIRTIO_IOMMU_F_TOPOLOGY))) { + pci_dbg(dev, "device doesn't have topology description"); + goto out_reset; + } + + ret = viommu_pci_find_capability(dev, VIRTIO_PCI_CAP_DEVICE_CFG, &cap); + if (!ret) { + pci_warn(dev, "device config capability not found\n"); + goto out_reset; + } + + regs = pci_iomap(dev, cap.bar, 0); + if (!regs) + goto out_reset; + + pci_info(dev, "parsing virtio-iommu topology\n"); + ret = viommu_parse_topology(&dev->dev, regs + cap.offset, + pci_resource_len(dev, 0) - cap.offset); + if (ret) + pci_warn(dev, "failed to parse topology: %d\n", ret); + + pci_iounmap(dev, regs); +out_reset: + ret = viommu_pci_reset(common_cfg); + if (ret) + pci_warn(dev, "unable to reset device\n"); +out_unmap_common: + pci_iounmap(dev, common_regs); +} + +/* + * Catch a PCI virtio-iommu implementation early to get the topology description + * before we start probing other endpoints. + */ +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_REDHAT_QUMRANET, 0x1040 + VIRTIO_ID_IOMMU, + viommu_pci_parse_topology); From patchwork Fri Aug 21 13:15:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 1349242 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=linux-pci-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=pY2YbYHS; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4BY28s2Yrdz9sR4 for ; Fri, 21 Aug 2020 23:16:29 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728755AbgHUNQ2 (ORCPT ); Fri, 21 Aug 2020 09:16:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32948 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728756AbgHUNQR (ORCPT ); Fri, 21 Aug 2020 09:16:17 -0400 Received: from mail-ej1-x642.google.com (mail-ej1-x642.google.com [IPv6:2a00:1450:4864:20::642]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 952C4C061342 for ; Fri, 21 Aug 2020 06:16:15 -0700 (PDT) Received: by mail-ej1-x642.google.com with SMTP id m22so2209082eje.10 for ; Fri, 21 Aug 2020 06:16:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ZnnZtMxmP4b7OMlDsIV6bQJbOj4fdGL8aaL1hhmjLLA=; b=pY2YbYHS5mikDdweoT7I0A6q9uT3ometn8FGbkCmiALLLRBZ7T5CUUIzOPSzePumsr 5nVU/Of+D1O09VPiw+V19VBWqEeiR+ed6F2FuDNqj5OXZVpR1r7CKaXoH8BU2TGA//Mk REi4qfELDk/LPFv51pecAc0wLz0sjnbltg48c2UZ6oEGqEddU0eeHvEiktKMfM8CrXAR 24BjGg9QPwJCXtKW16GNd3wBjTWgXDlouU7YYfmHXPSVH2UUgSKlFi6UCokoDcksLjeF CK67SeJGYmClge7RphPcpwaKaSeXvKeSAqpLlgFvQ5ACoV5W0wlnksDr2TVEpp4Owz1b j69Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ZnnZtMxmP4b7OMlDsIV6bQJbOj4fdGL8aaL1hhmjLLA=; b=Co9qGe6xx768mBmH4mzUNjW4T059FMWIxrVJnfgNY1IgWIHXr6/z8ZCcQojQlx99+T ktt00KlwmGoBgYnJrlf2O/WnTdrQkus+epHEwck3AfkQ0xW5GerxppZ8V8ikuyL7/sW0 wndciND7iTDZtEs1Nj/FmL+tIzDmDcCOZImXs4wVImyDFf6nJv7a9cl6qBDArhcjmgra aCBi0N3VOjOINkViqFOT9SMf79wXRyjekPlmmK9JjSItN3gYyVNTry1GwB9mbwhrwLOg prQBWa1edmAu9bQCAoW5lYI2MYNmjvjZpvDfIDIO6CHCjSVLPghpZJOQabswvP/xdP7r c5EQ== X-Gm-Message-State: AOAM530BSfUpffUBu0HPJ8xQYWyjsABSN2y2x/uhvyEoQCzUDW2A1LIe GGIBQRDXb4LjM97HF4D4K9JXHA== X-Google-Smtp-Source: ABdhPJzPzKZv0XqkxFhftdpeIsh87fWGpOtYot+rgSUcL/9LlvBX6pXEuFdZEBC/z0H9ehxzTOYJaw== X-Received: by 2002:a17:906:e17:: with SMTP id l23mr2725404eji.13.1598015774044; Fri, 21 Aug 2020 06:16:14 -0700 (PDT) Received: from localhost.localdomain ([2001:1715:4e26:a7e0:116c:c27a:3e7f:5eaf]) by smtp.gmail.com with ESMTPSA id v4sm1299748eje.39.2020.08.21.06.16.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Aug 2020 06:16:13 -0700 (PDT) From: Jean-Philippe Brucker To: iommu@lists.linux-foundation.org, virtualization@lists.linux-foundation.org, virtio-dev@lists.oasis-open.org, linux-pci@vger.kernel.org Cc: joro@8bytes.org, bhelgaas@google.com, mst@redhat.com, jasowang@redhat.com, kevin.tian@intel.com, sebastien.boeuf@intel.com, eric.auger@redhat.com, lorenzo.pieralisi@arm.com, Jean-Philippe Brucker Subject: [PATCH v3 6/6] iommu/virtio: Enable x86 support Date: Fri, 21 Aug 2020 15:15:40 +0200 Message-Id: <20200821131540.2801801-7-jean-philippe@linaro.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200821131540.2801801-1-jean-philippe@linaro.org> References: <20200821131540.2801801-1-jean-philippe@linaro.org> MIME-Version: 1.0 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org With the built-in topology description in place, x86 platforms can now use the virtio-iommu. Architectures that use the generic iommu_dma_ops should normally select CONFIG_IOMMU_DMA themselves (from arch/*/Kconfig). Since not all x86 drivers have been converted yet, it's currently up to the IOMMU Kconfig to select it. Signed-off-by: Jean-Philippe Brucker --- drivers/iommu/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index 98d28fdbc19a..d7cf158745eb 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -383,8 +383,9 @@ config HYPERV_IOMMU config VIRTIO_IOMMU tristate "Virtio IOMMU driver" depends on VIRTIO - depends on ARM64 + depends on (ARM64 || X86) select IOMMU_API + select IOMMU_DMA if X86 select INTERVAL_TREE help Para-virtualised IOMMU driver with virtio.