From patchwork Tue Jan 26 22:58:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefano Stabellini X-Patchwork-Id: 12048573 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.3 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7DDEFC433DB for ; Tue, 26 Jan 2021 22:58:48 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 3FDBF2065C for ; Tue, 26 Jan 2021 22:58:48 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3FDBF2065C Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from list by lists.xenproject.org with outflank-mailman.75651.136258 (Exim 4.92) (envelope-from ) id 1l4XIG-0003iu-TV; Tue, 26 Jan 2021 22:58:40 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 75651.136258; Tue, 26 Jan 2021 22:58:40 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1l4XIG-0003in-Q2; Tue, 26 Jan 2021 22:58:40 +0000 Received: by outflank-mailman (input) for mailman id 75651; Tue, 26 Jan 2021 22:58:40 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1l4XIG-0003iY-9C for xen-devel@lists.xenproject.org; Tue, 26 Jan 2021 22:58:40 +0000 Received: from mail.kernel.org (unknown [198.145.29.99]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 6d930bfd-3ef4-4617-ada3-9a6cd5293c4b; Tue, 26 Jan 2021 22:58:39 +0000 (UTC) Received: by mail.kernel.org (Postfix) with ESMTPSA id 8F9622065C; Tue, 26 Jan 2021 22:58:38 +0000 (UTC) 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: 6d930bfd-3ef4-4617-ada3-9a6cd5293c4b DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1611701919; bh=X5JwX3pfbATTkWyuOF19GDXGj+hGTzEcnnjqPf/w56M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HBc15wq/Cc7HuYSUCxmZCh+vSR49F19odo6mrhOS0Dh2KMUNivcuYMWKk99rNBYOW OAzC6n9O7EZJox3L8/ik7NjoEsUDGx5+i9EfWkD6PEsmdYCv/s1nZPMR1aRZdkE6Jj mRQ6/8LsvxjgSDL7SnpgLYadGZ0vdASvSSD/TbiRFs9a9xWKlth/GpAL/UKeJHsPSe ZtMNjbIM6S/4TM8pV8FwzNG6t/POK4QPtd+bwCUsuUwkigqjzHEck3T3BfQ9EqVWCK psQnhFjr5cbO7FfYmqsK9h69hNUK2RXP1YV7bnzO+QoUiF1qOfDKMiD7Npa/k1q9vY CvGAfkriTR/wQ== From: Stefano Stabellini To: xen-devel@lists.xenproject.org Cc: sstabellini@kernel.org, julien@xen.org, Bertrand.Marquis@arm.com, Volodymyr_Babchuk@epam.com, rahul.singh@arm.com, brian.woods@xilinx.com, Stefano Stabellini Subject: [PATCH v3 1/3] arm,smmu: switch to using iommu_fwspec functions Date: Tue, 26 Jan 2021 14:58:34 -0800 Message-Id: <20210126225836.6017-1-sstabellini@kernel.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: References: From: Brian Woods Modify the smmu driver so that it uses the iommu_fwspec helper functions. This means both ARM IOMMU drivers will both use the iommu_fwspec helper functions, making enabling generic device tree bindings in the SMMU driver much cleaner. Signed-off-by: Brian Woods Signed-off-by: Stefano Stabellini Reviewed-by: Rahul Singh Tested-by: Rahul Singh --- Changes in v3: - add a comment in iommu_add_dt_device - don't allocate fwspec twice in arm_smmu_add_device - reuse existing fwspec pointer, don't add a second one - add comment about supporting fwspec at the top of the file --- xen/drivers/passthrough/arm/smmu.c | 98 ++++++++++++++++----------- xen/drivers/passthrough/device_tree.c | 7 ++ 2 files changed, 66 insertions(+), 39 deletions(-) diff --git a/xen/drivers/passthrough/arm/smmu.c b/xen/drivers/passthrough/arm/smmu.c index 3e8aa37866..3898d1d737 100644 --- a/xen/drivers/passthrough/arm/smmu.c +++ b/xen/drivers/passthrough/arm/smmu.c @@ -32,6 +32,9 @@ * - 4k and 64k pages, with contiguous pte hints. * - Up to 48-bit addressing (dependent on VA_BITS) * - Context fault reporting + * + * Changes compared to Linux driver: + * - support for fwspec */ @@ -49,6 +52,7 @@ #include #include #include +#include #include /* Xen: The below defines are redefined within the file. Undef it */ @@ -302,9 +306,6 @@ static struct iommu_group *iommu_group_get(struct device *dev) /***** Start of Linux SMMU code *****/ -/* Maximum number of stream IDs assigned to a single device */ -#define MAX_MASTER_STREAMIDS MAX_PHANDLE_ARGS - /* Maximum number of context banks per SMMU */ #define ARM_SMMU_MAX_CBS 128 @@ -597,8 +598,6 @@ struct arm_smmu_smr { }; struct arm_smmu_master_cfg { - int num_streamids; - u16 streamids[MAX_MASTER_STREAMIDS]; struct arm_smmu_smr *smrs; }; @@ -686,6 +685,14 @@ static struct arm_smmu_option_prop arm_smmu_options[] = { { 0, NULL}, }; +static inline struct iommu_fwspec * +arm_smmu_get_fwspec(struct arm_smmu_master_cfg *cfg) +{ + struct arm_smmu_master *master = container_of(cfg, + struct arm_smmu_master, cfg); + return dev_iommu_fwspec_get(&master->of_node->dev); +} + static void parse_driver_options(struct arm_smmu_device *smmu) { int i = 0; @@ -779,8 +786,9 @@ static int register_smmu_master(struct arm_smmu_device *smmu, struct device *dev, struct of_phandle_args *masterspec) { - int i; + int i, ret = 0; struct arm_smmu_master *master; + struct iommu_fwspec *fwspec; master = find_smmu_master(smmu, masterspec->np); if (master) { @@ -790,34 +798,37 @@ static int register_smmu_master(struct arm_smmu_device *smmu, return -EBUSY; } - if (masterspec->args_count > MAX_MASTER_STREAMIDS) { - dev_err(dev, - "reached maximum number (%d) of stream IDs for master device %s\n", - MAX_MASTER_STREAMIDS, masterspec->np->name); - return -ENOSPC; - } - master = devm_kzalloc(dev, sizeof(*master), GFP_KERNEL); if (!master) return -ENOMEM; + master->of_node = masterspec->np; - master->of_node = masterspec->np; - master->cfg.num_streamids = masterspec->args_count; + ret = iommu_fwspec_init(&master->of_node->dev, smmu->dev); + if (ret) { + kfree(master); + return ret; + } + fwspec = dev_iommu_fwspec_get(dev); + + /* adding the ids here */ + ret = iommu_fwspec_add_ids(&masterspec->np->dev, + masterspec->args, + masterspec->args_count); + if (ret) + return ret; /* Xen: Let Xen know that the device is protected by an SMMU */ dt_device_set_protected(masterspec->np); - for (i = 0; i < master->cfg.num_streamids; ++i) { - u16 streamid = masterspec->args[i]; - - if (!(smmu->features & ARM_SMMU_FEAT_STREAM_MATCH) && - (streamid >= smmu->num_mapping_groups)) { - dev_err(dev, - "stream ID for master device %s greater than maximum allowed (%d)\n", - masterspec->np->name, smmu->num_mapping_groups); - return -ERANGE; + if (!(smmu->features & ARM_SMMU_FEAT_STREAM_MATCH)) { + for (i = 0; i < fwspec->num_ids; ++i) { + if (masterspec->args[i] >= smmu->num_mapping_groups) { + dev_err(dev, + "stream ID for master device %s greater than maximum allowed (%d)\n", + masterspec->np->name, smmu->num_mapping_groups); + return -ERANGE; + } } - master->cfg.streamids[i] = streamid; } return insert_smmu_master(smmu, master); } @@ -1390,6 +1401,7 @@ static int arm_smmu_master_configure_smrs(struct arm_smmu_device *smmu, int i; struct arm_smmu_smr *smrs; void __iomem *gr0_base = ARM_SMMU_GR0(smmu); + struct iommu_fwspec *fwspec = arm_smmu_get_fwspec(cfg); if (!(smmu->features & ARM_SMMU_FEAT_STREAM_MATCH)) return 0; @@ -1397,15 +1409,14 @@ static int arm_smmu_master_configure_smrs(struct arm_smmu_device *smmu, if (cfg->smrs) return -EEXIST; - smrs = kmalloc_array(cfg->num_streamids, sizeof(*smrs), GFP_KERNEL); + smrs = kmalloc_array(fwspec->num_ids, sizeof(*smrs), GFP_KERNEL); if (!smrs) { - dev_err(smmu->dev, "failed to allocate %d SMRs\n", - cfg->num_streamids); + dev_err(smmu->dev, "failed to allocate %d SMRs\n", fwspec->num_ids); return -ENOMEM; } /* Allocate the SMRs on the SMMU */ - for (i = 0; i < cfg->num_streamids; ++i) { + for (i = 0; i < fwspec->num_ids; ++i) { int idx = __arm_smmu_alloc_bitmap(smmu->smr_map, 0, smmu->num_mapping_groups); if (IS_ERR_VALUE(idx)) { @@ -1416,12 +1427,12 @@ static int arm_smmu_master_configure_smrs(struct arm_smmu_device *smmu, smrs[i] = (struct arm_smmu_smr) { .idx = idx, .mask = 0, /* We don't currently share SMRs */ - .id = cfg->streamids[i], + .id = fwspec->ids[i], }; } /* It worked! Now, poke the actual hardware */ - for (i = 0; i < cfg->num_streamids; ++i) { + for (i = 0; i < fwspec->num_ids; ++i) { u32 reg = SMR_VALID | smrs[i].id << SMR_ID_SHIFT | smrs[i].mask << SMR_MASK_SHIFT; writel_relaxed(reg, gr0_base + ARM_SMMU_GR0_SMR(smrs[i].idx)); @@ -1443,12 +1454,13 @@ static void arm_smmu_master_free_smrs(struct arm_smmu_device *smmu, int i; void __iomem *gr0_base = ARM_SMMU_GR0(smmu); struct arm_smmu_smr *smrs = cfg->smrs; + struct iommu_fwspec *fwspec = arm_smmu_get_fwspec(cfg); if (!smrs) return; /* Invalidate the SMRs before freeing back to the allocator */ - for (i = 0; i < cfg->num_streamids; ++i) { + for (i = 0; i < fwspec->num_ids; ++i) { u8 idx = smrs[i].idx; writel_relaxed(~SMR_VALID, gr0_base + ARM_SMMU_GR0_SMR(idx)); @@ -1465,16 +1477,17 @@ static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain, int i, ret; struct arm_smmu_device *smmu = smmu_domain->smmu; void __iomem *gr0_base = ARM_SMMU_GR0(smmu); + struct iommu_fwspec *fwspec = arm_smmu_get_fwspec(cfg); /* Devices in an IOMMU group may already be configured */ ret = arm_smmu_master_configure_smrs(smmu, cfg); if (ret) return ret == -EEXIST ? 0 : ret; - for (i = 0; i < cfg->num_streamids; ++i) { + for (i = 0; i < fwspec->num_ids; ++i) { u32 idx, s2cr; - idx = cfg->smrs ? cfg->smrs[i].idx : cfg->streamids[i]; + idx = cfg->smrs ? cfg->smrs[i].idx : fwspec->ids[i]; s2cr = S2CR_TYPE_TRANS | (smmu_domain->cfg.cbndx << S2CR_CBNDX_SHIFT); writel_relaxed(s2cr, gr0_base + ARM_SMMU_GR0_S2CR(idx)); @@ -1489,6 +1502,7 @@ static void arm_smmu_domain_remove_master(struct arm_smmu_domain *smmu_domain, int i; struct arm_smmu_device *smmu = smmu_domain->smmu; void __iomem *gr0_base = ARM_SMMU_GR0(smmu); + struct iommu_fwspec *fwspec = arm_smmu_get_fwspec(cfg); /* An IOMMU group is torn down by the first device to be removed */ if ((smmu->features & ARM_SMMU_FEAT_STREAM_MATCH) && !cfg->smrs) @@ -1499,8 +1513,8 @@ static void arm_smmu_domain_remove_master(struct arm_smmu_domain *smmu_domain, * that it can be re-allocated immediately. * Xen: Unlike Linux, any access to non-configured stream will fault. */ - for (i = 0; i < cfg->num_streamids; ++i) { - u32 idx = cfg->smrs ? cfg->smrs[i].idx : cfg->streamids[i]; + for (i = 0; i < fwspec->num_ids; ++i) { + u32 idx = cfg->smrs ? cfg->smrs[i].idx : fwspec->ids[i]; writel_relaxed(S2CR_TYPE_FAULT, gr0_base + ARM_SMMU_GR0_S2CR(idx)); @@ -1903,9 +1917,9 @@ static int arm_smmu_add_device(struct device *dev) struct arm_smmu_device *smmu; struct arm_smmu_master_cfg *cfg; struct iommu_group *group; + struct iommu_fwspec *fwspec; void (*releasefn)(void *) = NULL; int ret; - smmu = find_smmu_for_device(dev); if (!smmu) return -ENODEV; @@ -1925,13 +1939,19 @@ static int arm_smmu_add_device(struct device *dev) goto out_put_group; } - cfg->num_streamids = 1; + ret = iommu_fwspec_init(dev, smmu->dev); + if (ret) { + kfree(cfg); + goto out_put_group; + } + fwspec = dev_iommu_fwspec_get(dev); + /* * Assume Stream ID == Requester ID for now. * We need a way to describe the ID mappings in FDT. */ pci_for_each_dma_alias(pdev, __arm_smmu_get_pci_sid, - &cfg->streamids[0]); + &fwspec->ids[0]); releasefn = __arm_smmu_release_pci_iommudata; } else { struct arm_smmu_master *master; diff --git a/xen/drivers/passthrough/device_tree.c b/xen/drivers/passthrough/device_tree.c index 999b831d90..a51ae3c9c3 100644 --- a/xen/drivers/passthrough/device_tree.c +++ b/xen/drivers/passthrough/device_tree.c @@ -140,6 +140,13 @@ int iommu_add_dt_device(struct dt_device_node *np) if ( !ops ) return -EINVAL; + /* + * This is needed in case a device has both the iommus property and + * also apperars in the mmu-masters list. + */ + if ( dt_device_is_protected(np) ) + return 0; + if ( dev_iommu_fwspec_get(dev) ) return -EEXIST; From patchwork Tue Jan 26 22:58:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefano Stabellini X-Patchwork-Id: 12048571 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.3 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DE79BC433E6 for ; Tue, 26 Jan 2021 22:58:48 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 9ED952065C for ; Tue, 26 Jan 2021 22:58:48 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9ED952065C Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from list by lists.xenproject.org with outflank-mailman.75652.136271 (Exim 4.92) (envelope-from ) id 1l4XII-0003kp-4w; Tue, 26 Jan 2021 22:58:42 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 75652.136271; Tue, 26 Jan 2021 22:58:42 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1l4XII-0003ke-1i; Tue, 26 Jan 2021 22:58:42 +0000 Received: by outflank-mailman (input) for mailman id 75652; Tue, 26 Jan 2021 22:58:41 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1l4XIH-0003iw-23 for xen-devel@lists.xenproject.org; Tue, 26 Jan 2021 22:58:41 +0000 Received: from mail.kernel.org (unknown [198.145.29.99]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id f3734734-292e-4661-8063-0dcccaad7a10; Tue, 26 Jan 2021 22:58:40 +0000 (UTC) Received: by mail.kernel.org (Postfix) with ESMTPSA id 291122065E; Tue, 26 Jan 2021 22:58:39 +0000 (UTC) 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: f3734734-292e-4661-8063-0dcccaad7a10 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1611701919; bh=zOWrR4VH8CVYg9SMt9hKgpD629fQnlmWeS5U6jKieqE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=S+dK7+mrMvngn8plnOso2EjdwsLPFOpJ3JqK3vINRnD1OX23OxIwkPOXMRRYP7+uP 4hKXKCpNVCuwPRLbs3hEU3q6jLEN9OBFBdHLUIdlIzrLWg2U5RnADY1q7lTQgi9l0Y LZcJHfp5Rb72RweGUfsiD+sFZAg+5et5SmthIWHV7Z6GXRk0i4v+jfa7pR97yWai7J ukQ16ou/GyEvLT350boJnzcsrbokUlDWFxHEcbsPUalF+pnJiiTPkh1Zj+6H9pZRUl uAWmJTSKJgoVWB2CG0eIP49Wi0BcoRDKBoXjYcsEMqli0pl5Fg43bn0+jpjorKs2pt lwSAWsDUZ3LrA== From: Stefano Stabellini To: xen-devel@lists.xenproject.org Cc: sstabellini@kernel.org, julien@xen.org, Bertrand.Marquis@arm.com, Volodymyr_Babchuk@epam.com, rahul.singh@arm.com, brian.woods@xilinx.com, Stefano Stabellini Subject: [PATCH v3 2/3] arm,smmu: restructure code in preparation to new bindings support Date: Tue, 26 Jan 2021 14:58:35 -0800 Message-Id: <20210126225836.6017-2-sstabellini@kernel.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: References: From: Brian Woods Restructure some of the code and add supporting functions for adding generic device tree (DT) binding support. This will allow for using current Linux device trees with just modifying the chosen field to enable Xen. Signed-off-by: Brian Woods Signed-off-by: Stefano Stabellini Reviewed-by: Rahul Singh Tested-by: Rahul Singh --- Changes in v3: - split patch --- xen/drivers/passthrough/arm/smmu.c | 60 +++++++++++++++++------------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/xen/drivers/passthrough/arm/smmu.c b/xen/drivers/passthrough/arm/smmu.c index 3898d1d737..9687762283 100644 --- a/xen/drivers/passthrough/arm/smmu.c +++ b/xen/drivers/passthrough/arm/smmu.c @@ -782,50 +782,36 @@ static int insert_smmu_master(struct arm_smmu_device *smmu, return 0; } -static int register_smmu_master(struct arm_smmu_device *smmu, - struct device *dev, - struct of_phandle_args *masterspec) +static int arm_smmu_dt_add_device_legacy(struct arm_smmu_device *smmu, + struct device *dev, + struct iommu_fwspec *fwspec) { - int i, ret = 0; + int i; struct arm_smmu_master *master; - struct iommu_fwspec *fwspec; + struct device_node *dev_node = dev_get_dev_node(dev); - master = find_smmu_master(smmu, masterspec->np); + master = find_smmu_master(smmu, dev_node); if (master) { dev_err(dev, "rejecting multiple registrations for master device %s\n", - masterspec->np->name); + dev_node->name); return -EBUSY; } master = devm_kzalloc(dev, sizeof(*master), GFP_KERNEL); if (!master) return -ENOMEM; - master->of_node = masterspec->np; - - ret = iommu_fwspec_init(&master->of_node->dev, smmu->dev); - if (ret) { - kfree(master); - return ret; - } - fwspec = dev_iommu_fwspec_get(dev); - - /* adding the ids here */ - ret = iommu_fwspec_add_ids(&masterspec->np->dev, - masterspec->args, - masterspec->args_count); - if (ret) - return ret; + master->of_node = dev_node; /* Xen: Let Xen know that the device is protected by an SMMU */ - dt_device_set_protected(masterspec->np); + dt_device_set_protected(dev_node); if (!(smmu->features & ARM_SMMU_FEAT_STREAM_MATCH)) { for (i = 0; i < fwspec->num_ids; ++i) { - if (masterspec->args[i] >= smmu->num_mapping_groups) { + if (fwspec->ids[i] >= smmu->num_mapping_groups) { dev_err(dev, "stream ID for master device %s greater than maximum allowed (%d)\n", - masterspec->np->name, smmu->num_mapping_groups); + dev_node->name, smmu->num_mapping_groups); return -ERANGE; } } @@ -833,6 +819,30 @@ static int register_smmu_master(struct arm_smmu_device *smmu, return insert_smmu_master(smmu, master); } +static int register_smmu_master(struct arm_smmu_device *smmu, + struct device *dev, + struct of_phandle_args *masterspec) +{ + int ret = 0; + struct iommu_fwspec *fwspec; + + ret = iommu_fwspec_init(&masterspec->np->dev, smmu->dev); + if (ret) + return ret; + + fwspec = dev_iommu_fwspec_get(&masterspec->np->dev); + + ret = iommu_fwspec_add_ids(&masterspec->np->dev, + masterspec->args, + masterspec->args_count); + if (ret) + return ret; + + return arm_smmu_dt_add_device_legacy(smmu, + &masterspec->np->dev, + fwspec); +} + static struct arm_smmu_device *find_smmu_for_device(struct device *dev) { struct arm_smmu_device *smmu; From patchwork Tue Jan 26 22:58:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefano Stabellini X-Patchwork-Id: 12048575 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.3 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7A1DBC43381 for ; Tue, 26 Jan 2021 22:58:50 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 3EABA2065C for ; Tue, 26 Jan 2021 22:58:49 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3EABA2065C Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from list by lists.xenproject.org with outflank-mailman.75654.136283 (Exim 4.92) (envelope-from ) id 1l4XIJ-0003n3-EA; Tue, 26 Jan 2021 22:58:43 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 75654.136283; Tue, 26 Jan 2021 22:58:43 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1l4XIJ-0003mt-AP; Tue, 26 Jan 2021 22:58:43 +0000 Received: by outflank-mailman (input) for mailman id 75654; Tue, 26 Jan 2021 22:58:42 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1l4XII-0003iY-CK for xen-devel@lists.xenproject.org; Tue, 26 Jan 2021 22:58:42 +0000 Received: from mail.kernel.org (unknown [198.145.29.99]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 6c140295-193d-4b56-94ee-33fb97677d53; Tue, 26 Jan 2021 22:58:40 +0000 (UTC) Received: by mail.kernel.org (Postfix) with ESMTPSA id A79EA2067B; Tue, 26 Jan 2021 22:58:39 +0000 (UTC) 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: 6c140295-193d-4b56-94ee-33fb97677d53 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1611701920; bh=f04Fi/lIYdD7+J+KA0VjXybZ+sqQj9Rzhr9Y9B6vpgU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=J3Ot9nEGFAjMJlpm42N0j4RTmAr+SBBh4u8BgTeLBNp+RemkWHnBXo5YVrdckT0jH mtF+/XaAScv7Pf/uUM99nkaw2BIqesKz8Yt2MID9NsuqwWfRI96NSoi+cZBLiGGJtf a9ecgYTeXj+sVLWGfEcKOxG6Qv75dDOwwhgE8tFnmRV3JLCZ7BkWTPV98Rby3RnspI 3PEdUdSpPp0OmcCRVW6iCwtMpubs6sx7v3u/uOd+YijfqDMIeGWg3qbAMcOrrMzmns b+hzPuEbVPuy+mQlonMPM8XF4Fnc2H7fBXmVYAG2F8V+dSVppgT5w86ItZrw+hTWOz 5wf1NjXS9Xrhw== From: Stefano Stabellini To: xen-devel@lists.xenproject.org Cc: sstabellini@kernel.org, julien@xen.org, Bertrand.Marquis@arm.com, Volodymyr_Babchuk@epam.com, rahul.singh@arm.com, brian.woods@xilinx.com, Stefano Stabellini Subject: [PATCH v3 3/3] arm,smmu: add support for generic DT bindings. Implement add_device and dt_xlate. Date: Tue, 26 Jan 2021 14:58:36 -0800 Message-Id: <20210126225836.6017-3-sstabellini@kernel.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: References: From: Brian Woods Now that all arm iommu drivers support generic bindings we can remove the workaround from iommu_add_dt_device(). Note that if both legacy bindings and generic bindings are present in device tree, the legacy bindings are the ones that are used. Signed-off-by: Brian Woods Signed-off-by: Stefano Stabellini Reviewed-by: Rahul Singh Tested-by: Rahul Singh --- Changes in v3: - split patch - make find_smmu return non-const so that we can use it in arm_smmu_dt_add_device_generic - use dt_phandle_args - update commit message --- xen/drivers/passthrough/arm/smmu.c | 40 ++++++++++++++++++++++++++- xen/drivers/passthrough/device_tree.c | 17 +----------- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/xen/drivers/passthrough/arm/smmu.c b/xen/drivers/passthrough/arm/smmu.c index 9687762283..620ba5a4b5 100644 --- a/xen/drivers/passthrough/arm/smmu.c +++ b/xen/drivers/passthrough/arm/smmu.c @@ -254,6 +254,8 @@ struct iommu_group atomic_t ref; }; +static struct arm_smmu_device *find_smmu(const struct device *dev); + static struct iommu_group *iommu_group_alloc(void) { struct iommu_group *group = xzalloc(struct iommu_group); @@ -843,6 +845,40 @@ static int register_smmu_master(struct arm_smmu_device *smmu, fwspec); } +static int arm_smmu_dt_add_device_generic(u8 devfn, struct device *dev) +{ + struct arm_smmu_device *smmu; + struct iommu_fwspec *fwspec; + + fwspec = dev_iommu_fwspec_get(dev); + if (fwspec == NULL) + return -ENXIO; + + smmu = find_smmu(fwspec->iommu_dev); + if (smmu == NULL) + return -ENXIO; + + return arm_smmu_dt_add_device_legacy(smmu, dev, fwspec); +} + +static int arm_smmu_dt_xlate_generic(struct device *dev, + const struct dt_phandle_args *spec) +{ + uint32_t mask, fwid = 0; + + if (spec->args_count > 0) + fwid |= (SMR_ID_MASK & spec->args[0]) << SMR_ID_SHIFT; + + if (spec->args_count > 1) + fwid |= (SMR_MASK_MASK & spec->args[1]) << SMR_MASK_SHIFT; + else if (!of_property_read_u32(spec->np, "stream-match-mask", &mask)) + fwid |= (SMR_MASK_MASK & mask) << SMR_MASK_SHIFT; + + return iommu_fwspec_add_ids(dev, + &fwid, + 1); +} + static struct arm_smmu_device *find_smmu_for_device(struct device *dev) { struct arm_smmu_device *smmu; @@ -2766,6 +2802,7 @@ static void arm_smmu_iommu_domain_teardown(struct domain *d) static const struct iommu_ops arm_smmu_iommu_ops = { .init = arm_smmu_iommu_domain_init, .hwdom_init = arm_smmu_iommu_hwdom_init, + .add_device = arm_smmu_dt_add_device_generic, .teardown = arm_smmu_iommu_domain_teardown, .iotlb_flush = arm_smmu_iotlb_flush, .iotlb_flush_all = arm_smmu_iotlb_flush_all, @@ -2773,9 +2810,10 @@ static const struct iommu_ops arm_smmu_iommu_ops = { .reassign_device = arm_smmu_reassign_dev, .map_page = arm_iommu_map_page, .unmap_page = arm_iommu_unmap_page, + .dt_xlate = arm_smmu_dt_xlate_generic, }; -static __init const struct arm_smmu_device *find_smmu(const struct device *dev) +static struct arm_smmu_device *find_smmu(const struct device *dev) { struct arm_smmu_device *smmu; bool found = false; diff --git a/xen/drivers/passthrough/device_tree.c b/xen/drivers/passthrough/device_tree.c index a51ae3c9c3..ae07f272e1 100644 --- a/xen/drivers/passthrough/device_tree.c +++ b/xen/drivers/passthrough/device_tree.c @@ -162,22 +162,7 @@ int iommu_add_dt_device(struct dt_device_node *np) * these callback implemented. */ if ( !ops->add_device || !ops->dt_xlate ) - { - /* - * Some Device Trees may expose both legacy SMMU and generic - * IOMMU bindings together. However, the SMMU driver is only - * supporting the former and will protect them during the - * initialization. So we need to skip them and not return - * error here. - * - * XXX: This can be dropped when the SMMU is able to deal - * with generic bindings. - */ - if ( dt_device_is_protected(np) ) - return 0; - else - return -EINVAL; - } + return -EINVAL; if ( !dt_device_is_available(iommu_spec.np) ) break;