From patchwork Fri Oct 6 13:31:47 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 9989451 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 DE58B6029B for ; Fri, 6 Oct 2017 13:32:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D112228DA6 for ; Fri, 6 Oct 2017 13:32:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C592D28DA9; Fri, 6 Oct 2017 13:32:53 +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=-4.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6287928DA8 for ; Fri, 6 Oct 2017 13:32:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=W0EA8Z6K1zRsi/OxTskIhYChBMQnHMqnDQHZrlkyjNY=; b=dnWdgpJcasNpjpTw4+VXyIalv6 ZLFVRhiM1P3pLg01fMgd62v0r/D4iU7BRmBmJYYp988Jow7+PMhAbM/xm1YW6RboRbOVNtotLG72k A3SYd4ib0BRVBAxjwoMg4sE4woy9Wg9vEfur4kG2tJxasCEm0J4xuKOf1Sw+4aWvPwzOnInl7BByG FwmXwDXaEQ9s+GOdZWAvUtexjk6Ev0eJpZyk5FKoNV+W4cf67zJX8V8PpP+CxrTN+Xf0R1xMKZQar gQ1ZtMNMyRjYWUxoMIKIgN4wQQSKM7ZFpSdKiMl9LbvbMKsD3ETNDAwL58S5H3zvaDvfOvXkG7Y3N Gho112JA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1e0Sju-0006YL-NW; Fri, 06 Oct 2017 13:32:30 +0000 Received: from foss.arm.com ([217.140.101.70]) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1e0Sh4-0002AQ-PP for linux-arm-kernel@lists.infradead.org; Fri, 06 Oct 2017 13:30:16 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id A462715A2; Fri, 6 Oct 2017 06:29:34 -0700 (PDT) Received: from e106794-lin.cambridge.arm.com (e106794-lin.cambridge.arm.com [10.1.211.72]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id CB2603F578; Fri, 6 Oct 2017 06:29:29 -0700 (PDT) From: Jean-Philippe Brucker To: linux-arm-kernel@lists.infradead.org, linux-pci@vger.kernel.org, linux-acpi@vger.kernel.org, devicetree@vger.kernel.org, iommu@lists.linux-foundation.org Subject: [RFCv2 PATCH 20/36] iommu/arm-smmu-v3: Track ASID state Date: Fri, 6 Oct 2017 14:31:47 +0100 Message-Id: <20171006133203.22803-21-jean-philippe.brucker@arm.com> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20171006133203.22803-1-jean-philippe.brucker@arm.com> References: <20171006133203.22803-1-jean-philippe.brucker@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20171006_062935_658875_EC161483 X-CRM114-Status: GOOD ( 13.67 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, xieyisheng1@huawei.com, gabriele.paoloni@huawei.com, catalin.marinas@arm.com, will.deacon@arm.com, okaya@codeaurora.org, yi.l.liu@intel.com, lorenzo.pieralisi@arm.com, ashok.raj@intel.com, tn@semihalf.com, joro@8bytes.org, rfranz@cavium.com, lenb@kernel.org, jacob.jun.pan@linux.intel.com, alex.williamson@redhat.com, robh+dt@kernel.org, thunder.leizhen@huawei.com, bhelgaas@google.com, dwmw2@infradead.org, liubo95@huawei.com, rjw@rjwysocki.net, robdclark@gmail.com, hanjun.guo@linaro.org, sudeep.holla@arm.com, robin.murphy@arm.com, nwatters@codeaurora.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP At the moment each SMMU has a 8- or 16-bit ASID set and allocates one ASID per device via a bitmap. ASIDs are used to differentiate address spaces in SMMU TLB entries. With SVM, sharing process address spaces with the SMMU, we need to use CPU ASIDs in SMMU contexts, to ensure that broadcast TLB invalidations reach the right IOTLB entries. When binding a process address space to a device, we become slaves to the arch ASID allocator. We have to use whatever ASID they give us. If a domain is currently using it, then we'll either abort or steal that ASID. To make matters worse, tasks are global, while domains are per-SMMU. SMMU ASIDs can be aliased across different SMMUs, but the CPU ASID space is unique across the whole system. Introduce an IDR for SMMU ASID allocation. It allows to keep information about an ASID, for instance which domain it is assigned to or how many devices are using it. Signed-off-by: Jean-Philippe Brucker --- drivers/iommu/arm-smmu-v3.c | 53 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 96347aad605f..71fc3a2c8a95 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -640,6 +640,10 @@ struct arm_smmu_strtab_cfg { u32 strtab_base_cfg; }; +struct arm_smmu_asid_state { + struct arm_smmu_domain *domain; +}; + /* An SMMUv3 instance */ struct arm_smmu_device { struct device *dev; @@ -681,7 +685,8 @@ struct arm_smmu_device { #define ARM_SMMU_MAX_ASIDS (1 << 16) unsigned int asid_bits; - DECLARE_BITMAP(asid_map, ARM_SMMU_MAX_ASIDS); + struct idr asid_idr; + spinlock_t asid_lock; #define ARM_SMMU_MAX_VMIDS (1 << 16) unsigned int vmid_bits; @@ -1828,7 +1833,11 @@ static void arm_smmu_domain_free(struct iommu_domain *domain) struct arm_smmu_s1_cfg *cfg = &smmu_domain->s1_cfg; if (cfg->num_contexts) { arm_smmu_free_cd_tables(smmu_domain); - arm_smmu_bitmap_free(smmu->asid_map, cfg->cd.asid); + + spin_lock(&smmu->asid_lock); + kfree(idr_find(&smmu->asid_idr, cfg->cd.asid)); + idr_remove(&smmu->asid_idr, cfg->cd.asid); + spin_unlock(&smmu->asid_lock); } } else { struct arm_smmu_s2_cfg *cfg = &smmu_domain->s2_cfg; @@ -1844,25 +1853,48 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain, { int ret; int asid; + struct arm_smmu_asid_state *asid_state; struct arm_smmu_device *smmu = smmu_domain->smmu; struct arm_smmu_s1_cfg *cfg = &smmu_domain->s1_cfg; - asid = arm_smmu_bitmap_alloc(smmu->asid_map, smmu->asid_bits); - if (asid < 0) - return asid; - ret = arm_smmu_alloc_cd_tables(smmu_domain); if (ret) - goto out_free_asid; + return ret; + + asid_state = kzalloc(sizeof(*asid_state), GFP_KERNEL); + if (!asid_state) { + ret = -ENOMEM; + goto out_free_tables; + } + + asid_state->domain = smmu_domain; + + idr_preload(GFP_KERNEL); + spin_lock(&smmu->asid_lock); + asid = idr_alloc_cyclic(&smmu->asid_idr, asid_state, 0, + 1 << smmu->asid_bits, GFP_ATOMIC); cfg->cd.asid = (u16)asid; cfg->cd.ttbr = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0]; cfg->cd.tcr = pgtbl_cfg->arm_lpae_s1_cfg.tcr; cfg->cd.mair = pgtbl_cfg->arm_lpae_s1_cfg.mair[0]; + + spin_unlock(&smmu->asid_lock); + idr_preload_end(); + + if (asid < 0) { + ret = asid; + goto out_free_asid_state; + } + return 0; -out_free_asid: - arm_smmu_bitmap_free(smmu->asid_map, asid); +out_free_asid_state: + kfree(asid_state); + +out_free_tables: + arm_smmu_free_cd_tables(smmu_domain); + return ret; } @@ -2506,6 +2538,9 @@ static int arm_smmu_init_structures(struct arm_smmu_device *smmu) { int ret; + spin_lock_init(&smmu->asid_lock); + idr_init(&smmu->asid_idr); + ret = arm_smmu_init_queues(smmu); if (ret) return ret;