From: Sasha Levin Date: Mon, 28 Nov 2022 01:21:39 +0000 (-0500) Subject: Fixes for 5.15 X-Git-Tag: v5.10.157~77 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4ab2475e872caa29926503d1f74854af86026ced;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.15 Signed-off-by: Sasha Levin --- diff --git a/queue-5.15/dmaengine-idxd-do-not-enable-user-type-work-queue-wi.patch b/queue-5.15/dmaengine-idxd-do-not-enable-user-type-work-queue-wi.patch new file mode 100644 index 00000000000..46e4f72a1d7 --- /dev/null +++ b/queue-5.15/dmaengine-idxd-do-not-enable-user-type-work-queue-wi.patch @@ -0,0 +1,83 @@ +From 91c740fee4773eac5ca7b8b463e78d44c7557c20 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Oct 2022 15:25:41 -0700 +Subject: dmaengine: idxd: Do not enable user type Work Queue without Shared + Virtual Addressing + +From: Fenghua Yu + +When the idxd_user_drv driver is bound to a Work Queue (WQ) device +without IOMMU or with IOMMU Passthrough without Shared Virtual +Addressing (SVA), the application gains direct access to physical +memory via the device by programming physical address to a submitted +descriptor. This allows direct userspace read and write access to +arbitrary physical memory. This is inconsistent with the security +goals of a good kernel API. + +Unlike vfio_pci driver, the IDXD char device driver does not provide any +ways to pin user pages and translate the address from user VA to IOVA or +PA without IOMMU SVA. Therefore the application has no way to instruct the +device to perform DMA function. This makes the char device not usable for +normal application usage. + +Since user type WQ without SVA cannot be used for normal application usage +and presents the security issue, bind idxd_user_drv driver and enable user +type WQ only when SVA is enabled (i.e. user PASID is enabled). + +Fixes: 448c3de8ac83 ("dmaengine: idxd: create user driver for wq 'device'") +Cc: stable@vger.kernel.org +Suggested-by: Arjan Van De Ven +Signed-off-by: Fenghua Yu +Reviewed-by: Dave Jiang +Reviewed-by: Jerry Snitselaar +Link: https://lore.kernel.org/r/20221014222541.3912195-1-fenghua.yu@intel.com +Signed-off-by: Vinod Koul +--- + drivers/dma/idxd/cdev.c | 18 ++++++++++++++++++ + include/uapi/linux/idxd.h | 1 + + 2 files changed, 19 insertions(+) + +diff --git a/drivers/dma/idxd/cdev.c b/drivers/dma/idxd/cdev.c +index 033df43db0ce..91e335f62b30 100644 +--- a/drivers/dma/idxd/cdev.c ++++ b/drivers/dma/idxd/cdev.c +@@ -312,6 +312,24 @@ static int idxd_user_drv_probe(struct idxd_dev *idxd_dev) + if (idxd->state != IDXD_DEV_ENABLED) + return -ENXIO; + ++ /* ++ * User type WQ is enabled only when SVA is enabled for two reasons: ++ * - If no IOMMU or IOMMU Passthrough without SVA, userspace ++ * can directly access physical address through the WQ. ++ * - The IDXD cdev driver does not provide any ways to pin ++ * user pages and translate the address from user VA to IOVA or ++ * PA without IOMMU SVA. Therefore the application has no way ++ * to instruct the device to perform DMA function. This makes ++ * the cdev not usable for normal application usage. ++ */ ++ if (!device_user_pasid_enabled(idxd)) { ++ idxd->cmd_status = IDXD_SCMD_WQ_USER_NO_IOMMU; ++ dev_dbg(&idxd->pdev->dev, ++ "User type WQ cannot be enabled without SVA.\n"); ++ ++ return -EOPNOTSUPP; ++ } ++ + mutex_lock(&wq->wq_lock); + wq->type = IDXD_WQT_USER; + rc = __drv_enable_wq(wq); +diff --git a/include/uapi/linux/idxd.h b/include/uapi/linux/idxd.h +index c750eac09fc9..7355f498923e 100644 +--- a/include/uapi/linux/idxd.h ++++ b/include/uapi/linux/idxd.h +@@ -28,6 +28,7 @@ enum idxd_scmd_stat { + IDXD_SCMD_WQ_NONE_CONFIGURED = 0x800d0000, + IDXD_SCMD_WQ_NO_SIZE = 0x800e0000, + IDXD_SCMD_WQ_NO_PRIV = 0x800f0000, ++ IDXD_SCMD_WQ_USER_NO_IOMMU = 0x80110000, + }; + + #define IDXD_SCMD_SOFTERR_MASK 0x80000000 +-- +2.35.1 + diff --git a/queue-5.15/mmc-sdhci-brcmstb-enable-clock-gating-to-save-power.patch b/queue-5.15/mmc-sdhci-brcmstb-enable-clock-gating-to-save-power.patch new file mode 100644 index 00000000000..f1473cca02d --- /dev/null +++ b/queue-5.15/mmc-sdhci-brcmstb-enable-clock-gating-to-save-power.patch @@ -0,0 +1,110 @@ +From d2361b1368004b379b5f709686c35709869b9686 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Apr 2022 14:08:51 -0400 +Subject: mmc: sdhci-brcmstb: Enable Clock Gating to save power + +From: Al Cooper + +[ Upstream commit 6bcc55fe648b860ef0c2b8dc23adc05bcddb93c2 ] + +Enabling this feature will allow the controller to stop the bus +clock when the bus is idle. The feature is not part of the standard +and is unique to newer Arasan cores and is enabled with a bit in a +vendor specific register. This feature will only be enabled for +non-removable devices because they don't switch the voltage and +clock gating breaks SD Card volatge switching. + +Signed-off-by: Al Cooper +Signed-off-by: Kamal Dasu +Acked-by: Florian Fainelli +Acked-by: Adrian Hunter +Link: https://lore.kernel.org/r/20220427180853.35970-3-kdasu.kdev@gmail.com +Signed-off-by: Ulf Hansson +Stable-dep-of: 56baa208f910 ("mmc: sdhci-brcmstb: Fix SDHCI_RESET_ALL for CQHCI") +Signed-off-by: Sasha Levin +--- + drivers/mmc/host/sdhci-brcmstb.c | 35 +++++++++++++++++++++++++++++++- + 1 file changed, 34 insertions(+), 1 deletion(-) + +diff --git a/drivers/mmc/host/sdhci-brcmstb.c b/drivers/mmc/host/sdhci-brcmstb.c +index 244780481193..683d0c685748 100644 +--- a/drivers/mmc/host/sdhci-brcmstb.c ++++ b/drivers/mmc/host/sdhci-brcmstb.c +@@ -17,11 +17,14 @@ + + #define SDHCI_VENDOR 0x78 + #define SDHCI_VENDOR_ENHANCED_STRB 0x1 ++#define SDHCI_VENDOR_GATE_SDCLK_EN 0x2 + + #define BRCMSTB_MATCH_FLAGS_NO_64BIT BIT(0) + #define BRCMSTB_MATCH_FLAGS_BROKEN_TIMEOUT BIT(1) ++#define BRCMSTB_MATCH_FLAGS_HAS_CLOCK_GATE BIT(2) + + #define BRCMSTB_PRIV_FLAGS_HAS_CQE BIT(0) ++#define BRCMSTB_PRIV_FLAGS_GATE_CLOCK BIT(1) + + #define SDHCI_ARASAN_CQE_BASE_ADDR 0x200 + +@@ -36,6 +39,27 @@ struct brcmstb_match_priv { + const unsigned int flags; + }; + ++static inline void enable_clock_gating(struct sdhci_host *host) ++{ ++ u32 reg; ++ ++ reg = sdhci_readl(host, SDHCI_VENDOR); ++ reg |= SDHCI_VENDOR_GATE_SDCLK_EN; ++ sdhci_writel(host, reg, SDHCI_VENDOR); ++} ++ ++void brcmstb_reset(struct sdhci_host *host, u8 mask) ++{ ++ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); ++ struct sdhci_brcmstb_priv *priv = sdhci_pltfm_priv(pltfm_host); ++ ++ sdhci_reset(host, mask); ++ ++ /* Reset will clear this, so re-enable it */ ++ if (priv->flags & BRCMSTB_PRIV_FLAGS_GATE_CLOCK) ++ enable_clock_gating(host); ++} ++ + static void sdhci_brcmstb_hs400es(struct mmc_host *mmc, struct mmc_ios *ios) + { + struct sdhci_host *host = mmc_priv(mmc); +@@ -131,7 +155,7 @@ static struct sdhci_ops sdhci_brcmstb_ops = { + static struct sdhci_ops sdhci_brcmstb_ops_7216 = { + .set_clock = sdhci_brcmstb_set_clock, + .set_bus_width = sdhci_set_bus_width, +- .reset = sdhci_reset, ++ .reset = brcmstb_reset, + .set_uhs_signaling = sdhci_brcmstb_set_uhs_signaling, + }; + +@@ -147,6 +171,7 @@ static struct brcmstb_match_priv match_priv_7445 = { + }; + + static const struct brcmstb_match_priv match_priv_7216 = { ++ .flags = BRCMSTB_MATCH_FLAGS_HAS_CLOCK_GATE, + .hs400es = sdhci_brcmstb_hs400es, + .ops = &sdhci_brcmstb_ops_7216, + }; +@@ -273,6 +298,14 @@ static int sdhci_brcmstb_probe(struct platform_device *pdev) + if (res) + goto err; + ++ /* ++ * Automatic clock gating does not work for SD cards that may ++ * voltage switch so only enable it for non-removable devices. ++ */ ++ if ((match_priv->flags & BRCMSTB_MATCH_FLAGS_HAS_CLOCK_GATE) && ++ (host->mmc->caps & MMC_CAP_NONREMOVABLE)) ++ priv->flags |= BRCMSTB_PRIV_FLAGS_GATE_CLOCK; ++ + /* + * If the chip has enhanced strobe and it's enabled, add + * callback +-- +2.35.1 + diff --git a/queue-5.15/mmc-sdhci-brcmstb-fix-sdhci_reset_all-for-cqhci.patch b/queue-5.15/mmc-sdhci-brcmstb-fix-sdhci_reset_all-for-cqhci.patch new file mode 100644 index 00000000000..c9ce4642091 --- /dev/null +++ b/queue-5.15/mmc-sdhci-brcmstb-fix-sdhci_reset_all-for-cqhci.patch @@ -0,0 +1,71 @@ +From 9705c03dafb09a76ec1f6a91bf887b6a74874762 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Oct 2022 12:42:05 -0700 +Subject: mmc: sdhci-brcmstb: Fix SDHCI_RESET_ALL for CQHCI + +From: Brian Norris + +[ Upstream commit 56baa208f91061ff27ec2d93fbc483f624d373b4 ] + +[[ NOTE: this is completely untested by the author, but included solely + because, as noted in commit df57d73276b8 ("mmc: sdhci-pci: Fix + SDHCI_RESET_ALL for CQHCI for Intel GLK-based controllers"), "other + drivers using CQHCI might benefit from a similar change, if they + also have CQHCI reset by SDHCI_RESET_ALL." We've now seen the same + bug on at least MSM, Arasan, and Intel hardware. ]] + +SDHCI_RESET_ALL resets will reset the hardware CQE state, but we aren't +tracking that properly in software. When out of sync, we may trigger +various timeouts. + +It's not typical to perform resets while CQE is enabled, but this may +occur in some suspend or error recovery scenarios. + +Include this fix by way of the new sdhci_and_cqhci_reset() helper. + +I only patch the bcm7216 variant even though others potentially *could* +provide the 'supports-cqe' property (and thus enable CQHCI), because +d46ba2d17f90 ("mmc: sdhci-brcmstb: Add support for Command Queuing +(CQE)") and some Broadcom folks confirm that only the 7216 variant +actually supports it. + +This patch depends on (and should not compile without) the patch +entitled "mmc: cqhci: Provide helper for resetting both SDHCI and +CQHCI". + +Fixes: d46ba2d17f90 ("mmc: sdhci-brcmstb: Add support for Command Queuing (CQE)") +Signed-off-by: Brian Norris +Reviewed-by: Florian Fainelli +Acked-by: Adrian Hunter +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20221026124150.v4.3.I6a715feab6d01f760455865e968ecf0d85036018@changeid +Signed-off-by: Ulf Hansson +Signed-off-by: Sasha Levin +--- + drivers/mmc/host/sdhci-brcmstb.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/mmc/host/sdhci-brcmstb.c b/drivers/mmc/host/sdhci-brcmstb.c +index 683d0c685748..4d42b1810ace 100644 +--- a/drivers/mmc/host/sdhci-brcmstb.c ++++ b/drivers/mmc/host/sdhci-brcmstb.c +@@ -12,6 +12,7 @@ + #include + #include + ++#include "sdhci-cqhci.h" + #include "sdhci-pltfm.h" + #include "cqhci.h" + +@@ -53,7 +54,7 @@ void brcmstb_reset(struct sdhci_host *host, u8 mask) + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_brcmstb_priv *priv = sdhci_pltfm_priv(pltfm_host); + +- sdhci_reset(host, mask); ++ sdhci_and_cqhci_reset(host, mask); + + /* Reset will clear this, so re-enable it */ + if (priv->flags & BRCMSTB_PRIV_FLAGS_GATE_CLOCK) +-- +2.35.1 + diff --git a/queue-5.15/mmc-sdhci-brcmstb-re-organize-flags.patch b/queue-5.15/mmc-sdhci-brcmstb-re-organize-flags.patch new file mode 100644 index 00000000000..6a10301a2f1 --- /dev/null +++ b/queue-5.15/mmc-sdhci-brcmstb-re-organize-flags.patch @@ -0,0 +1,133 @@ +From 6b42dc1bfd0629b689cc9a806f2cf76e4ce50528 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Apr 2022 14:08:50 -0400 +Subject: mmc: sdhci-brcmstb: Re-organize flags + +From: Al Cooper + +[ Upstream commit f3a70f991dd07330225ea11e158e1d07ad5733fb ] + +Re-organize the flags by basing the bit names on the flag that they +apply to. Also change the "flags" member in the "brcmstb_match_priv" +struct to const. + +Signed-off-by: Al Cooper +Signed-off-by: Kamal Dasu +Acked-by: Florian Fainelli +Acked-by: Adrian Hunter +Link: https://lore.kernel.org/r/20220427180853.35970-2-kdasu.kdev@gmail.com +Signed-off-by: Ulf Hansson +Stable-dep-of: 56baa208f910 ("mmc: sdhci-brcmstb: Fix SDHCI_RESET_ALL for CQHCI") +Signed-off-by: Sasha Levin +--- + drivers/mmc/host/sdhci-brcmstb.c | 32 ++++++++++++++++---------------- + 1 file changed, 16 insertions(+), 16 deletions(-) + +diff --git a/drivers/mmc/host/sdhci-brcmstb.c b/drivers/mmc/host/sdhci-brcmstb.c +index f24623aac2db..244780481193 100644 +--- a/drivers/mmc/host/sdhci-brcmstb.c ++++ b/drivers/mmc/host/sdhci-brcmstb.c +@@ -18,20 +18,22 @@ + #define SDHCI_VENDOR 0x78 + #define SDHCI_VENDOR_ENHANCED_STRB 0x1 + +-#define BRCMSTB_PRIV_FLAGS_NO_64BIT BIT(0) +-#define BRCMSTB_PRIV_FLAGS_BROKEN_TIMEOUT BIT(1) ++#define BRCMSTB_MATCH_FLAGS_NO_64BIT BIT(0) ++#define BRCMSTB_MATCH_FLAGS_BROKEN_TIMEOUT BIT(1) ++ ++#define BRCMSTB_PRIV_FLAGS_HAS_CQE BIT(0) + + #define SDHCI_ARASAN_CQE_BASE_ADDR 0x200 + + struct sdhci_brcmstb_priv { + void __iomem *cfg_regs; +- bool has_cqe; ++ unsigned int flags; + }; + + struct brcmstb_match_priv { + void (*hs400es)(struct mmc_host *mmc, struct mmc_ios *ios); + struct sdhci_ops *ops; +- unsigned int flags; ++ const unsigned int flags; + }; + + static void sdhci_brcmstb_hs400es(struct mmc_host *mmc, struct mmc_ios *ios) +@@ -134,13 +136,13 @@ static struct sdhci_ops sdhci_brcmstb_ops_7216 = { + }; + + static struct brcmstb_match_priv match_priv_7425 = { +- .flags = BRCMSTB_PRIV_FLAGS_NO_64BIT | +- BRCMSTB_PRIV_FLAGS_BROKEN_TIMEOUT, ++ .flags = BRCMSTB_MATCH_FLAGS_NO_64BIT | ++ BRCMSTB_MATCH_FLAGS_BROKEN_TIMEOUT, + .ops = &sdhci_brcmstb_ops, + }; + + static struct brcmstb_match_priv match_priv_7445 = { +- .flags = BRCMSTB_PRIV_FLAGS_BROKEN_TIMEOUT, ++ .flags = BRCMSTB_MATCH_FLAGS_BROKEN_TIMEOUT, + .ops = &sdhci_brcmstb_ops, + }; + +@@ -176,7 +178,7 @@ static int sdhci_brcmstb_add_host(struct sdhci_host *host, + bool dma64; + int ret; + +- if (!priv->has_cqe) ++ if ((priv->flags & BRCMSTB_PRIV_FLAGS_HAS_CQE) == 0) + return sdhci_add_host(host); + + dev_dbg(mmc_dev(host->mmc), "CQE is enabled\n"); +@@ -225,7 +227,6 @@ static int sdhci_brcmstb_probe(struct platform_device *pdev) + struct sdhci_brcmstb_priv *priv; + struct sdhci_host *host; + struct resource *iomem; +- bool has_cqe = false; + struct clk *clk; + int res; + +@@ -244,10 +245,6 @@ static int sdhci_brcmstb_probe(struct platform_device *pdev) + return res; + + memset(&brcmstb_pdata, 0, sizeof(brcmstb_pdata)); +- if (device_property_read_bool(&pdev->dev, "supports-cqe")) { +- has_cqe = true; +- match_priv->ops->irq = sdhci_brcmstb_cqhci_irq; +- } + brcmstb_pdata.ops = match_priv->ops; + host = sdhci_pltfm_init(pdev, &brcmstb_pdata, + sizeof(struct sdhci_brcmstb_priv)); +@@ -258,7 +255,10 @@ static int sdhci_brcmstb_probe(struct platform_device *pdev) + + pltfm_host = sdhci_priv(host); + priv = sdhci_pltfm_priv(pltfm_host); +- priv->has_cqe = has_cqe; ++ if (device_property_read_bool(&pdev->dev, "supports-cqe")) { ++ priv->flags |= BRCMSTB_PRIV_FLAGS_HAS_CQE; ++ match_priv->ops->irq = sdhci_brcmstb_cqhci_irq; ++ } + + /* Map in the non-standard CFG registers */ + iomem = platform_get_resource(pdev, IORESOURCE_MEM, 1); +@@ -287,14 +287,14 @@ static int sdhci_brcmstb_probe(struct platform_device *pdev) + * properties through mmc_of_parse(). + */ + host->caps = sdhci_readl(host, SDHCI_CAPABILITIES); +- if (match_priv->flags & BRCMSTB_PRIV_FLAGS_NO_64BIT) ++ if (match_priv->flags & BRCMSTB_MATCH_FLAGS_NO_64BIT) + host->caps &= ~SDHCI_CAN_64BIT; + host->caps1 = sdhci_readl(host, SDHCI_CAPABILITIES_1); + host->caps1 &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 | + SDHCI_SUPPORT_DDR50); + host->quirks |= SDHCI_QUIRK_MISSING_CAPS; + +- if (match_priv->flags & BRCMSTB_PRIV_FLAGS_BROKEN_TIMEOUT) ++ if (match_priv->flags & BRCMSTB_MATCH_FLAGS_BROKEN_TIMEOUT) + host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; + + res = sdhci_brcmstb_add_host(host, priv); +-- +2.35.1 + diff --git a/queue-5.15/series b/queue-5.15/series index 508ce4c2525..84b621abf46 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -134,3 +134,7 @@ s390-crashdump-fix-tod-programmable-field-size.patch lib-vdso-use-grep-e-instead-of-egrep.patch init-kconfig-fix-cc_has_asm_goto_tied_output-test-wi.patch nios2-add-force-for-vmlinuz.gz.patch +mmc-sdhci-brcmstb-re-organize-flags.patch +mmc-sdhci-brcmstb-enable-clock-gating-to-save-power.patch +mmc-sdhci-brcmstb-fix-sdhci_reset_all-for-cqhci.patch +dmaengine-idxd-do-not-enable-user-type-work-queue-wi.patch