From patchwork Mon Jun 21 23:52:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 465447 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B4AE0C49EA4 for ; Mon, 21 Jun 2021 23:53:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9DA3561351 for ; Mon, 21 Jun 2021 23:53:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232361AbhFUXzd (ORCPT ); Mon, 21 Jun 2021 19:55:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45346 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232286AbhFUXz2 (ORCPT ); Mon, 21 Jun 2021 19:55:28 -0400 Received: from mail-pg1-x530.google.com (mail-pg1-x530.google.com [IPv6:2607:f8b0:4864:20::530]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3CE5CC061787 for ; Mon, 21 Jun 2021 16:53:11 -0700 (PDT) Received: by mail-pg1-x530.google.com with SMTP id n12so6716816pgs.13 for ; Mon, 21 Jun 2021 16:53:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=x4ITCUhU/nAWeClxOuhPcTZrOECIOg+GaezMrYjqOog=; b=BwLqztGB8hIbqFPIG2iz+F3ycDuDHHtj9AyQbRD6lqT60SE8LExVuskXB76EYzXjVG lca+htEYcRd7QfmkKugvc8c/OcxzCpyT3q8iyt7e0nJep78c/HVq1/rqRuwnfVRpXWTL jgfxiTc8Dit5C0AJEdXOVb+ofslWLH/3o7/Ms= 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=x4ITCUhU/nAWeClxOuhPcTZrOECIOg+GaezMrYjqOog=; b=L3RsJ1CUBS+xMTUH2RJ+bxu34qUvKGuq2mEs/p9IPQJJP2zsBKYzEcJ9q293sIwFT8 lwrYpxnSuQ2jjSPy/uIQimlGrSNhViFyTMgwRA4PO3rras9s6u1wdqvQlke/ZjM3Gyf2 E2+SUItAbHqQvb5PqC8/vX+0tihyF1jzhAVuhf+dWPt9p9QVmYnFPwW5aFzAP4Wn5dGt N2NzpK33KCLvD+6tcfZvWZwa7o+NEiwJ4nvi0/k11TMPCdJ4vQeI+zbCxlZtfyHIsQGb nPVemNVaR/T/6Z6EN1tF+FLZ7YMwrW1OtRaNtM1Go7lgmBnJAzEaO8ElhVmJhWwX9crk xBOg== X-Gm-Message-State: AOAM532LsNP1YaReusnvJv8mFleIs4UKwKARaLvslRRli+Shp11lDnqX jUHbjpdSZDQuhOz6O4KUy/gVxg== X-Google-Smtp-Source: ABdhPJwZ1ajw+esBAxjNDymFx29gIQcnd4y55FxkQu9BFhGgtAStKyAK4b4QtnH9CUPyj40m+KG3Dg== X-Received: by 2002:aa7:9729:0:b029:2ff:1e52:e284 with SMTP id k9-20020aa797290000b02902ff1e52e284mr675748pfg.71.1624319590637; Mon, 21 Jun 2021 16:53:10 -0700 (PDT) Received: from tictac2.mtv.corp.google.com ([2620:15c:202:201:bdc1:a4b1:b06e:91d1]) by smtp.gmail.com with ESMTPSA id s27sm4339663pfg.169.2021.06.21.16.53.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 21 Jun 2021 16:53:10 -0700 (PDT) From: Douglas Anderson To: gregkh@linuxfoundation.org, rafael@kernel.org, rafael.j.wysocki@intel.com, will@kernel.org, robin.murphy@arm.com, joro@8bytes.org, bjorn.andersson@linaro.org, ulf.hansson@linaro.org, adrian.hunter@intel.com, bhelgaas@google.com Cc: robdclark@chromium.org, linux-arm-msm@vger.kernel.org, linux-pci@vger.kernel.org, quic_c_gdjako@quicinc.com, iommu@lists.linux-foundation.org, sonnyrao@chromium.org, saiprakash.ranjan@codeaurora.org, linux-mmc@vger.kernel.org, vbadigan@codeaurora.org, rajatja@google.com, saravanak@google.com, joel@joelfernandes.org, Douglas Anderson , Geert Uytterhoeven , linux-kernel@vger.kernel.org Subject: [PATCH 1/6] drivers: base: Add the concept of "pre_probe" to drivers Date: Mon, 21 Jun 2021 16:52:43 -0700 Message-Id: <20210621165230.1.Id4ee5788c993294f66542721fca7719c00a5d8f3@changeid> X-Mailer: git-send-email 2.32.0.288.g62a8d224e6-goog In-Reply-To: <20210621235248.2521620-1-dianders@chromium.org> References: <20210621235248.2521620-1-dianders@chromium.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org Right now things are a bit awkward if a driver would like a chance to run before some of the more "automatic" things (pinctrl, DMA, IOMMUs, ...) happen to a device. This patch aims to fix that problem by introducing the concept of a "pre_probe" function that drivers can implement to run before the "automatic" stuff. Why would you want to run before the "automatic" stuff? The incentive in my case is that I want to be able to fill in some boolean flags in the "struct device" before the IOMMU init runs. It appears that the strictness vs. non-strictness of a device's iommu config is determined once at init time and can't be changed afterwards. However, I would like to avoid hardcoding the rules for strictness in the IOMMU driver. Instead I'd like to let individual drivers be able to make informed decisions about the appropriateness of strictness vs. non-strictness. The desire for running code pre_probe is likely not limited to my use case. I believe that the list "qcom_smmu_client_of_match" is hacked into the iommu driver specifically because there was no real good framework for this. For the existing list it wasn't _quite_ as ugly as my needs since the decision could be made solely on compatible string, but it still feels like it would have been better for individual drivers to run code and setup some state rather than coding up a big list in the IOMMU driver. Even without this patch, I believe it is possible for a driver to run before the "automatic" things by registering for "BUS_NOTIFY_BIND_DRIVER" in its init call, though I haven't personally tested this. Using the notifier is a bit awkward, though, and I'd rather avoid it. Also, using "BUS_NOTIFY_BIND_DRIVER" would require drivers to stop using the convenience module_platform_driver() helper and roll a bunch of boilerplate code. NOTE: the pre_probe here is listed in the driver structure. As a side effect of this it will be passed a "struct device *" rather than the more specific device type (like the "struct platform_device *" that most platform devices get passed to their probe). Presumably this won't cause trouble and it's a lot less code to write but if we need to make it more symmetric that's also possible by touching more files. Signed-off-by: Douglas Anderson --- drivers/base/dd.c | 10 ++++++++-- include/linux/device/driver.h | 9 +++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index ecd7cf848daf..9a13bff8dafa 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -549,10 +549,16 @@ static int really_probe(struct device *dev, struct device_driver *drv) re_probe: dev->driver = drv; + if (drv->pre_probe) { + ret = drv->pre_probe(dev); + if (ret) + goto probe_failed_pre_dma; + } + /* If using pinctrl, bind pins now before probing */ ret = pinctrl_bind_pins(dev); if (ret) - goto pinctrl_bind_failed; + goto probe_failed_pre_dma; if (dev->bus->dma_configure) { ret = dev->bus->dma_configure(dev); @@ -639,7 +645,7 @@ static int really_probe(struct device *dev, struct device_driver *drv) if (dev->bus) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, BUS_NOTIFY_DRIVER_NOT_BOUND, dev); -pinctrl_bind_failed: +probe_failed_pre_dma: device_links_no_driver(dev); devres_release_all(dev); arch_teardown_dma_ops(dev); diff --git a/include/linux/device/driver.h b/include/linux/device/driver.h index a498ebcf4993..f7305dd6ceb1 100644 --- a/include/linux/device/driver.h +++ b/include/linux/device/driver.h @@ -57,6 +57,14 @@ enum probe_type { * @probe_type: Type of the probe (synchronous or asynchronous) to use. * @of_match_table: The open firmware table. * @acpi_match_table: The ACPI match table. + * @pre_probe: Called after a device has been bound to a driver but before + * anything "automatic" (pinctrl, DMA, IOMMUs, ...) has been + * setup. This is mostly a chance for the driver to do things + * that might need to be run before any of those automatic + * processes. The vast majority of devices don't need to + * implement this. Note that there is no "post_remove" at the + * moment. If you need to undo something that you did in + * pre_probe() you can use devres. * @probe: Called to query the existence of a specific device, * whether this driver can work with it, and bind the driver * to a specific device. @@ -105,6 +113,7 @@ struct device_driver { const struct of_device_id *of_match_table; const struct acpi_device_id *acpi_match_table; + int (*pre_probe) (struct device *dev); int (*probe) (struct device *dev); void (*sync_state)(struct device *dev); int (*remove) (struct device *dev); From patchwork Mon Jun 21 23:52:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 465448 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F0B69C48BC2 for ; Mon, 21 Jun 2021 23:53:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DC87A611C1 for ; Mon, 21 Jun 2021 23:53:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232346AbhFUXzb (ORCPT ); Mon, 21 Jun 2021 19:55:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45358 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232303AbhFUXz3 (ORCPT ); Mon, 21 Jun 2021 19:55:29 -0400 Received: from mail-pl1-x62e.google.com (mail-pl1-x62e.google.com [IPv6:2607:f8b0:4864:20::62e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A7466C0617AD for ; Mon, 21 Jun 2021 16:53:13 -0700 (PDT) Received: by mail-pl1-x62e.google.com with SMTP id o21so9436046pll.6 for ; Mon, 21 Jun 2021 16:53:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=KLTgOAPTL/hdLPXehUk7jin9tlU4DA3I5amBsr+XFlI=; b=IakNO8AV5d2AjRngN+nO9dr4scVOZ/i0GXGfPwpIa86ahW3Gx5lGZr/Qvp7nX9QLEF ah2PHyMzxecYm5jvWAhtwLlNrNpFAqJF7xOfwTdlDZQDqN2rtdNZFIoQTtMU1ur4ZApC 7UbMpvJg4P3n/t96Z0aCStxGsE3he4J8bRing= 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=KLTgOAPTL/hdLPXehUk7jin9tlU4DA3I5amBsr+XFlI=; b=Q/eTAN/3NReUdcfI6CQ0st/A3Ev9FX9kSkHcVlE67MYtW49eD5HXp4MQ3Up8b0nt1R LuBjWk1yUEWHFgNn9OZ0lAKOCD0SEPTCOLRWk0cw7eLvaP8l16FUqEZ+ttZT4xXbOvan 2gP8+mfGIzWqqfGwYjE0fda0jpvjDP+qyw3J9wXGmLHuvZt2oiEvZRtG7UDcrmcHvRt5 AXzIaJ2kOSu7NdjwswAfgdF1PL3+y6vVnvXF981uXBq1Wqnz+LY0+YQBUwCSvfq+8s9F qnMG7WIQ3PYvq+cvtgnQXH5mwP43XgwvU2ZW/OB6+6fs80n+bG113bpQZ91ZG6Sp7l9A 9kqw== X-Gm-Message-State: AOAM533xqfmRQcgUfhvQ8QZEzWtRSpHD5+lFD5h6YT0MUDOBygUlMPIg ajWuAvk58tOA/nv2gtfQF2vIMA== X-Google-Smtp-Source: ABdhPJwRWBAs+yleFm5GhcTuxr1KlXgWqhCk+RoJTuTTOnsjL0UiSKVoBvEouzqIK5zI5rTU5FaO7A== X-Received: by 2002:a17:90a:be03:: with SMTP id a3mr611377pjs.43.1624319593246; Mon, 21 Jun 2021 16:53:13 -0700 (PDT) Received: from tictac2.mtv.corp.google.com ([2620:15c:202:201:bdc1:a4b1:b06e:91d1]) by smtp.gmail.com with ESMTPSA id s27sm4339663pfg.169.2021.06.21.16.53.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 21 Jun 2021 16:53:12 -0700 (PDT) From: Douglas Anderson To: gregkh@linuxfoundation.org, rafael@kernel.org, rafael.j.wysocki@intel.com, will@kernel.org, robin.murphy@arm.com, joro@8bytes.org, bjorn.andersson@linaro.org, ulf.hansson@linaro.org, adrian.hunter@intel.com, bhelgaas@google.com Cc: robdclark@chromium.org, linux-arm-msm@vger.kernel.org, linux-pci@vger.kernel.org, quic_c_gdjako@quicinc.com, iommu@lists.linux-foundation.org, sonnyrao@chromium.org, saiprakash.ranjan@codeaurora.org, linux-mmc@vger.kernel.org, vbadigan@codeaurora.org, rajatja@google.com, saravanak@google.com, joel@joelfernandes.org, Douglas Anderson , Bartosz Golaszewski , Dan Williams , Heikki Krogerus , Randy Dunlap , linux-kernel@vger.kernel.org Subject: [PATCH 2/6] drivers: base: Add bits to struct device to control iommu strictness Date: Mon, 21 Jun 2021 16:52:44 -0700 Message-Id: <20210621165230.2.Icfe7cbb2cc86a38dde0ee5ba240e0580a0ec9596@changeid> X-Mailer: git-send-email 2.32.0.288.g62a8d224e6-goog In-Reply-To: <20210621235248.2521620-1-dianders@chromium.org> References: <20210621235248.2521620-1-dianders@chromium.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org How to control the "strictness" of an IOMMU is a bit of a mess right now. As far as I can tell, right now: * You can set the default to "non-strict" and some devices (right now, only PCI devices) can request to run in "strict" mode. * You can set the default to "strict" and no devices in the system are allowed to run as "non-strict". I believe this needs to be improved a bit. Specifically: * We should be able to default to "strict" mode but let devices that claim to be fairly low risk request that they be run in "non-strict" mode. * We should allow devices outside of PCIe to request "strict" mode if the system default is "non-strict". I believe the correct way to do this is two bits in "struct device". One allows a device to force things to "strict" mode and the other allows a device to _request_ "non-strict" mode. The asymmetry here is on purpose. Generally if anything in the system makes a request for strictness of something then we want it strict. Thus drivers can only request (but not force) non-strictness. It's expected that the strictness fields can be filled in by the bus code like in the patch ("PCI: Indicate that we want to force strict DMA for untrusted devices") or by using the new pre_probe concept introduced in the patch ("drivers: base: Add the concept of "pre_probe" to drivers"). Signed-off-by: Douglas Anderson --- include/linux/device.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/linux/device.h b/include/linux/device.h index f1a00040fa53..c1b985e10c47 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -449,6 +449,15 @@ struct dev_links_info { * and optionall (if the coherent mask is large enough) also * for dma allocations. This flag is managed by the dma ops * instance from ->dma_supported. + * @force_strict_iommu: If set to %true then we should force this device to + * iommu.strict regardless of the other defaults in the + * system. Only has an effect if an IOMMU is in place. + * @request_non_strict_iommu: If set to %true and there are no other known + * reasons to make the iommu.strict for this device, + * then default to non-strict mode. This implies + * some belief that the DMA master for this device + * won't abuse the DMA path to compromise the kernel. + * Only has an effect if an IOMMU is in place. * * At the lowest level, every device in a Linux system is represented by an * instance of struct device. The device structure contains the information @@ -557,6 +566,8 @@ struct device { #ifdef CONFIG_DMA_OPS_BYPASS bool dma_ops_bypass : 1; #endif + bool force_strict_iommu:1; + bool request_non_strict_iommu:1; }; /** From patchwork Mon Jun 21 23:52:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 464799 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D1FA7C49EAB for ; Mon, 21 Jun 2021 23:53:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C08C0611C1 for ; Mon, 21 Jun 2021 23:53:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232382AbhFUXze (ORCPT ); Mon, 21 Jun 2021 19:55:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45370 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232342AbhFUXzb (ORCPT ); Mon, 21 Jun 2021 19:55:31 -0400 Received: from mail-pj1-x1035.google.com (mail-pj1-x1035.google.com [IPv6:2607:f8b0:4864:20::1035]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 92ABFC06175F for ; Mon, 21 Jun 2021 16:53:15 -0700 (PDT) Received: by mail-pj1-x1035.google.com with SMTP id h16so10927925pjv.2 for ; Mon, 21 Jun 2021 16:53:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=1hap5rrkK42QaF5phRIGliKevrZCv+fxjBjTLJ/pE7w=; b=SaTkql2WXjMyJO6whWG9JyCnglGg6faOh30E8Lhu9SgvFGWDGvulc9SplCY+Wx4hJB DCYHUv1GwmTka12BMkZes72rKui1uDoY0LzvsieTa2ZmIrnL4mVCj5E9Nvn0LnsgSd9a klTw+FraV7UJBMyr3e/hUg0h10KaCLpg93/bc= 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=1hap5rrkK42QaF5phRIGliKevrZCv+fxjBjTLJ/pE7w=; b=G3tg1Fmaxx19bozHN8GUZsi1tNBjeyXJERrG5UZsq9Q7Z+hujSdBNzXXAszBNrfABN pzRbsfr2cndafmUUPqlBRCycuaZWeB0bu5dVIdJbTEnd99O+HlSZX2uQSwmGUl8b6gdr 0gXVlCh4/njPGvLuq2k3P4av0tnLFKIw1abOoJ4llgVbChvXOf1DFhjJ1yXe4mCX8zq9 /yWOoy3SgExacvI10XqSU8cp0zSlysG1jWDNBfOlA49tGLWpC0XF6sEp8BgWfVsfE1Fc qbol7GdC0hACdSybZwA0Gt0KZveSOhKA2NE4t4A2j6yDRf4QRyKK8dsgwhtW+K57QdTI iQAQ== X-Gm-Message-State: AOAM533LdtX9A7Dzg6/h0Ql9NysUuCsu/yIos008CJqxpj2p+WG1hYxr 8ppkIrpMzcZyqErvwfipX5Dn+w== X-Google-Smtp-Source: ABdhPJwXH5vi0Xs9ZIXNanUJNzJ2JIBdTlSTrxUumm5ORFc6vCcYGBtgB9XO+d3fthNCPEvr8XR/lA== X-Received: by 2002:a17:90a:6be6:: with SMTP id w93mr598015pjj.171.1624319595138; Mon, 21 Jun 2021 16:53:15 -0700 (PDT) Received: from tictac2.mtv.corp.google.com ([2620:15c:202:201:bdc1:a4b1:b06e:91d1]) by smtp.gmail.com with ESMTPSA id s27sm4339663pfg.169.2021.06.21.16.53.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 21 Jun 2021 16:53:14 -0700 (PDT) From: Douglas Anderson To: gregkh@linuxfoundation.org, rafael@kernel.org, rafael.j.wysocki@intel.com, will@kernel.org, robin.murphy@arm.com, joro@8bytes.org, bjorn.andersson@linaro.org, ulf.hansson@linaro.org, adrian.hunter@intel.com, bhelgaas@google.com Cc: robdclark@chromium.org, linux-arm-msm@vger.kernel.org, linux-pci@vger.kernel.org, quic_c_gdjako@quicinc.com, iommu@lists.linux-foundation.org, sonnyrao@chromium.org, saiprakash.ranjan@codeaurora.org, linux-mmc@vger.kernel.org, vbadigan@codeaurora.org, rajatja@google.com, saravanak@google.com, joel@joelfernandes.org, Douglas Anderson , linux-kernel@vger.kernel.org Subject: [PATCH 3/6] PCI: Indicate that we want to force strict DMA for untrusted devices Date: Mon, 21 Jun 2021 16:52:45 -0700 Message-Id: <20210621165230.3.I7accc008905590bb2b46f40f91a4aeda5b378007@changeid> X-Mailer: git-send-email 2.32.0.288.g62a8d224e6-goog In-Reply-To: <20210621235248.2521620-1-dianders@chromium.org> References: <20210621235248.2521620-1-dianders@chromium.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org At the moment the generic IOMMU framework reaches into the PCIe device to check the "untrusted" state and uses this information to figure out if it should be running the IOMMU in strict or non-strict mode. Let's instead set the new boolean in "struct device" to indicate when we want forced strictness. NOTE: we still continue to set the "untrusted" bit in PCIe since that apparently is used for more than just IOMMU strictness. It probably makes sense for a later patchset to clarify all of the other needs we have for "untrusted" PCIe devices (perhaps add more booleans into the "struct device") so we can fully eliminate the need for the IOMMU framework to reach into a PCIe device. Signed-off-by: Douglas Anderson --- drivers/pci/probe.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 275204646c68..8d81f0fb3e50 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1572,8 +1572,10 @@ static void set_pcie_untrusted(struct pci_dev *dev) * untrusted as well. */ parent = pci_upstream_bridge(dev); - if (parent && (parent->untrusted || parent->external_facing)) + if (parent && (parent->untrusted || parent->external_facing)) { dev->untrusted = true; + dev->dev.force_strict_iommu = true; + } } /** From patchwork Mon Jun 21 23:52:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 464797 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 810D1C4743C for ; Mon, 21 Jun 2021 23:53:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6E33061289 for ; Mon, 21 Jun 2021 23:53:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232496AbhFUXzq (ORCPT ); Mon, 21 Jun 2021 19:55:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45390 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232284AbhFUXzg (ORCPT ); Mon, 21 Jun 2021 19:55:36 -0400 Received: from mail-pg1-x52d.google.com (mail-pg1-x52d.google.com [IPv6:2607:f8b0:4864:20::52d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A3A1EC0617AD for ; Mon, 21 Jun 2021 16:53:17 -0700 (PDT) Received: by mail-pg1-x52d.google.com with SMTP id d12so905684pgd.9 for ; Mon, 21 Jun 2021 16:53:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=I+55avrqH7PSLbd+BXUibv+6BHo9MYXZgAoz7DvAWSE=; b=Z9UiwsXVLViVRcDZDkhKhAP5wp6N2/7oCZHEi8zfIYlgyiaYzZTxOpttLl37nUeURD Np+KH8LyE0EQDTmqWBDDL1ser31YUdxduJp96bhjRqVJ9VwthhX8CurLb3IVXStzlfaa oeYNByH3L4dSED0VHepIX7XYepmWioWdaXHj4= 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=I+55avrqH7PSLbd+BXUibv+6BHo9MYXZgAoz7DvAWSE=; b=EuwvQAPJQm2cIFxm0El5/ZOFFyS9UM0ghBikYleWtIU/2bFdcfuYcl6rR0hbkFALE4 ZGCKctyg1FY9j+DdwPCp2FlzkNLaY5KOpZpL/LYUw0hrCgMjef9flBYTerBhkT0vVXrN cYf0eWbFZu3zWiUXoLnp+Nula5Q6L+Z2JNAImt/FCZ10/pBqaNEKEYnvCgCMV9MsRQal P97qET+6Gc5PKW38OqHt77IFWvRqnEAtFwmMLF6sLMrEov+aRuk0rrLN1icAAcLjA40o MHahXl9euAwM0nW4rTdyRtjrTR9WwRrhe2t7qFIv3+0+j8POfutGIFxKYrsrU+dMLpTU jMMA== X-Gm-Message-State: AOAM533suIVQGkHP+upECKr0RlVC2glfpk88sOWkZIHp+x/rOUD7vTIA Oh9V0pbQIuEH9G5PV3JobokViw== X-Google-Smtp-Source: ABdhPJy3/8zfBLBO8WRO6RAvlGTjYRKGlwjguf8az5cO3Oli5Gn9NpQXkk50ljDLX9KWheRiSWaDJQ== X-Received: by 2002:a63:4653:: with SMTP id v19mr953623pgk.240.1624319597222; Mon, 21 Jun 2021 16:53:17 -0700 (PDT) Received: from tictac2.mtv.corp.google.com ([2620:15c:202:201:bdc1:a4b1:b06e:91d1]) by smtp.gmail.com with ESMTPSA id s27sm4339663pfg.169.2021.06.21.16.53.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 21 Jun 2021 16:53:16 -0700 (PDT) From: Douglas Anderson To: gregkh@linuxfoundation.org, rafael@kernel.org, rafael.j.wysocki@intel.com, will@kernel.org, robin.murphy@arm.com, joro@8bytes.org, bjorn.andersson@linaro.org, ulf.hansson@linaro.org, adrian.hunter@intel.com, bhelgaas@google.com Cc: robdclark@chromium.org, linux-arm-msm@vger.kernel.org, linux-pci@vger.kernel.org, quic_c_gdjako@quicinc.com, iommu@lists.linux-foundation.org, sonnyrao@chromium.org, saiprakash.ranjan@codeaurora.org, linux-mmc@vger.kernel.org, vbadigan@codeaurora.org, rajatja@google.com, saravanak@google.com, joel@joelfernandes.org, Douglas Anderson , linux-kernel@vger.kernel.org Subject: [PATCH 4/6] iommu: Combine device strictness requests with the global default Date: Mon, 21 Jun 2021 16:52:46 -0700 Message-Id: <20210621165230.4.Id84a954e705fcad3fdb35beb2bc372e4bf2108c7@changeid> X-Mailer: git-send-email 2.32.0.288.g62a8d224e6-goog In-Reply-To: <20210621235248.2521620-1-dianders@chromium.org> References: <20210621235248.2521620-1-dianders@chromium.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org In the patch ("drivers: base: Add bits to struct device to control iommu strictness") we add the ability for devices to tell us about their IOMMU strictness requirements. Let's now take that into account in the IOMMU layer. A few notes here: * Presumably this is always how iommu_get_dma_strict() was intended to behave. Had this not been the intention then it never would have taken a domain as a parameter. * The iommu_set_dma_strict() feels awfully non-symmetric now. That function sets the _default_ strictness globally in the system whereas iommu_get_dma_strict() returns the value for a given domain (falling back to the default). Presumably, at least, the fact that iommu_set_dma_strict() doesn't take a domain makes this obvious. The function iommu_get_dma_strict() should now make it super obvious where strictness comes from and who overides who. Though the function changed a bunch to make the logic clearer, the only two new rules should be: * Devices can force strictness for themselves, overriding the cmdline "iommu.strict=0" or a call to iommu_set_dma_strict(false)). * Devices can request non-strictness for themselves, assuming there was no cmdline "iommu.strict=1" or a call to iommu_set_dma_strict(true). Signed-off-by: Douglas Anderson --- drivers/iommu/iommu.c | 56 +++++++++++++++++++++++++++++++++---------- include/linux/iommu.h | 2 ++ 2 files changed, 45 insertions(+), 13 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 808ab70d5df5..0c84a4c06110 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -28,8 +28,19 @@ static struct kset *iommu_group_kset; static DEFINE_IDA(iommu_group_ida); +enum iommu_strictness { + IOMMU_DEFAULT_STRICTNESS = -1, + IOMMU_NOT_STRICT = 0, + IOMMU_STRICT = 1, +}; +static inline enum iommu_strictness bool_to_strictness(bool strictness) +{ + return (enum iommu_strictness)strictness; +} + static unsigned int iommu_def_domain_type __read_mostly; -static bool iommu_dma_strict __read_mostly = true; +static enum iommu_strictness cmdline_dma_strict __read_mostly = IOMMU_DEFAULT_STRICTNESS; +static enum iommu_strictness driver_dma_strict __read_mostly = IOMMU_DEFAULT_STRICTNESS; static u32 iommu_cmd_line __read_mostly; struct iommu_group { @@ -69,7 +80,6 @@ static const char * const iommu_group_resv_type_string[] = { }; #define IOMMU_CMD_LINE_DMA_API BIT(0) -#define IOMMU_CMD_LINE_STRICT BIT(1) static int iommu_alloc_default_domain(struct iommu_group *group, struct device *dev); @@ -336,25 +346,38 @@ early_param("iommu.passthrough", iommu_set_def_domain_type); static int __init iommu_dma_setup(char *str) { - int ret = kstrtobool(str, &iommu_dma_strict); + bool strict; + int ret = kstrtobool(str, &strict); if (!ret) - iommu_cmd_line |= IOMMU_CMD_LINE_STRICT; + cmdline_dma_strict = bool_to_strictness(strict); return ret; } early_param("iommu.strict", iommu_dma_setup); void iommu_set_dma_strict(bool strict) { - if (strict || !(iommu_cmd_line & IOMMU_CMD_LINE_STRICT)) - iommu_dma_strict = strict; + /* A driver can request strictness but not the other way around */ + if (driver_dma_strict != IOMMU_STRICT) + driver_dma_strict = bool_to_strictness(strict); } bool iommu_get_dma_strict(struct iommu_domain *domain) { - /* only allow lazy flushing for DMA domains */ - if (domain->type == IOMMU_DOMAIN_DMA) - return iommu_dma_strict; + /* Non-DMA domains or anyone forcing it to strict makes it strict */ + if (domain->type != IOMMU_DOMAIN_DMA || + cmdline_dma_strict == IOMMU_STRICT || + driver_dma_strict == IOMMU_STRICT || + domain->force_strict) + return true; + + /* Anyone requesting non-strict (if no forces) makes it non-strict */ + if (cmdline_dma_strict == IOMMU_NOT_STRICT || + driver_dma_strict == IOMMU_NOT_STRICT || + domain->request_non_strict) + return false; + + /* Nobody said anything, so it's strict by default */ return true; } EXPORT_SYMBOL_GPL(iommu_get_dma_strict); @@ -1519,7 +1542,8 @@ static int iommu_get_def_domain_type(struct device *dev) static int iommu_group_alloc_default_domain(struct bus_type *bus, struct iommu_group *group, - unsigned int type) + unsigned int type, + struct device *dev) { struct iommu_domain *dom; @@ -1534,6 +1558,12 @@ static int iommu_group_alloc_default_domain(struct bus_type *bus, if (!dom) return -ENOMEM; + /* Save the strictness requests from the device */ + if (dev && type == IOMMU_DOMAIN_DMA) { + dom->request_non_strict = dev->request_non_strict_iommu; + dom->force_strict = dev->force_strict_iommu; + } + group->default_domain = dom; if (!group->domain) group->domain = dom; @@ -1550,7 +1580,7 @@ static int iommu_alloc_default_domain(struct iommu_group *group, type = iommu_get_def_domain_type(dev) ? : iommu_def_domain_type; - return iommu_group_alloc_default_domain(dev->bus, group, type); + return iommu_group_alloc_default_domain(dev->bus, group, type, dev); } /** @@ -1721,7 +1751,7 @@ static void probe_alloc_default_domain(struct bus_type *bus, if (!gtype.type) gtype.type = iommu_def_domain_type; - iommu_group_alloc_default_domain(bus, group, gtype.type); + iommu_group_alloc_default_domain(bus, group, gtype.type, NULL); } @@ -3130,7 +3160,7 @@ static int iommu_change_dev_def_domain(struct iommu_group *group, } /* Sets group->default_domain to the newly allocated domain */ - ret = iommu_group_alloc_default_domain(dev->bus, group, type); + ret = iommu_group_alloc_default_domain(dev->bus, group, type, dev); if (ret) goto out; diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 32d448050bf7..0bddef77f415 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -81,6 +81,8 @@ struct iommu_domain_geometry { struct iommu_domain { unsigned type; + bool force_strict:1; + bool request_non_strict:1; const struct iommu_ops *ops; unsigned long pgsize_bitmap; /* Bitmap of page sizes in use */ iommu_fault_handler_t handler; From patchwork Mon Jun 21 23:52:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 464798 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 635A8C49EA4 for ; Mon, 21 Jun 2021 23:53:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 497356128E for ; Mon, 21 Jun 2021 23:53:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232482AbhFUXzm (ORCPT ); Mon, 21 Jun 2021 19:55:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45384 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232387AbhFUXze (ORCPT ); Mon, 21 Jun 2021 19:55:34 -0400 Received: from mail-pf1-x430.google.com (mail-pf1-x430.google.com [IPv6:2607:f8b0:4864:20::430]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 97ABBC061756 for ; Mon, 21 Jun 2021 16:53:19 -0700 (PDT) Received: by mail-pf1-x430.google.com with SMTP id g6so14941173pfq.1 for ; Mon, 21 Jun 2021 16:53:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=THKoO1RWudj0KxP+z9XOrOgTVnvtbYYdvVkwmldz9OE=; b=DSphfoFZ7DM95K+RvdByDg8W0x0HzT372m/CTEnE3pqPeq323dI65P/rlVSfLPKJQ1 28O9oN0CLLEtsLKgQ6MlMRXyKqjvpu/VGmk9AAzNr4tU542Ko0Ca8Ro0ReN1BsCsYzhm FrHRvl46FXtYmbbghamYqJa+AdyJraOwaTHvI= 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=THKoO1RWudj0KxP+z9XOrOgTVnvtbYYdvVkwmldz9OE=; b=IRzb1495YYry0I8hyl3NmhVh+MwtGVkNtseG9rm3C7Hn3yVXsj0BtUHZ/xaZKbNDcV PS7pYCuLbp4qAJSuscrypRGQV04bqc1sV4Qbra37Dw2iGkQO70ZnEQwRYCDutfqg/c/q pik4qK2I96nyUXLY8Ac6Oitq/f0BLdAG2pvQPprrSpDgWUHlEUORIKNTk7Kvk2eAf0m7 8ala/nDRmMLE4a7thlSXqNQbBGtMwiAiUzbcfZBkzrXFqmequlT6cWiBi8VeOCx62ZEa MpsukBqIEPHy5ZFbCzzX3q+ThxZFlGjTl8QqcBKoGQKltCkYxQ+Sr+B0k3+LdnUrRomd fOGA== X-Gm-Message-State: AOAM531+fqNvcYZx7WuG6uVHgC5uyVOsIue6zKCZ4av6TmvOBxJ4U8l4 rn/7VojJGAX5ynnSpRySnwVJwg== X-Google-Smtp-Source: ABdhPJxcsyNJ4PVOdLaM5phhP72ONpeV+ZJ8ppg8iQL6bG+AB2umwHT1C064i27TPx/qxhDHxLJD1g== X-Received: by 2002:a62:1d8c:0:b029:300:73d5:f35f with SMTP id d134-20020a621d8c0000b029030073d5f35fmr723439pfd.36.1624319599173; Mon, 21 Jun 2021 16:53:19 -0700 (PDT) Received: from tictac2.mtv.corp.google.com ([2620:15c:202:201:bdc1:a4b1:b06e:91d1]) by smtp.gmail.com with ESMTPSA id s27sm4339663pfg.169.2021.06.21.16.53.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 21 Jun 2021 16:53:18 -0700 (PDT) From: Douglas Anderson To: gregkh@linuxfoundation.org, rafael@kernel.org, rafael.j.wysocki@intel.com, will@kernel.org, robin.murphy@arm.com, joro@8bytes.org, bjorn.andersson@linaro.org, ulf.hansson@linaro.org, adrian.hunter@intel.com, bhelgaas@google.com Cc: robdclark@chromium.org, linux-arm-msm@vger.kernel.org, linux-pci@vger.kernel.org, quic_c_gdjako@quicinc.com, iommu@lists.linux-foundation.org, sonnyrao@chromium.org, saiprakash.ranjan@codeaurora.org, linux-mmc@vger.kernel.org, vbadigan@codeaurora.org, rajatja@google.com, saravanak@google.com, joel@joelfernandes.org, Douglas Anderson , linux-kernel@vger.kernel.org Subject: [PATCH 5/6] iommu: Stop reaching into PCIe devices to decide strict vs. non-strict Date: Mon, 21 Jun 2021 16:52:47 -0700 Message-Id: <20210621165230.5.I091ed869d3b324a483a355d873ce6bf1dc2da5ba@changeid> X-Mailer: git-send-email 2.32.0.288.g62a8d224e6-goog In-Reply-To: <20210621235248.2521620-1-dianders@chromium.org> References: <20210621235248.2521620-1-dianders@chromium.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org We now have a way for PCIe devices to force iommu.strict through the "struct device" and that's now hooked up. Let's remove the special case for PCIe devices. NOTE: there are still other places in this file that make decisions based on the PCIe "untrusted" status. This patch only handles removing the one related to iommu.strict. Removing the other cases is left as an exercise to the reader. Signed-off-by: Douglas Anderson --- drivers/iommu/dma-iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index 7bcdd1205535..e50c06ce1a6b 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -368,7 +368,7 @@ static int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base, init_iova_domain(iovad, 1UL << order, base_pfn); - if (!cookie->fq_domain && (!dev || !dev_is_untrusted(dev)) && + if (!cookie->fq_domain && domain->ops->flush_iotlb_all && !iommu_get_dma_strict(domain)) { if (init_iova_flush_queue(iovad, iommu_dma_flush_iotlb_all, iommu_dma_entry_dtor)) From patchwork Mon Jun 21 23:52:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 465446 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D5CBEC48BE5 for ; Mon, 21 Jun 2021 23:53:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B64D961153 for ; Mon, 21 Jun 2021 23:53:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232402AbhFUXzo (ORCPT ); Mon, 21 Jun 2021 19:55:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45400 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232417AbhFUXzh (ORCPT ); Mon, 21 Jun 2021 19:55:37 -0400 Received: from mail-pl1-x629.google.com (mail-pl1-x629.google.com [IPv6:2607:f8b0:4864:20::629]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C1300C061787 for ; Mon, 21 Jun 2021 16:53:21 -0700 (PDT) Received: by mail-pl1-x629.google.com with SMTP id y21so3582961plb.4 for ; Mon, 21 Jun 2021 16:53:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=TEKHWQJp4n8yoFiHOuNtGCbJTSsuHccWZBKCtuc7Qts=; b=JfVj6R5c5gvmti+4j0JlnamjjPtwJC40uf1GOUKZBNoGRYiwsk9gN9EB47jU4GyrdB xt9uNo3jbU8+ZN08CVaYhgzUoi4ZKNEmEvp0W/f1M3/vIs9Q8AtbTKYGjpLEMeJJH90a 3Q3C/PI3x6byOZQohM26KarCNSpYlv4k3HqMA= 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=TEKHWQJp4n8yoFiHOuNtGCbJTSsuHccWZBKCtuc7Qts=; b=VcRBH6oV6ccyGxzTQwkjQ96R/yRZ+Qe/hX9XR1tjMkcvQGR055rH/AnKPf5YvnNqVW MkiLIJmeAdSMECYGbCYFb798GqJ+5g6uIE3Pc4UaxzKXXAAXZcp3lP1eD0WFYXSF/slB M1pOSKRCuqYAma9y0hKbGKAtSHvowSY7koQm3VHb3y/dXyX7CLFaAQ0iDKMh4cT916zp j28vCVInpwaozVWY35aGlcZ0HJInY+tCSat0JBg7yMfLmR536Rgj3R+Dn0m5DhN8Sg4F mcqrvZVTxeg2uHBd0nlVyKUY4a1nEXkPaJ0+2QT5VZdr4VkHpg3gl3Frq//jvcdJ9p+o R4bQ== X-Gm-Message-State: AOAM531u/noeW3E4ulTVPJu5ExbVSXUz4d87F0dqf0DJ0ERH3WMgATdj IOStuZcdfp6v+s07v0ngrSVSEg== X-Google-Smtp-Source: ABdhPJy2hHxfJrn4WVFmNTak00b5y5qz5F7V+JU2zimAB1kk2WW5Pzu2fcXDvLwNYMoHeCfmM4GdVw== X-Received: by 2002:a17:90a:73ca:: with SMTP id n10mr809631pjk.16.1624319601314; Mon, 21 Jun 2021 16:53:21 -0700 (PDT) Received: from tictac2.mtv.corp.google.com ([2620:15c:202:201:bdc1:a4b1:b06e:91d1]) by smtp.gmail.com with ESMTPSA id s27sm4339663pfg.169.2021.06.21.16.53.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 21 Jun 2021 16:53:20 -0700 (PDT) From: Douglas Anderson To: gregkh@linuxfoundation.org, rafael@kernel.org, rafael.j.wysocki@intel.com, will@kernel.org, robin.murphy@arm.com, joro@8bytes.org, bjorn.andersson@linaro.org, ulf.hansson@linaro.org, adrian.hunter@intel.com, bhelgaas@google.com Cc: robdclark@chromium.org, linux-arm-msm@vger.kernel.org, linux-pci@vger.kernel.org, quic_c_gdjako@quicinc.com, iommu@lists.linux-foundation.org, sonnyrao@chromium.org, saiprakash.ranjan@codeaurora.org, linux-mmc@vger.kernel.org, vbadigan@codeaurora.org, rajatja@google.com, saravanak@google.com, joel@joelfernandes.org, Douglas Anderson , Andy Gross , linux-kernel@vger.kernel.org Subject: [PATCH 6/6] mmc: sdhci-msm: Request non-strict IOMMU mode Date: Mon, 21 Jun 2021 16:52:48 -0700 Message-Id: <20210621165230.6.Icde6be7601a5939960caf802056c88cd5132eb4e@changeid> X-Mailer: git-send-email 2.32.0.288.g62a8d224e6-goog In-Reply-To: <20210621235248.2521620-1-dianders@chromium.org> References: <20210621235248.2521620-1-dianders@chromium.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org IOMMUs can be run in "strict" mode or in "non-strict" mode. The quick-summary difference between the two is that in "strict" mode we wait until everything is flushed out when we unmap DMA memory. In "non-strict" we don't. Using the IOMMU in "strict" mode is more secure/safer but slower because we have to sit and wait for flushes while we're unmapping. To explain a bit why "non-strict" mode is unsafe, let's imagine two examples. An example of "non-strict" being insecure when reading from a device: a) Linux driver maps memory for DMA. b) Linux driver starts DMA on the device. c) Device write to RAM subject to bounds checking done by IOMMU. d) Device finishes writing to RAM and signals transfer is finished. e) Linux driver starts unmapping DMA memory but doesn't flush. f) Linux driver validates that the data in memory looks sane and that accessing it won't cause the driver to, for instance, overflow a buffer. g) Device takes advantage of knowledge of how the Linux driver works and sneaks in a modification to the data after the validation but before the IOMMU unmap flush finishes. h) Device has now caused the Linux driver to access memory it shouldn't. An example of "non-strict" being insecure when writing to a device: a) Linux driver writes data intended for the device to RAM. b) Linux driver maps memory for DMA. c) Linux driver starts DMA on the device. d) Device reads from RAM subject to bounds checking done by IOMMU. e) Device finishes reading from RAM and signals transfer is finished. f) Linux driver starts unmapping DMA memory but doesn't flush. g) Linux driver frees memory and returns it to the pool. h) Memory is allocated for another purpose. i) Device takes advantage of the period of time before IOMMU flush to read memory that it shouldn't have had access to. As you can see from the above examples, using the iommu in "non-strict" mode might not sound _too_ scary (the window of badness is small and the exposed memory is small) but there is certainly risk. Let's evaluate the risk by breaking it down into two problems that IOMMUs are supposed to be protecting us against: Case 1: IOMMUs prevent malicious code running on the peripheral (maybe a malicious peripheral or maybe someone exploited a benign peripheral) from turning into an exploit of the Linux kernel. This is particularly important if the peripheral has loadable / updatable firmware or if the peripheral has some type of general purpose processor and is processing untrusted inputs. It's also important if the device is something that can be easily plugged into the host and the device has direct DMA access itself, like a PCIe device. Case 2: IOMMUs limit the severity of a class of software bugs in the kernel. If we misconfigure a peripheral by accident then instead of the peripheral clobbering random memory due to a bug we might get an IOMMU error. Now that we understand the issue and the risks, let's evaluate whether we really need "strict" mode for the Qualcomm SDHCI controllers. I will make the argument that we don't _need_ strict mode for them. Why? * The SDHCI controller on Qualcomm SoCs doesn't appear to have loadable / updatable firmware and, assuming it's got some firmware baked into it, I see no evidence that the firmware could be compromised. * Even though, for external SD cards in particular, the controller is dealing with "untrusted" inputs, it's dealing with them in a very controlled way. It seems unlikely that a rogue SD card would be able to present something to the SDHCI controller that would cause it to DMA to/from an address other than one the kernel told it about. * Although it would be nice to catch more software bugs, once the Linux driver has been debugged and stressed the value is not very high. If the IOMMU caught something like this the system would be in a pretty bad shape anyway (we don't really recover from IOMMU errors) and the only benefit would be a better spotlight on what went wrong. Now we have a good understanding of the benefits of "strict" mode for our SDHCI controllers, let's look at some performance numbers. I used "dd" to measure read speeds from eMMC on a sc7180-trogdor-lazor board. Basic test command (while booted from USB): echo 3 > /proc/sys/vm/drop_caches dd if=/dev/mmcblk1 of=/dev/null bs=4M count=512 I attempted to run my tests for enough iterations that results stabilized and weren't too noisy. Tests were run with patches picked to the chromeos-5.4 tree (sanity checked against v5.13-rc7). I also attempted to compare to other attempts to address IOMMU problems and/or attempts to bump the cpufreq up to solve this problem: - eMMC datasheet spec: 300 MB/s "Typical Sequential Performance" NOTE: we're driving the bus at 192 MHz instead of 200 Mhz so we might not be able to achieve the full 300 MB/s. - Baseline: 210.9 MB/s - Baseline + peg cpufreq to max: 284.3 MB/s - This patch: 279.6 MB/s - This patch + peg cpufreq to max: 288.1 MB/s - Joel's IO Wait fix [1]: 258.4 MB/s - Joel's IO Wait fix [1] + peg cpufreq to max: 287.8 MB/s - TLBIVA patches [2] + [3]: 214.7 MB/s - TLBIVA patches [2] + [3] + peg cpufreq to max: 285.7 MB/s - This patch plus Joel's [1]: 280.2 MB/s - This patch plus Joel's [1] + peg...: 279.0 MB/s NOTE: I suspect something in the system was thermal throttling since there's a heat wave right now. I also spent a little bit of time trying to see if I could get the IOMMU flush for MMC out of the critical path but was unable to figure out how to do this and get good performance. Overall I'd say that the performance results above show: * It's really not straightforward to point at "one thing" that is making our eMMC performance bad. * It's certainly possible to get pretty good eMMC performance even without this patch. * This patch makes it much easier to get good eMMC performance. * No other solutions that I found resulted in quite as good eMMC performance as having this patch. Given all the above (security safety concerns are minimal and it's a nice performance win), I'm proposing that running SDHCI on Qualcomm SoCs in non-strict mode is the right thing to do until such point in time as someone can come up with a better solution to get good SD/eMMC performance without it. NOTES: * It's likely that arguments similar to the above can be made for other SDHCI controllers. However, given that this is something that can have an impact on security it feels like we want each SDHCI controller to opt-in. I believe it is conceivable, for instance, that some SDHCI controllers might have loadable or updatable firmware. * It's also likely other peripherals will want this to get the quick performance win. That also should be fine, though anyone landing a similar patch should be very careful that it is low risk for all users of a given peripheral. * Conceivably if even this patch is considered too "high risk", we could limit this to just non-removable cards (like eMMC) by just checking the device tree. This is one nice advantage of using the pre_probe() to set this. [1] https://lore.kernel.org/r/20210618040639.3113489-1-joel@joelfernandes.org [2] https://lore.kernel.org/r/1623850736-389584-1-git-send-email-quic_c_gdjako@quicinc.com/ [3] https://lore.kernel.org/r/cover.1623981933.git.saiprakash.ranjan@codeaurora.org/ Signed-off-by: Douglas Anderson --- drivers/mmc/host/sdhci-msm.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index e44b7a66b73c..33ef5e6941d7 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -2465,6 +2465,13 @@ static inline void sdhci_msm_get_of_property(struct platform_device *pdev, } +static int sdhci_msm_pre_probe(struct device *dev) +{ + dev->request_non_strict_iommu = true; + + return 0; +} + static int sdhci_msm_probe(struct platform_device *pdev) { struct sdhci_host *host; @@ -2811,6 +2818,7 @@ static struct platform_driver sdhci_msm_driver = { .of_match_table = sdhci_msm_dt_match, .pm = &sdhci_msm_pm_ops, .probe_type = PROBE_PREFER_ASYNCHRONOUS, + .pre_probe = sdhci_msm_pre_probe, }, };