From patchwork Tue Oct 25 00:17:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Kirill A. Shutemov" X-Patchwork-Id: 10445 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp738130wru; Mon, 24 Oct 2022 18:11:25 -0700 (PDT) X-Google-Smtp-Source: AMsMyM59ddiys6Fkm7Zl8AY3qHsDs9DVG1wPR3yiTgd2C63Nhy5WB/ORdrbZctFsEs+UpOHXy8fC X-Received: by 2002:a05:6402:270b:b0:45d:61cd:73cc with SMTP id y11-20020a056402270b00b0045d61cd73ccmr33541038edd.136.1666660274710; Mon, 24 Oct 2022 18:11:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666660274; cv=none; d=google.com; s=arc-20160816; b=Hl30JEUbLKxAf62JDMl1nXfKwfzAQrNWEpKDGLzklSvrPmwsEbI03wS6MWE2DBk201 Hf5MViqDGYxoxK4MSlwOf21i4iRdiAWy54K1s0Zl9oJh/RSj1BhFYLo74z3n2JaJfaQG W18xokR+Zm+CLm4xEKUWcb7K4ZAAdzV+8mIJytxiP7G6AHG5WobnFW3566vU7JEbcoTk ZncCJB4MIqkAi3xxaGTIahxbo2eqJ/SgfvGx/OgPhqyTKd6D7GzrRJJ5QckFmICtIu1s fEqmOlTP504usxATy0PsexVWemjjdO3pK5Povkyn9+xXWaVFsRyBXcQgyXqvYtw37PNC MNrw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=SqZpGW07FSaZUpk18lzAxyl4dAWwqbU3UNN1fG+SyLQ=; b=Zzom41YiS+arTHWOStD1U1/HXlVFw+LeeQwaZxz9eGcPrce1cAg/jCjQ3Dq2S0pNPE fIb/KTyJqdQvbhLnPP1YA9Ow/Lk/sM8J+Pu2WT293igZcP1KS8vh/Ff8k/PHmO8mEJnk iHEgq1lPVjVQMK8kBjtsTH4EGOyMBvJB4mfr958geIFaXw1LfcTby+jJr+MZW2SG+tZa rpPtj9IWRIGsfLJz7sQA10q1qwMh94C63dZ0ge4rYYBMDfg3Exr9XDD3cXHd9tt2ZbDH 8HbDEY6v+Hv2BT0Vkhz0s8I4slzsZdXZgwU18grzZe+l1nCEq2inGV5JCKCNdpRmL3E9 /xuQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=QPS7DvVd; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id hs33-20020a1709073ea100b0078d8c03a5a6si1493917ejc.759.2022.10.24.18.10.51; Mon, 24 Oct 2022 18:11:14 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=QPS7DvVd; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230500AbiJYBJu (ORCPT + 99 others); Mon, 24 Oct 2022 21:09:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40988 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230310AbiJYBIb (ORCPT ); Mon, 24 Oct 2022 21:08:31 -0400 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DEB73DDB5C for ; Mon, 24 Oct 2022 17:17:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1666657064; x=1698193064; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=rkwPYyuJLz3iWfInhtJeHv/DEtaKne5cyxOafJEfnU8=; b=QPS7DvVdxJvNfms0MsP2Lq9Fh3frwy3KDU/lGHJ1ib63ZIb1kJHnxSg2 ueSFhdMJ+Hk1tgVxrOaX7byzvsvsg+SrKO0XIeJlDOFdJzFSiPwyh8VIl I27725CV/8AY6qDCXs6tc+X0NsuTf0vF5LRyK3Numf7jDtIJxJk1SlUTt Ko9H69qAaqWmsv//QXpJrJ3mIe4piLgVciFqeopUUmEgGPhqob2Luirr0 CU11+18mFnbyQhe6S4UtyvFkcxyyGenqIl6frd42p+Nor35E0Wb0DVqg1 2U7ZI0R9eivUkkYQjM0kbbN2/+eSLyfevxXvRoRumUkVa0qSM4W7nvMb3 g==; X-IronPort-AV: E=McAfee;i="6500,9779,10510"; a="334143880" X-IronPort-AV: E=Sophos;i="5.95,210,1661842800"; d="scan'208";a="334143880" Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Oct 2022 17:17:42 -0700 X-IronPort-AV: E=McAfee;i="6500,9779,10510"; a="631447754" X-IronPort-AV: E=Sophos;i="5.95,210,1661842800"; d="scan'208";a="631447754" Received: from ghoyler-mobl.ger.corp.intel.com (HELO box.shutemov.name) ([10.249.39.118]) by orsmga002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Oct 2022 17:17:35 -0700 Received: by box.shutemov.name (Postfix, from userid 1000) id 194451095C0; Tue, 25 Oct 2022 03:17:26 +0300 (+03) From: "Kirill A. Shutemov" To: Dave Hansen , Andy Lutomirski , Peter Zijlstra Cc: x86@kernel.org, Kostya Serebryany , Andrey Ryabinin , Andrey Konovalov , Alexander Potapenko , Taras Madan , Dmitry Vyukov , "H . J . Lu" , Andi Kleen , Rick Edgecombe , Bharata B Rao , Jacob Pan , Ashok Raj , linux-mm@kvack.org, linux-kernel@vger.kernel.org, "Kirill A. Shutemov" Subject: [PATCHv11 11/16] x86/mm, iommu/sva: Make LAM and SVA mutually exclusive Date: Tue, 25 Oct 2022 03:17:17 +0300 Message-Id: <20221025001722.17466-12-kirill.shutemov@linux.intel.com> X-Mailer: git-send-email 2.38.0 In-Reply-To: <20221025001722.17466-1-kirill.shutemov@linux.intel.com> References: <20221025001722.17466-1-kirill.shutemov@linux.intel.com> MIME-Version: 1.0 X-Spam-Status: No, score=-7.5 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1747619964336064995?= X-GMAIL-MSGID: =?utf-8?q?1747619964336064995?= IOMMU and SVA-capable devices know nothing about LAM and only expect canonical addresses. An attempt to pass down tagged pointer will lead to address translation failure. By default do not allow to enable both LAM and use SVA in the same process. The new ARCH_FORCE_TAGGED_SVA arch_prctl() overrides the limitation. By using the arch_prctl() userspace takes responsibility to never pass tagged address to the device. Signed-off-by: Kirill A. Shutemov Reviewed-by: Ashok Raj Reviewed-by: Jacob Pan --- arch/x86/include/asm/mmu.h | 6 ++++-- arch/x86/include/asm/mmu_context.h | 6 ++++++ arch/x86/include/uapi/asm/prctl.h | 1 + arch/x86/kernel/process_64.c | 12 ++++++++++++ drivers/iommu/iommu-sva-lib.c | 12 ++++++++++++ include/linux/mmu_context.h | 7 +++++++ 6 files changed, 42 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/mmu.h b/arch/x86/include/asm/mmu.h index 2fdb390040b5..1215b0a714c9 100644 --- a/arch/x86/include/asm/mmu.h +++ b/arch/x86/include/asm/mmu.h @@ -9,9 +9,11 @@ #include /* Uprobes on this MM assume 32-bit code */ -#define MM_CONTEXT_UPROBE_IA32 BIT(0) +#define MM_CONTEXT_UPROBE_IA32 BIT(0) /* vsyscall page is accessible on this MM */ -#define MM_CONTEXT_HAS_VSYSCALL BIT(1) +#define MM_CONTEXT_HAS_VSYSCALL BIT(1) +/* Allow LAM and SVA coexisting */ +#define MM_CONTEXT_FORCE_TAGGED_SVA BIT(2) /* * x86 has arch-specific MMU state beyond what lives in mm_struct. diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h index 84277547ad28..7bb572d3f612 100644 --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h @@ -114,6 +114,12 @@ static inline void mm_reset_untag_mask(struct mm_struct *mm) mm->context.untag_mask = -1UL; } +#define arch_pgtable_dma_compat arch_pgtable_dma_compat +static inline bool arch_pgtable_dma_compat(struct mm_struct *mm) +{ + return !mm_lam_cr3_mask(mm) || + (mm->context.flags & MM_CONTEXT_FORCE_TAGGED_SVA); +} #else static inline unsigned long mm_lam_cr3_mask(struct mm_struct *mm) diff --git a/arch/x86/include/uapi/asm/prctl.h b/arch/x86/include/uapi/asm/prctl.h index a31e27b95b19..eb290d89cb32 100644 --- a/arch/x86/include/uapi/asm/prctl.h +++ b/arch/x86/include/uapi/asm/prctl.h @@ -23,5 +23,6 @@ #define ARCH_GET_UNTAG_MASK 0x4001 #define ARCH_ENABLE_TAGGED_ADDR 0x4002 #define ARCH_GET_MAX_TAG_BITS 0x4003 +#define ARCH_FORCE_TAGGED_SVA 0x4004 #endif /* _ASM_X86_PRCTL_H */ diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 9952e9f517ec..3c9a4d923d6d 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -783,6 +783,12 @@ static int prctl_enable_tagged_addr(struct mm_struct *mm, unsigned long nr_bits) goto out; } + if (mm_valid_pasid(mm) && + !(mm->context.flags & MM_CONTEXT_FORCE_TAGGED_SVA)) { + ret = -EBUSY; + goto out; + } + if (!nr_bits) { ret = -EINVAL; goto out; @@ -893,6 +899,12 @@ long do_arch_prctl_64(struct task_struct *task, int option, unsigned long arg2) (unsigned long __user *)arg2); case ARCH_ENABLE_TAGGED_ADDR: return prctl_enable_tagged_addr(task->mm, arg2); + case ARCH_FORCE_TAGGED_SVA: + if (mmap_write_lock_killable(task->mm)) + return -EINTR; + task->mm->context.flags |= MM_CONTEXT_FORCE_TAGGED_SVA; + mmap_write_unlock(task->mm); + return 0; case ARCH_GET_MAX_TAG_BITS: if (!cpu_feature_enabled(X86_FEATURE_LAM)) return put_user(0, (unsigned long __user *)arg2); diff --git a/drivers/iommu/iommu-sva-lib.c b/drivers/iommu/iommu-sva-lib.c index 27be6b81e0b5..8934c32e923c 100644 --- a/drivers/iommu/iommu-sva-lib.c +++ b/drivers/iommu/iommu-sva-lib.c @@ -2,6 +2,8 @@ /* * Helpers for IOMMU drivers implementing SVA */ +#include +#include #include #include @@ -31,6 +33,15 @@ int iommu_sva_alloc_pasid(struct mm_struct *mm, ioasid_t min, ioasid_t max) min == 0 || max < min) return -EINVAL; + /* Serialize against address tagging enabling */ + if (mmap_write_lock_killable(mm)) + return -EINTR; + + if (!arch_pgtable_dma_compat(mm)) { + mmap_write_unlock(mm); + return -EBUSY; + } + mutex_lock(&iommu_sva_lock); /* Is a PASID already associated with this mm? */ if (mm_valid_pasid(mm)) { @@ -46,6 +57,7 @@ int iommu_sva_alloc_pasid(struct mm_struct *mm, ioasid_t min, ioasid_t max) mm_pasid_set(mm, pasid); out: mutex_unlock(&iommu_sva_lock); + mmap_write_unlock(mm); return ret; } EXPORT_SYMBOL_GPL(iommu_sva_alloc_pasid); diff --git a/include/linux/mmu_context.h b/include/linux/mmu_context.h index 14b9c1fa05c4..f2b7a3f04099 100644 --- a/include/linux/mmu_context.h +++ b/include/linux/mmu_context.h @@ -35,4 +35,11 @@ static inline unsigned long mm_untag_mask(struct mm_struct *mm) } #endif +#ifndef arch_pgtable_dma_compat +static inline bool arch_pgtable_dma_compat(struct mm_struct *mm) +{ + return true; +} +#endif + #endif