diff options
51 files changed, 4088 insertions, 0 deletions
diff --git a/queue-5.10/alsa-hda-add-new-pci-id-for-amd-gpu-display-hd-audio.patch b/queue-5.10/alsa-hda-add-new-pci-id-for-amd-gpu-display-hd-audio.patch new file mode 100644 index 0000000000..c399639ca7 --- /dev/null +++ b/queue-5.10/alsa-hda-add-new-pci-id-for-amd-gpu-display-hd-audio.patch @@ -0,0 +1,37 @@ +From 3de816930fd8eea39cc1894753f975241c459ff6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Thu, 29 May 2025 11:08:13 +0530 +Subject: ALSA: hda: Add new pci id for AMD GPU display HD audio controller + +From: Vijendar Mukunda <Vijendar.Mukunda@amd.com> + +[ Upstream commit ab72bfce7647522e01a181e3600c3d14ff5c143e ] + +Add new pci id for AMD GPU display HD audio controller(device id- 0xab40). + +Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com> +Reviewed-by: Alex Deucher <alexander.deucher@amd.com> +Link: https://patch.msgid.link/20250529053838.2350071-1-Vijendar.Mukunda@amd.com +Signed-off-by: Takashi Iwai <tiwai@suse.de> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + sound/pci/hda/hda_intel.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c +index dd7c7cb0de140..cb3dccdf3911c 100644 +--- a/sound/pci/hda/hda_intel.c ++++ b/sound/pci/hda/hda_intel.c +@@ -2793,6 +2793,9 @@ static const struct pci_device_id azx_ids[] = { + { PCI_DEVICE(0x1002, 0xab38), + .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS | + AZX_DCAPS_PM_RUNTIME }, ++ { PCI_VDEVICE(ATI, 0xab40), ++ .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS | ++ AZX_DCAPS_PM_RUNTIME }, + /* GLENFLY */ + { PCI_DEVICE(PCI_VENDOR_ID_GLENFLY, PCI_ANY_ID), + .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, +-- +2.39.5 + diff --git a/queue-5.10/alsa-hda-ignore-unsol-events-for-cards-being-shut-do.patch b/queue-5.10/alsa-hda-ignore-unsol-events-for-cards-being-shut-do.patch new file mode 100644 index 0000000000..96657e3384 --- /dev/null +++ b/queue-5.10/alsa-hda-ignore-unsol-events-for-cards-being-shut-do.patch @@ -0,0 +1,48 @@ +From d8ecc4210fc6014076bb2e88405e7ae24eca6072 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Fri, 30 May 2025 16:13:09 +0200 +Subject: ALSA: hda: Ignore unsol events for cards being shut down +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Cezary Rojewski <cezary.rojewski@intel.com> + +[ Upstream commit 3f100f524e75586537e337b34d18c8d604b398e7 ] + +For the classic snd_hda_intel driver, codec->card and bus->card point to +the exact same thing. When snd_card_diconnect() fires, bus->shutdown is +set thanks to azx_dev_disconnect(). card->shutdown is already set when +that happens but both provide basically the same functionality. + +For the DSP snd_soc_avs driver where multiple codecs are located on +multiple cards, bus->shutdown 'shortcut' is not sufficient. One codec +card may be unregistered while other codecs are still operational. +Proper check in form of card->shutdown must be used to verify whether +the codec's card is being shut down. + +Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com> +Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com> +Link: https://patch.msgid.link/20250530141309.2943404-1-cezary.rojewski@intel.com +Signed-off-by: Takashi Iwai <tiwai@suse.de> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + sound/pci/hda/hda_bind.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c +index 0a83afa5f373c..6625643f333e8 100644 +--- a/sound/pci/hda/hda_bind.c ++++ b/sound/pci/hda/hda_bind.c +@@ -44,7 +44,7 @@ static void hda_codec_unsol_event(struct hdac_device *dev, unsigned int ev) + struct hda_codec *codec = container_of(dev, struct hda_codec, core); + + /* ignore unsol events during shutdown */ +- if (codec->bus->shutdown) ++ if (codec->card->shutdown || codec->bus->shutdown) + return; + + /* ignore unsol events during system suspend/resume */ +-- +2.39.5 + diff --git a/queue-5.10/asoc-codec-wcd9335-convert-to-gpio-descriptors.patch b/queue-5.10/asoc-codec-wcd9335-convert-to-gpio-descriptors.patch new file mode 100644 index 0000000000..894127166d --- /dev/null +++ b/queue-5.10/asoc-codec-wcd9335-convert-to-gpio-descriptors.patch @@ -0,0 +1,85 @@ +From abb59de07dbce537619cdce4291ac0aec60aa6b8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Mon, 24 Mar 2025 19:51:29 +0800 +Subject: ASoC: codec: wcd9335: Convert to GPIO descriptors + +From: Peng Fan <peng.fan@nxp.com> + +[ Upstream commit d5099bc1b56417733f4cccf10c61ee74dadd5562 ] + +of_gpio.h is deprecated, update the driver to use GPIO descriptors. +- Use dev_gpiod_get to get GPIO descriptor. +- Use gpiod_set_value to configure output value. + +With legacy of_gpio API, the driver set gpio value 0 to assert reset, +and 1 to deassert reset. And the reset-gpios use GPIO_ACTIVE_LOW flag in +DTS, so set GPIOD_OUT_LOW when get GPIO descriptors, and set value 1 means +output low, set value 0 means output high with gpiod API. + +The in-tree DTS files have the right polarity set up already so we can +expect this to "just work" + +Reviewed-by: Linus Walleij <linus.walleij@linaro.org> +Signed-off-by: Peng Fan <peng.fan@nxp.com> +Link: https://patch.msgid.link/20250324-wcd-gpiod-v2-3-773f67ce3b56@nxp.com +Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> +Signed-off-by: Mark Brown <broonie@kernel.org> +Stable-dep-of: 9079db287fc3 ("ASoC: codecs: wcd9335: Fix missing free of regulator supplies") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + sound/soc/codecs/wcd9335.c | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c +index ac297bc6c9a12..a4d1cd296a76d 100644 +--- a/sound/soc/codecs/wcd9335.c ++++ b/sound/soc/codecs/wcd9335.c +@@ -16,7 +16,7 @@ + #include <sound/soc.h> + #include <sound/pcm_params.h> + #include <sound/soc-dapm.h> +-#include <linux/of_gpio.h> ++#include <linux/gpio/consumer.h> + #include <linux/of.h> + #include <linux/of_irq.h> + #include <sound/tlv.h> +@@ -338,7 +338,7 @@ struct wcd9335_codec { + int comp_enabled[COMPANDER_MAX]; + + int intr1; +- int reset_gpio; ++ struct gpio_desc *reset_gpio; + struct regulator_bulk_data supplies[WCD9335_MAX_SUPPLY]; + + unsigned int rx_port_value; +@@ -5024,12 +5024,11 @@ static const struct regmap_irq_chip wcd9335_regmap_irq1_chip = { + static int wcd9335_parse_dt(struct wcd9335_codec *wcd) + { + struct device *dev = wcd->dev; +- struct device_node *np = dev->of_node; + int ret; + +- wcd->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0); +- if (wcd->reset_gpio < 0) +- return dev_err_probe(dev, wcd->reset_gpio, "Reset GPIO missing from DT\n"); ++ wcd->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); ++ if (IS_ERR(wcd->reset_gpio)) ++ return dev_err_probe(dev, PTR_ERR(wcd->reset_gpio), "Reset GPIO missing from DT\n"); + + wcd->mclk = devm_clk_get(dev, "mclk"); + if (IS_ERR(wcd->mclk)) +@@ -5072,9 +5071,9 @@ static int wcd9335_power_on_reset(struct wcd9335_codec *wcd) + */ + usleep_range(600, 650); + +- gpio_direction_output(wcd->reset_gpio, 0); ++ gpiod_set_value(wcd->reset_gpio, 1); + msleep(20); +- gpio_set_value(wcd->reset_gpio, 1); ++ gpiod_set_value(wcd->reset_gpio, 0); + msleep(20); + + return 0; +-- +2.39.5 + diff --git a/queue-5.10/asoc-codecs-wcd9335-fix-missing-free-of-regulator-su.patch b/queue-5.10/asoc-codecs-wcd9335-fix-missing-free-of-regulator-su.patch new file mode 100644 index 0000000000..698e944406 --- /dev/null +++ b/queue-5.10/asoc-codecs-wcd9335-fix-missing-free-of-regulator-su.patch @@ -0,0 +1,88 @@ +From d123202ff5409b54bb2ad776f00cc88fb4f2717f Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Mon, 26 May 2025 11:47:01 +0200 +Subject: ASoC: codecs: wcd9335: Fix missing free of regulator supplies + +From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> + +[ Upstream commit 9079db287fc3e38e040b0edeb0a25770bb679c8e ] + +Driver gets and enables all regulator supplies in probe path +(wcd9335_parse_dt() and wcd9335_power_on_reset()), but does not cleanup +in final error paths and in unbind (missing remove() callback). This +leads to leaked memory and unbalanced regulator enable count during +probe errors or unbind. + +Fix this by converting entire code into devm_regulator_bulk_get_enable() +which also greatly simplifies the code. + +Fixes: 20aedafdf492 ("ASoC: wcd9335: add support to wcd9335 codec") +Cc: stable@vger.kernel.org +Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> +Link: https://patch.msgid.link/20250526-b4-b4-asoc-wcd9395-vdd-px-fixes-v1-1-0b8a2993b7d3@linaro.org +Signed-off-by: Mark Brown <broonie@kernel.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + sound/soc/codecs/wcd9335.c | 25 +++++++------------------ + 1 file changed, 7 insertions(+), 18 deletions(-) + +diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c +index a4d1cd296a76d..fe364cb353967 100644 +--- a/sound/soc/codecs/wcd9335.c ++++ b/sound/soc/codecs/wcd9335.c +@@ -339,7 +339,6 @@ struct wcd9335_codec { + + int intr1; + struct gpio_desc *reset_gpio; +- struct regulator_bulk_data supplies[WCD9335_MAX_SUPPLY]; + + unsigned int rx_port_value; + unsigned int tx_port_value; +@@ -366,6 +365,10 @@ struct wcd9335_irq { + char *name; + }; + ++static const char * const wcd9335_supplies[] = { ++ "vdd-buck", "vdd-buck-sido", "vdd-tx", "vdd-rx", "vdd-io", ++}; ++ + static const struct wcd9335_slim_ch wcd9335_tx_chs[WCD9335_TX_MAX] = { + WCD9335_SLIM_TX_CH(0), + WCD9335_SLIM_TX_CH(1), +@@ -5038,30 +5041,16 @@ static int wcd9335_parse_dt(struct wcd9335_codec *wcd) + if (IS_ERR(wcd->native_clk)) + return dev_err_probe(dev, PTR_ERR(wcd->native_clk), "slimbus clock not found\n"); + +- wcd->supplies[0].supply = "vdd-buck"; +- wcd->supplies[1].supply = "vdd-buck-sido"; +- wcd->supplies[2].supply = "vdd-tx"; +- wcd->supplies[3].supply = "vdd-rx"; +- wcd->supplies[4].supply = "vdd-io"; +- +- ret = regulator_bulk_get(dev, WCD9335_MAX_SUPPLY, wcd->supplies); ++ ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(wcd9335_supplies), ++ wcd9335_supplies); + if (ret) +- return dev_err_probe(dev, ret, "Failed to get supplies\n"); ++ return dev_err_probe(dev, ret, "Failed to get and enable supplies\n"); + + return 0; + } + + static int wcd9335_power_on_reset(struct wcd9335_codec *wcd) + { +- struct device *dev = wcd->dev; +- int ret; +- +- ret = regulator_bulk_enable(WCD9335_MAX_SUPPLY, wcd->supplies); +- if (ret) { +- dev_err(dev, "Failed to get supplies: err = %d\n", ret); +- return ret; +- } +- + /* + * For WCD9335, it takes about 600us for the Vout_A and + * Vout_D to be ready after BUCK_SIDO is powered up. +-- +2.39.5 + diff --git a/queue-5.10/asoc-codecs-wcd9335-handle-nicer-probe-deferral-and-.patch b/queue-5.10/asoc-codecs-wcd9335-handle-nicer-probe-deferral-and-.patch new file mode 100644 index 0000000000..7d6eaab8ea --- /dev/null +++ b/queue-5.10/asoc-codecs-wcd9335-handle-nicer-probe-deferral-and-.patch @@ -0,0 +1,85 @@ +From 38eac094424e3aa4dee1b706dc5e0e14be1864cb Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Wed, 12 Jun 2024 18:15:17 +0200 +Subject: ASoC: codecs: wcd9335: Handle nicer probe deferral and simplify with + dev_err_probe() + +From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> + +[ Upstream commit 4a03b5dbad466c902d522f3405daa4e5d80578c5 ] + +wcd9335_parse_dt() function is called only from probe(), so printing +errors on resource acquisition is discouraged, because it can pollute +dmesg. Use dev_err_probe() to fix this and also make the code a bit +simpler. + +Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> +Link: https://msgid.link/r/20240612-asoc-wcd9xxx-wide-cleanups-v1-4-0d15885b2a06@linaro.org +Signed-off-by: Mark Brown <broonie@kernel.org> +Stable-dep-of: 9079db287fc3 ("ASoC: codecs: wcd9335: Fix missing free of regulator supplies") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + sound/soc/codecs/wcd9335.c | 28 +++++++++------------------- + 1 file changed, 9 insertions(+), 19 deletions(-) + +diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c +index 33c29a1f52d00..ac297bc6c9a12 100644 +--- a/sound/soc/codecs/wcd9335.c ++++ b/sound/soc/codecs/wcd9335.c +@@ -5028,22 +5028,16 @@ static int wcd9335_parse_dt(struct wcd9335_codec *wcd) + int ret; + + wcd->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0); +- if (wcd->reset_gpio < 0) { +- dev_err(dev, "Reset GPIO missing from DT\n"); +- return wcd->reset_gpio; +- } ++ if (wcd->reset_gpio < 0) ++ return dev_err_probe(dev, wcd->reset_gpio, "Reset GPIO missing from DT\n"); + + wcd->mclk = devm_clk_get(dev, "mclk"); +- if (IS_ERR(wcd->mclk)) { +- dev_err(dev, "mclk not found\n"); +- return PTR_ERR(wcd->mclk); +- } ++ if (IS_ERR(wcd->mclk)) ++ return dev_err_probe(dev, PTR_ERR(wcd->mclk), "mclk not found\n"); + + wcd->native_clk = devm_clk_get(dev, "slimbus"); +- if (IS_ERR(wcd->native_clk)) { +- dev_err(dev, "slimbus clock not found\n"); +- return PTR_ERR(wcd->native_clk); +- } ++ if (IS_ERR(wcd->native_clk)) ++ return dev_err_probe(dev, PTR_ERR(wcd->native_clk), "slimbus clock not found\n"); + + wcd->supplies[0].supply = "vdd-buck"; + wcd->supplies[1].supply = "vdd-buck-sido"; +@@ -5052,10 +5046,8 @@ static int wcd9335_parse_dt(struct wcd9335_codec *wcd) + wcd->supplies[4].supply = "vdd-io"; + + ret = regulator_bulk_get(dev, WCD9335_MAX_SUPPLY, wcd->supplies); +- if (ret) { +- dev_err(dev, "Failed to get supplies: err = %d\n", ret); +- return ret; +- } ++ if (ret) ++ return dev_err_probe(dev, ret, "Failed to get supplies\n"); + + return 0; + } +@@ -5158,10 +5150,8 @@ static int wcd9335_slim_probe(struct slim_device *slim) + + wcd->dev = dev; + ret = wcd9335_parse_dt(wcd); +- if (ret) { +- dev_err(dev, "Error parsing DT: %d\n", ret); ++ if (ret) + return ret; +- } + + ret = wcd9335_power_on_reset(wcd); + if (ret) +-- +2.39.5 + diff --git a/queue-5.10/bcache-fix-null-pointer-in-cache_set_flush.patch b/queue-5.10/bcache-fix-null-pointer-in-cache_set_flush.patch new file mode 100644 index 0000000000..075c0be676 --- /dev/null +++ b/queue-5.10/bcache-fix-null-pointer-in-cache_set_flush.patch @@ -0,0 +1,151 @@ +From 9a1140149a39c879117f60449dedd14b23b6ab44 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 27 May 2025 13:15:59 +0800 +Subject: bcache: fix NULL pointer in cache_set_flush() + +From: Linggang Zeng <linggang.zeng@easystack.cn> + +[ Upstream commit 1e46ed947ec658f89f1a910d880cd05e42d3763e ] + +1. LINE#1794 - LINE#1887 is some codes about function of + bch_cache_set_alloc(). +2. LINE#2078 - LINE#2142 is some codes about function of + register_cache_set(). +3. register_cache_set() will call bch_cache_set_alloc() in LINE#2098. + + 1794 struct cache_set *bch_cache_set_alloc(struct cache_sb *sb) + 1795 { + ... + 1860 if (!(c->devices = kcalloc(c->nr_uuids, sizeof(void *), GFP_KERNEL)) || + 1861 mempool_init_slab_pool(&c->search, 32, bch_search_cache) || + 1862 mempool_init_kmalloc_pool(&c->bio_meta, 2, + 1863 sizeof(struct bbio) + sizeof(struct bio_vec) * + 1864 bucket_pages(c)) || + 1865 mempool_init_kmalloc_pool(&c->fill_iter, 1, iter_size) || + 1866 bioset_init(&c->bio_split, 4, offsetof(struct bbio, bio), + 1867 BIOSET_NEED_BVECS|BIOSET_NEED_RESCUER) || + 1868 !(c->uuids = alloc_bucket_pages(GFP_KERNEL, c)) || + 1869 !(c->moving_gc_wq = alloc_workqueue("bcache_gc", + 1870 WQ_MEM_RECLAIM, 0)) || + 1871 bch_journal_alloc(c) || + 1872 bch_btree_cache_alloc(c) || + 1873 bch_open_buckets_alloc(c) || + 1874 bch_bset_sort_state_init(&c->sort, ilog2(c->btree_pages))) + 1875 goto err; + ^^^^^^^^ + 1876 + ... + 1883 return c; + 1884 err: + 1885 bch_cache_set_unregister(c); + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 1886 return NULL; + 1887 } + ... + 2078 static const char *register_cache_set(struct cache *ca) + 2079 { + ... + 2098 c = bch_cache_set_alloc(&ca->sb); + 2099 if (!c) + 2100 return err; + ^^^^^^^^^^ + ... + 2128 ca->set = c; + 2129 ca->set->cache[ca->sb.nr_this_dev] = ca; + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ... + 2138 return NULL; + 2139 err: + 2140 bch_cache_set_unregister(c); + 2141 return err; + 2142 } + +(1) If LINE#1860 - LINE#1874 is true, then do 'goto err'(LINE#1875) and + call bch_cache_set_unregister()(LINE#1885). +(2) As (1) return NULL(LINE#1886), LINE#2098 - LINE#2100 would return. +(3) As (2) has returned, LINE#2128 - LINE#2129 would do *not* give the + value to c->cache[], it means that c->cache[] is NULL. + +LINE#1624 - LINE#1665 is some codes about function of cache_set_flush(). +As (1), in LINE#1885 call +bch_cache_set_unregister() +---> bch_cache_set_stop() + ---> closure_queue() + -.-> cache_set_flush() (as below LINE#1624) + + 1624 static void cache_set_flush(struct closure *cl) + 1625 { + ... + 1654 for_each_cache(ca, c, i) + 1655 if (ca->alloc_thread) + ^^ + 1656 kthread_stop(ca->alloc_thread); + ... + 1665 } + +(4) In LINE#1655 ca is NULL(see (3)) in cache_set_flush() then the + kernel crash occurred as below: +[ 846.712887] bcache: register_cache() error drbd6: cannot allocate memory +[ 846.713242] bcache: register_bcache() error : failed to register device +[ 846.713336] bcache: cache_set_free() Cache set 2f84bdc1-498a-4f2f-98a7-01946bf54287 unregistered +[ 846.713768] BUG: unable to handle kernel NULL pointer dereference at 00000000000009f8 +[ 846.714790] PGD 0 P4D 0 +[ 846.715129] Oops: 0000 [#1] SMP PTI +[ 846.715472] CPU: 19 PID: 5057 Comm: kworker/19:16 Kdump: loaded Tainted: G OE --------- - - 4.18.0-147.5.1.el8_1.5es.3.x86_64 #1 +[ 846.716082] Hardware name: ESPAN GI-25212/X11DPL-i, BIOS 2.1 06/15/2018 +[ 846.716451] Workqueue: events cache_set_flush [bcache] +[ 846.716808] RIP: 0010:cache_set_flush+0xc9/0x1b0 [bcache] +[ 846.717155] Code: 00 4c 89 a5 b0 03 00 00 48 8b 85 68 f6 ff ff a8 08 0f 84 88 00 00 00 31 db 66 83 bd 3c f7 ff ff 00 48 8b 85 48 ff ff ff 74 28 <48> 8b b8 f8 09 00 00 48 85 ff 74 05 e8 b6 58 a2 e1 0f b7 95 3c f7 +[ 846.718026] RSP: 0018:ffffb56dcf85fe70 EFLAGS: 00010202 +[ 846.718372] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000 +[ 846.718725] RDX: 0000000000000001 RSI: 0000000040000001 RDI: 0000000000000000 +[ 846.719076] RBP: ffffa0ccc0f20df8 R08: ffffa0ce1fedb118 R09: 000073746e657665 +[ 846.719428] R10: 8080808080808080 R11: 0000000000000000 R12: ffffa0ce1fee8700 +[ 846.719779] R13: ffffa0ccc0f211a8 R14: ffffa0cd1b902840 R15: ffffa0ccc0f20e00 +[ 846.720132] FS: 0000000000000000(0000) GS:ffffa0ce1fec0000(0000) knlGS:0000000000000000 +[ 846.720726] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 846.721073] CR2: 00000000000009f8 CR3: 00000008ba00a005 CR4: 00000000007606e0 +[ 846.721426] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +[ 846.721778] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +[ 846.722131] PKRU: 55555554 +[ 846.722467] Call Trace: +[ 846.722814] process_one_work+0x1a7/0x3b0 +[ 846.723157] worker_thread+0x30/0x390 +[ 846.723501] ? create_worker+0x1a0/0x1a0 +[ 846.723844] kthread+0x112/0x130 +[ 846.724184] ? kthread_flush_work_fn+0x10/0x10 +[ 846.724535] ret_from_fork+0x35/0x40 + +Now, check whether that ca is NULL in LINE#1655 to fix the issue. + +Signed-off-by: Linggang Zeng <linggang.zeng@easystack.cn> +Signed-off-by: Mingzhe Zou <mingzhe.zou@easystack.cn> +Signed-off-by: Coly Li <colyli@kernel.org> +Link: https://lore.kernel.org/r/20250527051601.74407-2-colyli@kernel.org +Signed-off-by: Jens Axboe <axboe@kernel.dk> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/md/bcache/super.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c +index 85569bd253b2c..a80de1cfbbd07 100644 +--- a/drivers/md/bcache/super.c ++++ b/drivers/md/bcache/super.c +@@ -1765,7 +1765,12 @@ static void cache_set_flush(struct closure *cl) + mutex_unlock(&b->write_lock); + } + +- if (ca->alloc_thread) ++ /* ++ * If the register_cache_set() call to bch_cache_set_alloc() failed, ++ * ca has not been assigned a value and return error. ++ * So we need check ca is not NULL during bch_cache_set_unregister(). ++ */ ++ if (ca && ca->alloc_thread) + kthread_stop(ca->alloc_thread); + + if (c->journal.cur) { +-- +2.39.5 + diff --git a/queue-5.10/can-tcan4x5x-fix-power-regulator-retrieval-during-pr.patch b/queue-5.10/can-tcan4x5x-fix-power-regulator-retrieval-during-pr.patch new file mode 100644 index 0000000000..199adca7cf --- /dev/null +++ b/queue-5.10/can-tcan4x5x-fix-power-regulator-retrieval-during-pr.patch @@ -0,0 +1,46 @@ +From 2d5fde602b891949288358bbe8b359dcd6df4fb8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Thu, 12 Jun 2025 14:18:25 -0500 +Subject: can: tcan4x5x: fix power regulator retrieval during probe + +From: Brett Werling <brett.werling@garmin.com> + +[ Upstream commit db22720545207f734aaa9d9f71637bfc8b0155e0 ] + +Fixes the power regulator retrieval in tcan4x5x_can_probe() by ensuring +the regulator pointer is not set to NULL in the successful return from +devm_regulator_get_optional(). + +Fixes: 3814ca3a10be ("can: tcan4x5x: tcan4x5x_can_probe(): turn on the power before parsing the config") +Signed-off-by: Brett Werling <brett.werling@garmin.com> +Link: https://patch.msgid.link/20250612191825.3646364-1-brett.werling@garmin.com +Cc: stable@vger.kernel.org +Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/net/can/m_can/tcan4x5x.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/can/m_can/tcan4x5x.c b/drivers/net/can/m_can/tcan4x5x.c +index f903f78af087a..4bdea945c4862 100644 +--- a/drivers/net/can/m_can/tcan4x5x.c ++++ b/drivers/net/can/m_can/tcan4x5x.c +@@ -417,10 +417,11 @@ static int tcan4x5x_can_probe(struct spi_device *spi) + } + + priv->power = devm_regulator_get_optional(&spi->dev, "vsup"); +- if (PTR_ERR(priv->power) == -EPROBE_DEFER) { +- ret = -EPROBE_DEFER; +- goto out_m_can_class_free_dev; +- } else { ++ if (IS_ERR(priv->power)) { ++ if (PTR_ERR(priv->power) == -EPROBE_DEFER) { ++ ret = -EPROBE_DEFER; ++ goto out_m_can_class_free_dev; ++ } + priv->power = NULL; + } + +-- +2.39.5 + diff --git a/queue-5.10/ceph-fix-possible-integer-overflow-in-ceph_zero_obje.patch b/queue-5.10/ceph-fix-possible-integer-overflow-in-ceph_zero_obje.patch new file mode 100644 index 0000000000..02b97721ce --- /dev/null +++ b/queue-5.10/ceph-fix-possible-integer-overflow-in-ceph_zero_obje.patch @@ -0,0 +1,40 @@ +From e6dcdb401a5e58adcd0da6b909183e6ee021954a Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 22 Apr 2025 12:32:04 +0300 +Subject: ceph: fix possible integer overflow in ceph_zero_objects() + +From: Dmitry Kandybka <d.kandybka@gmail.com> + +[ Upstream commit 0abd87942e0c93964e93224836944712feba1d91 ] + +In 'ceph_zero_objects', promote 'object_size' to 'u64' to avoid possible +integer overflow. + +Compile tested only. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Signed-off-by: Dmitry Kandybka <d.kandybka@gmail.com> +Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com> +Signed-off-by: Ilya Dryomov <idryomov@gmail.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + fs/ceph/file.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/ceph/file.c b/fs/ceph/file.c +index d4974c652e8e4..c1eafff45b194 100644 +--- a/fs/ceph/file.c ++++ b/fs/ceph/file.c +@@ -2034,7 +2034,7 @@ static int ceph_zero_objects(struct inode *inode, loff_t offset, loff_t length) + s32 stripe_unit = ci->i_layout.stripe_unit; + s32 stripe_count = ci->i_layout.stripe_count; + s32 object_size = ci->i_layout.object_size; +- u64 object_set_size = object_size * stripe_count; ++ u64 object_set_size = (u64) object_size * stripe_count; + u64 nearly, t; + + /* round offset up to next period boundary */ +-- +2.39.5 + diff --git a/queue-5.10/cifs-fix-cifs_query_path_info-for-windows-nt-servers.patch b/queue-5.10/cifs-fix-cifs_query_path_info-for-windows-nt-servers.patch new file mode 100644 index 0000000000..d102906b2e --- /dev/null +++ b/queue-5.10/cifs-fix-cifs_query_path_info-for-windows-nt-servers.patch @@ -0,0 +1,55 @@ +From d65ade866e3f1f636b95909c97bdef9b762ab0e8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 31 Dec 2024 16:06:22 +0100 +Subject: cifs: Fix cifs_query_path_info() for Windows NT servers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Pali Rohár <pali@kernel.org> + +[ Upstream commit a3e771afbb3bce91c8296828304903e7348003fe ] + +For TRANS2 QUERY_PATH_INFO request when the path does not exist, the +Windows NT SMB server returns error response STATUS_OBJECT_NAME_NOT_FOUND +or ERRDOS/ERRbadfile without the SMBFLG_RESPONSE flag set. Similarly it +returns STATUS_DELETE_PENDING when the file is being deleted. And looks +like that any error response from TRANS2 QUERY_PATH_INFO does not have +SMBFLG_RESPONSE flag set. + +So relax check in check_smb_hdr() for detecting if the packet is response +for this special case. + +This change fixes stat() operation against Windows NT SMB servers and also +all operations which depends on -ENOENT result from stat like creat() or +mkdir(). + +Signed-off-by: Pali Rohár <pali@kernel.org> +Signed-off-by: Steve French <stfrench@microsoft.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + fs/cifs/misc.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c +index 2d46018b02839..54c443686daba 100644 +--- a/fs/cifs/misc.c ++++ b/fs/cifs/misc.c +@@ -310,6 +310,14 @@ check_smb_hdr(struct smb_hdr *smb) + if (smb->Command == SMB_COM_LOCKING_ANDX) + return 0; + ++ /* ++ * Windows NT server returns error resposne (e.g. STATUS_DELETE_PENDING ++ * or STATUS_OBJECT_NAME_NOT_FOUND or ERRDOS/ERRbadfile or any other) ++ * for some TRANS2 requests without the RESPONSE flag set in header. ++ */ ++ if (smb->Command == SMB_COM_TRANSACTION2 && smb->Status.CifsError != 0) ++ return 0; ++ + cifs_dbg(VFS, "Server sent request, not response. mid=%u\n", + get_mid(smb)); + return 1; +-- +2.39.5 + diff --git a/queue-5.10/dmaengine-xilinx_dma-set-dma_device-directions.patch b/queue-5.10/dmaengine-xilinx_dma-set-dma_device-directions.patch new file mode 100644 index 0000000000..67bea3e05a --- /dev/null +++ b/queue-5.10/dmaengine-xilinx_dma-set-dma_device-directions.patch @@ -0,0 +1,40 @@ +From b5cb773f32b0b285f5d56156c2888e3d49b99925 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Wed, 7 May 2025 20:21:01 +0200 +Subject: dmaengine: xilinx_dma: Set dma_device directions + +From: Thomas Gessler <thomas.gessler@brueckmann-gmbh.de> + +[ Upstream commit 7e01511443c30a55a5ae78d3debd46d4d872517e ] + +Coalesce the direction bits from the enabled TX and/or RX channels into +the directions bit mask of dma_device. Without this mask set, +dma_get_slave_caps() in the DMAEngine fails, which prevents the driver +from being used with an IIO DMAEngine buffer. + +Signed-off-by: Thomas Gessler <thomas.gessler@brueckmann-gmbh.de> +Reviewed-by: Suraj Gupta <suraj.gupta2@amd.com> +Tested-by: Folker Schwesinger <dev@folker-schwesinger.de> +Link: https://lore.kernel.org/r/20250507182101.909010-1-thomas.gessler@brueckmann-gmbh.de +Signed-off-by: Vinod Koul <vkoul@kernel.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/dma/xilinx/xilinx_dma.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c +index 12ad4bb3c5f28..3ecf0109af2ba 100644 +--- a/drivers/dma/xilinx/xilinx_dma.c ++++ b/drivers/dma/xilinx/xilinx_dma.c +@@ -2844,6 +2844,8 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev, + return -EINVAL; + } + ++ xdev->common.directions |= chan->direction; ++ + /* Request the interrupt */ + chan->irq = irq_of_parse_and_map(node, chan->tdest); + err = request_irq(chan->irq, xdev->dma_config->irq_handler, +-- +2.39.5 + diff --git a/queue-5.10/drivers-hv-rename-alloced-to-allocated.patch b/queue-5.10/drivers-hv-rename-alloced-to-allocated.patch new file mode 100644 index 0000000000..13b5331146 --- /dev/null +++ b/queue-5.10/drivers-hv-rename-alloced-to-allocated.patch @@ -0,0 +1,145 @@ +From 65c37f75e235785ce39476ac32f2648a9d346479 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Fri, 28 Jan 2022 11:34:11 +0100 +Subject: Drivers: hv: Rename 'alloced' to 'allocated' + +From: Vitaly Kuznetsov <vkuznets@redhat.com> + +[ Upstream commit de96e8a09889b35dd8d1cb6d19ef2bb123b05be1 ] + +'Alloced' is not a real word and only saves us two letters, let's +use 'allocated' instead. + +No functional change intended. + +Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com> +Reviewed-by: Michael Kelley <mikelley@microsoft.com> +Link: https://lore.kernel.org/r/20220128103412.3033736-2-vkuznets@redhat.com +Signed-off-by: Wei Liu <wei.liu@kernel.org> +Stable-dep-of: 0315fef2aff9 ("uio_hv_generic: Align ring size to system page") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/hv/channel_mgmt.c | 18 +++++++++--------- + drivers/hv/hyperv_vmbus.h | 14 +++++++------- + drivers/hv/vmbus_drv.c | 2 +- + 3 files changed, 17 insertions(+), 17 deletions(-) + +diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c +index 9da36d87ee2c7..4ee8b9b22bb9d 100644 +--- a/drivers/hv/channel_mgmt.c ++++ b/drivers/hv/channel_mgmt.c +@@ -429,7 +429,7 @@ void hv_process_channel_removal(struct vmbus_channel *channel) + * init_vp_index() can (re-)use the CPU. + */ + if (hv_is_perf_channel(channel)) +- hv_clear_alloced_cpu(channel->target_cpu); ++ hv_clear_allocated_cpu(channel->target_cpu); + + /* + * Upon suspend, an in-use hv_sock channel is marked as "rescinded" and +@@ -703,7 +703,7 @@ static void init_vp_index(struct vmbus_channel *channel) + bool perf_chn = hv_is_perf_channel(channel); + u32 i, ncpu = num_online_cpus(); + cpumask_var_t available_mask; +- struct cpumask *alloced_mask; ++ struct cpumask *allocated_mask; + u32 target_cpu; + int numa_node; + +@@ -720,7 +720,7 @@ static void init_vp_index(struct vmbus_channel *channel) + */ + channel->target_cpu = VMBUS_CONNECT_CPU; + if (perf_chn) +- hv_set_alloced_cpu(VMBUS_CONNECT_CPU); ++ hv_set_allocated_cpu(VMBUS_CONNECT_CPU); + return; + } + +@@ -735,22 +735,22 @@ static void init_vp_index(struct vmbus_channel *channel) + continue; + break; + } +- alloced_mask = &hv_context.hv_numa_map[numa_node]; ++ allocated_mask = &hv_context.hv_numa_map[numa_node]; + +- if (cpumask_weight(alloced_mask) == ++ if (cpumask_weight(allocated_mask) == + cpumask_weight(cpumask_of_node(numa_node))) { + /* + * We have cycled through all the CPUs in the node; +- * reset the alloced map. ++ * reset the allocated map. + */ +- cpumask_clear(alloced_mask); ++ cpumask_clear(allocated_mask); + } + +- cpumask_xor(available_mask, alloced_mask, ++ cpumask_xor(available_mask, allocated_mask, + cpumask_of_node(numa_node)); + + target_cpu = cpumask_first(available_mask); +- cpumask_set_cpu(target_cpu, alloced_mask); ++ cpumask_set_cpu(target_cpu, allocated_mask); + + if (channel->offermsg.offer.sub_channel_index >= ncpu || + i > ncpu || !hv_cpuself_used(target_cpu, channel)) +diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h +index a785d790e0aae..323c56152fa1b 100644 +--- a/drivers/hv/hyperv_vmbus.h ++++ b/drivers/hv/hyperv_vmbus.h +@@ -406,7 +406,7 @@ static inline bool hv_is_perf_channel(struct vmbus_channel *channel) + return vmbus_devs[channel->device_id].perf_device; + } + +-static inline bool hv_is_alloced_cpu(unsigned int cpu) ++static inline bool hv_is_allocated_cpu(unsigned int cpu) + { + struct vmbus_channel *channel, *sc; + +@@ -428,23 +428,23 @@ static inline bool hv_is_alloced_cpu(unsigned int cpu) + return false; + } + +-static inline void hv_set_alloced_cpu(unsigned int cpu) ++static inline void hv_set_allocated_cpu(unsigned int cpu) + { + cpumask_set_cpu(cpu, &hv_context.hv_numa_map[cpu_to_node(cpu)]); + } + +-static inline void hv_clear_alloced_cpu(unsigned int cpu) ++static inline void hv_clear_allocated_cpu(unsigned int cpu) + { +- if (hv_is_alloced_cpu(cpu)) ++ if (hv_is_allocated_cpu(cpu)) + return; + cpumask_clear_cpu(cpu, &hv_context.hv_numa_map[cpu_to_node(cpu)]); + } + +-static inline void hv_update_alloced_cpus(unsigned int old_cpu, ++static inline void hv_update_allocated_cpus(unsigned int old_cpu, + unsigned int new_cpu) + { +- hv_set_alloced_cpu(new_cpu); +- hv_clear_alloced_cpu(old_cpu); ++ hv_set_allocated_cpu(new_cpu); ++ hv_clear_allocated_cpu(old_cpu); + } + + #ifdef CONFIG_HYPERV_TESTING +diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c +index e8bea7c791691..2fed2b169a910 100644 +--- a/drivers/hv/vmbus_drv.c ++++ b/drivers/hv/vmbus_drv.c +@@ -1790,7 +1790,7 @@ static ssize_t target_cpu_store(struct vmbus_channel *channel, + + /* See init_vp_index(). */ + if (hv_is_perf_channel(channel)) +- hv_update_alloced_cpus(origin_cpu, target_cpu); ++ hv_update_allocated_cpus(origin_cpu, target_cpu); + + /* Currently set only for storvsc channels. */ + if (channel->change_target_cpu_callback) { +-- +2.39.5 + diff --git a/queue-5.10/drivers-hv-vmbus-add-utility-function-for-querying-r.patch b/queue-5.10/drivers-hv-vmbus-add-utility-function-for-querying-r.patch new file mode 100644 index 0000000000..17f5e80cb6 --- /dev/null +++ b/queue-5.10/drivers-hv-vmbus-add-utility-function-for-querying-r.patch @@ -0,0 +1,93 @@ +From 936f5872813d2ab48e2211f8ff7ff6038fdc3522 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Sat, 30 Mar 2024 01:51:57 -0700 +Subject: Drivers: hv: vmbus: Add utility function for querying ring size + +From: Saurabh Sengar <ssengar@linux.microsoft.com> + +[ Upstream commit e8c4bd6c6e6b7e7b416c42806981c2a81370001e ] + +Add a function to query for the preferred ring buffer size of VMBus +device. This will allow the drivers (eg. UIO) to allocate the most +optimized ring buffer size for devices. + +Signed-off-by: Saurabh Sengar <ssengar@linux.microsoft.com> +Reviewed-by: Long Li <longli@microsoft.com> +Link: https://lore.kernel.org/r/1711788723-8593-2-git-send-email-ssengar@linux.microsoft.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Stable-dep-of: 0315fef2aff9 ("uio_hv_generic: Align ring size to system page") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/hv/channel_mgmt.c | 15 ++++++++++++--- + drivers/hv/hyperv_vmbus.h | 5 +++++ + include/linux/hyperv.h | 2 ++ + 3 files changed, 19 insertions(+), 3 deletions(-) + +diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c +index 4ee8b9b22bb9d..8300ffb1ea9ae 100644 +--- a/drivers/hv/channel_mgmt.c ++++ b/drivers/hv/channel_mgmt.c +@@ -106,7 +106,9 @@ const struct vmbus_device vmbus_devs[] = { + }, + + /* File copy */ +- { .dev_type = HV_FCOPY, ++ /* fcopy always uses 16KB ring buffer size and is working well for last many years */ ++ { .pref_ring_size = 0x4000, ++ .dev_type = HV_FCOPY, + HV_FCOPY_GUID, + .perf_device = false, + }, +@@ -123,11 +125,18 @@ const struct vmbus_device vmbus_devs[] = { + .perf_device = false, + }, + +- /* Unknown GUID */ +- { .dev_type = HV_UNKNOWN, ++ /* ++ * Unknown GUID ++ * 64 KB ring buffer + 4 KB header should be sufficient size for any Hyper-V device apart ++ * from HV_NIC and HV_SCSI. This case avoid the fallback for unknown devices to allocate ++ * much bigger (2 MB) of ring size. ++ */ ++ { .pref_ring_size = 0x11000, ++ .dev_type = HV_UNKNOWN, + .perf_device = false, + }, + }; ++EXPORT_SYMBOL_GPL(vmbus_devs); + + static const struct { + guid_t guid; +diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h +index 323c56152fa1b..1137c25d9a7ae 100644 +--- a/drivers/hv/hyperv_vmbus.h ++++ b/drivers/hv/hyperv_vmbus.h +@@ -406,6 +406,11 @@ static inline bool hv_is_perf_channel(struct vmbus_channel *channel) + return vmbus_devs[channel->device_id].perf_device; + } + ++static inline size_t hv_dev_ring_size(struct vmbus_channel *channel) ++{ ++ return vmbus_devs[channel->device_id].pref_ring_size; ++} ++ + static inline bool hv_is_allocated_cpu(unsigned int cpu) + { + struct vmbus_channel *channel, *sc; +diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h +index 5e019d26b5b72..987cc04f13182 100644 +--- a/include/linux/hyperv.h ++++ b/include/linux/hyperv.h +@@ -802,6 +802,8 @@ struct vmbus_requestor { + #define VMBUS_RQST_ID_NO_RESPONSE (U64_MAX - 2) + + struct vmbus_device { ++ /* preferred ring buffer size in KB, 0 means no preferred size for this device */ ++ size_t pref_ring_size; + u16 dev_type; + guid_t guid; + bool perf_device; +-- +2.39.5 + diff --git a/queue-5.10/drivers-hv-vmbus-fix-duplicate-cpu-assignments-withi.patch b/queue-5.10/drivers-hv-vmbus-fix-duplicate-cpu-assignments-withi.patch new file mode 100644 index 0000000000..d496234ed2 --- /dev/null +++ b/queue-5.10/drivers-hv-vmbus-fix-duplicate-cpu-assignments-withi.patch @@ -0,0 +1,209 @@ +From 22a364146eabb1d9f95b9ffe1dbd770a20ae9c42 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Fri, 16 Jul 2021 11:21:13 -0700 +Subject: Drivers: hv: vmbus: Fix duplicate CPU assignments within a device + +From: Haiyang Zhang <haiyangz@microsoft.com> + +[ Upstream commit 7c9ff3deeee61b253715dcf968a6307af148c9b2 ] + +The vmbus module uses a rotational algorithm to assign target CPUs to +a device's channels. Depending on the timing of different device's channel +offers, different channels of a device may be assigned to the same CPU. + +For example on a VM with 2 CPUs, if NIC A and B's channels are offered +in the following order, NIC A will have both channels on CPU0, and +NIC B will have both channels on CPU1 -- see below. This kind of +assignment causes RSS load that is spreading across different channels +to end up on the same CPU. + +Timing of channel offers: +NIC A channel 0 +NIC B channel 0 +NIC A channel 1 +NIC B channel 1 + +VMBUS ID 14: Class_ID = {f8615163-df3e-46c5-913f-f2d2f965ed0e} - Synthetic network adapter + Device_ID = {cab064cd-1f31-47d5-a8b4-9d57e320cccd} + Sysfs path: /sys/bus/vmbus/devices/cab064cd-1f31-47d5-a8b4-9d57e320cccd + Rel_ID=14, target_cpu=0 + Rel_ID=17, target_cpu=0 + +VMBUS ID 16: Class_ID = {f8615163-df3e-46c5-913f-f2d2f965ed0e} - Synthetic network adapter + Device_ID = {244225ca-743e-4020-a17d-d7baa13d6cea} + Sysfs path: /sys/bus/vmbus/devices/244225ca-743e-4020-a17d-d7baa13d6cea + Rel_ID=16, target_cpu=1 + Rel_ID=18, target_cpu=1 + +Update the vmbus CPU assignment algorithm to avoid duplicate CPU +assignments within a device. + +The new algorithm iterates num_online_cpus + 1 times. +The existing rotational algorithm to find "next NUMA & CPU" is still here. +But if the resulting CPU is already used by the same device, it will try +the next CPU. +In the last iteration, it assigns the channel to the next available CPU +like the existing algorithm. This is not normally expected, because +during device probe, we limit the number of channels of a device to +be <= number of online CPUs. + +Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com> +Reviewed-by: Michael Kelley <mikelley@microsoft.com> +Tested-by: Michael Kelley <mikelley@microsoft.com> +Link: https://lore.kernel.org/r/1626459673-17420-1-git-send-email-haiyangz@microsoft.com +Signed-off-by: Wei Liu <wei.liu@kernel.org> +Stable-dep-of: 0315fef2aff9 ("uio_hv_generic: Align ring size to system page") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/hv/channel_mgmt.c | 96 ++++++++++++++++++++++++++------------- + 1 file changed, 64 insertions(+), 32 deletions(-) + +diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c +index 0c6c54061088e..9da36d87ee2c7 100644 +--- a/drivers/hv/channel_mgmt.c ++++ b/drivers/hv/channel_mgmt.c +@@ -579,6 +579,17 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) + */ + mutex_lock(&vmbus_connection.channel_mutex); + ++ list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) { ++ if (guid_equal(&channel->offermsg.offer.if_type, ++ &newchannel->offermsg.offer.if_type) && ++ guid_equal(&channel->offermsg.offer.if_instance, ++ &newchannel->offermsg.offer.if_instance)) { ++ fnew = false; ++ newchannel->primary_channel = channel; ++ break; ++ } ++ } ++ + init_vp_index(newchannel); + + /* Remember the channels that should be cleaned up upon suspend. */ +@@ -591,16 +602,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) + */ + atomic_dec(&vmbus_connection.offer_in_progress); + +- list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) { +- if (guid_equal(&channel->offermsg.offer.if_type, +- &newchannel->offermsg.offer.if_type) && +- guid_equal(&channel->offermsg.offer.if_instance, +- &newchannel->offermsg.offer.if_instance)) { +- fnew = false; +- break; +- } +- } +- + if (fnew) { + list_add_tail(&newchannel->listentry, + &vmbus_connection.chn_list); +@@ -622,7 +623,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) + /* + * Process the sub-channel. + */ +- newchannel->primary_channel = channel; + list_add_tail(&newchannel->sc_list, &channel->sc_list); + } + +@@ -658,6 +658,30 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) + queue_work(wq, &newchannel->add_channel_work); + } + ++/* ++ * Check if CPUs used by other channels of the same device. ++ * It should only be called by init_vp_index(). ++ */ ++static bool hv_cpuself_used(u32 cpu, struct vmbus_channel *chn) ++{ ++ struct vmbus_channel *primary = chn->primary_channel; ++ struct vmbus_channel *sc; ++ ++ lockdep_assert_held(&vmbus_connection.channel_mutex); ++ ++ if (!primary) ++ return false; ++ ++ if (primary->target_cpu == cpu) ++ return true; ++ ++ list_for_each_entry(sc, &primary->sc_list, sc_list) ++ if (sc != chn && sc->target_cpu == cpu) ++ return true; ++ ++ return false; ++} ++ + /* + * We use this state to statically distribute the channel interrupt load. + */ +@@ -677,6 +701,7 @@ static int next_numa_node_id; + static void init_vp_index(struct vmbus_channel *channel) + { + bool perf_chn = hv_is_perf_channel(channel); ++ u32 i, ncpu = num_online_cpus(); + cpumask_var_t available_mask; + struct cpumask *alloced_mask; + u32 target_cpu; +@@ -699,31 +724,38 @@ static void init_vp_index(struct vmbus_channel *channel) + return; + } + +- while (true) { +- numa_node = next_numa_node_id++; +- if (numa_node == nr_node_ids) { +- next_numa_node_id = 0; +- continue; ++ for (i = 1; i <= ncpu + 1; i++) { ++ while (true) { ++ numa_node = next_numa_node_id++; ++ if (numa_node == nr_node_ids) { ++ next_numa_node_id = 0; ++ continue; ++ } ++ if (cpumask_empty(cpumask_of_node(numa_node))) ++ continue; ++ break; + } +- if (cpumask_empty(cpumask_of_node(numa_node))) +- continue; +- break; +- } +- alloced_mask = &hv_context.hv_numa_map[numa_node]; ++ alloced_mask = &hv_context.hv_numa_map[numa_node]; + +- if (cpumask_weight(alloced_mask) == +- cpumask_weight(cpumask_of_node(numa_node))) { +- /* +- * We have cycled through all the CPUs in the node; +- * reset the alloced map. +- */ +- cpumask_clear(alloced_mask); +- } ++ if (cpumask_weight(alloced_mask) == ++ cpumask_weight(cpumask_of_node(numa_node))) { ++ /* ++ * We have cycled through all the CPUs in the node; ++ * reset the alloced map. ++ */ ++ cpumask_clear(alloced_mask); ++ } + +- cpumask_xor(available_mask, alloced_mask, cpumask_of_node(numa_node)); ++ cpumask_xor(available_mask, alloced_mask, ++ cpumask_of_node(numa_node)); + +- target_cpu = cpumask_first(available_mask); +- cpumask_set_cpu(target_cpu, alloced_mask); ++ target_cpu = cpumask_first(available_mask); ++ cpumask_set_cpu(target_cpu, alloced_mask); ++ ++ if (channel->offermsg.offer.sub_channel_index >= ncpu || ++ i > ncpu || !hv_cpuself_used(target_cpu, channel)) ++ break; ++ } + + channel->target_cpu = target_cpu; + +-- +2.39.5 + diff --git a/queue-5.10/f2fs-don-t-over-report-free-space-or-inodes-in-statv.patch b/queue-5.10/f2fs-don-t-over-report-free-space-or-inodes-in-statv.patch new file mode 100644 index 0000000000..7b26ad7830 --- /dev/null +++ b/queue-5.10/f2fs-don-t-over-report-free-space-or-inodes-in-statv.patch @@ -0,0 +1,99 @@ +From ef9dcf7a1f254d779a946a3374f7a8780df3599e Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 13 May 2025 19:25:38 +0800 +Subject: f2fs: don't over-report free space or inodes in statvfs + +From: Chao Yu <chao@kernel.org> + +[ Upstream commit a9201960623287927bf5776de3f70fb2fbde7e02 ] + +This fixes an analogus bug that was fixed in modern filesystems: +a) xfs in commit 4b8d867ca6e2 ("xfs: don't over-report free space or +inodes in statvfs") +b) ext4 in commit f87d3af74193 ("ext4: don't over-report free space +or inodes in statvfs") +where statfs can report misleading / incorrect information where +project quota is enabled, and the free space is less than the +remaining quota. + +This commit will resolve a test failure in generic/762 which tests +for this bug. + +generic/762 - output mismatch (see /share/git/fstests/results//generic/762.out.bad) + --- tests/generic/762.out 2025-04-15 10:21:53.371067071 +0800 + +++ /share/git/fstests/results//generic/762.out.bad 2025-05-13 16:13:37.000000000 +0800 + @@ -6,8 +6,10 @@ + root blocks2 is in range + dir blocks2 is in range + root bavail2 is in range + -dir bavail2 is in range + +dir bavail2 has value of 1539066 + +dir bavail2 is NOT in range 304734.87 .. 310891.13 + root blocks3 is in range + ... + (Run 'diff -u /share/git/fstests/tests/generic/762.out /share/git/fstests/results//generic/762.out.bad' to see the entire diff) + +HINT: You _MAY_ be missing kernel fix: + XXXXXXXXXXXXXX xfs: don't over-report free space or inodes in statvfs + +Cc: stable@kernel.org +Fixes: ddc34e328d06 ("f2fs: introduce f2fs_statfs_project") +Signed-off-by: Chao Yu <chao@kernel.org> +Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + fs/f2fs/super.c | 30 ++++++++++++++++++------------ + 1 file changed, 18 insertions(+), 12 deletions(-) + +diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c +index b7997df291a66..d7fd28a477011 100644 +--- a/fs/f2fs/super.c ++++ b/fs/f2fs/super.c +@@ -1433,26 +1433,32 @@ static int f2fs_statfs_project(struct super_block *sb, + + limit = min_not_zero(dquot->dq_dqb.dqb_bsoftlimit, + dquot->dq_dqb.dqb_bhardlimit); +- if (limit) +- limit >>= sb->s_blocksize_bits; ++ limit >>= sb->s_blocksize_bits; ++ ++ if (limit) { ++ uint64_t remaining = 0; + +- if (limit && buf->f_blocks > limit) { + curblock = (dquot->dq_dqb.dqb_curspace + + dquot->dq_dqb.dqb_rsvspace) >> sb->s_blocksize_bits; +- buf->f_blocks = limit; +- buf->f_bfree = buf->f_bavail = +- (buf->f_blocks > curblock) ? +- (buf->f_blocks - curblock) : 0; ++ if (limit > curblock) ++ remaining = limit - curblock; ++ ++ buf->f_blocks = min(buf->f_blocks, limit); ++ buf->f_bfree = min(buf->f_bfree, remaining); ++ buf->f_bavail = min(buf->f_bavail, remaining); + } + + limit = min_not_zero(dquot->dq_dqb.dqb_isoftlimit, + dquot->dq_dqb.dqb_ihardlimit); + +- if (limit && buf->f_files > limit) { +- buf->f_files = limit; +- buf->f_ffree = +- (buf->f_files > dquot->dq_dqb.dqb_curinodes) ? +- (buf->f_files - dquot->dq_dqb.dqb_curinodes) : 0; ++ if (limit) { ++ uint64_t remaining = 0; ++ ++ if (limit > dquot->dq_dqb.dqb_curinodes) ++ remaining = limit - dquot->dq_dqb.dqb_curinodes; ++ ++ buf->f_files = min(buf->f_files, limit); ++ buf->f_ffree = min(buf->f_ffree, remaining); + } + + spin_unlock(&dquot->dq_dqb_lock); +-- +2.39.5 + diff --git a/queue-5.10/fs-jfs-consolidate-sanity-checking-in-dbmount.patch b/queue-5.10/fs-jfs-consolidate-sanity-checking-in-dbmount.patch new file mode 100644 index 0000000000..51918e177b --- /dev/null +++ b/queue-5.10/fs-jfs-consolidate-sanity-checking-in-dbmount.patch @@ -0,0 +1,81 @@ +From fbab278f5fbeec12092fce37ac1b2cfc6a640ecb Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Thu, 20 Feb 2025 10:31:19 -0600 +Subject: fs/jfs: consolidate sanity checking in dbMount + +From: Dave Kleikamp <dave.kleikamp@oracle.com> + +[ Upstream commit 0d250b1c52484d489e31df2cf9118b7c4bd49d31 ] + +Sanity checks have been added to dbMount as individual if clauses with +identical error handling. Move these all into one clause. + +Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com> +Stable-dep-of: 37bfb464ddca ("jfs: validate AG parameters in dbMount() to prevent crashes") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + fs/jfs/jfs_dmap.c | 37 +++++++++---------------------------- + 1 file changed, 9 insertions(+), 28 deletions(-) + +diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c +index 9dccebbee55ad..ba60e24b30a45 100644 +--- a/fs/jfs/jfs_dmap.c ++++ b/fs/jfs/jfs_dmap.c +@@ -178,45 +178,26 @@ int dbMount(struct inode *ipbmap) + dbmp_le = (struct dbmap_disk *) mp->data; + bmp->db_mapsize = le64_to_cpu(dbmp_le->dn_mapsize); + bmp->db_nfree = le64_to_cpu(dbmp_le->dn_nfree); +- + bmp->db_l2nbperpage = le32_to_cpu(dbmp_le->dn_l2nbperpage); +- if (bmp->db_l2nbperpage > L2PSIZE - L2MINBLOCKSIZE || +- bmp->db_l2nbperpage < 0) { +- err = -EINVAL; +- goto err_release_metapage; +- } +- + bmp->db_numag = le32_to_cpu(dbmp_le->dn_numag); +- if (!bmp->db_numag || bmp->db_numag > MAXAG) { +- err = -EINVAL; +- goto err_release_metapage; +- } +- + bmp->db_maxlevel = le32_to_cpu(dbmp_le->dn_maxlevel); + bmp->db_maxag = le32_to_cpu(dbmp_le->dn_maxag); + bmp->db_agpref = le32_to_cpu(dbmp_le->dn_agpref); +- if (bmp->db_maxag >= MAXAG || bmp->db_maxag < 0 || +- bmp->db_agpref >= MAXAG || bmp->db_agpref < 0) { +- err = -EINVAL; +- goto err_release_metapage; +- } +- + bmp->db_aglevel = le32_to_cpu(dbmp_le->dn_aglevel); + bmp->db_agheight = le32_to_cpu(dbmp_le->dn_agheight); + bmp->db_agwidth = le32_to_cpu(dbmp_le->dn_agwidth); +- if (!bmp->db_agwidth) { +- err = -EINVAL; +- goto err_release_metapage; +- } + bmp->db_agstart = le32_to_cpu(dbmp_le->dn_agstart); + bmp->db_agl2size = le32_to_cpu(dbmp_le->dn_agl2size); +- if (bmp->db_agl2size > L2MAXL2SIZE - L2MAXAG || +- bmp->db_agl2size < 0) { +- err = -EINVAL; +- goto err_release_metapage; +- } + +- if (((bmp->db_mapsize - 1) >> bmp->db_agl2size) > MAXAG) { ++ if ((bmp->db_l2nbperpage > L2PSIZE - L2MINBLOCKSIZE) || ++ (bmp->db_l2nbperpage < 0) || ++ !bmp->db_numag || (bmp->db_numag > MAXAG) || ++ (bmp->db_maxag >= MAXAG) || (bmp->db_maxag < 0) || ++ (bmp->db_agpref >= MAXAG) || (bmp->db_agpref < 0) || ++ !bmp->db_agwidth || ++ (bmp->db_agl2size > L2MAXL2SIZE - L2MAXAG) || ++ (bmp->db_agl2size < 0) || ++ ((bmp->db_mapsize - 1) >> bmp->db_agl2size) > MAXAG) { + err = -EINVAL; + goto err_release_metapage; + } +-- +2.39.5 + diff --git a/queue-5.10/hwmon-pmbus-max34440-fix-support-for-max34451.patch b/queue-5.10/hwmon-pmbus-max34440-fix-support-for-max34451.patch new file mode 100644 index 0000000000..d7da42a5e4 --- /dev/null +++ b/queue-5.10/hwmon-pmbus-max34440-fix-support-for-max34451.patch @@ -0,0 +1,144 @@ +From 8fa7ccd081bf968b0665ee487c9c18737be4dec0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Mon, 7 Apr 2025 11:47:24 +0800 +Subject: hwmon: (pmbus/max34440) Fix support for max34451 + +From: Alexis Czezar Torreno <alexisczezar.torreno@analog.com> + +[ Upstream commit 19932f844f3f51646f762f3eac4744ec3a405064 ] + +The max344** family has an issue with some PMBUS address being switched. +This includes max34451 however version MAX34451-NA6 and later has this +issue fixed and this commit supports that update. + +Signed-off-by: Alexis Czezar Torreno <alexisczezar.torreno@analog.com> +Link: https://lore.kernel.org/r/20250407-dev_adpm12160-v3-1-9cd3095445c8@analog.com +Signed-off-by: Guenter Roeck <linux@roeck-us.net> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/hwmon/pmbus/max34440.c | 48 +++++++++++++++++++++++++++++++--- + 1 file changed, 44 insertions(+), 4 deletions(-) + +diff --git a/drivers/hwmon/pmbus/max34440.c b/drivers/hwmon/pmbus/max34440.c +index f4cb196aaaf31..f8108f6bd58cf 100644 +--- a/drivers/hwmon/pmbus/max34440.c ++++ b/drivers/hwmon/pmbus/max34440.c +@@ -34,16 +34,21 @@ enum chips { max34440, max34441, max34446, max34451, max34460, max34461 }; + /* + * The whole max344* family have IOUT_OC_WARN_LIMIT and IOUT_OC_FAULT_LIMIT + * swapped from the standard pmbus spec addresses. ++ * For max34451, version MAX34451ETNA6+ and later has this issue fixed. + */ + #define MAX34440_IOUT_OC_WARN_LIMIT 0x46 + #define MAX34440_IOUT_OC_FAULT_LIMIT 0x4A + ++#define MAX34451ETNA6_MFR_REV 0x0012 ++ + #define MAX34451_MFR_CHANNEL_CONFIG 0xe4 + #define MAX34451_MFR_CHANNEL_CONFIG_SEL_MASK 0x3f + + struct max34440_data { + int id; + struct pmbus_driver_info info; ++ u8 iout_oc_warn_limit; ++ u8 iout_oc_fault_limit; + }; + + #define to_max34440_data(x) container_of(x, struct max34440_data, info) +@@ -60,11 +65,11 @@ static int max34440_read_word_data(struct i2c_client *client, int page, + switch (reg) { + case PMBUS_IOUT_OC_FAULT_LIMIT: + ret = pmbus_read_word_data(client, page, phase, +- MAX34440_IOUT_OC_FAULT_LIMIT); ++ data->iout_oc_fault_limit); + break; + case PMBUS_IOUT_OC_WARN_LIMIT: + ret = pmbus_read_word_data(client, page, phase, +- MAX34440_IOUT_OC_WARN_LIMIT); ++ data->iout_oc_warn_limit); + break; + case PMBUS_VIRT_READ_VOUT_MIN: + ret = pmbus_read_word_data(client, page, phase, +@@ -133,11 +138,11 @@ static int max34440_write_word_data(struct i2c_client *client, int page, + + switch (reg) { + case PMBUS_IOUT_OC_FAULT_LIMIT: +- ret = pmbus_write_word_data(client, page, MAX34440_IOUT_OC_FAULT_LIMIT, ++ ret = pmbus_write_word_data(client, page, data->iout_oc_fault_limit, + word); + break; + case PMBUS_IOUT_OC_WARN_LIMIT: +- ret = pmbus_write_word_data(client, page, MAX34440_IOUT_OC_WARN_LIMIT, ++ ret = pmbus_write_word_data(client, page, data->iout_oc_warn_limit, + word); + break; + case PMBUS_VIRT_RESET_POUT_HISTORY: +@@ -235,6 +240,25 @@ static int max34451_set_supported_funcs(struct i2c_client *client, + */ + + int page, rv; ++ bool max34451_na6 = false; ++ ++ rv = i2c_smbus_read_word_data(client, PMBUS_MFR_REVISION); ++ if (rv < 0) ++ return rv; ++ ++ if (rv >= MAX34451ETNA6_MFR_REV) { ++ max34451_na6 = true; ++ data->info.format[PSC_VOLTAGE_IN] = direct; ++ data->info.format[PSC_CURRENT_IN] = direct; ++ data->info.m[PSC_VOLTAGE_IN] = 1; ++ data->info.b[PSC_VOLTAGE_IN] = 0; ++ data->info.R[PSC_VOLTAGE_IN] = 3; ++ data->info.m[PSC_CURRENT_IN] = 1; ++ data->info.b[PSC_CURRENT_IN] = 0; ++ data->info.R[PSC_CURRENT_IN] = 2; ++ data->iout_oc_fault_limit = PMBUS_IOUT_OC_FAULT_LIMIT; ++ data->iout_oc_warn_limit = PMBUS_IOUT_OC_WARN_LIMIT; ++ } + + for (page = 0; page < 16; page++) { + rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page); +@@ -251,16 +275,30 @@ static int max34451_set_supported_funcs(struct i2c_client *client, + case 0x20: + data->info.func[page] = PMBUS_HAVE_VOUT | + PMBUS_HAVE_STATUS_VOUT; ++ ++ if (max34451_na6) ++ data->info.func[page] |= PMBUS_HAVE_VIN | ++ PMBUS_HAVE_STATUS_INPUT; + break; + case 0x21: + data->info.func[page] = PMBUS_HAVE_VOUT; ++ ++ if (max34451_na6) ++ data->info.func[page] |= PMBUS_HAVE_VIN; + break; + case 0x22: + data->info.func[page] = PMBUS_HAVE_IOUT | + PMBUS_HAVE_STATUS_IOUT; ++ ++ if (max34451_na6) ++ data->info.func[page] |= PMBUS_HAVE_IIN | ++ PMBUS_HAVE_STATUS_INPUT; + break; + case 0x23: + data->info.func[page] = PMBUS_HAVE_IOUT; ++ ++ if (max34451_na6) ++ data->info.func[page] |= PMBUS_HAVE_IIN; + break; + default: + break; +@@ -494,6 +532,8 @@ static int max34440_probe(struct i2c_client *client) + return -ENOMEM; + data->id = i2c_match_id(max34440_id, client)->driver_data; + data->info = max34440_info[data->id]; ++ data->iout_oc_fault_limit = MAX34440_IOUT_OC_FAULT_LIMIT; ++ data->iout_oc_warn_limit = MAX34440_IOUT_OC_WARN_LIMIT; + + if (data->id == max34451) { + rv = max34451_set_supported_funcs(client, data); +-- +2.39.5 + diff --git a/queue-5.10/iio-pressure-zpa2326-use-aligned_s64-for-the-timesta.patch b/queue-5.10/iio-pressure-zpa2326-use-aligned_s64-for-the-timesta.patch new file mode 100644 index 0000000000..113d3a32f9 --- /dev/null +++ b/queue-5.10/iio-pressure-zpa2326-use-aligned_s64-for-the-timesta.patch @@ -0,0 +1,36 @@ +From c3e006d66e4cce33c266a2c356d98d2405de1240 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Sun, 13 Apr 2025 11:34:41 +0100 +Subject: iio: pressure: zpa2326: Use aligned_s64 for the timestamp + +From: Jonathan Cameron <Jonathan.Cameron@huawei.com> + +[ Upstream commit 886a446b76afddfad307488e95e87f23a08ffd51 ] + +On x86_32 s64 fields are only 32-bit aligned. Hence force the alignment of +the field and padding in the structure by using aligned_s64 instead. + +Reviewed-by: David Lechner <dlechner@baylibre.com> +Link: https://patch.msgid.link/20250413103443.2420727-19-jic23@kernel.org +Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/iio/pressure/zpa2326.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/iio/pressure/zpa2326.c b/drivers/iio/pressure/zpa2326.c +index b8bc2c67462d7..00791bc65b700 100644 +--- a/drivers/iio/pressure/zpa2326.c ++++ b/drivers/iio/pressure/zpa2326.c +@@ -582,7 +582,7 @@ static int zpa2326_fill_sample_buffer(struct iio_dev *indio_dev, + struct { + u32 pressure; + u16 temperature; +- u64 timestamp; ++ aligned_s64 timestamp; + } sample; + int err; + +-- +2.39.5 + diff --git a/queue-5.10/jfs-validate-ag-parameters-in-dbmount-to-prevent-cra.patch b/queue-5.10/jfs-validate-ag-parameters-in-dbmount-to-prevent-cra.patch new file mode 100644 index 0000000000..90129920b7 --- /dev/null +++ b/queue-5.10/jfs-validate-ag-parameters-in-dbmount-to-prevent-cra.patch @@ -0,0 +1,78 @@ +From b9953f06172ebc836fb952e5bbe4b37cedc5a4b3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Mon, 10 Mar 2025 11:56:02 +0300 +Subject: jfs: validate AG parameters in dbMount() to prevent crashes + +From: Vasiliy Kovalev <kovalev@altlinux.org> + +[ Upstream commit 37bfb464ddca87f203071b5bd562cd91ddc0b40a ] + +Validate db_agheight, db_agwidth, and db_agstart in dbMount to catch +corrupted metadata early and avoid undefined behavior in dbAllocAG. +Limits are derived from L2LPERCTL, LPERCTL/MAXAG, and CTLTREESIZE: + +- agheight: 0 to L2LPERCTL/2 (0 to 5) ensures shift + (L2LPERCTL - 2*agheight) >= 0. +- agwidth: 1 to min(LPERCTL/MAXAG, 2^(L2LPERCTL - 2*agheight)) + ensures agperlev >= 1. + - Ranges: 1-8 (agheight 0-3), 1-4 (agheight 4), 1 (agheight 5). + - LPERCTL/MAXAG = 1024/128 = 8 limits leaves per AG; + 2^(10 - 2*agheight) prevents division to 0. +- agstart: 0 to CTLTREESIZE-1 - agwidth*(MAXAG-1) keeps ti within + stree (size 1365). + - Ranges: 0-1237 (agwidth 1), 0-348 (agwidth 8). + +UBSAN: shift-out-of-bounds in fs/jfs/jfs_dmap.c:1400:9 +shift exponent -335544310 is negative +CPU: 0 UID: 0 PID: 5822 Comm: syz-executor130 Not tainted 6.14.0-rc5-syzkaller #0 +Hardware name: Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2025 +Call Trace: + <TASK> + __dump_stack lib/dump_stack.c:94 [inline] + dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120 + ubsan_epilogue lib/ubsan.c:231 [inline] + __ubsan_handle_shift_out_of_bounds+0x3c8/0x420 lib/ubsan.c:468 + dbAllocAG+0x1087/0x10b0 fs/jfs/jfs_dmap.c:1400 + dbDiscardAG+0x352/0xa20 fs/jfs/jfs_dmap.c:1613 + jfs_ioc_trim+0x45a/0x6b0 fs/jfs/jfs_discard.c:105 + jfs_ioctl+0x2cd/0x3e0 fs/jfs/ioctl.c:131 + vfs_ioctl fs/ioctl.c:51 [inline] + __do_sys_ioctl fs/ioctl.c:906 [inline] + __se_sys_ioctl+0xf5/0x170 fs/ioctl.c:892 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +Found by Linux Verification Center (linuxtesting.org) with Syzkaller. + +Cc: stable@vger.kernel.org +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reported-by: syzbot+fe8264911355151c487f@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=fe8264911355151c487f +Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org> +Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + fs/jfs/jfs_dmap.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c +index ba60e24b30a45..37888187b9773 100644 +--- a/fs/jfs/jfs_dmap.c ++++ b/fs/jfs/jfs_dmap.c +@@ -194,7 +194,11 @@ int dbMount(struct inode *ipbmap) + !bmp->db_numag || (bmp->db_numag > MAXAG) || + (bmp->db_maxag >= MAXAG) || (bmp->db_maxag < 0) || + (bmp->db_agpref >= MAXAG) || (bmp->db_agpref < 0) || +- !bmp->db_agwidth || ++ (bmp->db_agheight < 0) || (bmp->db_agheight > (L2LPERCTL >> 1)) || ++ (bmp->db_agwidth < 1) || (bmp->db_agwidth > (LPERCTL / MAXAG)) || ++ (bmp->db_agwidth > (1 << (L2LPERCTL - (bmp->db_agheight << 1)))) || ++ (bmp->db_agstart < 0) || ++ (bmp->db_agstart > (CTLTREESIZE - 1 - bmp->db_agwidth * (MAXAG - 1))) || + (bmp->db_agl2size > L2MAXL2SIZE - L2MAXAG) || + (bmp->db_agl2size < 0) || + ((bmp->db_mapsize - 1) >> bmp->db_agl2size) > MAXAG) { +-- +2.39.5 + diff --git a/queue-5.10/leds-multicolor-fix-intensity-setting-while-sw-blink.patch b/queue-5.10/leds-multicolor-fix-intensity-setting-while-sw-blink.patch new file mode 100644 index 0000000000..4cf630a8bf --- /dev/null +++ b/queue-5.10/leds-multicolor-fix-intensity-setting-while-sw-blink.patch @@ -0,0 +1,48 @@ +From f748c4f981bf35406bf949b43324c8dd3b656028 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Fri, 4 Apr 2025 20:40:36 +0200 +Subject: leds: multicolor: Fix intensity setting while SW blinking + +From: Sven Schwermer <sven.schwermer@disruptive-technologies.com> + +[ Upstream commit e35ca991a777ef513040cbb36bc8245a031a2633 ] + +When writing to the multi_intensity file, don't unconditionally call +led_set_brightness. By only doing this if blinking is inactive we +prevent blinking from stopping if the blinking is in its off phase while +the file is written. + +Instead, if blinking is active, the changed intensity values are applied +upon the next blink. This is consistent with changing the brightness on +monochrome LEDs with active blinking. + +Suggested-by: Jacek Anaszewski <jacek.anaszewski@gmail.com> +Acked-by: Jacek Anaszewski <jacek.anaszewski@gmail.com> +Acked-by: Pavel Machek <pavel@ucw.cz> +Reviewed-by: Tobias Deiminger <tobias.deiminger@linutronix.de> +Tested-by: Sven Schuchmann <schuchmann@schleissheimer.de> +Signed-off-by: Sven Schwermer <sven.schwermer@disruptive-technologies.com> +Link: https://lore.kernel.org/r/20250404184043.227116-1-sven@svenschwermer.de +Signed-off-by: Lee Jones <lee@kernel.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/leds/led-class-multicolor.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/leds/led-class-multicolor.c b/drivers/leds/led-class-multicolor.c +index e317408583df9..5b1479b5d32ca 100644 +--- a/drivers/leds/led-class-multicolor.c ++++ b/drivers/leds/led-class-multicolor.c +@@ -59,7 +59,8 @@ static ssize_t multi_intensity_store(struct device *dev, + for (i = 0; i < mcled_cdev->num_colors; i++) + mcled_cdev->subled_info[i].intensity = intensity_value[i]; + +- led_set_brightness(led_cdev, led_cdev->brightness); ++ if (!test_bit(LED_BLINK_SW, &led_cdev->work_flags)) ++ led_set_brightness(led_cdev, led_cdev->brightness); + ret = size; + err_out: + mutex_unlock(&led_cdev->led_access); +-- +2.39.5 + diff --git a/queue-5.10/mailbox-not-protect-module_put-with-spin_lock_irqsav.patch b/queue-5.10/mailbox-not-protect-module_put-with-spin_lock_irqsav.patch new file mode 100644 index 0000000000..02ea1729b1 --- /dev/null +++ b/queue-5.10/mailbox-not-protect-module_put-with-spin_lock_irqsav.patch @@ -0,0 +1,38 @@ +From 518f87bab0582a382eaa7161d3db4e23e930cd20 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Fri, 11 Apr 2025 21:14:10 +0800 +Subject: mailbox: Not protect module_put with spin_lock_irqsave + +From: Peng Fan <peng.fan@nxp.com> + +[ Upstream commit dddbd233e67e792bb0a3f9694a4707e6be29b2c6 ] + +&chan->lock is not supposed to protect 'chan->mbox'. +And in __mbox_bind_client, try_module_get is also not protected +by &chan->lock. So move module_put out of the lock protected +region. + +Signed-off-by: Peng Fan <peng.fan@nxp.com> +Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/mailbox/mailbox.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c +index 6f54501dc7762..cb31ad917b352 100644 +--- a/drivers/mailbox/mailbox.c ++++ b/drivers/mailbox/mailbox.c +@@ -459,8 +459,8 @@ void mbox_free_channel(struct mbox_chan *chan) + if (chan->txdone_method == TXDONE_BY_ACK) + chan->txdone_method = TXDONE_BY_POLL; + +- module_put(chan->mbox->dev->driver->owner); + spin_unlock_irqrestore(&chan->lock, flags); ++ module_put(chan->mbox->dev->driver->owner); + } + EXPORT_SYMBOL_GPL(mbox_free_channel); + +-- +2.39.5 + diff --git a/queue-5.10/md-md-bitmap-fix-dm-raid-max_write_behind-setting.patch b/queue-5.10/md-md-bitmap-fix-dm-raid-max_write_behind-setting.patch new file mode 100644 index 0000000000..50415b15cd --- /dev/null +++ b/queue-5.10/md-md-bitmap-fix-dm-raid-max_write_behind-setting.patch @@ -0,0 +1,36 @@ +From eaf1d77ae61b541ec98a810fe622bcd348d25410 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Sat, 24 May 2025 14:13:10 +0800 +Subject: md/md-bitmap: fix dm-raid max_write_behind setting + +From: Yu Kuai <yukuai3@huawei.com> + +[ Upstream commit 2afe17794cfed5f80295b1b9facd66e6f65e5002 ] + +It's supposed to be COUNTER_MAX / 2, not COUNTER_MAX. + +Link: https://lore.kernel.org/linux-raid/20250524061320.370630-14-yukuai1@huaweicloud.com +Signed-off-by: Yu Kuai <yukuai3@huawei.com> +Reviewed-by: Christoph Hellwig <hch@lst.de> +Reviewed-by: Hannes Reinecke <hare@suse.de> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/md/md-bitmap.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c +index 91bc764a854c6..f2ba541ed89d4 100644 +--- a/drivers/md/md-bitmap.c ++++ b/drivers/md/md-bitmap.c +@@ -546,7 +546,7 @@ static int md_bitmap_new_disk_sb(struct bitmap *bitmap) + * is a good choice? We choose COUNTER_MAX / 2 arbitrarily. + */ + write_behind = bitmap->mddev->bitmap_info.max_write_behind; +- if (write_behind > COUNTER_MAX) ++ if (write_behind > COUNTER_MAX / 2) + write_behind = COUNTER_MAX / 2; + sb->write_behind = cpu_to_le32(write_behind); + bitmap->mddev->bitmap_info.max_write_behind = write_behind; +-- +2.39.5 + diff --git a/queue-5.10/media-omap3isp-use-sgtable-based-scatterlist-wrapper.patch b/queue-5.10/media-omap3isp-use-sgtable-based-scatterlist-wrapper.patch new file mode 100644 index 0000000000..43757fe2f8 --- /dev/null +++ b/queue-5.10/media-omap3isp-use-sgtable-based-scatterlist-wrapper.patch @@ -0,0 +1,79 @@ +From bcbf6c7bfbb1b8c33d4728df7a296b9808f9d9bb Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Wed, 7 May 2025 18:09:13 +0200 +Subject: media: omap3isp: use sgtable-based scatterlist wrappers + +From: Marek Szyprowski <m.szyprowski@samsung.com> + +[ Upstream commit 3de572fe2189a4a0bd80295e1f478401e739498e ] + +Use common wrappers operating directly on the struct sg_table objects to +fix incorrect use of scatterlists sync calls. dma_sync_sg_for_*() +functions have to be called with the number of elements originally passed +to dma_map_sg_*() function, not the one returned in sgtable's nents. + +Fixes: d33186d0be18 ("[media] omap3isp: ccdc: Use the DMA API for LSC") +Fixes: 0e24e90f2ca7 ("[media] omap3isp: stat: Use the DMA API") +CC: stable@vger.kernel.org +Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> +Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/media/platform/omap3isp/ispccdc.c | 8 ++++---- + drivers/media/platform/omap3isp/ispstat.c | 6 ++---- + 2 files changed, 6 insertions(+), 8 deletions(-) + +diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c +index 0fbb2aa6dd2c0..6f46e23989532 100644 +--- a/drivers/media/platform/omap3isp/ispccdc.c ++++ b/drivers/media/platform/omap3isp/ispccdc.c +@@ -446,8 +446,8 @@ static int ccdc_lsc_config(struct isp_ccdc_device *ccdc, + if (ret < 0) + goto done; + +- dma_sync_sg_for_cpu(isp->dev, req->table.sgt.sgl, +- req->table.sgt.nents, DMA_TO_DEVICE); ++ dma_sync_sgtable_for_cpu(isp->dev, &req->table.sgt, ++ DMA_TO_DEVICE); + + if (copy_from_user(req->table.addr, config->lsc, + req->config.size)) { +@@ -455,8 +455,8 @@ static int ccdc_lsc_config(struct isp_ccdc_device *ccdc, + goto done; + } + +- dma_sync_sg_for_device(isp->dev, req->table.sgt.sgl, +- req->table.sgt.nents, DMA_TO_DEVICE); ++ dma_sync_sgtable_for_device(isp->dev, &req->table.sgt, ++ DMA_TO_DEVICE); + } + + spin_lock_irqsave(&ccdc->lsc.req_lock, flags); +diff --git a/drivers/media/platform/omap3isp/ispstat.c b/drivers/media/platform/omap3isp/ispstat.c +index 5b9b57f4d9bf8..e8a1837b1b74f 100644 +--- a/drivers/media/platform/omap3isp/ispstat.c ++++ b/drivers/media/platform/omap3isp/ispstat.c +@@ -161,8 +161,7 @@ static void isp_stat_buf_sync_for_device(struct ispstat *stat, + if (ISP_STAT_USES_DMAENGINE(stat)) + return; + +- dma_sync_sg_for_device(stat->isp->dev, buf->sgt.sgl, +- buf->sgt.nents, DMA_FROM_DEVICE); ++ dma_sync_sgtable_for_device(stat->isp->dev, &buf->sgt, DMA_FROM_DEVICE); + } + + static void isp_stat_buf_sync_for_cpu(struct ispstat *stat, +@@ -171,8 +170,7 @@ static void isp_stat_buf_sync_for_cpu(struct ispstat *stat, + if (ISP_STAT_USES_DMAENGINE(stat)) + return; + +- dma_sync_sg_for_cpu(stat->isp->dev, buf->sgt.sgl, +- buf->sgt.nents, DMA_FROM_DEVICE); ++ dma_sync_sgtable_for_cpu(stat->isp->dev, &buf->sgt, DMA_FROM_DEVICE); + } + + static void isp_stat_buf_clear(struct ispstat *stat) +-- +2.39.5 + diff --git a/queue-5.10/mfd-max14577-fix-wakeup-source-leaks-on-device-unbin.patch b/queue-5.10/mfd-max14577-fix-wakeup-source-leaks-on-device-unbin.patch new file mode 100644 index 0000000000..1f84a13879 --- /dev/null +++ b/queue-5.10/mfd-max14577-fix-wakeup-source-leaks-on-device-unbin.patch @@ -0,0 +1,35 @@ +From a88b362300db20abc8f6583be4d08d39dc3aebe7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Sun, 6 Apr 2025 21:50:11 +0200 +Subject: mfd: max14577: Fix wakeup source leaks on device unbind + +From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> + +[ Upstream commit d905d06e64b0eb3da43af6186c132f5282197998 ] + +Device can be unbound, so driver must also release memory for the wakeup +source. + +Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> +Link: https://lore.kernel.org/r/20250406-mfd-device-wakekup-leak-v1-3-318e14bdba0a@linaro.org +Signed-off-by: Lee Jones <lee@kernel.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/mfd/max14577.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/mfd/max14577.c b/drivers/mfd/max14577.c +index be185e9d5f16b..c9e56145b08bd 100644 +--- a/drivers/mfd/max14577.c ++++ b/drivers/mfd/max14577.c +@@ -467,6 +467,7 @@ static int max14577_i2c_remove(struct i2c_client *i2c) + { + struct max14577 *max14577 = i2c_get_clientdata(i2c); + ++ device_init_wakeup(max14577->dev, false); + mfd_remove_devices(max14577->dev); + regmap_del_irq_chip(max14577->irq, max14577->irq_data); + if (max14577->dev_type == MAXIM_DEVICE_TYPE_MAX77836) +-- +2.39.5 + diff --git a/queue-5.10/net_sched-sch_sfq-reject-invalid-perturb-period.patch b/queue-5.10/net_sched-sch_sfq-reject-invalid-perturb-period.patch new file mode 100644 index 0000000000..aa2c854627 --- /dev/null +++ b/queue-5.10/net_sched-sch_sfq-reject-invalid-perturb-period.patch @@ -0,0 +1,77 @@ +From 44037553ae6dab02cd455118c03a4a05b6eec751 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Wed, 11 Jun 2025 08:35:01 +0000 +Subject: net_sched: sch_sfq: reject invalid perturb period + +From: Eric Dumazet <edumazet@google.com> + +[ Upstream commit 7ca52541c05c832d32b112274f81a985101f9ba8 ] + +Gerrard Tai reported that SFQ perturb_period has no range check yet, +and this can be used to trigger a race condition fixed in a separate patch. + +We want to make sure ctl->perturb_period * HZ will not overflow +and is positive. + +Tested: + +tc qd add dev lo root sfq perturb -10 # negative value : error +Error: sch_sfq: invalid perturb period. + +tc qd add dev lo root sfq perturb 1000000000 # too big : error +Error: sch_sfq: invalid perturb period. + +tc qd add dev lo root sfq perturb 2000000 # acceptable value +tc -s -d qd sh dev lo +qdisc sfq 8005: root refcnt 2 limit 127p quantum 64Kb depth 127 flows 128 divisor 1024 perturb 2000000sec + Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) + backlog 0b 0p requeues 0 + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reported-by: Gerrard Tai <gerrard.tai@starlabs.sg> +Signed-off-by: Eric Dumazet <edumazet@google.com> +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/20250611083501.1810459-1-edumazet@google.com +Signed-off-by: Jakub Kicinski <kuba@kernel.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + net/sched/sch_sfq.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c +index e87560e244861..4a10f794be588 100644 +--- a/net/sched/sch_sfq.c ++++ b/net/sched/sch_sfq.c +@@ -653,6 +653,14 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt, + NL_SET_ERR_MSG_MOD(extack, "invalid quantum"); + return -EINVAL; + } ++ ++ if (ctl->perturb_period < 0 || ++ ctl->perturb_period > INT_MAX / HZ) { ++ NL_SET_ERR_MSG_MOD(extack, "invalid perturb period"); ++ return -EINVAL; ++ } ++ perturb_period = ctl->perturb_period * HZ; ++ + if (ctl_v1 && !red_check_params(ctl_v1->qth_min, ctl_v1->qth_max, + ctl_v1->Wlog, ctl_v1->Scell_log, NULL)) + return -EINVAL; +@@ -669,14 +677,12 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt, + headdrop = q->headdrop; + maxdepth = q->maxdepth; + maxflows = q->maxflows; +- perturb_period = q->perturb_period; + quantum = q->quantum; + flags = q->flags; + + /* update and validate configuration */ + if (ctl->quantum) + quantum = ctl->quantum; +- perturb_period = ctl->perturb_period * HZ; + if (ctl->flows) + maxflows = min_t(u32, ctl->flows, SFQ_MAX_FLOWS); + if (ctl->divisor) { +-- +2.39.5 + diff --git a/queue-5.10/nfsv4.2-fix-listxattr-to-return-selinux-security-lab.patch b/queue-5.10/nfsv4.2-fix-listxattr-to-return-selinux-security-lab.patch new file mode 100644 index 0000000000..6575b8f8e4 --- /dev/null +++ b/queue-5.10/nfsv4.2-fix-listxattr-to-return-selinux-security-lab.patch @@ -0,0 +1,56 @@ +From 8f9d2332bc0e6e5b79a4d7c9b7335d0967cdb2b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Fri, 25 Apr 2025 14:09:21 -0400 +Subject: NFSv4.2: fix listxattr to return selinux security label + +From: Olga Kornievskaia <okorniev@redhat.com> + +[ Upstream commit 243fea134633ba3d64aceb4c16129c59541ea2c6 ] + +Currently, when NFS is queried for all the labels present on the +file via a command example "getfattr -d -m . /mnt/testfile", it +does not return the security label. Yet when asked specifically for +the label (getfattr -n security.selinux) it will be returned. +Include the security label when all attributes are queried. + +Signed-off-by: Olga Kornievskaia <okorniev@redhat.com> +Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + fs/nfs/nfs4proc.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index 1005ecf7c250b..77cc1c4219e15 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -10378,7 +10378,7 @@ const struct nfs4_minor_version_ops *nfs_v4_minor_ops[] = { + + static ssize_t nfs4_listxattr(struct dentry *dentry, char *list, size_t size) + { +- ssize_t error, error2, error3; ++ ssize_t error, error2, error3, error4; + size_t left = size; + + error = generic_listxattr(dentry, list, left); +@@ -10401,8 +10401,16 @@ static ssize_t nfs4_listxattr(struct dentry *dentry, char *list, size_t size) + error3 = nfs4_listxattr_nfs4_user(d_inode(dentry), list, left); + if (error3 < 0) + return error3; ++ if (list) { ++ list += error3; ++ left -= error3; ++ } ++ ++ error4 = security_inode_listsecurity(d_inode(dentry), list, left); ++ if (error4 < 0) ++ return error4; + +- error += error2 + error3; ++ error += error2 + error3 + error4; + if (size && error > size) + return -ERANGE; + return error; +-- +2.39.5 + diff --git a/queue-5.10/ovl-check-for-null-d_inode-in-ovl_dentry_upper.patch b/queue-5.10/ovl-check-for-null-d_inode-in-ovl_dentry_upper.patch new file mode 100644 index 0000000000..54f6ac8ba2 --- /dev/null +++ b/queue-5.10/ovl-check-for-null-d_inode-in-ovl_dentry_upper.patch @@ -0,0 +1,68 @@ +From c0965dd27d4ca534d58fdc64466fc78ebe0afaf8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Mon, 21 Apr 2025 16:15:19 -0700 +Subject: ovl: Check for NULL d_inode() in ovl_dentry_upper() + +From: Kees Cook <kees@kernel.org> + +[ Upstream commit 8a39f1c870e9d6fbac5638f3a42a6a6363829c49 ] + +In ovl_path_type() and ovl_is_metacopy_dentry() GCC notices that it is +possible for OVL_E() to return NULL (which implies that d_inode(dentry) +may be NULL). This would result in out of bounds reads via container_of(), +seen with GCC 15's -Warray-bounds -fdiagnostics-details. For example: + +In file included from arch/x86/include/generated/asm/rwonce.h:1, + from include/linux/compiler.h:339, + from include/linux/export.h:5, + from include/linux/linkage.h:7, + from include/linux/fs.h:5, + from fs/overlayfs/util.c:7: +In function 'ovl_upperdentry_dereference', + inlined from 'ovl_dentry_upper' at ../fs/overlayfs/util.c:305:9, + inlined from 'ovl_path_type' at ../fs/overlayfs/util.c:216:6: +include/asm-generic/rwonce.h:44:26: error: array subscript 0 is outside array bounds of 'struct inode[7486503276667837]' [-Werror=array-bounds=] + 44 | #define __READ_ONCE(x) (*(const volatile __unqual_scalar_typeof(x) *)&(x)) + | ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +include/asm-generic/rwonce.h:50:9: note: in expansion of macro '__READ_ONCE' + 50 | __READ_ONCE(x); \ + | ^~~~~~~~~~~ +fs/overlayfs/ovl_entry.h:195:16: note: in expansion of macro 'READ_ONCE' + 195 | return READ_ONCE(oi->__upperdentry); + | ^~~~~~~~~ + 'ovl_path_type': event 1 + 185 | return inode ? OVL_I(inode)->oe : NULL; + 'ovl_path_type': event 2 + +Avoid this by allowing ovl_dentry_upper() to return NULL if d_inode() is +NULL, as that means the problematic dereferencing can never be reached. +Note that this fixes the over-eager compiler warning in an effort to +being able to enable -Warray-bounds globally. There is no known +behavioral bug here. + +Suggested-by: Amir Goldstein <amir73il@gmail.com> +Signed-off-by: Kees Cook <kees@kernel.org> +Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + fs/overlayfs/util.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c +index 62a258c2b59cd..26f29a3e5ada0 100644 +--- a/fs/overlayfs/util.c ++++ b/fs/overlayfs/util.c +@@ -211,7 +211,9 @@ enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path) + + struct dentry *ovl_dentry_upper(struct dentry *dentry) + { +- return ovl_upperdentry_dereference(OVL_I(d_inode(dentry))); ++ struct inode *inode = d_inode(dentry); ++ ++ return inode ? ovl_upperdentry_dereference(OVL_I(inode)) : NULL; + } + + struct dentry *ovl_dentry_lower(struct dentry *dentry) +-- +2.39.5 + diff --git a/queue-5.10/pci-cadence-ep-correct-pba-offset-in-.set_msix-callb.patch b/queue-5.10/pci-cadence-ep-correct-pba-offset-in-.set_msix-callb.patch new file mode 100644 index 0000000000..45181ea9d5 --- /dev/null +++ b/queue-5.10/pci-cadence-ep-correct-pba-offset-in-.set_msix-callb.patch @@ -0,0 +1,65 @@ +From bbf94de244835b646f25d4c5708a3ac039e36853 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Wed, 14 May 2025 09:43:15 +0200 +Subject: PCI: cadence-ep: Correct PBA offset in .set_msix() callback + +From: Niklas Cassel <cassel@kernel.org> + +[ Upstream commit c8bcb01352a86bc5592403904109c22b66bd916e ] + +While cdns_pcie_ep_set_msix() writes the Table Size field correctly (N-1), +the calculation of the PBA offset is wrong because it calculates space for +(N-1) entries instead of N. + +This results in the following QEMU error when using PCI passthrough on a +device which relies on the PCI endpoint subsystem: + + failed to add PCI capability 0x11[0x50]@0xb0: table & pba overlap, or they don't fit in BARs, or don't align + +Fix the calculation of PBA offset in the MSI-X capability. + +[bhelgaas: more specific subject and commit log] + +Fixes: 3ef5d16f50f8 ("PCI: cadence: Add MSI-X support to Endpoint driver") +Signed-off-by: Niklas Cassel <cassel@kernel.org> +Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> +Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com> +Reviewed-by: Damien Le Moal <dlemoal@kernel.org> +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/20250514074313.283156-10-cassel@kernel.org +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/pci/controller/cadence/pcie-cadence-ep.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c +index 403ff93bc8509..f6edbe77e640a 100644 +--- a/drivers/pci/controller/cadence/pcie-cadence-ep.c ++++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c +@@ -253,11 +253,12 @@ static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u16 interrupts, + struct cdns_pcie *pcie = &ep->pcie; + u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET; + u32 val, reg; ++ u16 actual_interrupts = interrupts + 1; + + reg = cap + PCI_MSIX_FLAGS; + val = cdns_pcie_ep_fn_readw(pcie, fn, reg); + val &= ~PCI_MSIX_FLAGS_QSIZE; +- val |= interrupts; ++ val |= interrupts; /* 0's based value */ + cdns_pcie_ep_fn_writew(pcie, fn, reg, val); + + /* Set MSIX BAR and offset */ +@@ -267,7 +268,7 @@ static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u16 interrupts, + + /* Set PBA BAR and offset. BAR must match MSIX BAR */ + reg = cap + PCI_MSIX_PBA; +- val = (offset + (interrupts * PCI_MSIX_ENTRY_SIZE)) | bir; ++ val = (offset + (actual_interrupts * PCI_MSIX_ENTRY_SIZE)) | bir; + cdns_pcie_ep_fn_writel(pcie, fn, reg, val); + + return 0; +-- +2.39.5 + diff --git a/queue-5.10/rdma-core-use-refcount_t-instead-of-atomic_t-on-refc.patch b/queue-5.10/rdma-core-use-refcount_t-instead-of-atomic_t-on-refc.patch new file mode 100644 index 0000000000..4ffdcd996a --- /dev/null +++ b/queue-5.10/rdma-core-use-refcount_t-instead-of-atomic_t-on-refc.patch @@ -0,0 +1,80 @@ +From 691445fcd0f0d7fa8abba465e171261c7a2cca39 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Fri, 28 May 2021 17:37:32 +0800 +Subject: RDMA/core: Use refcount_t instead of atomic_t on refcount of + iwcm_id_private + +From: Weihang Li <liweihang@huawei.com> + +[ Upstream commit 60dff56d77292062789232f68354f567e1ccf1d2 ] + +The refcount_t API will WARN on underflow and overflow of a reference +counter, and avoid use-after-free risks. + +Link: https://lore.kernel.org/r/1622194663-2383-2-git-send-email-liweihang@huawei.com +Signed-off-by: Weihang Li <liweihang@huawei.com> +Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> +Stable-dep-of: 6883b680e703 ("RDMA/iwcm: Fix use-after-free of work objects after cm_id destruction") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/infiniband/core/iwcm.c | 9 ++++----- + drivers/infiniband/core/iwcm.h | 2 +- + 2 files changed, 5 insertions(+), 6 deletions(-) + +diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c +index 44362f693df9f..3e4941754b48d 100644 +--- a/drivers/infiniband/core/iwcm.c ++++ b/drivers/infiniband/core/iwcm.c +@@ -211,8 +211,7 @@ static void free_cm_id(struct iwcm_id_private *cm_id_priv) + */ + static int iwcm_deref_id(struct iwcm_id_private *cm_id_priv) + { +- BUG_ON(atomic_read(&cm_id_priv->refcount)==0); +- if (atomic_dec_and_test(&cm_id_priv->refcount)) { ++ if (refcount_dec_and_test(&cm_id_priv->refcount)) { + BUG_ON(!list_empty(&cm_id_priv->work_list)); + free_cm_id(cm_id_priv); + return 1; +@@ -225,7 +224,7 @@ static void add_ref(struct iw_cm_id *cm_id) + { + struct iwcm_id_private *cm_id_priv; + cm_id_priv = container_of(cm_id, struct iwcm_id_private, id); +- atomic_inc(&cm_id_priv->refcount); ++ refcount_inc(&cm_id_priv->refcount); + } + + static void rem_ref(struct iw_cm_id *cm_id) +@@ -257,7 +256,7 @@ struct iw_cm_id *iw_create_cm_id(struct ib_device *device, + cm_id_priv->id.add_ref = add_ref; + cm_id_priv->id.rem_ref = rem_ref; + spin_lock_init(&cm_id_priv->lock); +- atomic_set(&cm_id_priv->refcount, 1); ++ refcount_set(&cm_id_priv->refcount, 1); + init_waitqueue_head(&cm_id_priv->connect_wait); + init_completion(&cm_id_priv->destroy_comp); + INIT_LIST_HEAD(&cm_id_priv->work_list); +@@ -1097,7 +1096,7 @@ static int cm_event_handler(struct iw_cm_id *cm_id, + } + } + +- atomic_inc(&cm_id_priv->refcount); ++ refcount_inc(&cm_id_priv->refcount); + if (list_empty(&cm_id_priv->work_list)) { + list_add_tail(&work->list, &cm_id_priv->work_list); + queue_work(iwcm_wq, &work->work); +diff --git a/drivers/infiniband/core/iwcm.h b/drivers/infiniband/core/iwcm.h +index 82c2cd1b0a804..bf74639be1287 100644 +--- a/drivers/infiniband/core/iwcm.h ++++ b/drivers/infiniband/core/iwcm.h +@@ -52,7 +52,7 @@ struct iwcm_id_private { + wait_queue_head_t connect_wait; + struct list_head work_list; + spinlock_t lock; +- atomic_t refcount; ++ refcount_t refcount; + struct list_head work_free_list; + }; + +-- +2.39.5 + diff --git a/queue-5.10/rdma-iwcm-fix-use-after-free-of-work-objects-after-c.patch b/queue-5.10/rdma-iwcm-fix-use-after-free-of-work-objects-after-c.patch new file mode 100644 index 0000000000..b4c717da5e --- /dev/null +++ b/queue-5.10/rdma-iwcm-fix-use-after-free-of-work-objects-after-c.patch @@ -0,0 +1,196 @@ +From e89e9767bce4447a86c4b5e92e8676e2aeb036b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Sat, 10 May 2025 19:10:36 +0900 +Subject: RDMA/iwcm: Fix use-after-free of work objects after cm_id destruction + +From: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com> + +[ Upstream commit 6883b680e703c6b2efddb4e7a8d891ce1803d06b ] + +The commit 59c68ac31e15 ("iw_cm: free cm_id resources on the last +deref") simplified cm_id resource management by freeing cm_id once all +references to the cm_id were removed. The references are removed either +upon completion of iw_cm event handlers or when the application destroys +the cm_id. This commit introduced the use-after-free condition where +cm_id_private object could still be in use by event handler works during +the destruction of cm_id. The commit aee2424246f9 ("RDMA/iwcm: Fix a +use-after-free related to destroying CM IDs") addressed this use-after- +free by flushing all pending works at the cm_id destruction. + +However, still another use-after-free possibility remained. It happens +with the work objects allocated for each cm_id_priv within +alloc_work_entries() during cm_id creation, and subsequently freed in +dealloc_work_entries() once all references to the cm_id are removed. +If the cm_id's last reference is decremented in the event handler work, +the work object for the work itself gets removed, and causes the use- +after-free BUG below: + + BUG: KASAN: slab-use-after-free in __pwq_activate_work+0x1ff/0x250 + Read of size 8 at addr ffff88811f9cf800 by task kworker/u16:1/147091 + + CPU: 2 UID: 0 PID: 147091 Comm: kworker/u16:1 Not tainted 6.15.0-rc2+ #27 PREEMPT(voluntary) + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-3.fc41 04/01/2014 + Workqueue: 0x0 (iw_cm_wq) + Call Trace: + <TASK> + dump_stack_lvl+0x6a/0x90 + print_report+0x174/0x554 + ? __virt_addr_valid+0x208/0x430 + ? __pwq_activate_work+0x1ff/0x250 + kasan_report+0xae/0x170 + ? __pwq_activate_work+0x1ff/0x250 + __pwq_activate_work+0x1ff/0x250 + pwq_dec_nr_in_flight+0x8c5/0xfb0 + process_one_work+0xc11/0x1460 + ? __pfx_process_one_work+0x10/0x10 + ? assign_work+0x16c/0x240 + worker_thread+0x5ef/0xfd0 + ? __pfx_worker_thread+0x10/0x10 + kthread+0x3b0/0x770 + ? __pfx_kthread+0x10/0x10 + ? rcu_is_watching+0x11/0xb0 + ? _raw_spin_unlock_irq+0x24/0x50 + ? rcu_is_watching+0x11/0xb0 + ? __pfx_kthread+0x10/0x10 + ret_from_fork+0x30/0x70 + ? __pfx_kthread+0x10/0x10 + ret_from_fork_asm+0x1a/0x30 + </TASK> + + Allocated by task 147416: + kasan_save_stack+0x2c/0x50 + kasan_save_track+0x10/0x30 + __kasan_kmalloc+0xa6/0xb0 + alloc_work_entries+0xa9/0x260 [iw_cm] + iw_cm_connect+0x23/0x4a0 [iw_cm] + rdma_connect_locked+0xbfd/0x1920 [rdma_cm] + nvme_rdma_cm_handler+0x8e5/0x1b60 [nvme_rdma] + cma_cm_event_handler+0xae/0x320 [rdma_cm] + cma_work_handler+0x106/0x1b0 [rdma_cm] + process_one_work+0x84f/0x1460 + worker_thread+0x5ef/0xfd0 + kthread+0x3b0/0x770 + ret_from_fork+0x30/0x70 + ret_from_fork_asm+0x1a/0x30 + + Freed by task 147091: + kasan_save_stack+0x2c/0x50 + kasan_save_track+0x10/0x30 + kasan_save_free_info+0x37/0x60 + __kasan_slab_free+0x4b/0x70 + kfree+0x13a/0x4b0 + dealloc_work_entries+0x125/0x1f0 [iw_cm] + iwcm_deref_id+0x6f/0xa0 [iw_cm] + cm_work_handler+0x136/0x1ba0 [iw_cm] + process_one_work+0x84f/0x1460 + worker_thread+0x5ef/0xfd0 + kthread+0x3b0/0x770 + ret_from_fork+0x30/0x70 + ret_from_fork_asm+0x1a/0x30 + + Last potentially related work creation: + kasan_save_stack+0x2c/0x50 + kasan_record_aux_stack+0xa3/0xb0 + __queue_work+0x2ff/0x1390 + queue_work_on+0x67/0xc0 + cm_event_handler+0x46a/0x820 [iw_cm] + siw_cm_upcall+0x330/0x650 [siw] + siw_cm_work_handler+0x6b9/0x2b20 [siw] + process_one_work+0x84f/0x1460 + worker_thread+0x5ef/0xfd0 + kthread+0x3b0/0x770 + ret_from_fork+0x30/0x70 + ret_from_fork_asm+0x1a/0x30 + +This BUG is reproducible by repeating the blktests test case nvme/061 +for the rdma transport and the siw driver. + +To avoid the use-after-free of cm_id_private work objects, ensure that +the last reference to the cm_id is decremented not in the event handler +works, but in the cm_id destruction context. For that purpose, move +iwcm_deref_id() call from destroy_cm_id() to the callers of +destroy_cm_id(). In iw_destroy_cm_id(), call iwcm_deref_id() after +flushing the pending works. + +During the fix work, I noticed that iw_destroy_cm_id() is called from +cm_work_handler() and process_event() context. However, the comment of +iw_destroy_cm_id() notes that the function "cannot be called by the +event thread". Drop the false comment. + +Closes: https://lore.kernel.org/linux-rdma/r5676e754sv35aq7cdsqrlnvyhiq5zktteaurl7vmfih35efko@z6lay7uypy3c/ +Fixes: 59c68ac31e15 ("iw_cm: free cm_id resources on the last deref") +Cc: stable@vger.kernel.org +Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com> +Link: https://patch.msgid.link/20250510101036.1756439-1-shinichiro.kawasaki@wdc.com +Reviewed-by: Zhu Yanjun <yanjun.zhu@linux.dev> +Signed-off-by: Leon Romanovsky <leon@kernel.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/infiniband/core/iwcm.c | 29 +++++++++++++++-------------- + 1 file changed, 15 insertions(+), 14 deletions(-) + +diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c +index 3e4941754b48d..ce41f235af253 100644 +--- a/drivers/infiniband/core/iwcm.c ++++ b/drivers/infiniband/core/iwcm.c +@@ -367,12 +367,9 @@ EXPORT_SYMBOL(iw_cm_disconnect); + /* + * CM_ID <-- DESTROYING + * +- * Clean up all resources associated with the connection and release +- * the initial reference taken by iw_create_cm_id. +- * +- * Returns true if and only if the last cm_id_priv reference has been dropped. ++ * Clean up all resources associated with the connection. + */ +-static bool destroy_cm_id(struct iw_cm_id *cm_id) ++static void destroy_cm_id(struct iw_cm_id *cm_id) + { + struct iwcm_id_private *cm_id_priv; + struct ib_qp *qp; +@@ -441,20 +438,22 @@ static bool destroy_cm_id(struct iw_cm_id *cm_id) + iwpm_remove_mapinfo(&cm_id->local_addr, &cm_id->m_local_addr); + iwpm_remove_mapping(&cm_id->local_addr, RDMA_NL_IWCM); + } +- +- return iwcm_deref_id(cm_id_priv); + } + + /* +- * This function is only called by the application thread and cannot +- * be called by the event thread. The function will wait for all +- * references to be released on the cm_id and then kfree the cm_id +- * object. ++ * Destroy cm_id. If the cm_id still has other references, wait for all ++ * references to be released on the cm_id and then release the initial ++ * reference taken by iw_create_cm_id. + */ + void iw_destroy_cm_id(struct iw_cm_id *cm_id) + { +- if (!destroy_cm_id(cm_id)) ++ struct iwcm_id_private *cm_id_priv; ++ ++ cm_id_priv = container_of(cm_id, struct iwcm_id_private, id); ++ destroy_cm_id(cm_id); ++ if (refcount_read(&cm_id_priv->refcount) > 1) + flush_workqueue(iwcm_wq); ++ iwcm_deref_id(cm_id_priv); + } + EXPORT_SYMBOL(iw_destroy_cm_id); + +@@ -1037,8 +1036,10 @@ static void cm_work_handler(struct work_struct *_work) + + if (!test_bit(IWCM_F_DROP_EVENTS, &cm_id_priv->flags)) { + ret = process_event(cm_id_priv, &levent); +- if (ret) +- WARN_ON_ONCE(destroy_cm_id(&cm_id_priv->id)); ++ if (ret) { ++ destroy_cm_id(&cm_id_priv->id); ++ WARN_ON_ONCE(iwcm_deref_id(cm_id_priv)); ++ } + } else + pr_debug("dropping event %d\n", levent.event); + if (iwcm_deref_id(cm_id_priv)) +-- +2.39.5 + diff --git a/queue-5.10/regulator-add-devm-helpers-for-get-and-enable.patch b/queue-5.10/regulator-add-devm-helpers-for-get-and-enable.patch new file mode 100644 index 0000000000..24270f623c --- /dev/null +++ b/queue-5.10/regulator-add-devm-helpers-for-get-and-enable.patch @@ -0,0 +1,283 @@ +From b0d350e9828b248dd7b4c2cbdec4fbcba6ae05df Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Fri, 12 Aug 2022 13:10:37 +0300 +Subject: regulator: Add devm helpers for get and enable + +From: Matti Vaittinen <mazziesaccount@gmail.com> + +[ Upstream commit da279e6965b3838e99e5c0ab8f76b87bf86b31a5 ] + +A few regulator consumer drivers seem to be just getting a regulator, +enabling it and registering a devm-action to disable the regulator at +the driver detach and then forget about it. + +We can simplify this a bit by adding a devm-helper for this pattern. +Add devm_regulator_get_enable() and devm_regulator_get_enable_optional() + +Signed-off-by: Matti Vaittinen <mazziesaccount@gmail.com> +Link: https://lore.kernel.org/r/ed7b8841193bb9749d426f3cb3b199c9460794cd.1660292316.git.mazziesaccount@gmail.com +Signed-off-by: Mark Brown <broonie@kernel.org> +Stable-dep-of: 9079db287fc3 ("ASoC: codecs: wcd9335: Fix missing free of regulator supplies") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/regulator/devres.c | 164 +++++++++++++++++++++++++++++ + include/linux/regulator/consumer.h | 27 +++++ + 2 files changed, 191 insertions(+) + +diff --git a/drivers/regulator/devres.c b/drivers/regulator/devres.c +index 9aec9541f78fc..e9fb842e82faa 100644 +--- a/drivers/regulator/devres.c ++++ b/drivers/regulator/devres.c +@@ -70,6 +70,65 @@ struct regulator *devm_regulator_get_exclusive(struct device *dev, + } + EXPORT_SYMBOL_GPL(devm_regulator_get_exclusive); + ++static void regulator_action_disable(void *d) ++{ ++ struct regulator *r = (struct regulator *)d; ++ ++ regulator_disable(r); ++} ++ ++static int _devm_regulator_get_enable(struct device *dev, const char *id, ++ int get_type) ++{ ++ struct regulator *r; ++ int ret; ++ ++ r = _devm_regulator_get(dev, id, get_type); ++ if (IS_ERR(r)) ++ return PTR_ERR(r); ++ ++ ret = regulator_enable(r); ++ if (!ret) ++ ret = devm_add_action_or_reset(dev, ®ulator_action_disable, r); ++ ++ if (ret) ++ devm_regulator_put(r); ++ ++ return ret; ++} ++ ++/** ++ * devm_regulator_get_enable_optional - Resource managed regulator get and enable ++ * @dev: device to supply ++ * @id: supply name or regulator ID. ++ * ++ * Get and enable regulator for duration of the device life-time. ++ * regulator_disable() and regulator_put() are automatically called on driver ++ * detach. See regulator_get_optional() and regulator_enable() for more ++ * information. ++ */ ++int devm_regulator_get_enable_optional(struct device *dev, const char *id) ++{ ++ return _devm_regulator_get_enable(dev, id, OPTIONAL_GET); ++} ++EXPORT_SYMBOL_GPL(devm_regulator_get_enable_optional); ++ ++/** ++ * devm_regulator_get_enable - Resource managed regulator get and enable ++ * @dev: device to supply ++ * @id: supply name or regulator ID. ++ * ++ * Get and enable regulator for duration of the device life-time. ++ * regulator_disable() and regulator_put() are automatically called on driver ++ * detach. See regulator_get() and regulator_enable() for more ++ * information. ++ */ ++int devm_regulator_get_enable(struct device *dev, const char *id) ++{ ++ return _devm_regulator_get_enable(dev, id, NORMAL_GET); ++} ++EXPORT_SYMBOL_GPL(devm_regulator_get_enable); ++ + /** + * devm_regulator_get_optional - Resource managed regulator_get_optional() + * @dev: device to supply +@@ -194,6 +253,111 @@ int devm_regulator_bulk_get_const(struct device *dev, int num_consumers, + } + EXPORT_SYMBOL_GPL(devm_regulator_bulk_get_const); + ++static int devm_regulator_bulk_match(struct device *dev, void *res, ++ void *data) ++{ ++ struct regulator_bulk_devres *match = res; ++ struct regulator_bulk_data *target = data; ++ ++ /* ++ * We check the put uses same consumer list as the get did. ++ * We _could_ scan all entries in consumer array and check the ++ * regulators match but ATM I don't see the need. We can change this ++ * later if needed. ++ */ ++ return match->consumers == target; ++} ++ ++/** ++ * devm_regulator_bulk_put - Resource managed regulator_bulk_put() ++ * @consumers: consumers to free ++ * ++ * Deallocate regulators allocated with devm_regulator_bulk_get(). Normally ++ * this function will not need to be called and the resource management ++ * code will ensure that the resource is freed. ++ */ ++void devm_regulator_bulk_put(struct regulator_bulk_data *consumers) ++{ ++ int rc; ++ struct regulator *regulator = consumers[0].consumer; ++ ++ rc = devres_release(regulator->dev, devm_regulator_bulk_release, ++ devm_regulator_bulk_match, consumers); ++ if (rc != 0) ++ WARN_ON(rc); ++} ++EXPORT_SYMBOL_GPL(devm_regulator_bulk_put); ++ ++static void devm_regulator_bulk_disable(void *res) ++{ ++ struct regulator_bulk_devres *devres = res; ++ int i; ++ ++ for (i = 0; i < devres->num_consumers; i++) ++ regulator_disable(devres->consumers[i].consumer); ++} ++ ++/** ++ * devm_regulator_bulk_get_enable - managed get'n enable multiple regulators ++ * ++ * @dev: device to supply ++ * @num_consumers: number of consumers to register ++ * @id: list of supply names or regulator IDs ++ * ++ * @return 0 on success, an errno on failure. ++ * ++ * This helper function allows drivers to get several regulator ++ * consumers in one operation with management, the regulators will ++ * automatically be freed when the device is unbound. If any of the ++ * regulators cannot be acquired then any regulators that were ++ * allocated will be freed before returning to the caller. ++ */ ++int devm_regulator_bulk_get_enable(struct device *dev, int num_consumers, ++ const char * const *id) ++{ ++ struct regulator_bulk_devres *devres; ++ struct regulator_bulk_data *consumers; ++ int i, ret; ++ ++ devres = devm_kmalloc(dev, sizeof(*devres), GFP_KERNEL); ++ if (!devres) ++ return -ENOMEM; ++ ++ devres->consumers = devm_kcalloc(dev, num_consumers, sizeof(*consumers), ++ GFP_KERNEL); ++ consumers = devres->consumers; ++ if (!consumers) ++ return -ENOMEM; ++ ++ devres->num_consumers = num_consumers; ++ ++ for (i = 0; i < num_consumers; i++) ++ consumers[i].supply = id[i]; ++ ++ ret = devm_regulator_bulk_get(dev, num_consumers, consumers); ++ if (ret) ++ return ret; ++ ++ for (i = 0; i < num_consumers; i++) { ++ ret = regulator_enable(consumers[i].consumer); ++ if (ret) ++ goto unwind; ++ } ++ ++ ret = devm_add_action(dev, devm_regulator_bulk_disable, devres); ++ if (!ret) ++ return 0; ++ ++unwind: ++ while (--i >= 0) ++ regulator_disable(consumers[i].consumer); ++ ++ devm_regulator_bulk_put(consumers); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(devm_regulator_bulk_get_enable); ++ + static void devm_rdev_release(struct device *dev, void *res) + { + regulator_unregister(*(struct regulator_dev **)res); +diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h +index bba7c3e4cd870..3abb23c68fde7 100644 +--- a/include/linux/regulator/consumer.h ++++ b/include/linux/regulator/consumer.h +@@ -189,6 +189,8 @@ struct regulator *__must_check regulator_get_optional(struct device *dev, + const char *id); + struct regulator *__must_check devm_regulator_get_optional(struct device *dev, + const char *id); ++int devm_regulator_get_enable(struct device *dev, const char *id); ++int devm_regulator_get_enable_optional(struct device *dev, const char *id); + void regulator_put(struct regulator *regulator); + void devm_regulator_put(struct regulator *regulator); + +@@ -231,12 +233,15 @@ int __must_check regulator_bulk_get(struct device *dev, int num_consumers, + struct regulator_bulk_data *consumers); + int __must_check devm_regulator_bulk_get(struct device *dev, int num_consumers, + struct regulator_bulk_data *consumers); ++void devm_regulator_bulk_put(struct regulator_bulk_data *consumers); + int __must_check devm_regulator_bulk_get_const( + struct device *dev, int num_consumers, + const struct regulator_bulk_data *in_consumers, + struct regulator_bulk_data **out_consumers); + int __must_check regulator_bulk_enable(int num_consumers, + struct regulator_bulk_data *consumers); ++int devm_regulator_bulk_get_enable(struct device *dev, int num_consumers, ++ const char * const *id); + int regulator_bulk_disable(int num_consumers, + struct regulator_bulk_data *consumers); + int regulator_bulk_force_disable(int num_consumers, +@@ -341,6 +346,17 @@ devm_regulator_get_exclusive(struct device *dev, const char *id) + return ERR_PTR(-ENODEV); + } + ++static inline int devm_regulator_get_enable(struct device *dev, const char *id) ++{ ++ return -ENODEV; ++} ++ ++static inline int devm_regulator_get_enable_optional(struct device *dev, ++ const char *id) ++{ ++ return -ENODEV; ++} ++ + static inline struct regulator *__must_check + regulator_get_optional(struct device *dev, const char *id) + { +@@ -362,6 +378,10 @@ static inline void devm_regulator_put(struct regulator *regulator) + { + } + ++static inline void devm_regulator_bulk_put(struct regulator_bulk_data *consumers) ++{ ++} ++ + static inline int regulator_register_supply_alias(struct device *dev, + const char *id, + struct device *alias_dev, +@@ -462,6 +482,13 @@ static inline int regulator_bulk_enable(int num_consumers, + return 0; + } + ++static inline int devm_regulator_bulk_get_enable(struct device *dev, ++ int num_consumers, ++ const char * const *id) ++{ ++ return 0; ++} ++ + static inline int regulator_bulk_disable(int num_consumers, + struct regulator_bulk_data *consumers) + { +-- +2.39.5 + diff --git a/queue-5.10/regulator-core-allow-drivers-to-define-their-init-da.patch b/queue-5.10/regulator-core-allow-drivers-to-define-their-init-da.patch new file mode 100644 index 0000000000..450fbe57ff --- /dev/null +++ b/queue-5.10/regulator-core-allow-drivers-to-define-their-init-da.patch @@ -0,0 +1,110 @@ +From 7b7b3dd1748d9e2267e2083ae8a2f3b885aec12d Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 26 Jul 2022 10:38:23 -0700 +Subject: regulator: core: Allow drivers to define their init data as const + +From: Douglas Anderson <dianders@chromium.org> + +[ Upstream commit 1de452a0edda26f1483d1d934f692eab13ba669a ] + +Drivers tend to want to define the names of their regulators somewhere +in their source file as "static const". This means, inevitable, that +every driver out there open codes something like this: + +static const char * const supply_names[] = { + "vcc", "vccl", +}; + +static int get_regulators(struct my_data *data) +{ + int i; + + data->supplies = devm_kzalloc(...) + if (!data->supplies) + return -ENOMEM; + + for (i = 0; i < ARRAY_SIZE(supply_names); i++) + data->supplies[i].supply = supply_names[i]; + + return devm_regulator_bulk_get(data->dev, + ARRAY_SIZE(supply_names), + data->supplies); +} + +Let's make this more convenient by doing providing a helper that does +the copy. + +I have chosen to have the "const" input structure here be the exact +same structure as the normal one passed to +devm_regulator_bulk_get(). This is slightly inefficent since the input +data can't possibly have anything useful for "ret" or consumer and +thus we waste 8 bytes per structure. This seems an OK tradeoff for not +introducing an extra structure. + +Signed-off-by: Douglas Anderson <dianders@chromium.org> +Link: https://lore.kernel.org/r/20220726103631.v2.6.I38fc508a73135a5c1b873851f3553ff2a3a625f5@changeid +Signed-off-by: Mark Brown <broonie@kernel.org> +Stable-dep-of: 9079db287fc3 ("ASoC: codecs: wcd9335: Fix missing free of regulator supplies") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/regulator/devres.c | 28 ++++++++++++++++++++++++++++ + include/linux/regulator/consumer.h | 4 ++++ + 2 files changed, 32 insertions(+) + +diff --git a/drivers/regulator/devres.c b/drivers/regulator/devres.c +index 3091210889e31..9aec9541f78fc 100644 +--- a/drivers/regulator/devres.c ++++ b/drivers/regulator/devres.c +@@ -166,6 +166,34 @@ int devm_regulator_bulk_get(struct device *dev, int num_consumers, + } + EXPORT_SYMBOL_GPL(devm_regulator_bulk_get); + ++/** ++ * devm_regulator_bulk_get_const - devm_regulator_bulk_get() w/ const data ++ * ++ * @dev: device to supply ++ * @num_consumers: number of consumers to register ++ * @in_consumers: const configuration of consumers ++ * @out_consumers: in_consumers is copied here and this is passed to ++ * devm_regulator_bulk_get(). ++ * ++ * This is a convenience function to allow bulk regulator configuration ++ * to be stored "static const" in files. ++ * ++ * Return: 0 on success, an errno on failure. ++ */ ++int devm_regulator_bulk_get_const(struct device *dev, int num_consumers, ++ const struct regulator_bulk_data *in_consumers, ++ struct regulator_bulk_data **out_consumers) ++{ ++ *out_consumers = devm_kmemdup(dev, in_consumers, ++ num_consumers * sizeof(*in_consumers), ++ GFP_KERNEL); ++ if (*out_consumers == NULL) ++ return -ENOMEM; ++ ++ return devm_regulator_bulk_get(dev, num_consumers, *out_consumers); ++} ++EXPORT_SYMBOL_GPL(devm_regulator_bulk_get_const); ++ + static void devm_rdev_release(struct device *dev, void *res) + { + regulator_unregister(*(struct regulator_dev **)res); +diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h +index 20e84a84fb779..bba7c3e4cd870 100644 +--- a/include/linux/regulator/consumer.h ++++ b/include/linux/regulator/consumer.h +@@ -231,6 +231,10 @@ int __must_check regulator_bulk_get(struct device *dev, int num_consumers, + struct regulator_bulk_data *consumers); + int __must_check devm_regulator_bulk_get(struct device *dev, int num_consumers, + struct regulator_bulk_data *consumers); ++int __must_check devm_regulator_bulk_get_const( ++ struct device *dev, int num_consumers, ++ const struct regulator_bulk_data *in_consumers, ++ struct regulator_bulk_data **out_consumers); + int __must_check regulator_bulk_enable(int num_consumers, + struct regulator_bulk_data *consumers); + int regulator_bulk_disable(int num_consumers, +-- +2.39.5 + diff --git a/queue-5.10/revert-iommu-amd-prevent-binding-other-pci-drivers-t.patch b/queue-5.10/revert-iommu-amd-prevent-binding-other-pci-drivers-t.patch new file mode 100644 index 0000000000..bdc047a771 --- /dev/null +++ b/queue-5.10/revert-iommu-amd-prevent-binding-other-pci-drivers-t.patch @@ -0,0 +1,60 @@ +From a3781804b1b026f31e5fcd07f7a2a2b564d71c6a Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Fri, 25 Apr 2025 11:24:21 +0200 +Subject: Revert "iommu/amd: Prevent binding other PCI drivers to IOMMU PCI + devices" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Lukas Wunner <lukas@wunner.de> + +[ Upstream commit 3be5fa236649da6404f1bca1491bf02d4b0d5cce ] + +Commit 991de2e59090 ("PCI, x86: Implement pcibios_alloc_irq() and +pcibios_free_irq()") changed IRQ handling on PCI driver probing. +It inadvertently broke resume from system sleep on AMD platforms: + + https://lore.kernel.org/r/20150926164651.GA3640@pd.tnic/ + +This was fixed by two independent commits: + +* 8affb487d4a4 ("x86/PCI: Don't alloc pcibios-irq when MSI is enabled") +* cbbc00be2ce3 ("iommu/amd: Prevent binding other PCI drivers to IOMMU PCI devices") + +The breaking change and one of these two fixes were subsequently reverted: + +* fe25d078874f ("Revert "x86/PCI: Don't alloc pcibios-irq when MSI is enabled"") +* 6c777e8799a9 ("Revert "PCI, x86: Implement pcibios_alloc_irq() and pcibios_free_irq()"") + +This rendered the second fix unnecessary, so revert it as well. It used +the match_driver flag in struct pci_dev, which is internal to the PCI core +and not supposed to be touched by arbitrary drivers. + +Signed-off-by: Lukas Wunner <lukas@wunner.de> +Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> +Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org> +Acked-by: Joerg Roedel <jroedel@suse.de> +Link: https://patch.msgid.link/9a3ddff5cc49512044f963ba0904347bd404094d.1745572340.git.lukas@wunner.de +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/iommu/amd/init.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c +index e09391ab3deb0..752edbf529f5f 100644 +--- a/drivers/iommu/amd/init.c ++++ b/drivers/iommu/amd/init.c +@@ -1876,9 +1876,6 @@ static int __init iommu_init_pci(struct amd_iommu *iommu) + if (!iommu->dev) + return -ENODEV; + +- /* Prevent binding other PCI device drivers to IOMMU devices */ +- iommu->dev->match_driver = false; +- + /* ACPI _PRT won't have an IRQ for IOMMU */ + iommu->dev->irq_managed = 1; + +-- +2.39.5 + diff --git a/queue-5.10/series b/queue-5.10/series new file mode 100644 index 0000000000..0a13b3d0ef --- /dev/null +++ b/queue-5.10/series @@ -0,0 +1,50 @@ +cifs-fix-cifs_query_path_info-for-windows-nt-servers.patch +nfsv4.2-fix-listxattr-to-return-selinux-security-lab.patch +mailbox-not-protect-module_put-with-spin_lock_irqsav.patch +mfd-max14577-fix-wakeup-source-leaks-on-device-unbin.patch +leds-multicolor-fix-intensity-setting-while-sw-blink.patch +hwmon-pmbus-max34440-fix-support-for-max34451.patch +revert-iommu-amd-prevent-binding-other-pci-drivers-t.patch +dmaengine-xilinx_dma-set-dma_device-directions.patch +md-md-bitmap-fix-dm-raid-max_write_behind-setting.patch +bcache-fix-null-pointer-in-cache_set_flush.patch +iio-pressure-zpa2326-use-aligned_s64-for-the-timesta.patch +um-add-cmpxchg8b_emu-and-checksum-functions-to-asm-p.patch +usb-potential-integer-overflow-in-usbg_make_tpg.patch +usb-common-usb-conn-gpio-use-a-unique-name-for-usb-c.patch +usb-add-checks-for-snprintf-calls-in-usb_alloc_dev.patch +usb-cdc-wdm-avoid-setting-wdm_read-for-zlp-s.patch +usb-typec-displayport-receive-dp-status-update-nak-r.patch +alsa-hda-ignore-unsol-events-for-cards-being-shut-do.patch +alsa-hda-add-new-pci-id-for-amd-gpu-display-hd-audio.patch +ceph-fix-possible-integer-overflow-in-ceph_zero_obje.patch +ovl-check-for-null-d_inode-in-ovl_dentry_upper.patch +usb-usbtmc-fix-reading-stale-status-byte.patch +usb-usbtmc-add-usbtmc_ioctl_get_stb.patch +usb-usbtmc-fix-read_stb-function-and-get_stb-ioctl.patch +vmci-check-context-notify_page-after-call-to-get_use.patch +vmci-fix-race-between-vmci_host_setup_notify-and-vmc.patch +usb-typec-tcpci_maxim-fix-uninitialized-return-varia.patch +usb-typec-tcpci_maxim-remove-redundant-assignment.patch +usb-typec-tcpci_maxim-add-terminating-newlines-to-lo.patch +usb-typec-tcpm-tcpci_maxim-fix-bounds-check-in-proce.patch +fs-jfs-consolidate-sanity-checking-in-dbmount.patch +jfs-validate-ag-parameters-in-dbmount-to-prevent-cra.patch +media-omap3isp-use-sgtable-based-scatterlist-wrapper.patch +regulator-core-allow-drivers-to-define-their-init-da.patch +regulator-add-devm-helpers-for-get-and-enable.patch +asoc-codecs-wcd9335-handle-nicer-probe-deferral-and-.patch +asoc-codec-wcd9335-convert-to-gpio-descriptors.patch +asoc-codecs-wcd9335-fix-missing-free-of-regulator-su.patch +can-tcan4x5x-fix-power-regulator-retrieval-during-pr.patch +f2fs-don-t-over-report-free-space-or-inodes-in-statv.patch +rdma-core-use-refcount_t-instead-of-atomic_t-on-refc.patch +rdma-iwcm-fix-use-after-free-of-work-objects-after-c.patch +uio-uio_hv_generic-use-devm_kzalloc-for-private-data.patch +drivers-hv-vmbus-fix-duplicate-cpu-assignments-withi.patch +drivers-hv-rename-alloced-to-allocated.patch +drivers-hv-vmbus-add-utility-function-for-querying-r.patch +uio_hv_generic-query-the-ringbuffer-size-for-device.patch +uio_hv_generic-align-ring-size-to-system-page.patch +pci-cadence-ep-correct-pba-offset-in-.set_msix-callb.patch +net_sched-sch_sfq-reject-invalid-perturb-period.patch diff --git a/queue-5.10/uio-uio_hv_generic-use-devm_kzalloc-for-private-data.patch b/queue-5.10/uio-uio_hv_generic-use-devm_kzalloc-for-private-data.patch new file mode 100644 index 0000000000..724a844e10 --- /dev/null +++ b/queue-5.10/uio-uio_hv_generic-use-devm_kzalloc-for-private-data.patch @@ -0,0 +1,68 @@ +From 9d3d4cc5243951bdcfbbfe65be3b66f692da3bd6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Thu, 19 Nov 2020 17:49:03 +0200 +Subject: uio: uio_hv_generic: use devm_kzalloc() for private data alloc + +From: Alexandru Ardelean <alexandru.ardelean@analog.com> + +[ Upstream commit 74e71964b1a9ffd34fa4b6ec8f2fa13e7cf0ac7a ] + +This is a minor cleanup for the management of the private object of this +driver. The allocation can be tied to the life-time of the hv_device +object. +This cleans up a bit the exit & error paths, since the object doesn't need +to be explicitly free'd anymore. + +Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com> +Link: https://lore.kernel.org/r/20201119154903.82099-4-alexandru.ardelean@analog.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Stable-dep-of: 0315fef2aff9 ("uio_hv_generic: Align ring size to system page") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/uio/uio_hv_generic.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c +index 67cfe838a7874..f7f5106307627 100644 +--- a/drivers/uio/uio_hv_generic.c ++++ b/drivers/uio/uio_hv_generic.c +@@ -256,14 +256,14 @@ hv_uio_probe(struct hv_device *dev, + return -ENOTSUPP; + } + +- pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); ++ pdata = devm_kzalloc(&dev->device, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + ret = vmbus_alloc_ring(channel, HV_RING_SIZE * PAGE_SIZE, + HV_RING_SIZE * PAGE_SIZE); + if (ret) +- goto fail; ++ return ret; + + set_channel_read_mode(channel, HV_CALL_ISR); + +@@ -360,8 +360,6 @@ hv_uio_probe(struct hv_device *dev, + + fail_close: + hv_uio_cleanup(dev, pdata); +-fail: +- kfree(pdata); + + return ret; + } +@@ -377,10 +375,8 @@ hv_uio_remove(struct hv_device *dev) + sysfs_remove_bin_file(&dev->channel->kobj, &ring_buffer_bin_attr); + uio_unregister_device(&pdata->info); + hv_uio_cleanup(dev, pdata); +- hv_set_drvdata(dev, NULL); + + vmbus_free_ring(dev->channel); +- kfree(pdata); + return 0; + } + +-- +2.39.5 + diff --git a/queue-5.10/uio_hv_generic-align-ring-size-to-system-page.patch b/queue-5.10/uio_hv_generic-align-ring-size-to-system-page.patch new file mode 100644 index 0000000000..469837206e --- /dev/null +++ b/queue-5.10/uio_hv_generic-align-ring-size-to-system-page.patch @@ -0,0 +1,41 @@ +From f0db128873b551a603df0903c92705316e49216f Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Mon, 5 May 2025 17:56:35 -0700 +Subject: uio_hv_generic: Align ring size to system page + +From: Long Li <longli@microsoft.com> + +[ Upstream commit 0315fef2aff9f251ddef8a4b53db9187429c3553 ] + +Following the ring header, the ring data should align to system page +boundary. Adjust the size if necessary. + +Cc: stable@vger.kernel.org +Fixes: 95096f2fbd10 ("uio-hv-generic: new userspace i/o driver for VMBus") +Signed-off-by: Long Li <longli@microsoft.com> +Reviewed-by: Michael Kelley <mhklinux@outlook.com> +Link: https://lore.kernel.org/r/1746492997-4599-4-git-send-email-longli@linuxonhyperv.com +Signed-off-by: Wei Liu <wei.liu@kernel.org> +Message-ID: <1746492997-4599-4-git-send-email-longli@linuxonhyperv.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/uio/uio_hv_generic.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c +index 03a4ca762c499..6625d340f3ac5 100644 +--- a/drivers/uio/uio_hv_generic.c ++++ b/drivers/uio/uio_hv_generic.c +@@ -260,6 +260,9 @@ hv_uio_probe(struct hv_device *dev, + if (!ring_size) + ring_size = HV_RING_SIZE * PAGE_SIZE; + ++ /* Adjust ring size if necessary to have it page aligned */ ++ ring_size = VMBUS_RING_SIZE(ring_size); ++ + pdata = devm_kzalloc(&dev->device, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; +-- +2.39.5 + diff --git a/queue-5.10/uio_hv_generic-query-the-ringbuffer-size-for-device.patch b/queue-5.10/uio_hv_generic-query-the-ringbuffer-size-for-device.patch new file mode 100644 index 0000000000..20f59d8c1b --- /dev/null +++ b/queue-5.10/uio_hv_generic-query-the-ringbuffer-size-for-device.patch @@ -0,0 +1,56 @@ +From d61def7fcb89db3c22ab1dc092ffabefad7cd18d Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Sat, 30 Mar 2024 01:51:58 -0700 +Subject: uio_hv_generic: Query the ringbuffer size for device + +From: Saurabh Sengar <ssengar@linux.microsoft.com> + +[ Upstream commit e566ed5b64177a0c07b677568f623ed31d23406d ] + +Query the ring buffer size from pre defined table per device +and use that value for allocating the ring buffer for that +device. Keep the size as current default which is 2 MB if +the device doesn't have any preferred ring size. + +Signed-off-by: Saurabh Sengar <ssengar@linux.microsoft.com> +Reviewed-by: Long Li <longli@microsoft.com> +Link: https://lore.kernel.org/r/1711788723-8593-3-git-send-email-ssengar@linux.microsoft.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Stable-dep-of: 0315fef2aff9 ("uio_hv_generic: Align ring size to system page") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/uio/uio_hv_generic.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c +index f7f5106307627..03a4ca762c499 100644 +--- a/drivers/uio/uio_hv_generic.c ++++ b/drivers/uio/uio_hv_generic.c +@@ -249,6 +249,7 @@ hv_uio_probe(struct hv_device *dev, + struct hv_uio_private_data *pdata; + void *ring_buffer; + int ret; ++ size_t ring_size = hv_dev_ring_size(channel); + + /* Communicating with host has to be via shared memory not hypercall */ + if (!channel->offermsg.monitor_allocated) { +@@ -256,12 +257,14 @@ hv_uio_probe(struct hv_device *dev, + return -ENOTSUPP; + } + ++ if (!ring_size) ++ ring_size = HV_RING_SIZE * PAGE_SIZE; ++ + pdata = devm_kzalloc(&dev->device, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + +- ret = vmbus_alloc_ring(channel, HV_RING_SIZE * PAGE_SIZE, +- HV_RING_SIZE * PAGE_SIZE); ++ ret = vmbus_alloc_ring(channel, ring_size, ring_size); + if (ret) + return ret; + +-- +2.39.5 + diff --git a/queue-5.10/um-add-cmpxchg8b_emu-and-checksum-functions-to-asm-p.patch b/queue-5.10/um-add-cmpxchg8b_emu-and-checksum-functions-to-asm-p.patch new file mode 100644 index 0000000000..caf2ef66aa --- /dev/null +++ b/queue-5.10/um-add-cmpxchg8b_emu-and-checksum-functions-to-asm-p.patch @@ -0,0 +1,55 @@ +From e9030884574f03299126e779b4feff617d0424d8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Wed, 26 Mar 2025 19:05:00 +0000 +Subject: um: Add cmpxchg8b_emu and checksum functions to asm-prototypes.h + +From: Sami Tolvanen <samitolvanen@google.com> + +[ Upstream commit 674d03f6bd6b0f8327f1a4920ff5893557facfbd ] + +With CONFIG_GENDWARFKSYMS, um builds fail due to missing prototypes +in asm/asm-prototypes.h. Add declarations for cmpxchg8b_emu and the +exported checksum functions, including csum_partial_copy_generic as +it's also exported. + +Cc: Masahiro Yamada <masahiroy@kernel.org> +Cc: linux-kbuild@vger.kernel.org +Reported-by: kernel test robot <lkp@intel.com> +Closes: https://lore.kernel.org/oe-kbuild-all/202503251216.lE4t9Ikj-lkp@intel.com/ +Signed-off-by: Sami Tolvanen <samitolvanen@google.com> +Link: https://patch.msgid.link/20250326190500.847236-2-samitolvanen@google.com +Signed-off-by: Johannes Berg <johannes.berg@intel.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + arch/um/include/asm/asm-prototypes.h | 5 +++++ + arch/x86/um/asm/checksum.h | 3 +++ + 2 files changed, 8 insertions(+) + +diff --git a/arch/um/include/asm/asm-prototypes.h b/arch/um/include/asm/asm-prototypes.h +index 5898a26daa0dd..408b31d591279 100644 +--- a/arch/um/include/asm/asm-prototypes.h ++++ b/arch/um/include/asm/asm-prototypes.h +@@ -1 +1,6 @@ + #include <asm-generic/asm-prototypes.h> ++#include <asm/checksum.h> ++ ++#ifdef CONFIG_UML_X86 ++extern void cmpxchg8b_emu(void); ++#endif +diff --git a/arch/x86/um/asm/checksum.h b/arch/x86/um/asm/checksum.h +index b07824500363f..ddc144657efad 100644 +--- a/arch/x86/um/asm/checksum.h ++++ b/arch/x86/um/asm/checksum.h +@@ -20,6 +20,9 @@ + */ + extern __wsum csum_partial(const void *buff, int len, __wsum sum); + ++/* Do not call this directly. Declared for export type visibility. */ ++extern __visible __wsum csum_partial_copy_generic(const void *src, void *dst, int len); ++ + /** + * csum_fold - Fold and invert a 32bit checksum. + * sum: 32bit unfolded sum +-- +2.39.5 + diff --git a/queue-5.10/usb-add-checks-for-snprintf-calls-in-usb_alloc_dev.patch b/queue-5.10/usb-add-checks-for-snprintf-calls-in-usb_alloc_dev.patch new file mode 100644 index 0000000000..9ba76abd5b --- /dev/null +++ b/queue-5.10/usb-add-checks-for-snprintf-calls-in-usb_alloc_dev.patch @@ -0,0 +1,72 @@ +From a93600249cde6acd5f237ad85a660456a050a5b0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Fri, 21 Mar 2025 18:49:49 +0200 +Subject: usb: Add checks for snprintf() calls in usb_alloc_dev() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> + +[ Upstream commit 82fe5107fa3d21d6c3fba091c9dbc50495588630 ] + +When creating a device path in the driver the snprintf() takes +up to 16 characters long argument along with the additional up to +12 characters for the signed integer (as it can't see the actual limits) +and tries to pack this into 16 bytes array. GCC complains about that +when build with `make W=1`: + + drivers/usb/core/usb.c:705:25: note: ‘snprintf’ output between 3 and 28 bytes into a destination of size 16 + +Since everything works until now, let's just check for the potential +buffer overflow and bail out. It is most likely a never happen situation, +but at least it makes GCC happy. + +Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> +Link: https://lore.kernel.org/r/20250321164949.423957-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/usb/core/usb.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c +index c4cd9d46f9e3c..7be4e8f77a5ca 100644 +--- a/drivers/usb/core/usb.c ++++ b/drivers/usb/core/usb.c +@@ -704,15 +704,16 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, + dev_set_name(&dev->dev, "usb%d", bus->busnum); + root_hub = 1; + } else { ++ int n; ++ + /* match any labeling on the hubs; it's one-based */ + if (parent->devpath[0] == '0') { +- snprintf(dev->devpath, sizeof dev->devpath, +- "%d", port1); ++ n = snprintf(dev->devpath, sizeof(dev->devpath), "%d", port1); + /* Root ports are not counted in route string */ + dev->route = 0; + } else { +- snprintf(dev->devpath, sizeof dev->devpath, +- "%s.%d", parent->devpath, port1); ++ n = snprintf(dev->devpath, sizeof(dev->devpath), "%s.%d", ++ parent->devpath, port1); + /* Route string assumes hubs have less than 16 ports */ + if (port1 < 15) + dev->route = parent->route + +@@ -721,6 +722,11 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, + dev->route = parent->route + + (15 << ((parent->level - 1)*4)); + } ++ if (n >= sizeof(dev->devpath)) { ++ usb_put_hcd(bus_to_hcd(bus)); ++ usb_put_dev(dev); ++ return NULL; ++ } + + dev->dev.parent = &parent->dev; + dev_set_name(&dev->dev, "%d-%s", bus->busnum, dev->devpath); +-- +2.39.5 + diff --git a/queue-5.10/usb-cdc-wdm-avoid-setting-wdm_read-for-zlp-s.patch b/queue-5.10/usb-cdc-wdm-avoid-setting-wdm_read-for-zlp-s.patch new file mode 100644 index 0000000000..624153bbb7 --- /dev/null +++ b/queue-5.10/usb-cdc-wdm-avoid-setting-wdm_read-for-zlp-s.patch @@ -0,0 +1,114 @@ +From 5983a418d45f22518e566fc6fa0d5379da483fbd Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Thu, 3 Apr 2025 16:40:04 +0200 +Subject: usb: cdc-wdm: avoid setting WDM_READ for ZLP-s + +From: Robert Hodaszi <robert.hodaszi@digi.com> + +[ Upstream commit 387602d8a75574fafb451b7a8215e78dfd67ee63 ] + +Don't set WDM_READ flag in wdm_in_callback() for ZLP-s, otherwise when +userspace tries to poll for available data, it might - incorrectly - +believe there is something available, and when it tries to non-blocking +read it, it might get stuck in the read loop. + +For example this is what glib does for non-blocking read (briefly): + + 1. poll() + 2. if poll returns with non-zero, starts a read data loop: + a. loop on poll() (EINTR disabled) + b. if revents was set, reads data + I. if read returns with EINTR or EAGAIN, goto 2.a. + II. otherwise return with data + +So if ZLP sets WDM_READ (#1), we expect data, and try to read it (#2). +But as that was a ZLP, and we are doing non-blocking read, wdm_read() +returns with EAGAIN (#2.b.I), so loop again, and try to read again +(#2.a.). + +With glib, we might stuck in this loop forever, as EINTR is disabled +(#2.a). + +Signed-off-by: Robert Hodaszi <robert.hodaszi@digi.com> +Acked-by: Oliver Neukum <oneukum@suse.com> +Link: https://lore.kernel.org/r/20250403144004.3889125-1-robert.hodaszi@digi.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/usb/class/cdc-wdm.c | 23 +++++++++-------------- + 1 file changed, 9 insertions(+), 14 deletions(-) + +diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c +index aa91d561a0ace..26a59443d25f3 100644 +--- a/drivers/usb/class/cdc-wdm.c ++++ b/drivers/usb/class/cdc-wdm.c +@@ -89,7 +89,6 @@ struct wdm_device { + u16 wMaxCommand; + u16 wMaxPacketSize; + __le16 inum; +- int reslength; + int length; + int read; + int count; +@@ -201,6 +200,11 @@ static void wdm_in_callback(struct urb *urb) + if (desc->rerr == 0 && status != -EPIPE) + desc->rerr = status; + ++ if (length == 0) { ++ dev_dbg(&desc->intf->dev, "received ZLP\n"); ++ goto skip_zlp; ++ } ++ + if (length + desc->length > desc->wMaxCommand) { + /* The buffer would overflow */ + set_bit(WDM_OVERFLOW, &desc->flags); +@@ -209,18 +213,18 @@ static void wdm_in_callback(struct urb *urb) + if (!test_bit(WDM_OVERFLOW, &desc->flags)) { + memmove(desc->ubuf + desc->length, desc->inbuf, length); + desc->length += length; +- desc->reslength = length; + } + } + skip_error: + + if (desc->rerr) { + /* +- * Since there was an error, userspace may decide to not read +- * any data after poll'ing. ++ * If there was a ZLP or an error, userspace may decide to not ++ * read any data after poll'ing. + * We should respond to further attempts from the device to send + * data, so that we can get unstuck. + */ ++skip_zlp: + schedule_work(&desc->service_outs_intr); + } else { + set_bit(WDM_READ, &desc->flags); +@@ -571,15 +575,6 @@ static ssize_t wdm_read + goto retry; + } + +- if (!desc->reslength) { /* zero length read */ +- dev_dbg(&desc->intf->dev, "zero length - clearing WDM_READ\n"); +- clear_bit(WDM_READ, &desc->flags); +- rv = service_outstanding_interrupt(desc); +- spin_unlock_irq(&desc->iuspin); +- if (rv < 0) +- goto err; +- goto retry; +- } + cntr = desc->length; + spin_unlock_irq(&desc->iuspin); + } +@@ -839,7 +834,7 @@ static void service_interrupt_work(struct work_struct *work) + + spin_lock_irq(&desc->iuspin); + service_outstanding_interrupt(desc); +- if (!desc->resp_count) { ++ if (!desc->resp_count && (desc->length || desc->rerr)) { + set_bit(WDM_READ, &desc->flags); + wake_up(&desc->wait); + } +-- +2.39.5 + diff --git a/queue-5.10/usb-common-usb-conn-gpio-use-a-unique-name-for-usb-c.patch b/queue-5.10/usb-common-usb-conn-gpio-use-a-unique-name-for-usb-c.patch new file mode 100644 index 0000000000..4aee2b103b --- /dev/null +++ b/queue-5.10/usb-common-usb-conn-gpio-use-a-unique-name-for-usb-c.patch @@ -0,0 +1,93 @@ +From 620f1f95b541d69891f9beb287841fed8139cca1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Fri, 11 Apr 2025 16:33:26 +0800 +Subject: usb: common: usb-conn-gpio: use a unique name for usb connector + device + +From: Chance Yang <chance.yang@kneron.us> + +[ Upstream commit d4e5b10c55627e2f3fc9e5b337a28b4e2f02a55e ] + +The current implementation of the usb-conn-gpio driver uses a fixed +"usb-charger" name for all USB connector devices. This causes conflicts +in the power supply subsystem when multiple USB connectors are present, +as duplicate names are not allowed. + +Use IDA to manage unique IDs for naming usb connectors (e.g., +usb-charger-0, usb-charger-1). + +Signed-off-by: Chance Yang <chance.yang@kneron.us> +Link: https://lore.kernel.org/r/20250411-work-next-v3-1-7cd9aa80190c@kneron.us +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/usb/common/usb-conn-gpio.c | 25 ++++++++++++++++++++++--- + 1 file changed, 22 insertions(+), 3 deletions(-) + +diff --git a/drivers/usb/common/usb-conn-gpio.c b/drivers/usb/common/usb-conn-gpio.c +index 02446092520c8..f5a1981c9eb40 100644 +--- a/drivers/usb/common/usb-conn-gpio.c ++++ b/drivers/usb/common/usb-conn-gpio.c +@@ -20,6 +20,9 @@ + #include <linux/power_supply.h> + #include <linux/regulator/consumer.h> + #include <linux/usb/role.h> ++#include <linux/idr.h> ++ ++static DEFINE_IDA(usb_conn_ida); + + #define USB_GPIO_DEB_MS 20 /* ms */ + #define USB_GPIO_DEB_US ((USB_GPIO_DEB_MS) * 1000) /* us */ +@@ -29,6 +32,7 @@ + + struct usb_conn_info { + struct device *dev; ++ int conn_id; /* store the IDA-allocated ID */ + struct usb_role_switch *role_sw; + enum usb_role last_role; + struct regulator *vbus; +@@ -160,7 +164,17 @@ static int usb_conn_psy_register(struct usb_conn_info *info) + .of_node = dev->of_node, + }; + +- desc->name = "usb-charger"; ++ info->conn_id = ida_alloc(&usb_conn_ida, GFP_KERNEL); ++ if (info->conn_id < 0) ++ return info->conn_id; ++ ++ desc->name = devm_kasprintf(dev, GFP_KERNEL, "usb-charger-%d", ++ info->conn_id); ++ if (!desc->name) { ++ ida_free(&usb_conn_ida, info->conn_id); ++ return -ENOMEM; ++ } ++ + desc->properties = usb_charger_properties; + desc->num_properties = ARRAY_SIZE(usb_charger_properties); + desc->get_property = usb_charger_get_property; +@@ -168,8 +182,10 @@ static int usb_conn_psy_register(struct usb_conn_info *info) + cfg.drv_data = info; + + info->charger = devm_power_supply_register(dev, desc, &cfg); +- if (IS_ERR(info->charger)) +- dev_err(dev, "Unable to register charger\n"); ++ if (IS_ERR(info->charger)) { ++ dev_err(dev, "Unable to register charger %d\n", info->conn_id); ++ ida_free(&usb_conn_ida, info->conn_id); ++ } + + return PTR_ERR_OR_ZERO(info->charger); + } +@@ -296,6 +312,9 @@ static int usb_conn_remove(struct platform_device *pdev) + + cancel_delayed_work_sync(&info->dw_det); + ++ if (info->charger) ++ ida_free(&usb_conn_ida, info->conn_id); ++ + if (info->last_role == USB_ROLE_HOST && info->vbus) + regulator_disable(info->vbus); + +-- +2.39.5 + diff --git a/queue-5.10/usb-potential-integer-overflow-in-usbg_make_tpg.patch b/queue-5.10/usb-potential-integer-overflow-in-usbg_make_tpg.patch new file mode 100644 index 0000000000..1cb09cfd11 --- /dev/null +++ b/queue-5.10/usb-potential-integer-overflow-in-usbg_make_tpg.patch @@ -0,0 +1,53 @@ +From 6b24f0dcf0a32d3bbca26477ecd37eb7e496663d Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 15 Apr 2025 14:58:57 +0800 +Subject: usb: potential integer overflow in usbg_make_tpg() + +From: Chen Yufeng <chenyufeng@iie.ac.cn> + +[ Upstream commit 153874010354d050f62f8ae25cbb960c17633dc5 ] + +The variable tpgt in usbg_make_tpg() is defined as unsigned long and is +assigned to tpgt->tport_tpgt, which is defined as u16. This may cause an +integer overflow when tpgt is greater than USHRT_MAX (65535). I +haven't tried to trigger it myself, but it is possible to trigger it +by calling usbg_make_tpg() with a large value for tpgt. + +I modified the type of tpgt to match tpgt->tport_tpgt and adjusted the +relevant code accordingly. + +This patch is similar to commit 59c816c1f24d ("vhost/scsi: potential +memory corruption"). + +Signed-off-by: Chen Yufeng <chenyufeng@iie.ac.cn> +Link: https://lore.kernel.org/r/20250415065857.1619-1-chenyufeng@iie.ac.cn +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/usb/gadget/function/f_tcm.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c +index 7f825c961fb88..30c3a44abb183 100644 +--- a/drivers/usb/gadget/function/f_tcm.c ++++ b/drivers/usb/gadget/function/f_tcm.c +@@ -1325,14 +1325,14 @@ static struct se_portal_group *usbg_make_tpg(struct se_wwn *wwn, + struct usbg_tport *tport = container_of(wwn, struct usbg_tport, + tport_wwn); + struct usbg_tpg *tpg; +- unsigned long tpgt; ++ u16 tpgt; + int ret; + struct f_tcm_opts *opts; + unsigned i; + + if (strstr(name, "tpgt_") != name) + return ERR_PTR(-EINVAL); +- if (kstrtoul(name + 5, 0, &tpgt) || tpgt > UINT_MAX) ++ if (kstrtou16(name + 5, 0, &tpgt)) + return ERR_PTR(-EINVAL); + ret = -ENODEV; + mutex_lock(&tpg_instances_lock); +-- +2.39.5 + diff --git a/queue-5.10/usb-typec-displayport-receive-dp-status-update-nak-r.patch b/queue-5.10/usb-typec-displayport-receive-dp-status-update-nak-r.patch new file mode 100644 index 0000000000..491ca34edc --- /dev/null +++ b/queue-5.10/usb-typec-displayport-receive-dp-status-update-nak-r.patch @@ -0,0 +1,56 @@ +From 715b5f71a1d2592f59cbafbd508a59f33ed37e4c Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Sun, 9 Feb 2025 15:19:26 +0800 +Subject: usb: typec: displayport: Receive DP Status Update NAK request exit dp + altmode +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jos Wang <joswang@lenovo.com> + +[ Upstream commit b4b38ffb38c91afd4dc387608db26f6fc34ed40b ] + +Although some Type-C DRD devices that do not support the DP Sink +function (such as Huawei Mate 40Pro), the Source Port initiates +Enter Mode CMD, but the device responds to Enter Mode ACK, the +Source port then initiates DP Status Update CMD, and the device +responds to DP Status Update NAK. + +As PD2.0 spec ("6.4.4.3.4 Enter Mode Command"),A DR_Swap Message +Shall Not be sent during Modal Operation between the Port Partners. +At this time, the source port initiates DR_Swap message through the +"echo device > /sys/class/typec/port0/data_role" command to switch +the data role from host to device. The device will initiate a Hard +Reset for recovery, resulting in the failure of data role swap. + +Therefore, when DP Status Update NAK is received, Exit Mode CMD is +initiated to exit the currently entered DP altmode. + +Signed-off-by: Jos Wang <joswang@lenovo.com> +Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> +Link: https://lore.kernel.org/r/20250209071926.69625-1-joswang1221@gmail.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/usb/typec/altmodes/displayport.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/usb/typec/altmodes/displayport.c b/drivers/usb/typec/altmodes/displayport.c +index e0456e5e10b68..a577db01e67e1 100644 +--- a/drivers/usb/typec/altmodes/displayport.c ++++ b/drivers/usb/typec/altmodes/displayport.c +@@ -304,6 +304,10 @@ static int dp_altmode_vdm(struct typec_altmode *alt, + break; + case CMDT_RSP_NAK: + switch (cmd) { ++ case DP_CMD_STATUS_UPDATE: ++ if (typec_altmode_exit(alt)) ++ dev_err(&dp->alt->dev, "Exit Mode Failed!\n"); ++ break; + case DP_CMD_CONFIGURE: + dp->data.conf = 0; + ret = dp_altmode_configured(dp); +-- +2.39.5 + diff --git a/queue-5.10/usb-typec-tcpci_maxim-add-terminating-newlines-to-lo.patch b/queue-5.10/usb-typec-tcpci_maxim-add-terminating-newlines-to-lo.patch new file mode 100644 index 0000000000..c75a040d70 --- /dev/null +++ b/queue-5.10/usb-typec-tcpci_maxim-add-terminating-newlines-to-lo.patch @@ -0,0 +1,80 @@ +From 9e445b69644d64f1551b21089c76c8b7c75d3c8e Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Sun, 24 Jan 2021 22:39:47 +0800 +Subject: usb: typec: tcpci_maxim: add terminating newlines to logging + +From: Junlin Yang <yangjunlin@yulong.com> + +[ Upstream commit 7cbcd008e104d16849e5054e69f0a3d55eaeb664 ] + +Add terminating '\n' to the formats where missed. + +Reviewed-by: Guenter Roeck <linux@roeck-us.net> +Signed-off-by: Junlin Yang <yangjunlin@yulong.com> +Link: https://lore.kernel.org/r/20210124143947.1688-1-angkery@163.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Stable-dep-of: 0736299d090f ("usb: typec: tcpm/tcpci_maxim: Fix bounds check in process_rx()") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/usb/typec/tcpm/tcpci_maxim.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/usb/typec/tcpm/tcpci_maxim.c b/drivers/usb/typec/tcpm/tcpci_maxim.c +index 57c5c073139a9..df5887db46946 100644 +--- a/drivers/usb/typec/tcpm/tcpci_maxim.c ++++ b/drivers/usb/typec/tcpm/tcpci_maxim.c +@@ -151,7 +151,7 @@ static void process_rx(struct max_tcpci_chip *chip, u16 status) + */ + ret = regmap_raw_read(chip->data.regmap, TCPC_RX_BYTE_CNT, rx_buf, 2); + if (ret < 0) { +- dev_err(chip->dev, "TCPC_RX_BYTE_CNT read failed ret:%d", ret); ++ dev_err(chip->dev, "TCPC_RX_BYTE_CNT read failed ret:%d\n", ret); + return; + } + +@@ -160,13 +160,13 @@ static void process_rx(struct max_tcpci_chip *chip, u16 status) + + if (count == 0 || frame_type != TCPC_RX_BUF_FRAME_TYPE_SOP) { + max_tcpci_write16(chip, TCPC_ALERT, TCPC_ALERT_RX_STATUS); +- dev_err(chip->dev, "%s", count == 0 ? "error: count is 0" : ++ dev_err(chip->dev, "%s\n", count == 0 ? "error: count is 0" : + "error frame_type is not SOP"); + return; + } + + if (count > sizeof(struct pd_message) || count + 1 > TCPC_RECEIVE_BUFFER_LEN) { +- dev_err(chip->dev, "Invalid TCPC_RX_BYTE_CNT %d", count); ++ dev_err(chip->dev, "Invalid TCPC_RX_BYTE_CNT %d\n", count); + return; + } + +@@ -177,7 +177,7 @@ static void process_rx(struct max_tcpci_chip *chip, u16 status) + count += 1; + ret = regmap_raw_read(chip->data.regmap, TCPC_RX_BYTE_CNT, rx_buf, count); + if (ret < 0) { +- dev_err(chip->dev, "Error: TCPC_RX_BYTE_CNT read failed: %d", ret); ++ dev_err(chip->dev, "Error: TCPC_RX_BYTE_CNT read failed: %d\n", ret); + return; + } + +@@ -311,7 +311,7 @@ static irqreturn_t _max_tcpci_irq(struct max_tcpci_chip *chip, u16 status) + return ret; + + if (reg_status & TCPC_SINK_FAST_ROLE_SWAP) { +- dev_info(chip->dev, "FRS Signal"); ++ dev_info(chip->dev, "FRS Signal\n"); + tcpm_sink_frs(chip->port); + } + } +@@ -445,7 +445,7 @@ static int max_tcpci_probe(struct i2c_client *client, const struct i2c_device_id + max_tcpci_init_regs(chip); + chip->tcpci = tcpci_register_port(chip->dev, &chip->data); + if (IS_ERR(chip->tcpci)) { +- dev_err(&client->dev, "TCPCI port registration failed"); ++ dev_err(&client->dev, "TCPCI port registration failed\n"); + return PTR_ERR(chip->tcpci); + } + chip->port = tcpci_get_tcpm_port(chip->tcpci); +-- +2.39.5 + diff --git a/queue-5.10/usb-typec-tcpci_maxim-fix-uninitialized-return-varia.patch b/queue-5.10/usb-typec-tcpci_maxim-fix-uninitialized-return-varia.patch new file mode 100644 index 0000000000..4a69563819 --- /dev/null +++ b/queue-5.10/usb-typec-tcpci_maxim-fix-uninitialized-return-varia.patch @@ -0,0 +1,52 @@ +From 653802ec110e358d7ec70b4c239faab14d3ae545 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Wed, 28 Oct 2020 23:31:38 -0700 +Subject: usb: typec: tcpci_maxim: Fix uninitialized return variable + +From: Badhri Jagan Sridharan <badhri@google.com> + +[ Upstream commit 7695cae24b29edd2dbd3b3a77a7264cd6d9ca67a ] + +New smatch warnings: +drivers/usb/typec/tcpm/tcpci_maxim.c:324 max_tcpci_irq() error: uninitialized symbol 'irq_return'. +drivers/usb/typec/tcpm/tcpci_maxim.c:407 max_tcpci_probe() warn: passing zero to 'PTR_ERR' + +The change fixes the above warnings by initializing irq_return +and replacing IS_ERR_OR_NULL with IS_ERR. + +Reported-by: kernel test robot <lkp@intel.com> +Reported-by: Dan Carpenter <dan.carpenter@oracle.com> +Signed-off-by: Badhri Jagan Sridharan <badhri@google.com> +Link: https://lore.kernel.org/r/20201029063138.1429760-11-badhri@google.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Stable-dep-of: 0736299d090f ("usb: typec: tcpm/tcpci_maxim: Fix bounds check in process_rx()") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/usb/typec/tcpm/tcpci_maxim.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/usb/typec/tcpm/tcpci_maxim.c b/drivers/usb/typec/tcpm/tcpci_maxim.c +index 723d7dd38f75b..6bf0d1ebc1fae 100644 +--- a/drivers/usb/typec/tcpm/tcpci_maxim.c ++++ b/drivers/usb/typec/tcpm/tcpci_maxim.c +@@ -344,7 +344,7 @@ static irqreturn_t max_tcpci_irq(int irq, void *dev_id) + { + struct max_tcpci_chip *chip = dev_id; + u16 status; +- irqreturn_t irq_return; ++ irqreturn_t irq_return = IRQ_HANDLED; + int ret; + + if (!chip->port) +@@ -444,7 +444,7 @@ static int max_tcpci_probe(struct i2c_client *client, const struct i2c_device_id + + max_tcpci_init_regs(chip); + chip->tcpci = tcpci_register_port(chip->dev, &chip->data); +- if (IS_ERR_OR_NULL(chip->tcpci)) { ++ if (IS_ERR(chip->tcpci)) { + dev_err(&client->dev, "TCPCI port registration failed"); + ret = PTR_ERR(chip->tcpci); + return PTR_ERR(chip->tcpci); +-- +2.39.5 + diff --git a/queue-5.10/usb-typec-tcpci_maxim-remove-redundant-assignment.patch b/queue-5.10/usb-typec-tcpci_maxim-remove-redundant-assignment.patch new file mode 100644 index 0000000000..50398fa35b --- /dev/null +++ b/queue-5.10/usb-typec-tcpci_maxim-remove-redundant-assignment.patch @@ -0,0 +1,38 @@ +From 3df68b5b305c47477240b7b1429c9eaabfc10779 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Sun, 24 Jan 2021 22:38:53 +0800 +Subject: usb: typec: tcpci_maxim: remove redundant assignment + +From: Junlin Yang <yangjunlin@yulong.com> + +[ Upstream commit a63b53e19bdffd9338fab4536e8bc422ea812b4d ] + +PTR_ERR(chip->tcpci) has been used as a return value, +it is not necessary to assign it to ret, so remove it. + +Reviewed-by: Guenter Roeck <linux@roeck-us.net> +Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> +Signed-off-by: Junlin Yang <yangjunlin@yulong.com> +Link: https://lore.kernel.org/r/20210124143853.1630-1-angkery@163.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Stable-dep-of: 0736299d090f ("usb: typec: tcpm/tcpci_maxim: Fix bounds check in process_rx()") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/usb/typec/tcpm/tcpci_maxim.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/usb/typec/tcpm/tcpci_maxim.c b/drivers/usb/typec/tcpm/tcpci_maxim.c +index 6bf0d1ebc1fae..57c5c073139a9 100644 +--- a/drivers/usb/typec/tcpm/tcpci_maxim.c ++++ b/drivers/usb/typec/tcpm/tcpci_maxim.c +@@ -446,7 +446,6 @@ static int max_tcpci_probe(struct i2c_client *client, const struct i2c_device_id + chip->tcpci = tcpci_register_port(chip->dev, &chip->data); + if (IS_ERR(chip->tcpci)) { + dev_err(&client->dev, "TCPCI port registration failed"); +- ret = PTR_ERR(chip->tcpci); + return PTR_ERR(chip->tcpci); + } + chip->port = tcpci_get_tcpm_port(chip->tcpci); +-- +2.39.5 + diff --git a/queue-5.10/usb-typec-tcpm-tcpci_maxim-fix-bounds-check-in-proce.patch b/queue-5.10/usb-typec-tcpm-tcpci_maxim-fix-bounds-check-in-proce.patch new file mode 100644 index 0000000000..3fdbb96c56 --- /dev/null +++ b/queue-5.10/usb-typec-tcpm-tcpci_maxim-fix-bounds-check-in-proce.patch @@ -0,0 +1,50 @@ +From 3d37e19be512f26fb4cfd477b5f69213f1ca5faa Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Fri, 2 May 2025 16:57:03 -0700 +Subject: usb: typec: tcpm/tcpci_maxim: Fix bounds check in process_rx() + +From: Amit Sunil Dhamne <amitsd@google.com> + +[ Upstream commit 0736299d090f5c6a1032678705c4bc0a9511a3db ] + +Register read of TCPC_RX_BYTE_CNT returns the total size consisting of: + + PD message (pending read) size + 1 Byte for Frame Type (SOP*) + +This is validated against the max PD message (`struct pd_message`) size +without accounting for the extra byte for the frame type. Note that the +struct pd_message does not contain a field for the frame_type. This +results in false negatives when the "PD message (pending read)" is equal +to the max PD message size. + +Fixes: 6f413b559f86 ("usb: typec: tcpci_maxim: Chip level TCPC driver") +Signed-off-by: Amit Sunil Dhamne <amitsd@google.com> +Signed-off-by: Badhri Jagan Sridharan <badhri@google.com> +Reviewed-by: Kyle Tso <kyletso@google.com> +Cc: stable <stable@kernel.org> +Link: https://lore.kernel.org/stable/20250502-b4-new-fix-pd-rx-count-v1-1-e5711ed09b3d%40google.com +Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> +Link: https://lore.kernel.org/r/20250502-b4-new-fix-pd-rx-count-v1-1-e5711ed09b3d@google.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/usb/typec/tcpm/tcpci_maxim.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/usb/typec/tcpm/tcpci_maxim.c b/drivers/usb/typec/tcpm/tcpci_maxim.c +index df5887db46946..d694094084f85 100644 +--- a/drivers/usb/typec/tcpm/tcpci_maxim.c ++++ b/drivers/usb/typec/tcpm/tcpci_maxim.c +@@ -165,7 +165,8 @@ static void process_rx(struct max_tcpci_chip *chip, u16 status) + return; + } + +- if (count > sizeof(struct pd_message) || count + 1 > TCPC_RECEIVE_BUFFER_LEN) { ++ if (count > sizeof(struct pd_message) + 1 || ++ count + 1 > TCPC_RECEIVE_BUFFER_LEN) { + dev_err(chip->dev, "Invalid TCPC_RX_BYTE_CNT %d\n", count); + return; + } +-- +2.39.5 + diff --git a/queue-5.10/usb-usbtmc-add-usbtmc_ioctl_get_stb.patch b/queue-5.10/usb-usbtmc-add-usbtmc_ioctl_get_stb.patch new file mode 100644 index 0000000000..4fedf15297 --- /dev/null +++ b/queue-5.10/usb-usbtmc-add-usbtmc_ioctl_get_stb.patch @@ -0,0 +1,60 @@ +From 5ec45ce09425bdcde3031d74afeb448ec7783e44 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 15 Dec 2020 16:56:19 +0100 +Subject: USB: usbtmc: Add USBTMC_IOCTL_GET_STB + +From: Dave Penkler <dpenkler@gmail.com> + +[ Upstream commit c9784e23c1020e63d6dba5e10ca8bf3d8b85c19c ] + +This new ioctl reads the status byte (STB) from the device and returns +the STB unmodified to the application. The srq_asserted bit is not taken +into account and not changed. + +This ioctl is useful to support non USBTMC-488 compliant devices. + +Tested-by: Jian-Wei Wu <jian-wei_wu@keysight.com> +Reviewed-by: Guido Kiener <guido.kiener@rohde-schwarz.com> +Signed-off-by: Dave Penkler <dpenkler@gmail.com> +Link: https://lore.kernel.org/r/20201215155621.9592-3-dpenkler@gmail.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Stable-dep-of: acb3dac2805d ("usb: usbtmc: Fix read_stb function and get_stb ioctl") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/usb/class/usbtmc.c | 6 ++++++ + include/uapi/linux/usb/tmc.h | 2 ++ + 2 files changed, 8 insertions(+) + +diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c +index bfd99d461f813..093040ea7e065 100644 +--- a/drivers/usb/class/usbtmc.c ++++ b/drivers/usb/class/usbtmc.c +@@ -2173,6 +2173,12 @@ static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) + file_data->auto_abort = !!tmp_byte; + break; + ++ case USBTMC_IOCTL_GET_STB: ++ retval = usbtmc_get_stb(file_data, &tmp_byte); ++ if (retval > 0) ++ retval = put_user(tmp_byte, (__u8 __user *)arg); ++ break; ++ + case USBTMC_IOCTL_CANCEL_IO: + retval = usbtmc_ioctl_cancel_io(file_data); + break; +diff --git a/include/uapi/linux/usb/tmc.h b/include/uapi/linux/usb/tmc.h +index fdd4d88a7b95d..1e7878fe591f4 100644 +--- a/include/uapi/linux/usb/tmc.h ++++ b/include/uapi/linux/usb/tmc.h +@@ -102,6 +102,8 @@ struct usbtmc_message { + #define USBTMC_IOCTL_MSG_IN_ATTR _IOR(USBTMC_IOC_NR, 24, __u8) + #define USBTMC_IOCTL_AUTO_ABORT _IOW(USBTMC_IOC_NR, 25, __u8) + ++#define USBTMC_IOCTL_GET_STB _IOR(USBTMC_IOC_NR, 26, __u8) ++ + /* Cancel and cleanup asynchronous calls */ + #define USBTMC_IOCTL_CANCEL_IO _IO(USBTMC_IOC_NR, 35) + #define USBTMC_IOCTL_CLEANUP_IO _IO(USBTMC_IOC_NR, 36) +-- +2.39.5 + diff --git a/queue-5.10/usb-usbtmc-fix-read_stb-function-and-get_stb-ioctl.patch b/queue-5.10/usb-usbtmc-fix-read_stb-function-and-get_stb-ioctl.patch new file mode 100644 index 0000000000..f7e22e27cf --- /dev/null +++ b/queue-5.10/usb-usbtmc-fix-read_stb-function-and-get_stb-ioctl.patch @@ -0,0 +1,75 @@ +From 9b826392006da06fa29322c4dd553af139bfa944 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Wed, 21 May 2025 14:16:55 +0200 +Subject: usb: usbtmc: Fix read_stb function and get_stb ioctl + +From: Dave Penkler <dpenkler@gmail.com> + +[ Upstream commit acb3dac2805d3342ded7dbbd164add32bbfdf21c ] + +The usbtmc488_ioctl_read_stb function relied on a positive return from +usbtmc_get_stb to reset the srq condition in the driver. The +USBTMC_IOCTL_GET_STB case tested for a positive return to return the stb +to the user. + +Commit: <cac01bd178d6> ("usb: usbtmc: Fix erroneous get_stb ioctl +error returns") changed the return value of usbtmc_get_stb to 0 on +success instead of returning the value of usb_control_msg which is +positive in the normal case. This change caused the function +usbtmc488_ioctl_read_stb and the USBTMC_IOCTL_GET_STB ioctl to no +longer function correctly. + +Change the test in usbtmc488_ioctl_read_stb to test for failure +first and return the failure code immediately. +Change the test for the USBTMC_IOCTL_GET_STB ioctl to test for 0 +instead of a positive value. + +Fixes: cac01bd178d6 ("usb: usbtmc: Fix erroneous get_stb ioctl error returns") +Cc: stable@vger.kernel.org +Signed-off-by: Dave Penkler <dpenkler@gmail.com> +Link: https://lore.kernel.org/r/20250521121656.18174-3-dpenkler@gmail.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/usb/class/usbtmc.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c +index 093040ea7e065..fe1152e7053f4 100644 +--- a/drivers/usb/class/usbtmc.c ++++ b/drivers/usb/class/usbtmc.c +@@ -565,14 +565,15 @@ static int usbtmc488_ioctl_read_stb(struct usbtmc_file_data *file_data, + + rv = usbtmc_get_stb(file_data, &stb); + +- if (rv > 0) { +- srq_asserted = atomic_xchg(&file_data->srq_asserted, +- srq_asserted); +- if (srq_asserted) +- stb |= 0x40; /* Set RQS bit */ ++ if (rv < 0) ++ return rv; ++ ++ srq_asserted = atomic_xchg(&file_data->srq_asserted, srq_asserted); ++ if (srq_asserted) ++ stb |= 0x40; /* Set RQS bit */ ++ ++ rv = put_user(stb, (__u8 __user *)arg); + +- rv = put_user(stb, (__u8 __user *)arg); +- } + return rv; + + } +@@ -2175,7 +2176,7 @@ static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) + + case USBTMC_IOCTL_GET_STB: + retval = usbtmc_get_stb(file_data, &tmp_byte); +- if (retval > 0) ++ if (!retval) + retval = put_user(tmp_byte, (__u8 __user *)arg); + break; + +-- +2.39.5 + diff --git a/queue-5.10/usb-usbtmc-fix-reading-stale-status-byte.patch b/queue-5.10/usb-usbtmc-fix-reading-stale-status-byte.patch new file mode 100644 index 0000000000..c4a068e9b9 --- /dev/null +++ b/queue-5.10/usb-usbtmc-fix-reading-stale-status-byte.patch @@ -0,0 +1,126 @@ +From e729dd966dc7c2b933cc0e9aaf0e1d9f7a22735b Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 15 Dec 2020 16:56:18 +0100 +Subject: USB: usbtmc: Fix reading stale status byte + +From: Dave Penkler <dpenkler@gmail.com> + +[ Upstream commit 3c1037e2b6a94898f81ed1a68bea146a9db750a5 ] + +The ioctl USBTMC488_IOCTL_READ_STB either returns a cached status byte +(STB) sent by the device due to a service request (SRQ) condition or +the STB obtained from a query to the device with a READ_STATUS_BYTE +control message. + +When the query is interrupted by an SRQ message on the interrupt pipe, +the ioctl still returns the requested STB while the STB of the +out-of-band SRQ message is cached for the next call of this +ioctl. However the cached SRQ STB represents a state that was previous +to the last returned STB. Furthermore the cached SRQ STB can be stale +and not reflect the current state of the device. + +The fixed ioctl now always reads the STB from the device and if the +associated file descriptor has the srq_asserted bit set it ors in the +RQS bit to the returned STB and clears the srq_asserted bit conformant +to subclass USB488 devices. + +Tested-by: Jian-Wei Wu <jian-wei_wu@keysight.com> +Reviewed-by: Guido Kiener <guido.kiener@rohde-schwarz.com> +Signed-off-by: Dave Penkler <dpenkler@gmail.com> +Link: https://lore.kernel.org/r/20201215155621.9592-2-dpenkler@gmail.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Stable-dep-of: acb3dac2805d ("usb: usbtmc: Fix read_stb function and get_stb ioctl") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/usb/class/usbtmc.c | 46 +++++++++++++++++++++----------------- + 1 file changed, 25 insertions(+), 21 deletions(-) + +diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c +index ff706f48e0ada..bfd99d461f813 100644 +--- a/drivers/usb/class/usbtmc.c ++++ b/drivers/usb/class/usbtmc.c +@@ -475,15 +475,12 @@ static int usbtmc_ioctl_abort_bulk_out(struct usbtmc_device_data *data) + return usbtmc_ioctl_abort_bulk_out_tag(data, data->bTag_last_write); + } + +-static int usbtmc488_ioctl_read_stb(struct usbtmc_file_data *file_data, +- void __user *arg) ++static int usbtmc_get_stb(struct usbtmc_file_data *file_data, __u8 *stb) + { + struct usbtmc_device_data *data = file_data->data; + struct device *dev = &data->intf->dev; +- int srq_asserted = 0; + u8 *buffer; + u8 tag; +- __u8 stb; + int rv; + long wait_rv; + unsigned long expire; +@@ -491,19 +488,6 @@ static int usbtmc488_ioctl_read_stb(struct usbtmc_file_data *file_data, + dev_dbg(dev, "Enter ioctl_read_stb iin_ep_present: %d\n", + data->iin_ep_present); + +- spin_lock_irq(&data->dev_lock); +- srq_asserted = atomic_xchg(&file_data->srq_asserted, srq_asserted); +- if (srq_asserted) { +- /* a STB with SRQ is already received */ +- stb = file_data->srq_byte; +- spin_unlock_irq(&data->dev_lock); +- rv = put_user(stb, (__u8 __user *)arg); +- dev_dbg(dev, "stb:0x%02x with srq received %d\n", +- (unsigned int)stb, rv); +- return rv; +- } +- spin_unlock_irq(&data->dev_lock); +- + buffer = kmalloc(8, GFP_KERNEL); + if (!buffer) + return -ENOMEM; +@@ -552,13 +536,12 @@ static int usbtmc488_ioctl_read_stb(struct usbtmc_file_data *file_data, + data->iin_bTag, tag); + } + +- stb = data->bNotify2; ++ *stb = data->bNotify2; + } else { +- stb = buffer[2]; ++ *stb = buffer[2]; + } + +- rv = put_user(stb, (__u8 __user *)arg); +- dev_dbg(dev, "stb:0x%02x received %d\n", (unsigned int)stb, rv); ++ dev_dbg(dev, "stb:0x%02x received %d\n", (unsigned int)*stb, rv); + + rv = 0; + +@@ -573,6 +556,27 @@ static int usbtmc488_ioctl_read_stb(struct usbtmc_file_data *file_data, + return rv; + } + ++static int usbtmc488_ioctl_read_stb(struct usbtmc_file_data *file_data, ++ void __user *arg) ++{ ++ int srq_asserted = 0; ++ __u8 stb; ++ int rv; ++ ++ rv = usbtmc_get_stb(file_data, &stb); ++ ++ if (rv > 0) { ++ srq_asserted = atomic_xchg(&file_data->srq_asserted, ++ srq_asserted); ++ if (srq_asserted) ++ stb |= 0x40; /* Set RQS bit */ ++ ++ rv = put_user(stb, (__u8 __user *)arg); ++ } ++ return rv; ++ ++} ++ + static int usbtmc488_ioctl_wait_srq(struct usbtmc_file_data *file_data, + __u32 __user *arg) + { +-- +2.39.5 + diff --git a/queue-5.10/vmci-check-context-notify_page-after-call-to-get_use.patch b/queue-5.10/vmci-check-context-notify_page-after-call-to-get_use.patch new file mode 100644 index 0000000000..6a2781fff5 --- /dev/null +++ b/queue-5.10/vmci-check-context-notify_page-after-call-to-get_use.patch @@ -0,0 +1,56 @@ +From 49cb8be15d228994eb482bae35205dc69f2f73cd Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Mon, 28 Nov 2022 15:18:25 -0500 +Subject: VMCI: check context->notify_page after call to get_user_pages_fast() + to avoid GPF + +From: George Kennedy <george.kennedy@oracle.com> + +[ Upstream commit 1a726cb47fd204109c767409fa9ca15a96328f14 ] + +The call to get_user_pages_fast() in vmci_host_setup_notify() can return +NULL context->notify_page causing a GPF. To avoid GPF check if +context->notify_page == NULL and return error if so. + +general protection fault, probably for non-canonical address + 0xe0009d1000000060: 0000 [#1] PREEMPT SMP KASAN NOPTI +KASAN: maybe wild-memory-access in range [0x0005088000000300- + 0x0005088000000307] +CPU: 2 PID: 26180 Comm: repro_34802241 Not tainted 6.1.0-rc4 #1 +Hardware name: Red Hat KVM, BIOS 1.15.0-2.module+el8.6.0 04/01/2014 +RIP: 0010:vmci_ctx_check_signal_notify+0x91/0xe0 +Call Trace: + <TASK> + vmci_host_unlocked_ioctl+0x362/0x1f40 + __x64_sys_ioctl+0x1a1/0x230 + do_syscall_64+0x3a/0x90 + entry_SYSCALL_64_after_hwframe+0x63/0xcd + +Fixes: a1d88436d53a ("VMCI: Fix two UVA mapping bugs") +Reported-by: syzkaller <syzkaller@googlegroups.com> +Signed-off-by: George Kennedy <george.kennedy@oracle.com> +Reviewed-by: Vishnu Dasa <vdasa@vmware.com> +Link: https://lore.kernel.org/r/1669666705-24012-1-git-send-email-george.kennedy@oracle.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Stable-dep-of: 1bd6406fb5f3 ("VMCI: fix race between vmci_host_setup_notify and vmci_ctx_unset_notify") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/misc/vmw_vmci/vmci_host.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/misc/vmw_vmci/vmci_host.c b/drivers/misc/vmw_vmci/vmci_host.c +index 4a903770b8e1d..cc6da9e5a542b 100644 +--- a/drivers/misc/vmw_vmci/vmci_host.c ++++ b/drivers/misc/vmw_vmci/vmci_host.c +@@ -248,6 +248,8 @@ static int vmci_host_setup_notify(struct vmci_ctx *context, + context->notify_page = NULL; + return VMCI_ERROR_GENERIC; + } ++ if (context->notify_page == NULL) ++ return VMCI_ERROR_UNAVAILABLE; + + /* + * Map the locked page and set up notify pointer. +-- +2.39.5 + diff --git a/queue-5.10/vmci-fix-race-between-vmci_host_setup_notify-and-vmc.patch b/queue-5.10/vmci-fix-race-between-vmci_host_setup_notify-and-vmc.patch new file mode 100644 index 0000000000..c0437928dc --- /dev/null +++ b/queue-5.10/vmci-fix-race-between-vmci_host_setup_notify-and-vmc.patch @@ -0,0 +1,102 @@ +From 74453c1b4020355ff0272612dea7db3af34fadf3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Sat, 10 May 2025 11:30:40 +0800 +Subject: VMCI: fix race between vmci_host_setup_notify and + vmci_ctx_unset_notify + +From: Wupeng Ma <mawupeng1@huawei.com> + +[ Upstream commit 1bd6406fb5f36c2bb1e96e27d4c3e9f4d09edde4 ] + +During our test, it is found that a warning can be trigger in try_grab_folio +as follow: + + ------------[ cut here ]------------ + WARNING: CPU: 0 PID: 1678 at mm/gup.c:147 try_grab_folio+0x106/0x130 + Modules linked in: + CPU: 0 UID: 0 PID: 1678 Comm: syz.3.31 Not tainted 6.15.0-rc5 #163 PREEMPT(undef) + RIP: 0010:try_grab_folio+0x106/0x130 + Call Trace: + <TASK> + follow_huge_pmd+0x240/0x8e0 + follow_pmd_mask.constprop.0.isra.0+0x40b/0x5c0 + follow_pud_mask.constprop.0.isra.0+0x14a/0x170 + follow_page_mask+0x1c2/0x1f0 + __get_user_pages+0x176/0x950 + __gup_longterm_locked+0x15b/0x1060 + ? gup_fast+0x120/0x1f0 + gup_fast_fallback+0x17e/0x230 + get_user_pages_fast+0x5f/0x80 + vmci_host_unlocked_ioctl+0x21c/0xf80 + RIP: 0033:0x54d2cd + ---[ end trace 0000000000000000 ]--- + +Digging into the source, context->notify_page may init by get_user_pages_fast +and can be seen in vmci_ctx_unset_notify which will try to put_page. However +get_user_pages_fast is not finished here and lead to following +try_grab_folio warning. The race condition is shown as follow: + +cpu0 cpu1 +vmci_host_do_set_notify +vmci_host_setup_notify +get_user_pages_fast(uva, 1, FOLL_WRITE, &context->notify_page); +lockless_pages_from_mm +gup_pgd_range +gup_huge_pmd // update &context->notify_page + vmci_host_do_set_notify + vmci_ctx_unset_notify + notify_page = context->notify_page; + if (notify_page) + put_page(notify_page); // page is freed +__gup_longterm_locked +__get_user_pages +follow_trans_huge_pmd +try_grab_folio // warn here + +To slove this, use local variable page to make notify_page can be seen +after finish get_user_pages_fast. + +Fixes: a1d88436d53a ("VMCI: Fix two UVA mapping bugs") +Cc: stable <stable@kernel.org> +Closes: https://lore.kernel.org/all/e91da589-ad57-3969-d979-879bbd10dddd@huawei.com/ +Signed-off-by: Wupeng Ma <mawupeng1@huawei.com> +Link: https://lore.kernel.org/r/20250510033040.901582-1-mawupeng1@huawei.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/misc/vmw_vmci/vmci_host.c | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +diff --git a/drivers/misc/vmw_vmci/vmci_host.c b/drivers/misc/vmw_vmci/vmci_host.c +index cc6da9e5a542b..e7965ee6bdba9 100644 +--- a/drivers/misc/vmw_vmci/vmci_host.c ++++ b/drivers/misc/vmw_vmci/vmci_host.c +@@ -227,6 +227,7 @@ static int drv_cp_harray_to_user(void __user *user_buf_uva, + static int vmci_host_setup_notify(struct vmci_ctx *context, + unsigned long uva) + { ++ struct page *page; + int retval; + + if (context->notify_page) { +@@ -243,13 +244,11 @@ static int vmci_host_setup_notify(struct vmci_ctx *context, + /* + * Lock physical page backing a given user VA. + */ +- retval = get_user_pages_fast(uva, 1, FOLL_WRITE, &context->notify_page); +- if (retval != 1) { +- context->notify_page = NULL; ++ retval = get_user_pages_fast(uva, 1, FOLL_WRITE, &page); ++ if (retval != 1) + return VMCI_ERROR_GENERIC; +- } +- if (context->notify_page == NULL) +- return VMCI_ERROR_UNAVAILABLE; ++ ++ context->notify_page = page; + + /* + * Map the locked page and set up notify pointer. +-- +2.39.5 + |