Received: by 2002:a17:90a:1609:0:0:0:0 with SMTP id n9csp162845pja; Thu, 9 Apr 2020 16:36:16 -0700 (PDT) X-Google-Smtp-Source: APiQypI+jl6ezkL/6euA3+K4Yeb5MsZ/HrCNs9cLATA895WIZmXLRP71UTsKtAIEXuj0htKPG3hw X-Received: by 2002:a05:6214:294:: with SMTP id l20mr2744864qvv.46.1586475376686; Thu, 09 Apr 2020 16:36:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1586475376; cv=none; d=google.com; s=arc-20160816; b=Vp+ftfuBD5gXOVCsJXJt6P76+yI6x6uz9okkTbgc6cyTXudx3hPxXudz+HVYyvkYMq XRfQ3Xx4QzhJveZCQQze1XjS/XGde3O/1JS98SYEdUTLrTJI2xC6bzYLj/xWLMvPouPX fb1BW5z5MzvmQZfTLnHEMULDN1Am39qku0bfzghs3ZwmAj1prfXEz/Nq2ooFmtG4wmL8 BTZ1KKfuBzohyrogddrQz1JNmm74al7ecTrcw2G4OWZL3nZaW0pfSXsdDcvwSY3tNOaN u3b6JixZWVLkfj6XnPstI0azq5/emOPhBqcimLQBTxgff/839Gyw1aeFVi8PO53SOrz3 LsNA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dmarc-filter:dkim-signature; bh=UK2PydfYoICpS0Qk8vNme1sj9VZ+x5SklNglOnB1asM=; b=IcVo3n8PL4p2mI7Wg9kYfBw8R+68GmeHqKdGEYflG22pnTX/Pe3iD0TaBnBYBjFoJv 7WxX6wEjJytUdNCqOkSOXoQdyENeEJh1CyaSbqt49LLIht1MTogifRmh07hj4FdAXsOb Z8WF0ybd4dSxvoSjuhzbGR/04k4QnBXh3lZ8yAoPVLEfVliI4DajNj3sNWRBa0Nt61SC jUoxHznB2iP3YCeiF4KKE0d33ygQLw5Vj3QxupeW4EPR4kBJhCYmRyqI0AYgtme+1J8B uEp8c+bXx4psbNaqX2oFmGThA6vq7AKWPUP8M5UkNhCw8g/lSth7yBWHEeOfcGxbWStV IRKg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@mg.codeaurora.org header.s=smtp header.b=dQgtzTjQ; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id y67si384551qkb.105.2020.04.09.16.36.01; Thu, 09 Apr 2020 16:36:16 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=fail header.i=@mg.codeaurora.org header.s=smtp header.b=dQgtzTjQ; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727173AbgDIXeD (ORCPT + 99 others); Thu, 9 Apr 2020 19:34:03 -0400 Received: from mail27.static.mailgun.info ([104.130.122.27]:51733 "EHLO mail27.static.mailgun.info" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727073AbgDIXeD (ORCPT ); Thu, 9 Apr 2020 19:34:03 -0400 DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; q=dns/txt; s=smtp; t=1586475243; h=References: In-Reply-To: Message-Id: Date: Subject: Cc: To: From: Sender; bh=UK2PydfYoICpS0Qk8vNme1sj9VZ+x5SklNglOnB1asM=; b=dQgtzTjQ5Ymc02nyCCvLVv9mR7FL401pazK9Az+GYHndtjtNcVeJ+a3jfBRvO9zBP1JPgGdw 6sQcN+L5VK+sPX7LQAnOUY9rT+UVx5YdM2xZ+k5qOZSJVq31Pjry8ov0olAA8zCTJ9lQT2zV YWPEEgIkDLgWqUamKh4P494+XRs= X-Mailgun-Sending-Ip: 104.130.122.27 X-Mailgun-Sid: WyI0MWYwYSIsICJsaW51eC1rZXJuZWxAdmdlci5rZXJuZWwub3JnIiwgImJlOWU0YSJd Received: from smtp.codeaurora.org (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by mxa.mailgun.org with ESMTP id 5e8fb0ea.7f330a7ed228-smtp-out-n05; Thu, 09 Apr 2020 23:34:02 -0000 (UTC) Received: by smtp.codeaurora.org (Postfix, from userid 1001) id BD1D4C3855B; Thu, 9 Apr 2020 23:33:59 +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 autolearn=unavailable autolearn_force=no version=3.4.0 Received: from localhost.localdomain (c-71-237-101-98.hsd1.co.comcast.net [71.237.101.98]) (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 69891C43636; Thu, 9 Apr 2020 23:33:58 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 69891C43636 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: iommu@lists.linux-foundation.org Cc: linux-arm-msm@vger.kernel.org, robin.murphy@arm.com, will@kernel.org, linux-arm-kernel@lists.infradead.org, Joerg Roedel , linux-kernel@vger.kernel.org Subject: [PATCH v6 2/5] iommu/arm-smmu: Add support for TTBR1 Date: Thu, 9 Apr 2020 17:33:47 -0600 Message-Id: <20200409233350.6343-3-jcrouse@codeaurora.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200409233350.6343-1-jcrouse@codeaurora.org> References: <20200409233350.6343-1-jcrouse@codeaurora.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add support to enable TTBR1 if the domain requests it via the DOMAIN_ATTR_SPLIT_TABLES attribute. If enabled by the hardware and pagetable configuration the driver will configure the TTBR1 region and program the domain pagetable on TTBR1. TTBR0 will be disabled. After attaching the device the value of he domain attribute can be queried to see if the split pagetables were successfully programmed. The domain geometry will be updated as well so that the caller can determine the active region for the pagetable that was programmed. Signed-off-by: Jordan Crouse --- drivers/iommu/arm-smmu.c | 48 ++++++++++++++++++++++++++++++++++------ drivers/iommu/arm-smmu.h | 24 +++++++++++++++----- 2 files changed, 59 insertions(+), 13 deletions(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index a6a5796e9c41..db6d503c1673 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -555,11 +555,16 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain, cb->ttbr[0] = pgtbl_cfg->arm_v7s_cfg.ttbr; cb->ttbr[1] = 0; } else { - cb->ttbr[0] = pgtbl_cfg->arm_lpae_s1_cfg.ttbr; - cb->ttbr[0] |= FIELD_PREP(ARM_SMMU_TTBRn_ASID, - cfg->asid); - cb->ttbr[1] = FIELD_PREP(ARM_SMMU_TTBRn_ASID, - cfg->asid); + cb->ttbr[0] = FIELD_PREP(ARM_SMMU_TTBRn_ASID, + cfg->asid); + + if (pgtbl_cfg->quirks & IO_PGTABLE_QUIRK_ARM_TTBR1) { + cb->ttbr[1] = pgtbl_cfg->arm_lpae_s1_cfg.ttbr; + } else { + cb->ttbr[0] |= pgtbl_cfg->arm_lpae_s1_cfg.ttbr; + cb->ttbr[1] = FIELD_PREP(ARM_SMMU_TTBRn_ASID, + cfg->asid); + } } } else { cb->ttbr[0] = pgtbl_cfg->arm_lpae_s2_cfg.vttbr; @@ -673,6 +678,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, enum io_pgtable_fmt fmt; struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); struct arm_smmu_cfg *cfg = &smmu_domain->cfg; + unsigned long quirks = 0; mutex_lock(&smmu_domain->init_mutex); if (smmu_domain->smmu) @@ -741,6 +747,14 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, oas = smmu->ipa_size; if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH64) { fmt = ARM_64_LPAE_S1; + + /* + * We are assuming that split pagetables will always use + * SEP_UPSTREAM so we don't need to reduce the size of + * the ias to account for the sign extension bit + */ + if (smmu_domain->split_pagetables) + quirks |= IO_PGTABLE_QUIRK_ARM_TTBR1; } else if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH32_L) { fmt = ARM_32_LPAE_S1; ias = min(ias, 32UL); @@ -810,6 +824,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, .coherent_walk = smmu->features & ARM_SMMU_FEAT_COHERENT_WALK, .tlb = smmu_domain->flush_ops, .iommu_dev = smmu->dev, + .quirks = quirks, }; if (smmu_domain->non_strict) @@ -823,8 +838,16 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, /* Update the domain's page sizes to reflect the page table format */ domain->pgsize_bitmap = pgtbl_cfg.pgsize_bitmap; - domain->geometry.aperture_end = (1UL << ias) - 1; - domain->geometry.force_aperture = true; + + if (pgtbl_cfg.quirks & IO_PGTABLE_QUIRK_ARM_TTBR1) { + domain->geometry.aperture_start = ~0UL << ias; + domain->geometry.aperture_end = ~0UL; + domain->geometry.force_aperture = true; + } else { + domain->geometry.aperture_end = (1UL << ias) - 1; + domain->geometry.force_aperture = true; + smmu_domain->split_pagetables = false; + } /* Initialise the context bank with our page table cfg */ arm_smmu_init_context_bank(smmu_domain, &pgtbl_cfg); @@ -1526,6 +1549,9 @@ 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_SPLIT_TABLES: + *(int *)data = smmu_domain->split_pagetables; + return 0; default: return -ENODEV; } @@ -1566,6 +1592,14 @@ static int arm_smmu_domain_set_attr(struct iommu_domain *domain, else smmu_domain->stage = ARM_SMMU_DOMAIN_S1; break; + case DOMAIN_ATTR_SPLIT_TABLES: + if (smmu_domain->smmu) { + ret = -EPERM; + goto out_unlock; + } + if (*(int *)data) + smmu_domain->split_pagetables = true; + break; default: ret = -ENODEV; } diff --git a/drivers/iommu/arm-smmu.h b/drivers/iommu/arm-smmu.h index 8d1cd54d82a6..5f6d0af7c8c8 100644 --- a/drivers/iommu/arm-smmu.h +++ b/drivers/iommu/arm-smmu.h @@ -172,6 +172,7 @@ enum arm_smmu_cbar_type { #define ARM_SMMU_TCR_SH0 GENMASK(13, 12) #define ARM_SMMU_TCR_ORGN0 GENMASK(11, 10) #define ARM_SMMU_TCR_IRGN0 GENMASK(9, 8) +#define ARM_SMMU_TCR_EPD0 BIT(7) #define ARM_SMMU_TCR_T0SZ GENMASK(5, 0) #define ARM_SMMU_VTCR_RES1 BIT(31) @@ -343,16 +344,27 @@ struct arm_smmu_domain { struct mutex init_mutex; /* Protects smmu pointer */ spinlock_t cb_lock; /* Serialises ATS1* ops and TLB syncs */ struct iommu_domain domain; + bool split_pagetables; }; static inline u32 arm_smmu_lpae_tcr(struct io_pgtable_cfg *cfg) { - return ARM_SMMU_TCR_EPD1 | - FIELD_PREP(ARM_SMMU_TCR_TG0, cfg->arm_lpae_s1_cfg.tcr.tg) | - FIELD_PREP(ARM_SMMU_TCR_SH0, cfg->arm_lpae_s1_cfg.tcr.sh) | - FIELD_PREP(ARM_SMMU_TCR_ORGN0, cfg->arm_lpae_s1_cfg.tcr.orgn) | - FIELD_PREP(ARM_SMMU_TCR_IRGN0, cfg->arm_lpae_s1_cfg.tcr.irgn) | - FIELD_PREP(ARM_SMMU_TCR_T0SZ, cfg->arm_lpae_s1_cfg.tcr.tsz); + u32 tcr = FIELD_PREP(ARM_SMMU_TCR_TG0, cfg->arm_lpae_s1_cfg.tcr.tg) | + FIELD_PREP(ARM_SMMU_TCR_SH0, cfg->arm_lpae_s1_cfg.tcr.sh) | + FIELD_PREP(ARM_SMMU_TCR_ORGN0, cfg->arm_lpae_s1_cfg.tcr.orgn) | + FIELD_PREP(ARM_SMMU_TCR_IRGN0, cfg->arm_lpae_s1_cfg.tcr.irgn) | + FIELD_PREP(ARM_SMMU_TCR_T0SZ, cfg->arm_lpae_s1_cfg.tcr.tsz); + + /* + * When TTBR1 is selected shift the TCR fields by 16 bits and disable + * translation in TTBR0 + */ + if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_TTBR1) + tcr = (tcr << 16) | ARM_SMMU_TCR_EPD0; + else + tcr |= ARM_SMMU_TCR_EPD1; + + return tcr; } static inline u32 arm_smmu_lpae_tcr2(struct io_pgtable_cfg *cfg) -- 2.17.1