From patchwork Tue Apr 9 12:53:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Leizhen \(ThunderTown\)" X-Patchwork-Id: 161976 Delivered-To: patch@linaro.org Received: by 2002:a02:c6d8:0:0:0:0:0 with SMTP id r24csp4908228jan; Tue, 9 Apr 2019 05:54:21 -0700 (PDT) X-Google-Smtp-Source: APXvYqwJmTL91OZGlPftxudxTLrKYJ7UhU6MsAponm9A4nUAUEzCVFoO7fwAVt+lg+1bYSaE1Yg7 X-Received: by 2002:a63:243:: with SMTP id 64mr34329110pgc.214.1554814461217; Tue, 09 Apr 2019 05:54:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1554814461; cv=none; d=google.com; s=arc-20160816; b=yU9/yRxEF2r37KHKP+3RATjq5L44vNkoVUnfQUslZG+eTTN2Fdd1ltX5BD51OByUcs 9nQAjtsGt6aNCDUXP4U8byvZDa6wp1ILYQiXyLaJ5ZisAsCgA1W2yLkMVDZ3/1bExrpk 8sfHDzn0qOzCVT55VlBB220fLopmcCtz2Eitf9Qj6O11eiJRHX09UyehO7zvOJ7WSWLj JcR1sr25IO4UchVUvcBeYAyBof9RgRQfyGOUSZ6llg/b9Ogb/o0xIX2YSa5sLh026U7M XM/CG3kJrTBTPUkIyTjLZM3aB52HxOlMEn6ez8eR30yxaVoeYlB02QCzUqA4mA/6/vc8 HlBA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=ymkthyqzd4LqW49qGhcBPUApx3sNSlhPVYf4gLep4u8=; b=skM5a0uS45Gc9uAcp5vx7Ra177NFAcXoij6I9uLisaiWfa+QjCzK9Cjzw1goEYGOTM ZW1VunBHMqmjPp3uDxoYiAQgx1UqP1KDPPrwTjlo2RwBs8qUAW3kKFIFgMnjQJVbP+Xj 2GvBOkY2iuFYVK+7OVkR3vA7diG51wUq4aGFZ22cWKnpXn6+TN5L83R+SqYwRQE/HlFT fvyM5zyowQQIsu7g8VvkLvISKK9kGQ47pibfFGAlejhJJkoy8yLoaG8p0gQlOKLgk4Y4 WHwcSZ2UkK0mrUa1aUkQoG+iFFp/Gqab7YIo+zx4cHZLLJIBfnNw1AVoSRBINQNJXpzs TEug== ARC-Authentication-Results: i=1; mx.google.com; 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 g136si31089845pfb.29.2019.04.09.05.54.20; Tue, 09 Apr 2019 05:54:21 -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; 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 S1727302AbfDIMyT (ORCPT + 31 others); Tue, 9 Apr 2019 08:54:19 -0400 Received: from szxga06-in.huawei.com ([45.249.212.32]:44310 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726875AbfDIMyS (ORCPT ); Tue, 9 Apr 2019 08:54:18 -0400 Received: from DGGEMS414-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 4A97C6D5654AA5909F20; Tue, 9 Apr 2019 20:54:10 +0800 (CST) Received: from HGHY1l002753561.china.huawei.com (10.177.23.164) by DGGEMS414-HUB.china.huawei.com (10.3.19.214) with Microsoft SMTP Server id 14.3.408.0; Tue, 9 Apr 2019 20:54:01 +0800 From: Zhen Lei To: Jean-Philippe Brucker , John Garry , Robin Murphy , Will Deacon , Joerg Roedel , Jonathan Corbet , linux-doc , Sebastian Ott , Gerald Schaefer , "Martin Schwidefsky" , Heiko Carstens , Benjamin Herrenschmidt , Paul Mackerras , "Michael Ellerman" , Tony Luck , Fenghua Yu , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H . Peter Anvin" , David Woodhouse , iommu , linux-kernel , linux-s390 , linuxppc-dev , x86 , linux-ia64 CC: Zhen Lei , Hanjun Guo Subject: [PATCH v5 1/6] iommu: add generic boot option iommu.dma_mode Date: Tue, 9 Apr 2019 20:53:03 +0800 Message-ID: <20190409125308.18304-2-thunder.leizhen@huawei.com> X-Mailer: git-send-email 2.19.2.windows.1 In-Reply-To: <20190409125308.18304-1-thunder.leizhen@huawei.com> References: <20190409125308.18304-1-thunder.leizhen@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.177.23.164] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Currently the IOMMU dma contains 3 modes: passthrough, lazy, strict. The passthrough mode bypass the IOMMU, the lazy mode defer the invalidation of hardware TLBs, and the strict mode invalidate IOMMU hardware TLBs synchronously. The three modes are mutually exclusive. But the current boot options are confused, such as: iommu.passthrough and iommu.strict, because they are no good to be coexist. So add iommu.dma_mode. Signed-off-by: Zhen Lei --- Documentation/admin-guide/kernel-parameters.txt | 19 ++++++++ drivers/iommu/iommu.c | 59 ++++++++++++++++++++----- include/linux/iommu.h | 5 +++ 3 files changed, 71 insertions(+), 12 deletions(-) -- 1.8.3 diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 2b8ee90bb64470d..f7766f8ac8b9084 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -1811,6 +1811,25 @@ 1 - Bypass the IOMMU for DMA. unset - Use value of CONFIG_IOMMU_DEFAULT_PASSTHROUGH. + iommu.dma_mode= Configure default dma mode. if unset, use the value + of CONFIG_IOMMU_DEFAULT_PASSTHROUGH to determine + passthrough or not. + Note: For historical reasons, ARM64/S390/PPC/X86 have + their specific options. Currently, only ARM64 support + this boot option, and hope other ARCHs to use this as + generic boot option. + passthrough + Configure DMA to bypass the IOMMU by default. + lazy + Request that DMA unmap operations use deferred + invalidation of hardware TLBs, for increased + throughput at the cost of reduced device isolation. + Will fall back to strict mode if not supported by + the relevant IOMMU driver. + strict + DMA unmap operations invalidate IOMMU hardware TLBs + synchronously. + io7= [HW] IO7 for Marvel based alpha systems See comment before marvel_specify_io7 in arch/alpha/kernel/core_marvel.c. diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 109de67d5d727c2..df1ce8e22385b48 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -38,12 +38,13 @@ static struct kset *iommu_group_kset; static DEFINE_IDA(iommu_group_ida); + #ifdef CONFIG_IOMMU_DEFAULT_PASSTHROUGH -static unsigned int iommu_def_domain_type = IOMMU_DOMAIN_IDENTITY; +#define IOMMU_DEFAULT_DMA_MODE IOMMU_DMA_MODE_PASSTHROUGH #else -static unsigned int iommu_def_domain_type = IOMMU_DOMAIN_DMA; +#define IOMMU_DEFAULT_DMA_MODE IOMMU_DMA_MODE_STRICT #endif -static bool iommu_dma_strict __read_mostly = true; +static int iommu_default_dma_mode __read_mostly = IOMMU_DEFAULT_DMA_MODE; struct iommu_callback_data { const struct iommu_ops *ops; @@ -147,20 +148,51 @@ static int __init iommu_set_def_domain_type(char *str) int ret; ret = kstrtobool(str, &pt); - if (ret) - return ret; + if (!ret && pt) + iommu_default_dma_mode = IOMMU_DMA_MODE_PASSTHROUGH; - iommu_def_domain_type = pt ? IOMMU_DOMAIN_IDENTITY : IOMMU_DOMAIN_DMA; - return 0; + return ret; } early_param("iommu.passthrough", iommu_set_def_domain_type); static int __init iommu_dma_setup(char *str) { - return kstrtobool(str, &iommu_dma_strict); + bool strict; + int ret; + + ret = kstrtobool(str, &strict); + if (!ret) + iommu_default_dma_mode = strict ? + IOMMU_DMA_MODE_STRICT : IOMMU_DMA_MODE_LAZY; + + return ret; } early_param("iommu.strict", iommu_dma_setup); +static int __init iommu_dma_mode_setup(char *str) +{ + if (!str) + goto fail; + + if (!strncmp(str, "passthrough", 11)) + iommu_default_dma_mode = IOMMU_DMA_MODE_PASSTHROUGH; + else if (!strncmp(str, "lazy", 4)) + iommu_default_dma_mode = IOMMU_DMA_MODE_LAZY; + else if (!strncmp(str, "strict", 6)) + iommu_default_dma_mode = IOMMU_DMA_MODE_STRICT; + else + goto fail; + + pr_info("Force dma mode to be %d\n", iommu_default_dma_mode); + + return 0; + +fail: + pr_debug("Boot option iommu.dma_mode is incorrect, ignored\n"); + return -EINVAL; +} +early_param("iommu.dma_mode", iommu_dma_mode_setup); + static ssize_t iommu_group_attr_show(struct kobject *kobj, struct attribute *__attr, char *buf) { @@ -1102,14 +1134,17 @@ struct iommu_group *iommu_group_get_for_dev(struct device *dev) */ if (!group->default_domain) { struct iommu_domain *dom; + int def_domain_type = + (iommu_default_dma_mode == IOMMU_DMA_MODE_PASSTHROUGH) + ? IOMMU_DOMAIN_IDENTITY : IOMMU_DOMAIN_DMA; - dom = __iommu_domain_alloc(dev->bus, iommu_def_domain_type); - if (!dom && iommu_def_domain_type != IOMMU_DOMAIN_DMA) { + dom = __iommu_domain_alloc(dev->bus, def_domain_type); + if (!dom && def_domain_type != IOMMU_DOMAIN_DMA) { dom = __iommu_domain_alloc(dev->bus, IOMMU_DOMAIN_DMA); if (dom) { dev_warn(dev, "failed to allocate default IOMMU domain of type %u; falling back to IOMMU_DOMAIN_DMA", - iommu_def_domain_type); + def_domain_type); } } @@ -1117,7 +1152,7 @@ struct iommu_group *iommu_group_get_for_dev(struct device *dev) if (!group->domain) group->domain = dom; - if (dom && !iommu_dma_strict) { + if (dom && (iommu_default_dma_mode == IOMMU_DMA_MODE_LAZY)) { int attr = 1; iommu_domain_set_attr(dom, DOMAIN_ATTR_DMA_USE_FLUSH_QUEUE, diff --git a/include/linux/iommu.h b/include/linux/iommu.h index ffbbc7e39ceeba3..c3f4e3416176496 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -42,6 +42,11 @@ */ #define IOMMU_PRIV (1 << 5) + +#define IOMMU_DMA_MODE_STRICT 0x0 +#define IOMMU_DMA_MODE_LAZY 0x1 +#define IOMMU_DMA_MODE_PASSTHROUGH 0x2 + struct iommu_ops; struct iommu_group; struct bus_type;