From patchwork Thu Jul 23 14:57:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 11681135 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 7142613B4 for ; Thu, 23 Jul 2020 15:06:18 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 309DA208E4 for ; Thu, 23 Jul 2020 15:06:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="aCMH28yf" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 309DA208E4 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id C907D6B0006; Thu, 23 Jul 2020 11:06:16 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id C41756B0007; Thu, 23 Jul 2020 11:06:16 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id B33F16B0008; Thu, 23 Jul 2020 11:06:16 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0036.hostedemail.com [216.40.44.36]) by kanga.kvack.org (Postfix) with ESMTP id 9C73F6B0006 for ; Thu, 23 Jul 2020 11:06:16 -0400 (EDT) Received: from smtpin21.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay02.hostedemail.com (Postfix) with ESMTP id 5A85CBF03 for ; Thu, 23 Jul 2020 15:06:16 +0000 (UTC) X-FDA: 77069666352.21.value78_181711f26f3f Received: from filter.hostedemail.com (10.5.16.251.rfc1918.com [10.5.16.251]) by smtpin21.hostedemail.com (Postfix) with ESMTP id 0302E18044756 for ; Thu, 23 Jul 2020 15:06:10 +0000 (UTC) X-Spam-Summary: 1,0,0,8cd1e868e2efa4f2,d41d8cd98f00b204,jean-philippe@linaro.org,,RULES_HIT:2:41:69:355:379:541:800:960:966:973:982:988:989:1260:1311:1314:1345:1359:1437:1515:1535:1605:1606:1730:1747:1777:1792:2196:2199:2376:2393:2553:2559:2562:2693:2895:3138:3139:3140:3141:3142:3865:3866:3867:3868:3870:3871:3872:3874:4120:4250:4321:4385:4605:5007:6119:6261:6653:6742:7874:7903:9040:9592:10004:11026:11473:11658:11914:12043:12291:12296:12297:12438:12517:12519:12555:12683:12895:12986:13161:13229:13894:14096:14394:21080:21433:21444:21451:21627:21990:30054:30070:30090,0,RBL:209.85.218.67:@linaro.org:.lbl8.mailshell.net-66.100.201.201 62.2.0.100;04ygx1e7fsz91z3cfde5a56f4cp9yoc1twx53gmiurshxeiyqfhmfki13sicegx.ghnd75dpzwcwqmupewxn37b31mqs6tjodkw38kss4sjrdpzijuuj8m1hsx41qdr.q-lbl8.mailshell.net-223.238.255.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:ft,MSBL:0,DNSBL:neutral,Custom_rules:0:0:0,LFtime:25,LUA_SUMMARY:none X-HE-Tag: value78_181711f26f3f X-Filterd-Recvd-Size: 9088 Received: from mail-ej1-f67.google.com (mail-ej1-f67.google.com [209.85.218.67]) by imf12.hostedemail.com (Postfix) with ESMTP for ; Thu, 23 Jul 2020 15:05:57 +0000 (UTC) Received: by mail-ej1-f67.google.com with SMTP id br7so6756856ejb.5 for ; Thu, 23 Jul 2020 08:05:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=wskuJloDXQffCZslMedcsZLhDNM/RTcftR4W5M+lmWM=; b=aCMH28yfVT0dvw1jNUUZbraQg0/4QDSbSz+ipcvfIDhdbz2vRFp3gQyyZcGEeOpIOf Rk6ZnzcSzfP5U5s7YRqSVsQpUjLMeafohbmXpBJ7W3cP6eonBGltklz41+NaxrRh6KXR 8nNwD3m8wK5KJI5I9RTCs8hDN+qtGUb0sL89irJmOnt7TQswOSqjyvx+Wz0jNW/5DKde fBEmAZK5nmCq5IqFkb7+f6r0CSP5mi6nGaFF2fC/yjVrGHFemFsd/NxvuU7UB/IEY2QF 6M6jVyc3K+eUpLxJwuaNq2xpP+hdAOSlWiiFig33xtIJIKR1oyfLwAn2X87VVQSoEQqK xLlA== 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:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=wskuJloDXQffCZslMedcsZLhDNM/RTcftR4W5M+lmWM=; b=iDV+LaI0EwhrR0cPJTmmgUCknvxnGV5UJJ3foueUQ1Qvwpij/+ByX11L7XMwtr7HE5 /InsGKqksOZ+MwHJ1DGl9ZlR7063//kLgdrQ1hr0oNx9XEp3uBSRJofz7jCzwn/Qmp1L kp0kWFXEKzltHEbeCYLmOPebgInjxe3axBjvLUpSXSjUHQ0PDAb7ypWP9GGlbe2rhk80 Raru1t9WdwFxDZqxsj5wuUl2SJ1t7fjNRYzEvhcjKpmxUoWg4ht2dbZqB9pcWseLJRvV kehi/DVq+Dw1U+EaLtEBVt16rbHx9PDx6rME6OS0wxWa8sy313tcLOtUU2JuY3YeCiXR SjFw== X-Gm-Message-State: AOAM531WbRdEhjHB/LfXFHksWUkU49Auf9+FWs2JQFU+Lm2DOgb+g4AT Z0pxPedn/6AkvQx1u/eHhqSQ5Q== X-Google-Smtp-Source: ABdhPJyB1Vkh5KERl8YmjBS8VfddZR0PFejHbSzUL2vYjqtEO7CwYUzdDRG0iR2rh/YcuHmXTAF++A== X-Received: by 2002:a17:906:1747:: with SMTP id d7mr4752761eje.39.1595516756567; Thu, 23 Jul 2020 08:05:56 -0700 (PDT) Received: from localhost.localdomain ([2001:1715:4e26:a7e0:116c:c27a:3e7f:5eaf]) by smtp.gmail.com with ESMTPSA id k15sm2145952eji.49.2020.07.23.08.05.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Jul 2020 08:05:56 -0700 (PDT) From: Jean-Philippe Brucker To: iommu@lists.linux-foundation.org, linux-arm-kernel@lists.infradead.org, linux-mm@kvack.org Cc: joro@8bytes.org, catalin.marinas@arm.com, will@kernel.org, robin.murphy@arm.com, baolu.lu@linux.intel.com, Jonathan.Cameron@huawei.com, jacob.jun.pan@linux.intel.com, zhangfei.gao@linaro.org, xuzaibo@huawei.com, zhengxiang9@huawei.com, fenghua.yu@intel.com, hch@infradead.org, Jean-Philippe Brucker Subject: [PATCH v9 09/13] iommu/arm-smmu-v3: Seize private ASID Date: Thu, 23 Jul 2020 16:57:21 +0200 Message-Id: <20200723145724.3014766-10-jean-philippe@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200723145724.3014766-1-jean-philippe@linaro.org> References: <20200723145724.3014766-1-jean-philippe@linaro.org> MIME-Version: 1.0 X-Rspamd-Queue-Id: 0302E18044756 X-Spamd-Result: default: False [0.00 / 100.00] X-Rspamd-Server: rspam01 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: The SMMU has a single ASID space, the union of shared and private ASID sets. This means that the SMMU driver competes with the arch allocator for ASIDs. Shared ASIDs are those of Linux processes, allocated by the arch, and contribute in broadcast TLB maintenance. Private ASIDs are allocated by the SMMU driver and used for "classic" map/unmap DMA. They require command-queue TLB invalidations. When we pin down an mm_context and get an ASID that is already in use by the SMMU, it belongs to a private context. We used to simply abort the bind, but this is unfair to users that would be unable to bind a few seemingly random processes. Try to allocate a new private ASID for the context, and make the old ASID shared. Signed-off-by: Jean-Philippe Brucker --- drivers/iommu/arm-smmu-v3.h | 3 +++ drivers/iommu/arm-smmu-v3-sva.c | 36 +++++++++++++++++++++++++++++++-- drivers/iommu/arm-smmu-v3.c | 34 +++++++++++++++++++------------ 3 files changed, 58 insertions(+), 15 deletions(-) diff --git a/drivers/iommu/arm-smmu-v3.h b/drivers/iommu/arm-smmu-v3.h index 6b06a6f19604..90c08f156b43 100644 --- a/drivers/iommu/arm-smmu-v3.h +++ b/drivers/iommu/arm-smmu-v3.h @@ -678,6 +678,9 @@ struct arm_smmu_domain { extern struct xarray arm_smmu_asid_xa; extern struct mutex arm_smmu_asid_lock; +int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid, + struct arm_smmu_ctx_desc *cd); +void arm_smmu_tlb_inv_asid(struct arm_smmu_device *smmu, u16 asid); bool arm_smmu_free_asid(struct arm_smmu_ctx_desc *cd); #endif /* _ARM_SMMU_V3_H */ diff --git a/drivers/iommu/arm-smmu-v3-sva.c b/drivers/iommu/arm-smmu-v3-sva.c index 7c1541864688..d590c864bdf3 100644 --- a/drivers/iommu/arm-smmu-v3-sva.c +++ b/drivers/iommu/arm-smmu-v3-sva.c @@ -10,10 +10,19 @@ #include "arm-smmu-v3.h" #include "io-pgtable-arm.h" +/* + * Try to reserve this ASID in the SMMU. If it is in use, try to steal it from + * the private entry. Careful here, we may be modifying the context tables of + * another SMMU! + */ static struct arm_smmu_ctx_desc * arm_smmu_share_asid(struct mm_struct *mm, u16 asid) { + int ret; + u32 new_asid; struct arm_smmu_ctx_desc *cd; + struct arm_smmu_device *smmu; + struct arm_smmu_domain *smmu_domain; cd = xa_load(&arm_smmu_asid_xa, asid); if (!cd) @@ -27,8 +36,31 @@ arm_smmu_share_asid(struct mm_struct *mm, u16 asid) return cd; } - /* Ouch, ASID is already in use for a private cd. */ - return ERR_PTR(-EBUSY); + smmu_domain = container_of(cd, struct arm_smmu_domain, s1_cfg.cd); + smmu = smmu_domain->smmu; + + ret = xa_alloc(&arm_smmu_asid_xa, &new_asid, cd, + XA_LIMIT(1, 1 << smmu->asid_bits), GFP_KERNEL); + if (ret) + return ERR_PTR(-ENOSPC); + /* + * Race with unmap: TLB invalidations will start targeting the new ASID, + * which isn't assigned yet. We'll do an invalidate-all on the old ASID + * later, so it doesn't matter. + */ + cd->asid = new_asid; + /* + * Update ASID and invalidate CD in all associated masters. There will + * be some overlap between use of both ASIDs, until we invalidate the + * TLB. + */ + arm_smmu_write_ctx_desc(smmu_domain, 0, cd); + + /* Invalidate TLB entries previously associated with that context */ + arm_smmu_tlb_inv_asid(smmu, asid); + + xa_erase(&arm_smmu_asid_xa, asid); + return NULL; } __maybe_unused diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 06f148a9ed82..4a47b977ed01 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -873,6 +873,17 @@ static int arm_smmu_cmdq_batch_submit(struct arm_smmu_device *smmu, } /* Context descriptor manipulation functions */ +void arm_smmu_tlb_inv_asid(struct arm_smmu_device *smmu, u16 asid) +{ + struct arm_smmu_cmdq_ent cmd = { + .opcode = CMDQ_OP_TLBI_NH_ASID, + .tlbi.asid = asid, + }; + + arm_smmu_cmdq_issue_cmd(smmu, &cmd); + arm_smmu_cmdq_issue_sync(smmu); +} + static void arm_smmu_sync_cd(struct arm_smmu_domain *smmu_domain, int ssid, bool leaf) { @@ -953,8 +964,8 @@ static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_domain *smmu_domain, return l1_desc->l2ptr + idx * CTXDESC_CD_DWORDS; } -static int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, - int ssid, struct arm_smmu_ctx_desc *cd) +int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid, + struct arm_smmu_ctx_desc *cd) { /* * This function handles the following cases: @@ -1610,15 +1621,6 @@ static void arm_smmu_tlb_inv_context(void *cookie) struct arm_smmu_device *smmu = smmu_domain->smmu; struct arm_smmu_cmdq_ent cmd; - if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) { - cmd.opcode = CMDQ_OP_TLBI_NH_ASID; - cmd.tlbi.asid = smmu_domain->s1_cfg.cd.asid; - cmd.tlbi.vmid = 0; - } else { - cmd.opcode = CMDQ_OP_TLBI_S12_VMALL; - cmd.tlbi.vmid = smmu_domain->s2_cfg.vmid; - } - /* * NOTE: when io-pgtable is in non-strict mode, we may get here with * PTEs previously cleared by unmaps on the current CPU not yet visible @@ -1626,8 +1628,14 @@ static void arm_smmu_tlb_inv_context(void *cookie) * insertion to guarantee those are observed before the TLBI. Do be * careful, 007. */ - arm_smmu_cmdq_issue_cmd(smmu, &cmd); - arm_smmu_cmdq_issue_sync(smmu); + if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) { + arm_smmu_tlb_inv_asid(smmu, smmu_domain->s1_cfg.cd.asid); + } else { + cmd.opcode = CMDQ_OP_TLBI_S12_VMALL; + cmd.tlbi.vmid = smmu_domain->s2_cfg.vmid; + arm_smmu_cmdq_issue_cmd(smmu, &cmd); + arm_smmu_cmdq_issue_sync(smmu); + } arm_smmu_atc_inv_domain(smmu_domain, 0, 0, 0); }