From patchwork Fri Jun 26 20:04:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jordan Crouse X-Patchwork-Id: 11628563 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 17ED492A for ; Fri, 26 Jun 2020 20:04:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E019720720 for ; Fri, 26 Jun 2020 20:04:50 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=mg.codeaurora.org header.i=@mg.codeaurora.org header.b="mvVi/C4/" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725867AbgFZUEr (ORCPT ); Fri, 26 Jun 2020 16:04:47 -0400 Received: from mail29.static.mailgun.info ([104.130.122.29]:54779 "EHLO mail29.static.mailgun.info" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725781AbgFZUEq (ORCPT ); Fri, 26 Jun 2020 16:04:46 -0400 DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; q=dns/txt; s=smtp; t=1593201885; h=References: In-Reply-To: Message-Id: Date: Subject: Cc: To: From: Sender; bh=RLEjiSvoyXLjIgV4VayvZ3w+tjbV7z66u39nxKdVIKU=; b=mvVi/C4/3b+Ui5rPPgnO3XMF1S+8U3elFrKL+idkpbWWZmOR4O0YsYYyO/08npB3oB6Um5x+ SSLJfbNyNFyT/L+omI/5Dt05l8pNWEH8WTnOKJxXm2g2hMABZG7OvMsB+H/wkJDSZtXsuI2a fo1mLpaQR9voDPZFlNStZ8vis8s= X-Mailgun-Sending-Ip: 104.130.122.29 X-Mailgun-Sid: WyI1MzIzYiIsICJsaW51eC1hcm0tbXNtQHZnZXIua2VybmVsLm9yZyIsICJiZTllNGEiXQ== Received: from smtp.codeaurora.org (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by smtp-out-n08.prod.us-east-1.postgun.com with SMTP id 5ef654caa6e154319f63f2e9 (version=TLS1.2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); Fri, 26 Jun 2020 20:04:26 GMT Received: by smtp.codeaurora.org (Postfix, from userid 1001) id 32485C4344C; Fri, 26 Jun 2020 20:04:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE, URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from jordan-laptop.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: jcrouse) by smtp.codeaurora.org (Postfix) with ESMTPSA id B1A83C433CA; Fri, 26 Jun 2020 20:04:21 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org B1A83C433CA Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=jcrouse@codeaurora.org From: Jordan Crouse To: linux-arm-msm@vger.kernel.org Cc: Sai Prakash Ranjan , iommu@lists.linux-foundation.org, John Stultz , freedreno@lists.freedesktop.org, Joerg Roedel , Robin Murphy , Will Deacon , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 1/6] iommu/arm-smmu: Add auxiliary domain support for arm-smmuv2 Date: Fri, 26 Jun 2020 14:04:09 -0600 Message-Id: <20200626200414.14382-2-jcrouse@codeaurora.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200626200414.14382-1-jcrouse@codeaurora.org> References: <20200626200414.14382-1-jcrouse@codeaurora.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Support auxiliary domains for arm-smmu-v2 to initialize and support multiple pagetables for a single SMMU context bank. Since the smmu-v2 hardware doesn't have any built in support for switching the pagetable base it is left as an exercise to the caller to actually use the pagetable. Aux domains are supported if split pagetable (TTBR1) support has been enabled on the master domain. Each auxiliary domain will reuse the configuration of the master domain. By default the a domain with TTBR1 support will have the TTBR0 region disabled so the first attached aux domain will enable the TTBR0 region in the hardware and conversely the last domain to be detached will disable TTBR0 translations. All subsequent auxiliary domains create a pagetable but not touch the hardware. The leaf driver will be able to query the physical address of the pagetable with the DOMAIN_ATTR_PTBASE attribute so that it can use the address with whatever means it has to switch the pagetable base. Following is a pseudo code example of how a domain can be created /* Check to see if aux domains are supported */ if (iommu_dev_has_feature(dev, IOMMU_DEV_FEAT_AUX)) { iommu = iommu_domain_alloc(...); if (iommu_aux_attach_device(domain, dev)) return FAIL; /* Save the base address of the pagetable for use by the driver iommu_domain_get_attr(domain, DOMAIN_ATTR_PTBASE, &ptbase); } Then 'domain' can be used like any other iommu domain to map and unmap iova addresses in the pagetable. Signed-off-by: Jordan Crouse --- drivers/iommu/arm-smmu.c | 219 ++++++++++++++++++++++++++++++++++++--- drivers/iommu/arm-smmu.h | 1 + 2 files changed, 204 insertions(+), 16 deletions(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 060139452c54..ce6d654301bf 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -91,6 +91,7 @@ struct arm_smmu_cb { u32 tcr[2]; u32 mair[2]; struct arm_smmu_cfg *cfg; + atomic_t aux; }; struct arm_smmu_master_cfg { @@ -667,6 +668,86 @@ static void arm_smmu_write_context_bank(struct arm_smmu_device *smmu, int idx) arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_SCTLR, reg); } +/* + * Update the context context bank to enable TTBR0. Assumes AARCH64 S1 + * configuration. + */ +static void arm_smmu_context_set_ttbr0(struct arm_smmu_cb *cb, + struct io_pgtable_cfg *pgtbl_cfg) +{ + u32 tcr = cb->tcr[0]; + + /* Add the TCR configuration from the new pagetable config */ + tcr |= arm_smmu_lpae_tcr(pgtbl_cfg); + + /* Make sure that both TTBR0 and TTBR1 are enabled */ + tcr &= ~(ARM_SMMU_TCR_EPD0 | ARM_SMMU_TCR_EPD1); + + /* Udate the TCR register */ + cb->tcr[0] = tcr; + + /* Program the new TTBR0 */ + cb->ttbr[0] = pgtbl_cfg->arm_lpae_s1_cfg.ttbr; + cb->ttbr[0] |= FIELD_PREP(ARM_SMMU_TTBRn_ASID, cb->cfg->asid); +} + +/* + * Thus function assumes that the current model only allows aux domains for + * AARCH64 S1 configurations + */ +static int arm_smmu_aux_init_domain_context(struct iommu_domain *domain, + struct arm_smmu_device *smmu, struct arm_smmu_cfg *master) +{ + struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); + struct io_pgtable_ops *pgtbl_ops; + struct io_pgtable_cfg pgtbl_cfg; + + mutex_lock(&smmu_domain->init_mutex); + + /* Copy the configuration from the master */ + memcpy(&smmu_domain->cfg, master, sizeof(smmu_domain->cfg)); + + smmu_domain->flush_ops = &arm_smmu_s1_tlb_ops; + smmu_domain->smmu = smmu; + + pgtbl_cfg = (struct io_pgtable_cfg) { + .pgsize_bitmap = smmu->pgsize_bitmap, + .ias = smmu->va_size, + .oas = smmu->ipa_size, + .coherent_walk = smmu->features & ARM_SMMU_FEAT_COHERENT_WALK, + .tlb = smmu_domain->flush_ops, + .iommu_dev = smmu->dev, + .quirks = 0, + }; + + if (smmu_domain->non_strict) + pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_NON_STRICT; + + pgtbl_ops = alloc_io_pgtable_ops(ARM_64_LPAE_S1, &pgtbl_cfg, + smmu_domain); + if (!pgtbl_ops) { + mutex_unlock(&smmu_domain->init_mutex); + return -ENOMEM; + } + + domain->pgsize_bitmap = pgtbl_cfg.pgsize_bitmap; + + domain->geometry.aperture_end = (1UL << smmu->va_size) - 1; + domain->geometry.force_aperture = true; + + /* enable TTBR0 when the the first aux domain is attached */ + if (atomic_inc_return(&smmu->cbs[master->cbndx].aux) == 1) { + arm_smmu_context_set_ttbr0(&smmu->cbs[master->cbndx], + &pgtbl_cfg); + arm_smmu_write_context_bank(smmu, master->cbndx); + } + + smmu_domain->pgtbl_ops = pgtbl_ops; + mutex_unlock(&smmu_domain->init_mutex); + + return 0; +} + static int arm_smmu_init_domain_context(struct iommu_domain *domain, struct arm_smmu_device *smmu, struct device *dev) @@ -871,36 +952,70 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, return ret; } +static void +arm_smmu_destroy_aux_domain_context(struct arm_smmu_domain *smmu_domain) +{ + struct arm_smmu_device *smmu = smmu_domain->smmu; + struct arm_smmu_cfg *cfg = &smmu_domain->cfg; + int ret; + + /* + * If this is the last aux domain to be freed, disable TTBR0 by turning + * off translations and clearing TTBR0 + */ + if (atomic_dec_return(&smmu->cbs[cfg->cbndx].aux) == 0) { + /* Clear out the T0 region */ + smmu->cbs[cfg->cbndx].tcr[0] &= ~GENMASK(15, 0); + /* Disable TTBR0 translations */ + smmu->cbs[cfg->cbndx].tcr[0] |= ARM_SMMU_TCR_EPD0; + /* Clear the TTBR0 pagetable address */ + smmu->cbs[cfg->cbndx].ttbr[0] = + FIELD_PREP(ARM_SMMU_TTBRn_ASID, cfg->asid); + + ret = arm_smmu_rpm_get(smmu); + if (!ret) { + arm_smmu_write_context_bank(smmu, cfg->cbndx); + arm_smmu_rpm_put(smmu); + } + } + +} + static void arm_smmu_destroy_domain_context(struct iommu_domain *domain) { struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); struct arm_smmu_device *smmu = smmu_domain->smmu; struct arm_smmu_cfg *cfg = &smmu_domain->cfg; - int ret, irq; if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY) return; - ret = arm_smmu_rpm_get(smmu); - if (ret < 0) - return; + if (smmu_domain->aux) + arm_smmu_destroy_aux_domain_context(smmu_domain); - /* - * Disable the context bank and free the page tables before freeing - * it. - */ - smmu->cbs[cfg->cbndx].cfg = NULL; - arm_smmu_write_context_bank(smmu, cfg->cbndx); + /* Check if the last user is done with the context bank */ + if (atomic_read(&smmu->cbs[cfg->cbndx].aux) == 0) { + int ret = arm_smmu_rpm_get(smmu); + int irq; - if (cfg->irptndx != ARM_SMMU_INVALID_IRPTNDX) { - irq = smmu->irqs[smmu->num_global_irqs + cfg->irptndx]; - devm_free_irq(smmu->dev, irq, domain); + if (ret < 0) + return; + + /* Disable the context bank */ + smmu->cbs[cfg->cbndx].cfg = NULL; + arm_smmu_write_context_bank(smmu, cfg->cbndx); + + if (cfg->irptndx != ARM_SMMU_INVALID_IRPTNDX) { + irq = smmu->irqs[smmu->num_global_irqs + cfg->irptndx]; + devm_free_irq(smmu->dev, irq, domain); + } + + __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx); + arm_smmu_rpm_put(smmu); } + /* Destroy the pagetable */ free_io_pgtable_ops(smmu_domain->pgtbl_ops); - __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx); - - arm_smmu_rpm_put(smmu); } static struct iommu_domain *arm_smmu_domain_alloc(unsigned type) @@ -1161,6 +1276,74 @@ static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain, return 0; } +static bool arm_smmu_dev_has_feat(struct device *dev, + enum iommu_dev_features feat) +{ + if (feat != IOMMU_DEV_FEAT_AUX) + return false; + + return true; +} + +static int arm_smmu_dev_enable_feat(struct device *dev, + enum iommu_dev_features feat) +{ + /* aux domain support is always available */ + if (feat == IOMMU_DEV_FEAT_AUX) + return 0; + + return -ENODEV; +} + +static int arm_smmu_dev_disable_feat(struct device *dev, + enum iommu_dev_features feat) +{ + return -EBUSY; +} + +static int arm_smmu_aux_attach_dev(struct iommu_domain *domain, + struct device *dev) +{ + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); + struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev); + struct arm_smmu_device *smmu = cfg->smmu; + struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); + struct arm_smmu_cb *cb; + int idx, i, ret, cbndx = -1; + + /* Try to find the context bank configured for this device */ + for_each_cfg_sme(cfg, fwspec, i, idx) { + if (idx != INVALID_SMENDX) { + cbndx = smmu->s2crs[idx].cbndx; + break; + } + } + + if (cbndx == -1) + return -ENODEV; + + cb = &smmu->cbs[cbndx]; + + /* Aux domains are only supported for AARCH64 configurations */ + if (cb->cfg->fmt != ARM_SMMU_CTX_FMT_AARCH64) + return -EINVAL; + + /* Make sure that TTBR1 is enabled in the hardware */ + if ((cb->tcr[0] & ARM_SMMU_TCR_EPD1)) + return -EINVAL; + + smmu_domain->aux = true; + + ret = arm_smmu_rpm_get(smmu); + if (ret < 0) + return ret; + + ret = arm_smmu_aux_init_domain_context(domain, smmu, cb->cfg); + + arm_smmu_rpm_put(smmu); + return ret; +} + static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) { struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); @@ -1653,6 +1836,10 @@ static struct iommu_ops arm_smmu_ops = { .get_resv_regions = arm_smmu_get_resv_regions, .put_resv_regions = generic_iommu_put_resv_regions, .def_domain_type = arm_smmu_def_domain_type, + .dev_has_feat = arm_smmu_dev_has_feat, + .dev_enable_feat = arm_smmu_dev_enable_feat, + .dev_disable_feat = arm_smmu_dev_disable_feat, + .aux_attach_dev = arm_smmu_aux_attach_dev, .pgsize_bitmap = -1UL, /* Restricted during device attach */ }; diff --git a/drivers/iommu/arm-smmu.h b/drivers/iommu/arm-smmu.h index c417814f1d98..79d441024043 100644 --- a/drivers/iommu/arm-smmu.h +++ b/drivers/iommu/arm-smmu.h @@ -346,6 +346,7 @@ struct arm_smmu_domain { spinlock_t cb_lock; /* Serialises ATS1* ops and TLB syncs */ struct iommu_domain domain; struct device *dev; /* Device attached to this domain */ + bool aux; }; static inline u32 arm_smmu_lpae_tcr(struct io_pgtable_cfg *cfg) From patchwork Fri Jun 26 20:04:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jordan Crouse X-Patchwork-Id: 11628575 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 70ABC14B7 for ; Fri, 26 Jun 2020 20:05:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5211C206C3 for ; Fri, 26 Jun 2020 20:05:06 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=mg.codeaurora.org header.i=@mg.codeaurora.org header.b="B6klToc0" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725983AbgFZUFF (ORCPT ); Fri, 26 Jun 2020 16:05:05 -0400 Received: from m43-7.mailgun.net ([69.72.43.7]:28648 "EHLO m43-7.mailgun.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725838AbgFZUEu (ORCPT ); Fri, 26 Jun 2020 16:04:50 -0400 DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; q=dns/txt; s=smtp; t=1593201890; h=References: In-Reply-To: Message-Id: Date: Subject: Cc: To: From: Sender; bh=PQnTZkYVOn9g39XJGJ/Fc5lnyvhq0qe68meDTmbVWdk=; b=B6klToc0ueVMw+KbmLc+NynEdEjJYC9Wq0y0MeOcA3f+RRd/YmOs+FRhntp7t0V5m7nZork4 ivHORwRUZi4WQJFoIY8DA7cdTQqHI3nBOTKQngHlRhhCDs5kfysJ80qCTL/VZAsb13K0vPrg DUMN9k8lL2Z+lAtIC3a1HsCcitE= X-Mailgun-Sending-Ip: 69.72.43.7 X-Mailgun-Sid: WyI1MzIzYiIsICJsaW51eC1hcm0tbXNtQHZnZXIua2VybmVsLm9yZyIsICJiZTllNGEiXQ== Received: from smtp.codeaurora.org (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by smtp-out-n18.prod.us-east-1.postgun.com with SMTP id 5ef654cac76a4e7a2a945e32 (version=TLS1.2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); Fri, 26 Jun 2020 20:04:26 GMT Received: by smtp.codeaurora.org (Postfix, from userid 1001) id CE7A8C433CA; Fri, 26 Jun 2020 20:04:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE, URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from jordan-laptop.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: jcrouse) by smtp.codeaurora.org (Postfix) with ESMTPSA id C030EC433C6; Fri, 26 Jun 2020 20:04:23 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org C030EC433C6 Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=jcrouse@codeaurora.org From: Jordan Crouse To: linux-arm-msm@vger.kernel.org Cc: Sai Prakash Ranjan , iommu@lists.linux-foundation.org, John Stultz , freedreno@lists.freedesktop.org, Joerg Roedel , Robin Murphy , Will Deacon , Yong Wu , linux-kernel@vger.kernel.org Subject: [PATCH v2 2/6] iommu/io-pgtable: Allow a pgtable implementation to skip TLB operations Date: Fri, 26 Jun 2020 14:04:10 -0600 Message-Id: <20200626200414.14382-3-jcrouse@codeaurora.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200626200414.14382-1-jcrouse@codeaurora.org> References: <20200626200414.14382-1-jcrouse@codeaurora.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Allow a io-pgtable implementation to skip TLB operations by checking for NULL pointers in the helper functions. It will be up to to the owner of the io-pgtable instance to make sure that they independently handle the TLB correctly. Signed-off-by: Jordan Crouse --- include/linux/io-pgtable.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h index 53d53c6c2be9..bbed1d3925ba 100644 --- a/include/linux/io-pgtable.h +++ b/include/linux/io-pgtable.h @@ -210,21 +210,24 @@ struct io_pgtable { static inline void io_pgtable_tlb_flush_all(struct io_pgtable *iop) { - iop->cfg.tlb->tlb_flush_all(iop->cookie); + if (iop->cfg.tlb) + iop->cfg.tlb->tlb_flush_all(iop->cookie); } static inline void io_pgtable_tlb_flush_walk(struct io_pgtable *iop, unsigned long iova, size_t size, size_t granule) { - iop->cfg.tlb->tlb_flush_walk(iova, size, granule, iop->cookie); + if (iop->cfg.tlb) + iop->cfg.tlb->tlb_flush_walk(iova, size, granule, iop->cookie); } static inline void io_pgtable_tlb_flush_leaf(struct io_pgtable *iop, unsigned long iova, size_t size, size_t granule) { - iop->cfg.tlb->tlb_flush_leaf(iova, size, granule, iop->cookie); + if (iop->cfg.tlb) + iop->cfg.tlb->tlb_flush_leaf(iova, size, granule, iop->cookie); } static inline void @@ -232,7 +235,7 @@ io_pgtable_tlb_add_page(struct io_pgtable *iop, struct iommu_iotlb_gather * gather, unsigned long iova, size_t granule) { - if (iop->cfg.tlb->tlb_add_page) + if (iop->cfg.tlb && iop->cfg.tlb->tlb_add_page) iop->cfg.tlb->tlb_add_page(gather, iova, granule, iop->cookie); } From patchwork Fri Jun 26 20:04:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jordan Crouse X-Patchwork-Id: 11628579 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0CF5014F6 for ; Fri, 26 Jun 2020 20:05:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E99CF207E8 for ; Fri, 26 Jun 2020 20:05:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=mg.codeaurora.org header.i=@mg.codeaurora.org header.b="PIsiAn51" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725854AbgFZUFR (ORCPT ); Fri, 26 Jun 2020 16:05:17 -0400 Received: from m43-7.mailgun.net ([69.72.43.7]:61630 "EHLO m43-7.mailgun.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725833AbgFZUEs (ORCPT ); Fri, 26 Jun 2020 16:04:48 -0400 DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; q=dns/txt; s=smtp; t=1593201888; h=References: In-Reply-To: Message-Id: Date: Subject: Cc: To: From: Sender; bh=w7L9q0FJyrGR9ubHX5bPA568m/fho6YvIBGV3F8A+Ko=; b=PIsiAn51KkQCQXsoB8gIyoze3jNn91/7MhMorRxtN8nDquiy6z0Xe6+HTJ9KdyqWXSa03L/E t9gwicR7fQszu9sReJEYenrP9Gt/l0B+ZvtCYmlm7cl4qQsOgc44ipZWDlzJTuaHWpSWuund tmy/R375m1iF0WoMmROlUPNBlCM= X-Mailgun-Sending-Ip: 69.72.43.7 X-Mailgun-Sid: WyI1MzIzYiIsICJsaW51eC1hcm0tbXNtQHZnZXIua2VybmVsLm9yZyIsICJiZTllNGEiXQ== Received: from smtp.codeaurora.org (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by smtp-out-n11.prod.us-east-1.postgun.com with SMTP id 5ef654cca3d8a447438e843a (version=TLS1.2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); Fri, 26 Jun 2020 20:04:28 GMT Received: by smtp.codeaurora.org (Postfix, from userid 1001) id 4AEA3C433B2; Fri, 26 Jun 2020 20:04:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE, URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from jordan-laptop.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: jcrouse) by smtp.codeaurora.org (Postfix) with ESMTPSA id A88A6C433C8; Fri, 26 Jun 2020 20:04:25 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org A88A6C433C8 Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=jcrouse@codeaurora.org From: Jordan Crouse To: linux-arm-msm@vger.kernel.org Cc: Sai Prakash Ranjan , iommu@lists.linux-foundation.org, John Stultz , freedreno@lists.freedesktop.org, Joerg Roedel , Robin Murphy , Will Deacon , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 3/6] iommu/arm-smmu: Add a domain attribute to pass the pagetable config Date: Fri, 26 Jun 2020 14:04:11 -0600 Message-Id: <20200626200414.14382-4-jcrouse@codeaurora.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200626200414.14382-1-jcrouse@codeaurora.org> References: <20200626200414.14382-1-jcrouse@codeaurora.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org The Adreno GPU has the capacity to manage its own pagetables and switch them dynamically from the hardware. Add a domain attribute for arm-smmu-v2 to get the default pagetable configuration so that the GPU driver can match the format for its own pagetables. Signed-off-by: Jordan Crouse --- drivers/iommu/arm-smmu.c | 12 ++++++++++++ include/linux/iommu.h | 1 + 2 files changed, 13 insertions(+) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index ce6d654301bf..4bd247dfd703 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -1714,6 +1714,18 @@ static int arm_smmu_domain_get_attr(struct iommu_domain *domain, case DOMAIN_ATTR_NESTING: *(int *)data = (smmu_domain->stage == ARM_SMMU_DOMAIN_NESTED); return 0; + case DOMAIN_ATTR_PGTABLE_CFG: { + struct io_pgtable *pgtable; + struct io_pgtable_cfg *dest = data; + + if (!smmu_domain->pgtbl_ops) + return -ENODEV; + + pgtable = io_pgtable_ops_to_pgtable(smmu_domain->pgtbl_ops); + + memcpy(dest, &pgtable->cfg, sizeof(*dest)); + return 0; + } default: return -ENODEV; } diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 5f0b7859d2eb..2388117641f1 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -124,6 +124,7 @@ enum iommu_attr { DOMAIN_ATTR_FSL_PAMUV1, DOMAIN_ATTR_NESTING, /* two stages of translation */ DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE, + DOMAIN_ATTR_PGTABLE_CFG, DOMAIN_ATTR_MAX, }; From patchwork Fri Jun 26 20:04:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jordan Crouse X-Patchwork-Id: 11628565 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 34F9414F6 for ; Fri, 26 Jun 2020 20:04:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1DE5320720 for ; Fri, 26 Jun 2020 20:04:51 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=mg.codeaurora.org header.i=@mg.codeaurora.org header.b="NF+wFu7D" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725780AbgFZUEt (ORCPT ); Fri, 26 Jun 2020 16:04:49 -0400 Received: from mail29.static.mailgun.info ([104.130.122.29]:38596 "EHLO mail29.static.mailgun.info" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725835AbgFZUEs (ORCPT ); Fri, 26 Jun 2020 16:04:48 -0400 DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; q=dns/txt; s=smtp; t=1593201886; h=References: In-Reply-To: Message-Id: Date: Subject: Cc: To: From: Sender; bh=MYgenQyiQdZQEyqFDQ5odU+4+VgfI1wyx+54cF7dHG0=; b=NF+wFu7DgfPohQ8xAS0LhnRMbeDniJC5OMVXO23FKfEos0QLDvfJjMFEYmdnMqiFBdBVCNoE YpMv3/LI7xfx59VCRx49lmCgrHXuc9Z7YApckrAZY1Afti3iv6jRFpSnZBXCirrU9Z8nUHeT GjBI6q0B8mR5Uc3MulMNn4uZaXA= X-Mailgun-Sending-Ip: 104.130.122.29 X-Mailgun-Sid: WyI1MzIzYiIsICJsaW51eC1hcm0tbXNtQHZnZXIua2VybmVsLm9yZyIsICJiZTllNGEiXQ== Received: from smtp.codeaurora.org (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by smtp-out-n14.prod.us-east-1.postgun.com with SMTP id 5ef654ce356bcc26abeca3c5 (version=TLS1.2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); Fri, 26 Jun 2020 20:04:30 GMT Received: by smtp.codeaurora.org (Postfix, from userid 1001) id 32472C433C8; Fri, 26 Jun 2020 20:04:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from jordan-laptop.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: jcrouse) by smtp.codeaurora.org (Postfix) with ESMTPSA id 2270CC4339C; Fri, 26 Jun 2020 20:04:27 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 2270CC4339C Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=jcrouse@codeaurora.org From: Jordan Crouse To: linux-arm-msm@vger.kernel.org Cc: Sai Prakash Ranjan , iommu@lists.linux-foundation.org, John Stultz , freedreno@lists.freedesktop.org, Daniel Vetter , David Airlie , Rob Clark , Sean Paul , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 4/6] drm/msm: Add support to create a local pagetable Date: Fri, 26 Jun 2020 14:04:12 -0600 Message-Id: <20200626200414.14382-5-jcrouse@codeaurora.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200626200414.14382-1-jcrouse@codeaurora.org> References: <20200626200414.14382-1-jcrouse@codeaurora.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add support to create a io-pgtable for use by targets that support per-instance pagetables. In order to support per-instance pagetables the GPU SMMU device needs to have the qcom,adreno-smmu compatible string and split pagetables and auxiliary domains need to be supported and enabled. Signed-off-by: Jordan Crouse --- drivers/gpu/drm/msm/msm_gpummu.c | 2 +- drivers/gpu/drm/msm/msm_iommu.c | 180 ++++++++++++++++++++++++++++++- drivers/gpu/drm/msm/msm_mmu.h | 16 ++- 3 files changed, 195 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_gpummu.c b/drivers/gpu/drm/msm/msm_gpummu.c index 310a31b05faa..aab121f4beb7 100644 --- a/drivers/gpu/drm/msm/msm_gpummu.c +++ b/drivers/gpu/drm/msm/msm_gpummu.c @@ -102,7 +102,7 @@ struct msm_mmu *msm_gpummu_new(struct device *dev, struct msm_gpu *gpu) } gpummu->gpu = gpu; - msm_mmu_init(&gpummu->base, dev, &funcs); + msm_mmu_init(&gpummu->base, dev, &funcs, MSM_MMU_GPUMMU); return &gpummu->base; } diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c index 1b6635504069..f455c597f76d 100644 --- a/drivers/gpu/drm/msm/msm_iommu.c +++ b/drivers/gpu/drm/msm/msm_iommu.c @@ -4,15 +4,192 @@ * Author: Rob Clark */ +#include #include "msm_drv.h" #include "msm_mmu.h" struct msm_iommu { struct msm_mmu base; struct iommu_domain *domain; + struct iommu_domain *aux_domain; }; + #define to_msm_iommu(x) container_of(x, struct msm_iommu, base) +struct msm_iommu_pagetable { + struct msm_mmu base; + struct msm_mmu *parent; + struct io_pgtable_ops *pgtbl_ops; + phys_addr_t ttbr; + u32 asid; +}; + +static struct msm_iommu_pagetable *to_pagetable(struct msm_mmu *mmu) +{ + return container_of(mmu, struct msm_iommu_pagetable, base); +} + +static int msm_iommu_pagetable_unmap(struct msm_mmu *mmu, u64 iova, + size_t size) +{ + struct msm_iommu_pagetable *pagetable = to_pagetable(mmu); + struct io_pgtable_ops *ops = pagetable->pgtbl_ops; + size_t unmapped = 0; + + /* Unmap the block one page at a time */ + while (size) { + unmapped += ops->unmap(ops, iova, 4096, NULL); + iova += 4096; + size -= 4096; + } + + iommu_flush_tlb_all(to_msm_iommu(pagetable->parent)->domain); + + return (unmapped == size) ? 0 : -EINVAL; +} + +static int msm_iommu_pagetable_map(struct msm_mmu *mmu, u64 iova, + struct sg_table *sgt, size_t len, int prot) +{ + struct msm_iommu_pagetable *pagetable = to_pagetable(mmu); + struct io_pgtable_ops *ops = pagetable->pgtbl_ops; + struct scatterlist *sg; + size_t mapped = 0; + u64 addr = iova; + unsigned int i; + + for_each_sg(sgt->sgl, sg, sgt->nents, i) { + size_t size = sg->length; + phys_addr_t phys = sg_phys(sg); + + /* Map the block one page at a time */ + while (size) { + if (ops->map(ops, addr, phys, 4096, prot)) { + msm_iommu_pagetable_unmap(mmu, iova, mapped); + return -EINVAL; + } + + phys += 4096; + addr += 4096; + size -= 4096; + mapped += 4096; + } + } + + return 0; +} + +static void msm_iommu_pagetable_destroy(struct msm_mmu *mmu) +{ + struct msm_iommu_pagetable *pagetable = to_pagetable(mmu); + + free_io_pgtable_ops(pagetable->pgtbl_ops); + kfree(pagetable); +} + +/* + * Given a parent device, create and return an aux domain. This will enable the + * TTBR0 region + */ +static struct iommu_domain *msm_iommu_get_aux_domain(struct msm_mmu *parent) +{ + struct msm_iommu *iommu = to_msm_iommu(parent); + struct iommu_domain *domain; + int ret; + + if (iommu->aux_domain) + return iommu->aux_domain; + + if (!iommu_dev_has_feature(parent->dev, IOMMU_DEV_FEAT_AUX)) + return ERR_PTR(-ENODEV); + + domain = iommu_domain_alloc(&platform_bus_type); + if (!domain) + return ERR_PTR(-ENODEV); + + ret = iommu_aux_attach_device(domain, parent->dev); + if (ret) { + iommu_domain_free(domain); + return ERR_PTR(ret); + } + + iommu->aux_domain = domain; + return domain; +} + +int msm_iommu_pagetable_params(struct msm_mmu *mmu, + phys_addr_t *ttbr, int *asid) +{ + struct msm_iommu_pagetable *pagetable; + + if (mmu->type != MSM_MMU_IOMMU_PAGETABLE) + return -EINVAL; + + pagetable = to_pagetable(mmu); + + if (ttbr) + *ttbr = pagetable->ttbr; + + if (asid) + *asid = pagetable->asid; + + return 0; +} + +static const struct msm_mmu_funcs pagetable_funcs = { + .map = msm_iommu_pagetable_map, + .unmap = msm_iommu_pagetable_unmap, + .destroy = msm_iommu_pagetable_destroy, +}; + +struct msm_mmu *msm_iommu_pagetable_create(struct msm_mmu *parent) +{ + static int next_asid = 16; + struct msm_iommu_pagetable *pagetable; + struct iommu_domain *aux_domain; + struct io_pgtable_cfg cfg; + int ret; + + /* Make sure that the parent has a aux domain attached */ + aux_domain = msm_iommu_get_aux_domain(parent); + if (IS_ERR(aux_domain)) + return ERR_CAST(aux_domain); + + /* Get the pagetable configuration from the aux domain */ + ret = iommu_domain_get_attr(aux_domain, DOMAIN_ATTR_PGTABLE_CFG, &cfg); + if (ret) + return ERR_PTR(ret); + + pagetable = kzalloc(sizeof(*pagetable), GFP_KERNEL); + if (!pagetable) + return ERR_PTR(-ENOMEM); + + msm_mmu_init(&pagetable->base, parent->dev, &pagetable_funcs, + MSM_MMU_IOMMU_PAGETABLE); + + cfg.tlb = NULL; + + pagetable->pgtbl_ops = alloc_io_pgtable_ops(ARM_64_LPAE_S1, + &cfg, aux_domain); + + if (!pagetable->pgtbl_ops) { + kfree(pagetable); + return ERR_PTR(-ENOMEM); + } + + + /* Needed later for TLB flush */ + pagetable->parent = parent; + pagetable->ttbr = cfg.arm_lpae_s1_cfg.ttbr; + + pagetable->asid = next_asid; + next_asid = (next_asid + 1) % 255; + if (next_asid < 16) + next_asid = 16; + + return &pagetable->base; +} + static int msm_fault_handler(struct iommu_domain *domain, struct device *dev, unsigned long iova, int flags, void *arg) { @@ -40,6 +217,7 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova, if (iova & BIT_ULL(48)) iova |= GENMASK_ULL(63, 49); + ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot); WARN_ON(!ret); @@ -85,7 +263,7 @@ struct msm_mmu *msm_iommu_new(struct device *dev, struct iommu_domain *domain) return ERR_PTR(-ENOMEM); iommu->domain = domain; - msm_mmu_init(&iommu->base, dev, &funcs); + msm_mmu_init(&iommu->base, dev, &funcs, MSM_MMU_IOMMU); iommu_set_fault_handler(domain, msm_fault_handler, iommu); ret = iommu_attach_device(iommu->domain, dev); diff --git a/drivers/gpu/drm/msm/msm_mmu.h b/drivers/gpu/drm/msm/msm_mmu.h index 3a534ee59bf6..61ade89d9e48 100644 --- a/drivers/gpu/drm/msm/msm_mmu.h +++ b/drivers/gpu/drm/msm/msm_mmu.h @@ -17,18 +17,26 @@ struct msm_mmu_funcs { void (*destroy)(struct msm_mmu *mmu); }; +enum msm_mmu_type { + MSM_MMU_GPUMMU, + MSM_MMU_IOMMU, + MSM_MMU_IOMMU_PAGETABLE, +}; + struct msm_mmu { const struct msm_mmu_funcs *funcs; struct device *dev; int (*handler)(void *arg, unsigned long iova, int flags); void *arg; + enum msm_mmu_type type; }; static inline void msm_mmu_init(struct msm_mmu *mmu, struct device *dev, - const struct msm_mmu_funcs *funcs) + const struct msm_mmu_funcs *funcs, enum msm_mmu_type type) { mmu->dev = dev; mmu->funcs = funcs; + mmu->type = type; } struct msm_mmu *msm_iommu_new(struct device *dev, struct iommu_domain *domain); @@ -41,7 +49,13 @@ static inline void msm_mmu_set_fault_handler(struct msm_mmu *mmu, void *arg, mmu->handler = handler; } +struct msm_mmu *msm_iommu_pagetable_create(struct msm_mmu *parent); + void msm_gpummu_params(struct msm_mmu *mmu, dma_addr_t *pt_base, dma_addr_t *tran_error); + +int msm_iommu_pagetable_params(struct msm_mmu *mmu, phys_addr_t *ttbr, + int *asid); + #endif /* __MSM_MMU_H__ */ From patchwork Fri Jun 26 20:04:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jordan Crouse X-Patchwork-Id: 11628569 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 33E5592A for ; Fri, 26 Jun 2020 20:04:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 16056214F1 for ; Fri, 26 Jun 2020 20:04:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=mg.codeaurora.org header.i=@mg.codeaurora.org header.b="tGnSp7bb" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725828AbgFZUEx (ORCPT ); Fri, 26 Jun 2020 16:04:53 -0400 Received: from mail29.static.mailgun.info ([104.130.122.29]:62416 "EHLO mail29.static.mailgun.info" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725855AbgFZUEw (ORCPT ); Fri, 26 Jun 2020 16:04:52 -0400 DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; q=dns/txt; s=smtp; t=1593201891; h=References: In-Reply-To: Message-Id: Date: Subject: Cc: To: From: Sender; bh=D85sGJCwjjAQqj2vSMlo3N0ypP1ykjFcdiizwNh3ejQ=; b=tGnSp7bb5xWE+hgwnBSu+//o1UdTWYFOJkgQEfMBhXFRtThCPcyRl9K2j02BAYfLms8a1wS+ GQKR46I+lW0g5uygpt1pmZDPr/Onu9c8u2VPCeJOY8gCriHwM1o909J/6Hir4+24/W83n3kc lEHFyUL/hAIlLtSgZfhdnlcnK8w= X-Mailgun-Sending-Ip: 104.130.122.29 X-Mailgun-Sid: WyI1MzIzYiIsICJsaW51eC1hcm0tbXNtQHZnZXIua2VybmVsLm9yZyIsICJiZTllNGEiXQ== Received: from smtp.codeaurora.org (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by smtp-out-n18.prod.us-east-1.postgun.com with SMTP id 5ef654cfa3d8a447438e8eb8 (version=TLS1.2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); Fri, 26 Jun 2020 20:04:31 GMT Received: by smtp.codeaurora.org (Postfix, from userid 1001) id 035E5C4344B; Fri, 26 Jun 2020 20:04:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE, URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from jordan-laptop.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: jcrouse) by smtp.codeaurora.org (Postfix) with ESMTPSA id C5522C433A0; Fri, 26 Jun 2020 20:04:28 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org C5522C433A0 Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=jcrouse@codeaurora.org From: Jordan Crouse To: linux-arm-msm@vger.kernel.org Cc: Sai Prakash Ranjan , iommu@lists.linux-foundation.org, John Stultz , freedreno@lists.freedesktop.org, Daniel Vetter , David Airlie , Rob Clark , Sean Paul , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 5/6] drm/msm: Add support for address space instances Date: Fri, 26 Jun 2020 14:04:13 -0600 Message-Id: <20200626200414.14382-6-jcrouse@codeaurora.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200626200414.14382-1-jcrouse@codeaurora.org> References: <20200626200414.14382-1-jcrouse@codeaurora.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add support for allocating an address space instance. Targets that support per-instance pagetables should implement their own function to allocate a new instance. The default will return the existing generic address space. Signed-off-by: Jordan Crouse --- drivers/gpu/drm/msm/msm_drv.c | 15 +++++++++------ drivers/gpu/drm/msm/msm_drv.h | 4 ++++ drivers/gpu/drm/msm/msm_gem_vma.c | 9 +++++++++ drivers/gpu/drm/msm/msm_gpu.c | 17 +++++++++++++++++ drivers/gpu/drm/msm/msm_gpu.h | 5 +++++ 5 files changed, 44 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 6c57cc72d627..092c49552ddd 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -588,7 +588,7 @@ static int context_init(struct drm_device *dev, struct drm_file *file) msm_submitqueue_init(dev, ctx); - ctx->aspace = priv->gpu ? priv->gpu->aspace : NULL; + ctx->aspace = msm_gpu_address_space_instance(priv->gpu); file->driver_priv = ctx; return 0; @@ -607,6 +607,8 @@ static int msm_open(struct drm_device *dev, struct drm_file *file) static void context_close(struct msm_file_private *ctx) { msm_submitqueue_close(ctx); + + msm_gem_address_space_put(ctx->aspace); kfree(ctx); } @@ -771,18 +773,19 @@ static int msm_ioctl_gem_cpu_fini(struct drm_device *dev, void *data, } static int msm_ioctl_gem_info_iova(struct drm_device *dev, - struct drm_gem_object *obj, uint64_t *iova) + struct drm_file *file, struct drm_gem_object *obj, + uint64_t *iova) { - struct msm_drm_private *priv = dev->dev_private; + struct msm_file_private *ctx = file->driver_priv; - if (!priv->gpu) + if (!ctx->aspace) return -EINVAL; /* * Don't pin the memory here - just get an address so that userspace can * be productive */ - return msm_gem_get_iova(obj, priv->gpu->aspace, iova); + return msm_gem_get_iova(obj, ctx->aspace, iova); } static int msm_ioctl_gem_info(struct drm_device *dev, void *data, @@ -821,7 +824,7 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data, args->value = msm_gem_mmap_offset(obj); break; case MSM_INFO_GET_IOVA: - ret = msm_ioctl_gem_info_iova(dev, obj, &args->value); + ret = msm_ioctl_gem_info_iova(dev, file, obj, &args->value); break; case MSM_INFO_SET_NAME: /* length check should leave room for terminating null: */ diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index e2d6a6056418..983a8b7e5a74 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -249,6 +249,10 @@ int msm_gem_map_vma(struct msm_gem_address_space *aspace, void msm_gem_close_vma(struct msm_gem_address_space *aspace, struct msm_gem_vma *vma); + +struct msm_gem_address_space * +msm_gem_address_space_get(struct msm_gem_address_space *aspace); + void msm_gem_address_space_put(struct msm_gem_address_space *aspace); struct msm_gem_address_space * diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c b/drivers/gpu/drm/msm/msm_gem_vma.c index 5f6a11211b64..29cc1305cf37 100644 --- a/drivers/gpu/drm/msm/msm_gem_vma.c +++ b/drivers/gpu/drm/msm/msm_gem_vma.c @@ -27,6 +27,15 @@ void msm_gem_address_space_put(struct msm_gem_address_space *aspace) kref_put(&aspace->kref, msm_gem_address_space_destroy); } +struct msm_gem_address_space * +msm_gem_address_space_get(struct msm_gem_address_space *aspace) +{ + if (!IS_ERR_OR_NULL(aspace)) + kref_get(&aspace->kref); + + return aspace; +} + /* Actually unmap memory for the vma */ void msm_gem_purge_vma(struct msm_gem_address_space *aspace, struct msm_gem_vma *vma) diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 86a138641477..0fa614430799 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -821,6 +821,23 @@ static int get_clocks(struct platform_device *pdev, struct msm_gpu *gpu) return 0; } +/* Return a new address space instance */ +struct msm_gem_address_space * +msm_gpu_address_space_instance(struct msm_gpu *gpu) +{ + if (!gpu) + return NULL; + + /* + * If the GPU doesn't support instanced address spaces return the + * default address space + */ + if (!gpu->funcs->address_space_instance) + return msm_gem_address_space_get(gpu->aspace); + + return gpu->funcs->address_space_instance(gpu); +} + int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, struct msm_gpu *gpu, const struct msm_gpu_funcs *funcs, const char *name, struct msm_gpu_config *config) diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index 429cb40f7931..f1762b77bea8 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -64,6 +64,8 @@ struct msm_gpu_funcs { void (*gpu_set_freq)(struct msm_gpu *gpu, unsigned long freq); struct msm_gem_address_space *(*create_address_space) (struct msm_gpu *gpu, struct platform_device *pdev); + struct msm_gem_address_space *(*address_space_instance) + (struct msm_gpu *gpu); }; struct msm_gpu { @@ -286,6 +288,9 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, struct msm_gpu *gpu, const struct msm_gpu_funcs *funcs, const char *name, struct msm_gpu_config *config); +struct msm_gem_address_space * +msm_gpu_address_space_instance(struct msm_gpu *gpu); + void msm_gpu_cleanup(struct msm_gpu *gpu); struct msm_gpu *adreno_load_gpu(struct drm_device *dev); From patchwork Fri Jun 26 20:04:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jordan Crouse X-Patchwork-Id: 11628559 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A72AB92A for ; Fri, 26 Jun 2020 20:04:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9054A207D8 for ; Fri, 26 Jun 2020 20:04:46 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=mg.codeaurora.org header.i=@mg.codeaurora.org header.b="Gj1QS6r3" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725897AbgFZUEq (ORCPT ); Fri, 26 Jun 2020 16:04:46 -0400 Received: from m43-7.mailgun.net ([69.72.43.7]:28648 "EHLO m43-7.mailgun.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725864AbgFZUEp (ORCPT ); Fri, 26 Jun 2020 16:04:45 -0400 DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; q=dns/txt; s=smtp; t=1593201885; h=References: In-Reply-To: Message-Id: Date: Subject: Cc: To: From: Sender; bh=LdWbyAz364u7P6m0IEZru9FONBE/gZvu9Gt+jgjI10I=; b=Gj1QS6r3mCm1djou6wZLcMtttwmzJ+r9rOur+Po+XbxosOHUHTbrVK7++qq2FZqUBnlk2scj GV1M7X4AQB7CrMfH5T2wq8FlYTxyxNbTrwJbemM0zI/Eve0mUDBeK/HkGhMwJD8jVEdo74gn qTxD6mgXEk3gFbJkYb4uI9gMw6w= X-Mailgun-Sending-Ip: 69.72.43.7 X-Mailgun-Sid: WyI1MzIzYiIsICJsaW51eC1hcm0tbXNtQHZnZXIua2VybmVsLm9yZyIsICJiZTllNGEiXQ== Received: from smtp.codeaurora.org (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by smtp-out-n16.prod.us-east-1.postgun.com with SMTP id 5ef654d2bfb34e631c1a7c1f (version=TLS1.2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); Fri, 26 Jun 2020 20:04:34 GMT Received: by smtp.codeaurora.org (Postfix, from userid 1001) id 78ECFC433C8; Fri, 26 Jun 2020 20:04:33 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE, URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from jordan-laptop.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: jcrouse) by smtp.codeaurora.org (Postfix) with ESMTPSA id 96B86C433C6; Fri, 26 Jun 2020 20:04:30 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 96B86C433C6 Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=jcrouse@codeaurora.org From: Jordan Crouse To: linux-arm-msm@vger.kernel.org Cc: Sai Prakash Ranjan , iommu@lists.linux-foundation.org, John Stultz , freedreno@lists.freedesktop.org, Akhil P Oommen , Daniel Vetter , David Airlie , Emil Velikov , Eric Anholt , Jonathan Marek , Rob Clark , Sean Paul , Sharat Masetty , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 6/6] drm/msm/a6xx: Add support for per-instance pagetables Date: Fri, 26 Jun 2020 14:04:14 -0600 Message-Id: <20200626200414.14382-7-jcrouse@codeaurora.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200626200414.14382-1-jcrouse@codeaurora.org> References: <20200626200414.14382-1-jcrouse@codeaurora.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add support for using per-instance pagetables if all the dependencies are available. Signed-off-by: Jordan Crouse --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 43 +++++++++++++++++++++++++++ drivers/gpu/drm/msm/msm_ringbuffer.h | 1 + 2 files changed, 44 insertions(+) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index aa53f47b7e8b..95ed2ceac121 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -79,6 +79,34 @@ static void get_stats_counter(struct msm_ringbuffer *ring, u32 counter, OUT_RING(ring, upper_32_bits(iova)); } +static void a6xx_set_pagetable(struct msm_gpu *gpu, struct msm_ringbuffer *ring, + struct msm_file_private *ctx) +{ + phys_addr_t ttbr; + u32 asid; + + if (msm_iommu_pagetable_params(ctx->aspace->mmu, &ttbr, &asid)) + return; + + /* Execute the table update */ + OUT_PKT7(ring, CP_SMMU_TABLE_UPDATE, 4); + OUT_RING(ring, lower_32_bits(ttbr)); + OUT_RING(ring, (((u64) asid) << 48) | upper_32_bits(ttbr)); + /* CONTEXTIDR is currently unused */ + OUT_RING(ring, 0); + /* CONTEXTBANK is currently unused */ + OUT_RING(ring, 0); + + /* + * Write the new TTBR0 to the memstore. This is good for debugging. + */ + OUT_PKT7(ring, CP_MEM_WRITE, 4); + OUT_RING(ring, lower_32_bits(rbmemptr(ring, ttbr0))); + OUT_RING(ring, upper_32_bits(rbmemptr(ring, ttbr0))); + OUT_RING(ring, lower_32_bits(ttbr)); + OUT_RING(ring, (((u64) asid) << 48) | upper_32_bits(ttbr)); +} + static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, struct msm_file_private *ctx) { @@ -89,6 +117,8 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, struct msm_ringbuffer *ring = submit->ring; unsigned int i; + a6xx_set_pagetable(gpu, ring, ctx); + get_stats_counter(ring, REG_A6XX_RBBM_PERFCTR_CP_0_LO, rbmemptr_stats(ring, index, cpcycles_start)); @@ -872,6 +902,18 @@ static unsigned long a6xx_gpu_busy(struct msm_gpu *gpu) return (unsigned long)busy_time; } +struct msm_gem_address_space *a6xx_address_space_instance(struct msm_gpu *gpu) +{ + struct msm_mmu *mmu; + + mmu = msm_iommu_pagetable_create(gpu->aspace->mmu); + if (IS_ERR(mmu)) + return msm_gem_address_space_get(gpu->aspace); + + return msm_gem_address_space_create(mmu, + "gpu", 0x100000000ULL, 0x1ffffffffULL); +} + static const struct adreno_gpu_funcs funcs = { .base = { .get_param = adreno_get_param, @@ -895,6 +937,7 @@ static const struct adreno_gpu_funcs funcs = { .gpu_state_put = a6xx_gpu_state_put, #endif .create_address_space = adreno_iommu_create_address_space, + .address_space_instance = a6xx_address_space_instance, }, .get_timestamp = a6xx_get_timestamp, }; diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.h b/drivers/gpu/drm/msm/msm_ringbuffer.h index 7764373d0ed2..0987d6bf848c 100644 --- a/drivers/gpu/drm/msm/msm_ringbuffer.h +++ b/drivers/gpu/drm/msm/msm_ringbuffer.h @@ -31,6 +31,7 @@ struct msm_rbmemptrs { volatile uint32_t fence; volatile struct msm_gpu_submit_stats stats[MSM_GPU_SUBMIT_STATS_COUNT]; + volatile u64 ttbr0; }; struct msm_ringbuffer {