From patchwork Mon Aug 26 17:56:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 13778315 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (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 08982C5472D for ; Mon, 26 Aug 2024 17:57:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc: To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=nJ23+pLVcV1YLo+DOWiwMwlffZaSUayxfrEBlEY2X7Q=; b=ntiftJS86t7p95vKbUz5sWVpZD uiT3BJwWJIhZ/4AiV9G0N5NofIdNeJ4z6Gt2zHbjpwgaIqpZTT1HVfMrlcxdlIpnvI5qNXTK5cLI3 fC110kTrkE/Bla2kaciJtb17+RgNe/yX8Il15YZYFFVN/MCTrkAp/W7W3EiGkvU9d1+dGDuxG/Mbz h7A7mVuBFH4kX0epJcZh48IY+h+ZK2O8Kpo/e4ZCaN7qa4b3HitrzlnZiCgYB6csowG5SDd99ab/H DQHBtEizbnek1FkskT8KZLN4ccRVocK+NSVxc+4yxvr0S1nzsB1NowwSpAC7hd4FVmiYhdQPcpdXB ZNEhK5sA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sidxi-00000008Id5-2YUh; Mon, 26 Aug 2024 17:57:06 +0000 Received: from mta-64-225.siemens.flowmailer.net ([185.136.64.225]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sidwu-00000008IQA-0Rba for linux-arm-kernel@lists.infradead.org; Mon, 26 Aug 2024 17:56:18 +0000 Received: by mta-64-225.siemens.flowmailer.net with ESMTPSA id 20240826175613ddd5b81a7646d80b63 for ; Mon, 26 Aug 2024 19:56:13 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=fm1; d=siemens.com; i=jan.kiszka@siemens.com; h=Date:From:Subject:To:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Cc:References:In-Reply-To; bh=nJ23+pLVcV1YLo+DOWiwMwlffZaSUayxfrEBlEY2X7Q=; b=dJkgaW0PBZXN/y8k+iuFJc0yTOju9G/gxH7wkruIh2Ga3nV6YvwGcEeblSIBw280kpbDtX FGbP3hQ5DGgawv1OklhtQiA3drCIk6WxbW0ITbCvQVo9aUhBgAF4knwd+eqm9eb1etnZPeNg tSdjibjht/bCHkE8Iylh2b95n4gqI5qHcUhafqGAXijt/SB1EhwM7e+6da6X1A8c1DnjRkZR 2u7FoOtvHj5mIdx7GNANFUzjmlvy1vEcLu5YeIyFlPnDJndYkPjOU0bcR0CI8g/Ze0KnCzo6 NxfczY11O0Fe1P4r+k+SCjp9A/bw4Z8jC50F8cw68s8zFyVwDQ2FOdvg==; From: Jan Kiszka To: Nishanth Menon , Santosh Shilimkar , Vignesh Raghavendra , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Siddharth Vadapalli , Bao Cheng Su , Hua Qian Li , Diogo Ivo , Lorenzo Pieralisi , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , Bjorn Helgaas , linux-pci@vger.kernel.org Subject: [PATCH 4/5] PCI: keystone: Add supported for PVU-based DMA isolation on AM654 Date: Mon, 26 Aug 2024 19:56:08 +0200 Message-ID: <3a41969d3f3af044fbde04c9314e9644c833451c.1724694969.git.jan.kiszka@siemens.com> In-Reply-To: References: MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-294854:519-21489:flowmailer X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240826_105616_697766_D7544D5F X-CRM114-Status: GOOD ( 20.74 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Jan Kiszka The AM654 lacks an IOMMU, thus does not support isolating DMA requests from untrusted PCI devices to selected memory regions this way. Use static PVU-based protection instead. For this, we use the availability of restricted-dma-pool memory regions as trigger and register those as valid DMA targets with the PVU. In addition, we need to enable the mapping of requester IDs to VirtIDs in the PCI RC. We only use a single VirtID so far, catching all devices. This may be extended later on. Signed-off-by: Jan Kiszka --- CC: Lorenzo Pieralisi CC: "Krzysztof WilczyƄski" CC: Bjorn Helgaas CC: linux-pci@vger.kernel.org --- drivers/pci/controller/dwc/pci-keystone.c | 101 ++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c index 2219b1a866fa..96b871656da4 100644 --- a/drivers/pci/controller/dwc/pci-keystone.c +++ b/drivers/pci/controller/dwc/pci-keystone.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -26,6 +27,7 @@ #include #include #include +#include #include "../../pci.h" #include "pcie-designware.h" @@ -111,6 +113,16 @@ #define PCI_DEVICE_ID_TI_AM654X 0xb00c +#define KS_PCI_VIRTID 0 + +#define PCIE_VMAP_xP_CTRL 0x0 +#define PCIE_VMAP_xP_REQID 0x4 +#define PCIE_VMAP_xP_VIRTID 0x8 + +#define PCIE_VMAP_xP_CTRL_EN BIT(0) + +#define PCIE_VMAP_xP_VIRTID_VID_MASK 0xfff + struct ks_pcie_of_data { enum dw_pcie_device_mode mode; const struct dw_pcie_host_ops *host_ops; @@ -1125,6 +1137,89 @@ static const struct of_device_id ks_pcie_of_match[] = { { }, }; +#ifdef CONFIG_TI_PVU +static const char *ks_vmap_res[] = {"vmap_lp", "vmap_hp"}; + +static int ks_init_restricted_dma(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct of_phandle_iterator it; + bool init_vmap = false; + struct resource phys; + struct resource *res; + void __iomem *base; + unsigned int n; + u32 val; + int err; + + of_for_each_phandle(&it, err, dev->of_node, "memory-region", + NULL, 0) { + if (!of_device_is_compatible(it.node, "restricted-dma-pool")) + continue; + + err = of_address_to_resource(it.node, 0, &phys); + if (err < 0) { + dev_err(dev, "failed to parse memory region %pOF: %d\n", + it.node, err); + continue; + } + + err = ti_pvu_create_region(KS_PCI_VIRTID, &phys); + if (err < 0) + return err; + + init_vmap = true; + } + + if (init_vmap) { + for (n = 0; n < ARRAY_SIZE(ks_vmap_res); n++) { + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + ks_vmap_res[n]); + base = devm_pci_remap_cfg_resource(dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + writel(0, base + PCIE_VMAP_xP_REQID); + + val = readl(base + PCIE_VMAP_xP_VIRTID); + val &= ~PCIE_VMAP_xP_VIRTID_VID_MASK; + val |= KS_PCI_VIRTID; + writel(val, base + PCIE_VMAP_xP_VIRTID); + + val = readl(base + PCIE_VMAP_xP_CTRL); + val |= PCIE_VMAP_xP_CTRL_EN; + writel(val, base + PCIE_VMAP_xP_CTRL); + } + } + + return 0; +} + +static void ks_release_restricted_dma(struct platform_device *pdev) +{ + struct of_phandle_iterator it; + struct resource phys; + int err; + + of_for_each_phandle(&it, err, pdev->dev.of_node, "memory-region", + NULL, 0) { + if (of_device_is_compatible(it.node, "restricted-dma-pool") && + of_address_to_resource(it.node, 0, &phys) == 0) + ti_pvu_remove_region(KS_PCI_VIRTID, &phys); + + } +} +#else +static inline int ks_init_restricted_dma(struct platform_device *pdev) +{ + return 0; +} + +static inline void ks_release_restricted_dma(struct platform_device *pdev) +{ +} +#endif + static int ks_pcie_probe(struct platform_device *pdev) { const struct dw_pcie_host_ops *host_ops; @@ -1273,6 +1368,10 @@ static int ks_pcie_probe(struct platform_device *pdev) if (ret < 0) goto err_get_sync; + ret = ks_init_restricted_dma(pdev); + if (ret < 0) + goto err_get_sync; + switch (mode) { case DW_PCIE_RC_TYPE: if (!IS_ENABLED(CONFIG_PCI_KEYSTONE_HOST)) { @@ -1354,6 +1453,8 @@ static void ks_pcie_remove(struct platform_device *pdev) int num_lanes = ks_pcie->num_lanes; struct device *dev = &pdev->dev; + ks_release_restricted_dma(pdev); + pm_runtime_put(dev); pm_runtime_disable(dev); ks_pcie_disable_phy(ks_pcie);