From patchwork Wed May 17 10:07:20 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Magnus Damm X-Patchwork-Id: 9730669 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0BA0460138 for ; Wed, 17 May 2017 10:12:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F263827F7F for ; Wed, 17 May 2017 10:12:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E666A2872D; Wed, 17 May 2017 10:12:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.3 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5BC6B27F7F for ; Wed, 17 May 2017 10:12:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751908AbdEQKMB (ORCPT ); Wed, 17 May 2017 06:12:01 -0400 Received: from mail-pg0-f68.google.com ([74.125.83.68]:32923 "EHLO mail-pg0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753920AbdEQKL6 (ORCPT ); Wed, 17 May 2017 06:11:58 -0400 Received: by mail-pg0-f68.google.com with SMTP id s62so1280637pgc.0; Wed, 17 May 2017 03:11:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:date:message-id:in-reply-to:references:subject; bh=SfT9w08upsZK4VD3WNzHAkNnWFp5x/MurxAy44O9Quk=; b=lp8s1wEw+LVhPakPS90i9RoHwg0l4xclYqrxbn/DwVoEzoT/1bjSlCgb6+YQWIUZxX LAGjqZ7fNxehYwy3OFIvVw0JnNtjhMRXPj+dHlKXQoWVKXkvCvHRLRyhLILgcSgn6OHe 4wYpM002V3epA/m0+qw6FrRD/LvkoNxuP4qwfI8VOxsYvb/8hkjkdO2UEJWGnDO3eE0N 5Z4mqIw04shUJODsl+o2GnFUi6REBoVZF8cuEF9ClvoUvJZ8J8nJGC1zB34VnpmvhygU Bvs5JVeFWRFVQADand0XVoU6EG5LU18/N2ijKSyX0jjKO4A+M2rEAgXLJu5CexrrqrvM 8Kxw== 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:date:message-id:in-reply-to :references:subject; bh=SfT9w08upsZK4VD3WNzHAkNnWFp5x/MurxAy44O9Quk=; b=NhjsX+WZ3MHfdrzD3YrKsJhgpCpDZwqmGrR8J/x4WniHg/KLN4sR7jpgE51F9g49wU VUQSiq+HcTP5ECNMEXE3tU+YWWPUT2rURXMB13PzjFRtYXMTh27DA2P8EQPEfDNvvdrK ekA3MCrb6t6bFY457CeMmEOkn2JmFmcSPvAJbou3sMQgpWb6hXWXY1zZBa5Ld4Dp8kcG 5MToE8GLbvvCqPjAUbPQLH5h6Tn4XEWbjz6gU+FkqVm7noRfbbJYVbomJCs7bajNcdbM C1INjwZQdHWTJnqdMax4e1unOYHPKanArqWJJ+hBcWMp2AZC6MTIlIE4FnB5bI1t84/B YCUg== X-Gm-Message-State: AODbwcCjuoJ+fmyAI+4tEXC4LDH7/DPG6OceggrcSOW37DWFL8ghJUwt PrPfvXSfcp4xbA== X-Received: by 10.84.217.139 with SMTP id p11mr3352734pli.146.1495015907443; Wed, 17 May 2017 03:11:47 -0700 (PDT) Received: from [127.0.0.1] (s214090.ppp.asahi-net.or.jp. [220.157.214.90]) by smtp.gmail.com with ESMTPSA id p84sm3520009pfi.25.2017.05.17.03.11.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 17 May 2017 03:11:45 -0700 (PDT) From: Magnus Damm To: joro@8bytes.org Cc: laurent.pinchart+renesas@ideasonboard.com, geert+renesas@glider.be, sricharan@codeaurora.org, will.deacon@arm.com, linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org, iommu@lists.linux-foundation.org, horms+renesas@verge.net.au, Magnus Damm , robin.murphy@arm.com, m.szyprowski@samsung.com Date: Wed, 17 May 2017 19:07:20 +0900 Message-Id: <149501564036.21593.16964345443958773870.sendpatchset@little-apple> In-Reply-To: <149501557669.21593.1017116915706613060.sendpatchset@little-apple> References: <149501557669.21593.1017116915706613060.sendpatchset@little-apple> Subject: [PATCH v8 06/08] iommu/ipmmu-vmsa: Use fwspec iommu_priv on ARM64 Sender: linux-renesas-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Magnus Damm Convert from archdata to iommu_priv via iommu_fwspec on ARM64 but let 32-bit ARM keep on using archdata for now. Once the 32-bit ARM code and the IPMMU driver is able to move over to CONFIG_IOMMU_DMA=y then coverting to fwspec via ->of_xlate() will be easy. For now fwspec ids and num_ids are not used to allow code sharing between 32-bit and 64-bit ARM code inside the driver. Signed-off-by: Magnus Damm --- Changes since V7: - Rewrote code to use iommu_fwspec, thanks Robin! - Dropped reviewed-by from Joerg, also skipped tag from Geert drivers/iommu/ipmmu-vmsa.c | 97 ++++++++++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 39 deletions(-) --- 0011/drivers/iommu/ipmmu-vmsa.c +++ work/drivers/iommu/ipmmu-vmsa.c 2017-05-17 16:45:07.510607110 +0900 @@ -56,7 +56,7 @@ struct ipmmu_vmsa_domain { spinlock_t lock; /* Protects mappings */ }; -struct ipmmu_vmsa_archdata { +struct ipmmu_vmsa_iommu_priv { struct ipmmu_vmsa_device *mmu; unsigned int *utlbs; unsigned int num_utlbs; @@ -72,6 +72,24 @@ static struct ipmmu_vmsa_domain *to_vmsa return container_of(dom, struct ipmmu_vmsa_domain, io_domain); } + +static struct ipmmu_vmsa_iommu_priv *to_priv(struct device *dev) +{ +#if defined(CONFIG_ARM) + return dev->archdata.iommu; +#else + return dev->iommu_fwspec->iommu_priv; +#endif +} +static void set_priv(struct device *dev, struct ipmmu_vmsa_iommu_priv *p) +{ +#if defined(CONFIG_ARM) + dev->archdata.iommu = p; +#else + dev->iommu_fwspec->iommu_priv = p; +#endif +} + #define TLB_LOOP_TIMEOUT 100 /* 100us */ /* ----------------------------------------------------------------------------- @@ -543,8 +561,8 @@ static void ipmmu_domain_free(struct iom static int ipmmu_attach_device(struct iommu_domain *io_domain, struct device *dev) { - struct ipmmu_vmsa_archdata *archdata = dev->archdata.iommu; - struct ipmmu_vmsa_device *mmu = archdata->mmu; + struct ipmmu_vmsa_iommu_priv *priv = to_priv(dev); + struct ipmmu_vmsa_device *mmu = priv->mmu; struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain); unsigned long flags; unsigned int i; @@ -577,8 +595,8 @@ static int ipmmu_attach_device(struct io if (ret < 0) return ret; - for (i = 0; i < archdata->num_utlbs; ++i) - ipmmu_utlb_enable(domain, archdata->utlbs[i]); + for (i = 0; i < priv->num_utlbs; ++i) + ipmmu_utlb_enable(domain, priv->utlbs[i]); return 0; } @@ -586,12 +604,12 @@ static int ipmmu_attach_device(struct io static void ipmmu_detach_device(struct iommu_domain *io_domain, struct device *dev) { - struct ipmmu_vmsa_archdata *archdata = dev->archdata.iommu; + struct ipmmu_vmsa_iommu_priv *priv = to_priv(dev); struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain); unsigned int i; - for (i = 0; i < archdata->num_utlbs; ++i) - ipmmu_utlb_disable(domain, archdata->utlbs[i]); + for (i = 0; i < priv->num_utlbs; ++i) + ipmmu_utlb_disable(domain, priv->utlbs[i]); /* * TODO: Optimize by disabling the context when no device is attached. @@ -654,7 +672,7 @@ static int ipmmu_find_utlbs(struct ipmmu static int ipmmu_init_platform_device(struct device *dev) { - struct ipmmu_vmsa_archdata *archdata; + struct ipmmu_vmsa_iommu_priv *priv; struct ipmmu_vmsa_device *mmu; unsigned int *utlbs; unsigned int i; @@ -697,17 +715,17 @@ static int ipmmu_init_platform_device(st } } - archdata = kzalloc(sizeof(*archdata), GFP_KERNEL); - if (!archdata) { + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) { ret = -ENOMEM; goto error; } - archdata->mmu = mmu; - archdata->utlbs = utlbs; - archdata->num_utlbs = num_utlbs; - archdata->dev = dev; - dev->archdata.iommu = archdata; + priv->mmu = mmu; + priv->utlbs = utlbs; + priv->num_utlbs = num_utlbs; + priv->dev = dev; + set_priv(dev, priv); return 0; error: @@ -727,12 +745,11 @@ static struct iommu_domain *ipmmu_domain static int ipmmu_add_device(struct device *dev) { - struct ipmmu_vmsa_archdata *archdata; struct ipmmu_vmsa_device *mmu = NULL; struct iommu_group *group; int ret; - if (dev->archdata.iommu) { + if (to_priv(dev)) { dev_warn(dev, "IOMMU driver already assigned to device %s\n", dev_name(dev)); return -EINVAL; @@ -768,8 +785,7 @@ static int ipmmu_add_device(struct devic * - Make the mapping size configurable ? We currently use a 2GB mapping * at a 1GB offset to ensure that NULL VAs will fault. */ - archdata = dev->archdata.iommu; - mmu = archdata->mmu; + mmu = to_priv(dev)->mmu; if (!mmu->mapping) { struct dma_iommu_mapping *mapping; @@ -800,24 +816,24 @@ error: if (!IS_ERR_OR_NULL(group)) iommu_group_remove_device(dev); - kfree(archdata->utlbs); - kfree(archdata); - dev->archdata.iommu = NULL; + kfree(to_priv(dev)->utlbs); + kfree(to_priv(dev)); + set_priv(dev, NULL); return ret; } static void ipmmu_remove_device(struct device *dev) { - struct ipmmu_vmsa_archdata *archdata = dev->archdata.iommu; + struct ipmmu_vmsa_iommu_priv *priv = to_priv(dev); arm_iommu_detach_device(dev); iommu_group_remove_device(dev); - kfree(archdata->utlbs); - kfree(archdata); + kfree(priv->utlbs); + kfree(priv); - dev->archdata.iommu = NULL; + set_priv(dev, NULL); } static const struct iommu_ops ipmmu_ops = { @@ -874,11 +890,14 @@ static void ipmmu_domain_free_dma(struct static int ipmmu_add_device_dma(struct device *dev) { - struct ipmmu_vmsa_archdata *archdata = dev->archdata.iommu; + struct iommu_fwspec *fwspec = dev->iommu_fwspec; struct iommu_group *group; - /* The device has been verified in xlate() */ - if (!archdata) + /* + * Only let through devices that have been verified in xlate() + * We may get called with dev->iommu_fwspec set to NULL. + */ + if (!fwspec || !fwspec->iommu_priv) return -ENODEV; group = iommu_group_get_for_dev(dev); @@ -886,17 +905,17 @@ static int ipmmu_add_device_dma(struct d return PTR_ERR(group); spin_lock(&ipmmu_slave_devices_lock); - list_add(&archdata->list, &ipmmu_slave_devices); + list_add(&to_priv(dev)->list, &ipmmu_slave_devices); spin_unlock(&ipmmu_slave_devices_lock); return 0; } static void ipmmu_remove_device_dma(struct device *dev) { - struct ipmmu_vmsa_archdata *archdata = dev->archdata.iommu; + struct ipmmu_vmsa_iommu_priv *priv = to_priv(dev); spin_lock(&ipmmu_slave_devices_lock); - list_del(&archdata->list); + list_del(&priv->list); spin_unlock(&ipmmu_slave_devices_lock); iommu_group_remove_device(dev); @@ -904,16 +923,16 @@ static void ipmmu_remove_device_dma(stru static struct device *ipmmu_find_sibling_device(struct device *dev) { - struct ipmmu_vmsa_archdata *archdata = dev->archdata.iommu; - struct ipmmu_vmsa_archdata *sibling_archdata = NULL; + struct ipmmu_vmsa_iommu_priv *priv = to_priv(dev); + struct ipmmu_vmsa_iommu_priv *sibling_priv = NULL; bool found = false; spin_lock(&ipmmu_slave_devices_lock); - list_for_each_entry(sibling_archdata, &ipmmu_slave_devices, list) { - if (archdata == sibling_archdata) + list_for_each_entry(sibling_priv, &ipmmu_slave_devices, list) { + if (priv == sibling_priv) continue; - if (sibling_archdata->mmu == archdata->mmu) { + if (sibling_priv->mmu == priv->mmu) { found = true; break; } @@ -921,7 +940,7 @@ static struct device *ipmmu_find_sibling spin_unlock(&ipmmu_slave_devices_lock); - return found ? sibling_archdata->dev : NULL; + return found ? sibling_priv->dev : NULL; } static struct iommu_group *ipmmu_find_group_dma(struct device *dev)