From patchwork Mon Jan 20 21:53:51 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Herrmann X-Patchwork-Id: 3514691 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id B53B7C02DC for ; Mon, 20 Jan 2014 21:54:33 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CD3C92015A for ; Mon, 20 Jan 2014 21:54:32 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C4E8320122 for ; Mon, 20 Jan 2014 21:54:31 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1W5Mnb-0000BK-Kt; Mon, 20 Jan 2014 21:54:27 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1W5MnZ-0004hm-CM; Mon, 20 Jan 2014 21:54:25 +0000 Received: from smtp113.iad3a.emailsrvr.com ([173.203.187.113]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1W5MnW-0004gi-T3 for linux-arm-kernel@lists.infradead.org; Mon, 20 Jan 2014 21:54:23 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp15.relay.iad3a.emailsrvr.com (SMTP Server) with ESMTP id B1FF4400BA; Mon, 20 Jan 2014 16:53:56 -0500 (EST) X-Virus-Scanned: OK Received: by smtp15.relay.iad3a.emailsrvr.com (Authenticated sender: andreas.herrmann-AT-calxeda.com) with ESMTPSA id A19AA400B0; Mon, 20 Jan 2014 16:53:54 -0500 (EST) Date: Mon, 20 Jan 2014 22:53:51 +0100 From: Andreas Herrmann To: Will Deacon Subject: [PATCH v2 02/11] iommu/arm-smmu: Introduce iommu_group notifier block Message-ID: <20140120215351.GG3471@alberich> References: <1389876263-25759-1-git-send-email-andreas.herrmann@calxeda.com> <1389876263-25759-3-git-send-email-andreas.herrmann@calxeda.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <1389876263-25759-3-git-send-email-andreas.herrmann@calxeda.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140120_165422_974534_3F22923A X-CRM114-Status: GOOD ( 16.74 ) X-Spam-Score: -1.9 (-) Cc: "iommu@lists.linux-foundation.org" , Andreas Herrmann , "linux-arm-kernel@lists.infradead.org" X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.8 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP At the moment just handle BUS_NOTIFY_BIND_DRIVER to conditionally isolate all master devices for an SMMU. Depending on DT information each device is put into its own protection domain (if possible). For configuration with one or just a few masters per SMMU that is easy to achieve. In case of many devices per SMMU (e.g. MMU-500 with it's distributed translation support) isolation of each device might not be possible -- depending on number of available SMR groups and/or context banks. Default is that device isolation is contolled per SMMU with SMMU node property "arm,smmu-isolate-devices" in a DT. If this property is set for an SMMU node, device isolation is performed. W/o device isolation the driver detects SMMUs but no translation is configured (transactions just bypass translation process). Note that for device isolation dma_base and size are fixed as 0 and SZ_128M at the moment. Additional patches will address this restriction and allow automatic growth of mapping size. Cc: Varun Sethi Cc: Andreas Herrmann Signed-off-by: Andreas Herrmann --- drivers/iommu/arm-smmu.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) Hi Will, This new patch addresses Varun's comments: - use iommu_group notifier instead of bus notifier - remove superfluous call to arm_smmu_add_device in notifier function This patch depends on commit "iommu/arm-smmu: add devices attached to the SMMU to an IOMMU group" as found in your git tree (e.g. in branch iommu/devel or for-joerg/arm-smmu/updates). Andreas diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 0a5649f..edd0ffb 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -46,6 +46,7 @@ #include #include +#include /* Driver options */ #define ARM_SMMU_OPT_ISOLATE_DEVICES (1 << 0) @@ -402,6 +403,13 @@ struct arm_smmu_domain { static DEFINE_SPINLOCK(arm_smmu_devices_lock); static LIST_HEAD(arm_smmu_devices); +static int arm_smmu_group_notifier(struct notifier_block *nb, + unsigned long action, void *data); + +static struct notifier_block group_nb = { + .notifier_call = arm_smmu_group_notifier, +}; + struct arm_smmu_option_prop { u32 opt; const char *prop; @@ -1566,6 +1574,8 @@ static int arm_smmu_add_device(struct device *dev) return PTR_ERR(group); } + iommu_group_register_notifier(group, &group_nb); + ret = iommu_group_add_device(group, dev); iommu_group_put(group); dev->archdata.iommu = smmu; @@ -1981,6 +1991,43 @@ static int arm_smmu_device_remove(struct platform_device *pdev) return 0; } +static int arm_smmu_group_notifier(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct device *dev = data; + struct dma_iommu_mapping *mapping; + struct arm_smmu_device *smmu; + int ret; + + switch (action) { + case BUS_NOTIFY_BIND_DRIVER: + + smmu = dev->archdata.iommu; + if (!smmu || !(smmu->options & ARM_SMMU_OPT_ISOLATE_DEVICES)) + break; + + mapping = arm_iommu_create_mapping(&platform_bus_type, + 0, SZ_128M, 0); + if (IS_ERR(mapping)) { + ret = PTR_ERR(mapping); + dev_info(dev, "arm_iommu_create_mapping failed\n"); + break; + } + + ret = arm_iommu_attach_device(dev, mapping); + if (ret < 0) { + dev_info(dev, "arm_iommu_attach_device failed\n"); + arm_iommu_release_mapping(mapping); + } + + break; + default: + break; + } + + return 0; +} + #ifdef CONFIG_OF static struct of_device_id arm_smmu_of_match[] = { { .compatible = "arm,smmu-v1", },