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: 465273 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 D59ACC48BE5 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 BFB66611C1 for ; Mon, 21 Jun 2021 23:53:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232348AbhFUXzb (ORCPT ); Mon, 21 Jun 2021 19:55:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45336 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232217AbhFUXz2 (ORCPT ); Mon, 21 Jun 2021 19:55:28 -0400 Received: from mail-pg1-x535.google.com (mail-pg1-x535.google.com [IPv6:2607:f8b0:4864:20::535]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3CDDEC061768 for ; Mon, 21 Jun 2021 16:53:11 -0700 (PDT) Received: by mail-pg1-x535.google.com with SMTP id h4so3927950pgp.5 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=V9wJKnm3FRYGEUXI9lFZu/PAk70Mr2EPtQ6tOW0a5UFNu/KwRTwXYVGVgiW0r3nlYU oPtzRXyP9RjOPmAWNjAgg8KSSgduJFUz9tb4kCrdifUm+dMN2xett7qBBDTXSXoFrUpg mimVftTIWeASg1m0WB3S+eSX1iaOV21hxDg0CeM/VSdr7YoMOo2QOkvTuFQlwD6NUY5T DIlCvW8fV5Eyy9TH00IYudX0nojKQRCslmrYQdENHh07oTtE6wjqcO0RxAchJZYpqo22 5AEE+r67CaCHSPF4M/CsbUfG4dtynL6mU0yz/yIE9anvrnW4BNesIXV3GGFqEfjw+CQO JUDQ== X-Gm-Message-State: AOAM533lxKdf4RKRS345d13B7Yi2NtC1gKPD3aCmBB4P6fxyqyxOpwPC SLkwmZJykwveblKT6KNDoqquCA== 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-arm-msm@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: 464689 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 9AE5BC49EA2 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 85B1061289 for ; Mon, 21 Jun 2021 23:53:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232366AbhFUXzd (ORCPT ); Mon, 21 Jun 2021 19:55:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45314 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231486AbhFUXza (ORCPT ); Mon, 21 Jun 2021 19:55:30 -0400 Received: from mail-pl1-x635.google.com (mail-pl1-x635.google.com [IPv6:2607:f8b0:4864:20::635]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A91B1C0617AE for ; Mon, 21 Jun 2021 16:53:13 -0700 (PDT) Received: by mail-pl1-x635.google.com with SMTP id v13so9434661ple.9 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=hJ09CMdxIokzxZX/fwzdcfRDPRtBpYwya50HVhDUtHfWchpNbEwTnOUglx/Zlc4vFW xU2Is1m/Xp/4fc5SGzjd0yinc8PABc/jp8ejeqliz3+BCIsq4alRaITADOq0niRYna+8 MWTxPHCgHBv7cwt3sOwYn5ML7eckL3YOk7dfpnCAd2otXh5IkHlU1kZty/3xZTuJofLR WORAPKphYpCGyDiQ/jH5e+Z3q5b2x5llL/xQAAmruVQVUPEtGFtp81feWmEAulNiULbm iE1C+CIDShloHjYIhAitzN1TIslXPURCGckiPtV8SEasaomUxo88cozLTV3NAXwRE05x JH0g== X-Gm-Message-State: AOAM530mJTAlwEsLAv51nycwIBPqbWGllCqKbVc1ejo6s6Q7lnaj37Jy Z1xPtErupZS/LVlH/1c1JA20tA== 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-arm-msm@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: 465272 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 91DA9C4743C 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 7BAA461153 for ; Mon, 21 Jun 2021 23:53:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231486AbhFUXzd (ORCPT ); Mon, 21 Jun 2021 19:55:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45368 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232340AbhFUXzb (ORCPT ); Mon, 21 Jun 2021 19:55:31 -0400 Received: from mail-pl1-x636.google.com (mail-pl1-x636.google.com [IPv6:2607:f8b0:4864:20::636]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 92756C061756 for ; Mon, 21 Jun 2021 16:53:15 -0700 (PDT) Received: by mail-pl1-x636.google.com with SMTP id v12so9440312plo.10 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=JIacTP285RAcBkAsJGfBnyRRwX8E4rDS6AAw/nyqDZrHYjxHfc/xM4xwyauj6+4U63 oiDc+bhtcx1oFZtfNSVFcC9VCqxTQU+LwVFrVq7EYs+Fz1CkgT2MnEciz4uAlzVliVLp +cUd8c3seHjXPgAyjrflMYUG36lepGgSn9yeT+CYalOB5Y4x6LC9BrlKZ7ZGIQtmIvAt mb2qX3FmaKrkNXyJ0Y29+4UVTIbVGwcHrjUGGDPtA5aq85GoSomqLUPxqiy19AMiu5By fYOoCzWwapk480kw6s32nX4TWbDDteZtKTEWsxVOKp/9yPG9sT5jsWU+Z9mEXossO4Kd 2LZw== X-Gm-Message-State: AOAM530H+5VpQniGEeuIrfVrozKN10NKrBYiDTRVKt0UcyYebXMUHVXi NJ3tfYcvkQatHmuGIDFcYyJCLw== 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-arm-msm@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: 464688 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 15ECDC48BE5 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 0501161153 for ; Mon, 21 Jun 2021 23:53:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232478AbhFUXzm (ORCPT ); Mon, 21 Jun 2021 19:55:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45388 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232375AbhFUXzd (ORCPT ); Mon, 21 Jun 2021 19:55:33 -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 A0FF0C0617A6 for ; Mon, 21 Jun 2021 16:53:17 -0700 (PDT) Received: by mail-pg1-x52d.google.com with SMTP id t13so3653199pgu.11 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=H9TLPQ1l+MkL8Hpae+sYaUabNeg0vu6QCt1pr/QTPIAgzE/dyrSUiykJP/OMDXYMVT NTUZ8vcWtyAoTobuJHKYXB4tDXxwOhvI0D+ynDmBF/cFBhwDLWPip7B3fFl0upPuBtB/ iq22CjM56LtzsBLJYxogssNpqHMtHNQOTVZd2Y33QjKACkSCugVQne72u1SvLMDuWos5 YcmM0Um01BgyxGaLWtvQys72DhlmLpMSCOY91zgKRWn0gjCpZ3vWW5VCXX3Ywm1FPDO3 Y1RmfYfiBCr1STtQC6Fnj0ERcleggYZe+9poDj6eFsVSnYrm3PgKt6ikZnufCZVKrC7e QCkA== X-Gm-Message-State: AOAM533n0xiRxUt4H/bBu3YEwsfcGgFwIrd4mZrZWD+YDkYsFKFRjBHI OkHMs/7lcpIktGmRmKlL1XJHTg== 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-arm-msm@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: 465271 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 B39B7C49EA5 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 9E59B61358 for ; Mon, 21 Jun 2021 23:53:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232347AbhFUXzm (ORCPT ); Mon, 21 Jun 2021 19:55:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45314 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232396AbhFUXzf (ORCPT ); Mon, 21 Jun 2021 19:55:35 -0400 Received: from mail-pg1-x531.google.com (mail-pg1-x531.google.com [IPv6:2607:f8b0:4864:20::531]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 95AD6C061574 for ; Mon, 21 Jun 2021 16:53:19 -0700 (PDT) Received: by mail-pg1-x531.google.com with SMTP id t13so3653259pgu.11 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=PPBOx7hBzOGKPIudQnHpYcoqcSxR+f/Ejpg2Q40/vNME/D+kN+P0WwE3Uf0rFcUXxc UIWNa2uuI7wu1FFAjeY4Qbq+fcZpBoQYzZC0/EG5xNcmzKm4D4teK033U1fBfvVT02rT J346OsKFXycJOHeKGCsYj12AprIGPaYQz+SzJ9CS2oqfpxt8K48KGaoiDePvMpMDF+Un /BuC/pZ+MRVW+NmFK95eyWKpArGxXSJdYm6i9MhaFwEJxEqyHGTkWFyFlz7ltgy6qG1R IVxtwfRulgahoLHvx4+tjXglD44q0REb61IPEMUmGtg9F1F6+4d171FFcWNMAQl7pe0H JPAg== X-Gm-Message-State: AOAM533vR2wX1XeDCFkYBaFlmKia5UECFPintpN5EKKNtJkh60hyw5MK xQkv8mpwjfP+QDQMuUsTdONvpQ== 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-arm-msm@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: 464687 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 1185CC49EA7 for ; Mon, 21 Jun 2021 23:53:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EDA2A611C1 for ; Mon, 21 Jun 2021 23:53:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232417AbhFUXzo (ORCPT ); Mon, 21 Jun 2021 19:55:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45426 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232422AbhFUXzh (ORCPT ); Mon, 21 Jun 2021 19:55:37 -0400 Received: from mail-pl1-x631.google.com (mail-pl1-x631.google.com [IPv6:2607:f8b0:4864:20::631]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CB581C0613A4 for ; Mon, 21 Jun 2021 16:53:21 -0700 (PDT) Received: by mail-pl1-x631.google.com with SMTP id o21so9436180pll.6 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=feSRqNPmUgXIlPTRSaNjV2P9iXvyzmO7Ihipun2KSOnLs5Vnmf8Je16IwyoCVoLKQB Qu/egUmn/58c8HjM/t6e465bqBtpAHZ3AJqdxoNedJ3lePkQEvElwp00Y2GZMavrqVVz pXJdlSVY6M2fIWXFI6FqYkDs5ej0qAyVnyKv4V0lLBNCQtzNmJLXvFZYm9dqSNK9GYQu VJlxUIjveDzC6wjWl4qxw2Y7jTIWLYP7pWN03SCD5cC2VHOoXpkqfs71gDOO3617sZVf W01B2wgWPj5+yKZKWNPllQH3CfK1YagIRObc4Jzi+q6ntb6Mr0FW/477+D4hXe4F7NZ2 q09A== X-Gm-Message-State: AOAM531TwNJ3Hw5VtRNkTPwVrVFAXyWcxGwkdj4nuG5Zn9GvFMjoYeE9 j2bYgDKtD3TAuH7x7ZDAkMSSSA== 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-arm-msm@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, }, };