diff options
59 files changed, 5721 insertions, 0 deletions
diff --git a/queue-5.15/alsa-hda-add-new-pci-id-for-amd-gpu-display-hd-audio.patch b/queue-5.15/alsa-hda-add-new-pci-id-for-amd-gpu-display-hd-audio.patch new file mode 100644 index 0000000000..fc7d7c4bb2 --- /dev/null +++ b/queue-5.15/alsa-hda-add-new-pci-id-for-amd-gpu-display-hd-audio.patch @@ -0,0 +1,37 @@ +From c80ef7016d2f9c0dfe73582aad4f47b66e022d78 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 cc8c066327b6c..c69f4e5989d4f 100644 +--- a/sound/pci/hda/hda_intel.c ++++ b/sound/pci/hda/hda_intel.c +@@ -2731,6 +2731,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.15/alsa-hda-ignore-unsol-events-for-cards-being-shut-do.patch b/queue-5.15/alsa-hda-ignore-unsol-events-for-cards-being-shut-do.patch new file mode 100644 index 0000000000..0c5240f7a4 --- /dev/null +++ b/queue-5.15/alsa-hda-ignore-unsol-events-for-cards-being-shut-do.patch @@ -0,0 +1,48 @@ +From d9b2e224ff65f4df6d1b67e49955a40ec286761b 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 8e35009ec25cb..a22f723ab3ab6 100644 +--- a/sound/pci/hda/hda_bind.c ++++ b/sound/pci/hda/hda_bind.c +@@ -45,7 +45,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.15/alsa-usb-audio-add-a-quirk-for-lenovo-thinkpad-thund.patch b/queue-5.15/alsa-usb-audio-add-a-quirk-for-lenovo-thinkpad-thund.patch new file mode 100644 index 0000000000..95f5d9b062 --- /dev/null +++ b/queue-5.15/alsa-usb-audio-add-a-quirk-for-lenovo-thinkpad-thund.patch @@ -0,0 +1,39 @@ +From bc8119a5ff12e462555798b891adf01e99b6f316 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 27 May 2025 12:26:56 -0500 +Subject: ALSA: usb-audio: Add a quirk for Lenovo Thinkpad Thunderbolt 3 dock + +From: Mario Limonciello <mario.limonciello@amd.com> + +[ Upstream commit 4919353c7789b8047e06a9b2b943f775a8f72883 ] + +The audio controller in the Lenovo Thinkpad Thunderbolt 3 dock doesn't +support reading the sampling rate. + +Add a quirk for it. + +Suggested-by: Takashi Iwai <tiwai@suse.de> +Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> +Link: https://patch.msgid.link/20250527172657.1972565-1-superm1@kernel.org +Signed-off-by: Takashi Iwai <tiwai@suse.de> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + sound/usb/quirks.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c +index 488fcdbb6a2d4..f24a334316a29 100644 +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -1877,6 +1877,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { + QUIRK_FLAG_DISABLE_AUTOSUSPEND), + DEVICE_FLG(0x17aa, 0x104d, /* Lenovo ThinkStation P620 Internal Speaker + Front Headset */ + QUIRK_FLAG_DISABLE_AUTOSUSPEND), ++ DEVICE_FLG(0x17ef, 0x3083, /* Lenovo TBT3 dock */ ++ QUIRK_FLAG_GET_SAMPLE_RATE), + DEVICE_FLG(0x1852, 0x5062, /* Luxman D-08u */ + QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY), + DEVICE_FLG(0x1852, 0x5065, /* Luxman DA-06 */ +-- +2.39.5 + diff --git a/queue-5.15/asoc-codec-wcd9335-convert-to-gpio-descriptors.patch b/queue-5.15/asoc-codec-wcd9335-convert-to-gpio-descriptors.patch new file mode 100644 index 0000000000..928daa49c8 --- /dev/null +++ b/queue-5.15/asoc-codec-wcd9335-convert-to-gpio-descriptors.patch @@ -0,0 +1,85 @@ +From 01d44ef331f5fa633cded81b14cb22b1574b1072 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 dc4ce2c3f2188..08b7ca26c3c97 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.15/asoc-codecs-wcd9335-fix-missing-free-of-regulator-su.patch b/queue-5.15/asoc-codecs-wcd9335-fix-missing-free-of-regulator-su.patch new file mode 100644 index 0000000000..a995d4b435 --- /dev/null +++ b/queue-5.15/asoc-codecs-wcd9335-fix-missing-free-of-regulator-su.patch @@ -0,0 +1,88 @@ +From f790b9c961884c7660fc8757b9b6655f869daf5a 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 08b7ca26c3c97..f20d0c9e91e49 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.15/asoc-codecs-wcd9335-handle-nicer-probe-deferral-and-.patch b/queue-5.15/asoc-codecs-wcd9335-handle-nicer-probe-deferral-and-.patch new file mode 100644 index 0000000000..c7e3fe22df --- /dev/null +++ b/queue-5.15/asoc-codecs-wcd9335-handle-nicer-probe-deferral-and-.patch @@ -0,0 +1,85 @@ +From e2bc0e5dd72e5873642518be3eb38166b4daa53b 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 075ed20e9fad8..dc4ce2c3f2188 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.15/bcache-fix-null-pointer-in-cache_set_flush.patch b/queue-5.15/bcache-fix-null-pointer-in-cache_set_flush.patch new file mode 100644 index 0000000000..b0d15be379 --- /dev/null +++ b/queue-5.15/bcache-fix-null-pointer-in-cache_set_flush.patch @@ -0,0 +1,151 @@ +From 5d6df08cd7ac36160d55ef3fa01b1478a116c18a 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 4b79b793cb806..7e0176e43acec 100644 +--- a/drivers/md/bcache/super.c ++++ b/drivers/md/bcache/super.c +@@ -1746,7 +1746,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.15/ceph-fix-possible-integer-overflow-in-ceph_zero_obje.patch b/queue-5.15/ceph-fix-possible-integer-overflow-in-ceph_zero_obje.patch new file mode 100644 index 0000000000..ab777db9d5 --- /dev/null +++ b/queue-5.15/ceph-fix-possible-integer-overflow-in-ceph_zero_obje.patch @@ -0,0 +1,40 @@ +From ff240b7e5542ff362f35929420d1ccc5158ef241 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 f3fba3d27efa6..e92a10ba58b3f 100644 +--- a/fs/ceph/file.c ++++ b/fs/ceph/file.c +@@ -2032,7 +2032,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.15/cifs-fix-cifs_query_path_info-for-windows-nt-servers.patch b/queue-5.15/cifs-fix-cifs_query_path_info-for-windows-nt-servers.patch new file mode 100644 index 0000000000..7d8bd9de2e --- /dev/null +++ b/queue-5.15/cifs-fix-cifs_query_path_info-for-windows-nt-servers.patch @@ -0,0 +1,55 @@ +From 6fb92aabaf285ae9e18d96eaa27e81f2ae8aa50d 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 33328eae03d7a..a3d37e7769e61 100644 +--- a/fs/cifs/misc.c ++++ b/fs/cifs/misc.c +@@ -297,6 +297,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.15/clk-ti-am43xx-add-clkctrl-data-for-am43xx-adc1.patch b/queue-5.15/clk-ti-am43xx-add-clkctrl-data-for-am43xx-adc1.patch new file mode 100644 index 0000000000..a39ae39f69 --- /dev/null +++ b/queue-5.15/clk-ti-am43xx-add-clkctrl-data-for-am43xx-adc1.patch @@ -0,0 +1,51 @@ +From 72e8a7415f56a3261af7a16be93a0d85cd93662c Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Fri, 15 Oct 2021 10:14:19 +0200 +Subject: clk: ti: am43xx: Add clkctrl data for am43xx ADC1 + +From: Miquel Raynal <miquel.raynal@bootlin.com> + +[ Upstream commit 59139ada4a7eacd4db378ee40a3d6ffbf1d0d72f ] + +Declare ADC1 clkctrl which feeds the magnetic-reader/ADC1 hardware +module. + +Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> +Acked-by: Stephen Boyd <sboyd@kernel.org> +Acked-by: Tony Lindgren <tony@atomide.com> +Signed-off-by: Lee Jones <lee.jones@linaro.org> +Link: https://lore.kernel.org/r/20211015081506.933180-2-miquel.raynal@bootlin.com +Stable-dep-of: d52b9b7e2f10 ("media: imx-jpeg: Drop the first error frames") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/clk/ti/clk-43xx.c | 1 + + include/dt-bindings/clock/am4.h | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/drivers/clk/ti/clk-43xx.c b/drivers/clk/ti/clk-43xx.c +index 46c0add995700..6e97a541cfd36 100644 +--- a/drivers/clk/ti/clk-43xx.c ++++ b/drivers/clk/ti/clk-43xx.c +@@ -116,6 +116,7 @@ static const struct omap_clkctrl_reg_data am4_l3s_clkctrl_regs[] __initconst = { + { AM4_L3S_VPFE0_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, + { AM4_L3S_VPFE1_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, + { AM4_L3S_GPMC_CLKCTRL, NULL, CLKF_SW_SUP, "l3s_gclk" }, ++ { AM4_L3S_ADC1_CLKCTRL, NULL, CLKF_SW_SUP, "l3s_gclk" }, + { AM4_L3S_MCASP0_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp0_fck" }, + { AM4_L3S_MCASP1_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp1_fck" }, + { AM4_L3S_MMC3_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" }, +diff --git a/include/dt-bindings/clock/am4.h b/include/dt-bindings/clock/am4.h +index d961e7cb36821..4be6c5961f342 100644 +--- a/include/dt-bindings/clock/am4.h ++++ b/include/dt-bindings/clock/am4.h +@@ -158,6 +158,7 @@ + #define AM4_L3S_VPFE0_CLKCTRL AM4_L3S_CLKCTRL_INDEX(0x68) + #define AM4_L3S_VPFE1_CLKCTRL AM4_L3S_CLKCTRL_INDEX(0x70) + #define AM4_L3S_GPMC_CLKCTRL AM4_L3S_CLKCTRL_INDEX(0x220) ++#define AM4_L3S_ADC1_CLKCTRL AM4_L3S_CLKCTRL_INDEX(0x230) + #define AM4_L3S_MCASP0_CLKCTRL AM4_L3S_CLKCTRL_INDEX(0x238) + #define AM4_L3S_MCASP1_CLKCTRL AM4_L3S_CLKCTRL_INDEX(0x240) + #define AM4_L3S_MMC3_CLKCTRL AM4_L3S_CLKCTRL_INDEX(0x248) +-- +2.39.5 + diff --git a/queue-5.15/coresight-only-check-bottom-two-claim-bits.patch b/queue-5.15/coresight-only-check-bottom-two-claim-bits.patch new file mode 100644 index 0000000000..9bbe0c4a03 --- /dev/null +++ b/queue-5.15/coresight-only-check-bottom-two-claim-bits.patch @@ -0,0 +1,55 @@ +From 5d5b765c53ef767940d974b0e7f72db81edd1b68 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 25 Mar 2025 11:58:47 +0000 +Subject: coresight: Only check bottom two claim bits + +From: James Clark <james.clark@linaro.org> + +[ Upstream commit a4e65842e1142aa18ef36113fbd81d614eaefe5a ] + +The use of the whole register and == could break the claim mechanism if +any of the other bits are used in the future. The referenced doc "PSCI - +ARM DEN 0022D" also says to only read and clear the bottom two bits. + +Use FIELD_GET() to extract only the relevant part. + +Reviewed-by: Leo Yan <leo.yan@arm.com> +Reviewed-by: Yeoreum Yun <yeoreum.yun@arm.com> +Signed-off-by: James Clark <james.clark@linaro.org> +Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> +Link: https://lore.kernel.org/r/20250325-james-coresight-claim-tags-v4-2-dfbd3822b2e5@linaro.org +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/hwtracing/coresight/coresight-core.c | 3 ++- + drivers/hwtracing/coresight/coresight-priv.h | 1 + + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c +index 3ea6900542223..f6989a74fec94 100644 +--- a/drivers/hwtracing/coresight/coresight-core.c ++++ b/drivers/hwtracing/coresight/coresight-core.c +@@ -161,7 +161,8 @@ static int coresight_find_link_outport(struct coresight_device *csdev, + + static inline u32 coresight_read_claim_tags(struct coresight_device *csdev) + { +- return csdev_access_relaxed_read32(&csdev->access, CORESIGHT_CLAIMCLR); ++ return FIELD_GET(CORESIGHT_CLAIM_MASK, ++ csdev_access_relaxed_read32(&csdev->access, CORESIGHT_CLAIMCLR)); + } + + static inline bool coresight_is_claimed_self_hosted(struct coresight_device *csdev) +diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h +index ff1dd2092ac5b..b416edcdf797d 100644 +--- a/drivers/hwtracing/coresight/coresight-priv.h ++++ b/drivers/hwtracing/coresight/coresight-priv.h +@@ -32,6 +32,7 @@ + * Coresight device CLAIM protocol. + * See PSCI - ARM DEN 0022D, Section: 6.8.1 Debug and Trace save and restore. + */ ++#define CORESIGHT_CLAIM_MASK GENMASK(1, 0) + #define CORESIGHT_CLAIM_SELF_HOSTED BIT(1) + + #define TIMEOUT_US 100 +-- +2.39.5 + diff --git a/queue-5.15/dmaengine-xilinx_dma-set-dma_device-directions.patch b/queue-5.15/dmaengine-xilinx_dma-set-dma_device-directions.patch new file mode 100644 index 0000000000..8ece31168c --- /dev/null +++ b/queue-5.15/dmaengine-xilinx_dma-set-dma_device-directions.patch @@ -0,0 +1,40 @@ +From 13df1e437841c2c6bf453f8e70cc4244d51148e6 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 edc2bb8f0523c..48ac51447baee 100644 +--- a/drivers/dma/xilinx/xilinx_dma.c ++++ b/drivers/dma/xilinx/xilinx_dma.c +@@ -2861,6 +2861,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.15/drivers-hv-rename-alloced-to-allocated.patch b/queue-5.15/drivers-hv-rename-alloced-to-allocated.patch new file mode 100644 index 0000000000..affed25672 --- /dev/null +++ b/queue-5.15/drivers-hv-rename-alloced-to-allocated.patch @@ -0,0 +1,145 @@ +From a3138d972344773023f3090e232fa7954facabca 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 62c864f8d991b..029f8269ad15d 100644 +--- a/drivers/hv/channel_mgmt.c ++++ b/drivers/hv/channel_mgmt.c +@@ -459,7 +459,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 +@@ -733,7 +733,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; + +@@ -750,7 +750,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; + } + +@@ -765,22 +765,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 631f0a138c2b9..6a0ae815a198e 100644 +--- a/drivers/hv/hyperv_vmbus.h ++++ b/drivers/hv/hyperv_vmbus.h +@@ -405,7 +405,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; + +@@ -427,23 +427,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 cb3a5b13c3ec2..f42c3cb3cc0aa 100644 +--- a/drivers/hv/vmbus_drv.c ++++ b/drivers/hv/vmbus_drv.c +@@ -1878,7 +1878,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.15/drivers-hv-vmbus-add-utility-function-for-querying-r.patch b/queue-5.15/drivers-hv-vmbus-add-utility-function-for-querying-r.patch new file mode 100644 index 0000000000..b70dc036bc --- /dev/null +++ b/queue-5.15/drivers-hv-vmbus-add-utility-function-for-querying-r.patch @@ -0,0 +1,94 @@ +From 205af7b258f17bc3c5ddd06f94a5b9c513a21834 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 029f8269ad15d..cd9f01b7d37dd 100644 +--- a/drivers/hv/channel_mgmt.c ++++ b/drivers/hv/channel_mgmt.c +@@ -119,7 +119,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, + .allowed_in_isolated = false, +@@ -139,12 +141,19 @@ const struct vmbus_device vmbus_devs[] = { + .allowed_in_isolated = 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, + .allowed_in_isolated = 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 6a0ae815a198e..b87adb3a98211 100644 +--- a/drivers/hv/hyperv_vmbus.h ++++ b/drivers/hv/hyperv_vmbus.h +@@ -405,6 +405,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 aff435a42ead9..62d5bb1f726f6 100644 +--- a/include/linux/hyperv.h ++++ b/include/linux/hyperv.h +@@ -815,6 +815,8 @@ struct vmbus_requestor { + #define VMBUS_RQST_RESET (U64_MAX - 3) + + 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.15/dummycon-trigger-redraw-when-switching-consoles-with.patch b/queue-5.15/dummycon-trigger-redraw-when-switching-consoles-with.patch new file mode 100644 index 0000000000..22fdacc81b --- /dev/null +++ b/queue-5.15/dummycon-trigger-redraw-when-switching-consoles-with.patch @@ -0,0 +1,96 @@ +From 7aba9b612d73fc657c2cc6906a97c307a752f521 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 20 May 2025 09:14:00 +0200 +Subject: dummycon: Trigger redraw when switching consoles with deferred + takeover + +From: Thomas Zimmermann <tzimmermann@suse.de> + +[ Upstream commit 03bcbbb3995ba5df43af9aba45334e35f2dfe27b ] + +Signal vt subsystem to redraw console when switching to dummycon +with deferred takeover enabled. Makes the console switch to fbcon +and displays the available output. + +With deferred takeover enabled, dummycon acts as the placeholder +until the first output to the console happens. At that point, fbcon +takes over. If the output happens while dummycon is not active, it +cannot inform fbcon. This is the case if the vt subsystem runs in +graphics mode. + +A typical graphical boot starts plymouth, a display manager and a +compositor; all while leaving out dummycon. Switching to a text-mode +console leaves the console with dummycon even if a getty terminal +has been started. + +Returning true from dummycon's con_switch helper signals the vt +subsystem to redraw the screen. If there's output available dummycon's +con_putc{s} helpers trigger deferred takeover of fbcon, which sets a +display mode and displays the output. If no output is available, +dummycon remains active. + +v2: +- make the comment slightly more verbose (Javier) + +Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> +Reported-by: Andrei Borzenkov <arvidjaar@gmail.com> +Closes: https://bugzilla.suse.com/show_bug.cgi?id=1242191 +Tested-by: Andrei Borzenkov <arvidjaar@gmail.com> +Acked-by: Javier Martinez Canillas <javierm@redhat.com> +Fixes: 83d83bebf401 ("console/fbcon: Add support for deferred console takeover") +Cc: Hans de Goede <hdegoede@redhat.com> +Cc: linux-fbdev@vger.kernel.org +Cc: dri-devel@lists.freedesktop.org +Cc: <stable@vger.kernel.org> # v4.19+ +Link: https://lore.kernel.org/r/20250520071418.8462-1-tzimmermann@suse.de +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/video/console/dummycon.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c +index d701f2b51f5b1..d99e1b3e4e5c1 100644 +--- a/drivers/video/console/dummycon.c ++++ b/drivers/video/console/dummycon.c +@@ -82,6 +82,15 @@ static int dummycon_blank(struct vc_data *vc, int blank, int mode_switch) + /* Redraw, so that we get putc(s) for output done while blanked */ + return 1; + } ++ ++static bool dummycon_switch(struct vc_data *vc) ++{ ++ /* ++ * Redraw, so that we get putc(s) for output done while switched ++ * away. Informs deferred consoles to take over the display. ++ */ ++ return true; ++} + #else + static void dummycon_putc(struct vc_data *vc, int c, int ypos, int xpos) { } + static void dummycon_putcs(struct vc_data *vc, const unsigned short *s, +@@ -90,6 +99,10 @@ static int dummycon_blank(struct vc_data *vc, int blank, int mode_switch) + { + return 0; + } ++static bool dummycon_switch(struct vc_data *vc) ++{ ++ return false; ++} + #endif + + static const char *dummycon_startup(void) +@@ -119,11 +132,6 @@ static bool dummycon_scroll(struct vc_data *vc, unsigned int top, + return false; + } + +-static bool dummycon_switch(struct vc_data *vc) +-{ +- return false; +-} +- + /* + * The console `switch' structure for the dummy console + * +-- +2.39.5 + diff --git a/queue-5.15/f2fs-don-t-over-report-free-space-or-inodes-in-statv.patch b/queue-5.15/f2fs-don-t-over-report-free-space-or-inodes-in-statv.patch new file mode 100644 index 0000000000..4f2035a418 --- /dev/null +++ b/queue-5.15/f2fs-don-t-over-report-free-space-or-inodes-in-statv.patch @@ -0,0 +1,99 @@ +From eef5a0268a4170ad101953759cfc21dd2f0cadbd 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 194d3f93ac5f2..b9da3074a1af8 100644 +--- a/fs/f2fs/super.c ++++ b/fs/f2fs/super.c +@@ -1737,26 +1737,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.15/fbcon-delete-a-few-unneeded-forward-decl.patch b/queue-5.15/fbcon-delete-a-few-unneeded-forward-decl.patch new file mode 100644 index 0000000000..b6802edd4e --- /dev/null +++ b/queue-5.15/fbcon-delete-a-few-unneeded-forward-decl.patch @@ -0,0 +1,79 @@ +From 2b6cd27cba2f0d105d7ab11dd16116e82f609f1c Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 5 Apr 2022 23:03:19 +0200 +Subject: fbcon: delete a few unneeded forward decl + +From: Daniel Vetter <daniel.vetter@ffwll.ch> + +[ Upstream commit 9ad7acdad1d91545b99bf9fda3de4b86cf48b272 ] + +I didn't bother with any code movement to fix the others, these just +got a bit in the way. + +v2: Rebase on top of Helge's reverts. + +Acked-by: Thomas Zimmermann <tzimmermann@suse.de> +Acked-by: Sam Ravnborg <sam@ravnborg.org> (v1) +Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org> (v1) +Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> +Cc: Helge Deller <deller@gmx.de> +Cc: Daniel Vetter <daniel@ffwll.ch> +Cc: Thomas Zimmermann <tzimmermann@suse.de> +Cc: Du Cheng <ducheng2@gmail.com> +Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> +Cc: Claudio Suarez <cssk@net-c.es> +Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Link: https://patchwork.freedesktop.org/patch/msgid/20220405210335.3434130-2-daniel.vetter@ffwll.ch +Stable-dep-of: 03bcbbb3995b ("dummycon: Trigger redraw when switching consoles with deferred takeover") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/video/fbdev/core/fbcon.c | 17 +---------------- + 1 file changed, 1 insertion(+), 16 deletions(-) + +diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c +index a67f982fe2ec0..a3af7aacfaf11 100644 +--- a/drivers/video/fbdev/core/fbcon.c ++++ b/drivers/video/fbdev/core/fbcon.c +@@ -163,29 +163,14 @@ static int fbcon_cursor_noblink; + * Interface used by the world + */ + +-static const char *fbcon_startup(void); +-static void fbcon_init(struct vc_data *vc, int init); +-static void fbcon_deinit(struct vc_data *vc); +-static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height, +- int width); +-static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos); +-static void fbcon_putcs(struct vc_data *vc, const unsigned short *s, +- int count, int ypos, int xpos); + static void fbcon_clear_margins(struct vc_data *vc, int bottom_only); +-static void fbcon_cursor(struct vc_data *vc, int mode); + static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx, + int height, int width); +-static int fbcon_switch(struct vc_data *vc); +-static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch); + static void fbcon_set_palette(struct vc_data *vc, const unsigned char *table); + + /* + * Internal routines + */ +-static __inline__ void ywrap_up(struct vc_data *vc, int count); +-static __inline__ void ywrap_down(struct vc_data *vc, int count); +-static __inline__ void ypan_up(struct vc_data *vc, int count); +-static __inline__ void ypan_down(struct vc_data *vc, int count); + static void fbcon_bmove_rec(struct vc_data *vc, struct fbcon_display *p, int sy, int sx, + int dy, int dx, int height, int width, u_int y_break); + static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var, +@@ -194,8 +179,8 @@ static void fbcon_redraw_move(struct vc_data *vc, struct fbcon_display *p, + int line, int count, int dy); + static void fbcon_modechanged(struct fb_info *info); + static void fbcon_set_all_vcs(struct fb_info *info); +-static void fbcon_start(void); + static void fbcon_exit(void); ++ + static struct device *fbcon_device; + + #ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION +-- +2.39.5 + diff --git a/queue-5.15/fbcon-extract-fbcon_open-release-helpers.patch b/queue-5.15/fbcon-extract-fbcon_open-release-helpers.patch new file mode 100644 index 0000000000..d5763c7196 --- /dev/null +++ b/queue-5.15/fbcon-extract-fbcon_open-release-helpers.patch @@ -0,0 +1,212 @@ +From bc80d7e1d1e199f1f758528182c999d4b879b915 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 5 Apr 2022 23:03:27 +0200 +Subject: fbcon: Extract fbcon_open/release helpers + +From: Daniel Vetter <daniel.vetter@ffwll.ch> + +[ Upstream commit bd6026a8c4e6b7edf4bafcb71da885b284b8f4fd ] + +There's two minor behaviour changes in here: +- in error paths we now consistently call fb_ops->fb_release +- fb_release really can't fail (fbmem.c ignores it too) and there's no + reasonable cleanup we can do anyway. + +Note that everything in fbcon.c is protected by the big console_lock() +lock (especially all the global variables), so the minor changes in +ordering of setup/cleanup do not matter. + +v2: Explain a bit better why this is all correct (Sam) + +Acked-by: Sam Ravnborg <sam@ravnborg.org> +Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> +Cc: Daniel Vetter <daniel@ffwll.ch> +Cc: Claudio Suarez <cssk@net-c.es> +Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> +Cc: Du Cheng <ducheng2@gmail.com> +Link: https://patchwork.freedesktop.org/patch/msgid/20220405210335.3434130-10-daniel.vetter@ffwll.ch +Stable-dep-of: 17186f1f90d3 ("fbdev: Fix do_register_framebuffer to prevent null-ptr-deref in fb_videomode_to_var") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/video/fbdev/core/fbcon.c | 107 +++++++++++++++---------------- + 1 file changed, 53 insertions(+), 54 deletions(-) + +diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c +index abea89d101626..2a230a6335a81 100644 +--- a/drivers/video/fbdev/core/fbcon.c ++++ b/drivers/video/fbdev/core/fbcon.c +@@ -691,19 +691,37 @@ static int fbcon_invalid_charcount(struct fb_info *info, unsigned charcount) + + #endif /* CONFIG_MISC_TILEBLITTING */ + ++static int fbcon_open(struct fb_info *info) ++{ ++ if (!try_module_get(info->fbops->owner)) ++ return -ENODEV; ++ ++ if (info->fbops->fb_open && ++ info->fbops->fb_open(info, 0)) { ++ module_put(info->fbops->owner); ++ return -ENODEV; ++ } ++ ++ return 0; ++} ++ ++static void fbcon_release(struct fb_info *info) ++{ ++ if (info->fbops->fb_release) ++ info->fbops->fb_release(info, 0); ++ ++ module_put(info->fbops->owner); ++} + + static int con2fb_acquire_newinfo(struct vc_data *vc, struct fb_info *info, + int unit, int oldidx) + { + struct fbcon_ops *ops = NULL; +- int err = 0; +- +- if (!try_module_get(info->fbops->owner)) +- err = -ENODEV; ++ int err; + +- if (!err && info->fbops->fb_open && +- info->fbops->fb_open(info, 0)) +- err = -ENODEV; ++ err = fbcon_open(info); ++ if (err) ++ return err; + + if (!err) { + ops = kzalloc(sizeof(struct fbcon_ops), GFP_KERNEL); +@@ -724,7 +742,7 @@ static int con2fb_acquire_newinfo(struct vc_data *vc, struct fb_info *info, + + if (err) { + con2fb_map[unit] = oldidx; +- module_put(info->fbops->owner); ++ fbcon_release(info); + } + + return err; +@@ -735,45 +753,34 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo, + int oldidx, int found) + { + struct fbcon_ops *ops = oldinfo->fbcon_par; +- int err = 0, ret; ++ int ret; + +- if (oldinfo->fbops->fb_release && +- oldinfo->fbops->fb_release(oldinfo, 0)) { +- con2fb_map[unit] = oldidx; +- if (!found && newinfo->fbops->fb_release) +- newinfo->fbops->fb_release(newinfo, 0); +- if (!found) +- module_put(newinfo->fbops->owner); +- err = -ENODEV; +- } ++ fbcon_release(oldinfo); + +- if (!err) { +- fbcon_del_cursor_work(oldinfo); +- kfree(ops->cursor_state.mask); +- kfree(ops->cursor_data); +- kfree(ops->cursor_src); +- kfree(ops->fontbuffer); +- kfree(oldinfo->fbcon_par); +- oldinfo->fbcon_par = NULL; +- module_put(oldinfo->fbops->owner); +- /* +- If oldinfo and newinfo are driving the same hardware, +- the fb_release() method of oldinfo may attempt to +- restore the hardware state. This will leave the +- newinfo in an undefined state. Thus, a call to +- fb_set_par() may be needed for the newinfo. +- */ +- if (newinfo && newinfo->fbops->fb_set_par) { +- ret = newinfo->fbops->fb_set_par(newinfo); ++ fbcon_del_cursor_work(oldinfo); ++ kfree(ops->cursor_state.mask); ++ kfree(ops->cursor_data); ++ kfree(ops->cursor_src); ++ kfree(ops->fontbuffer); ++ kfree(oldinfo->fbcon_par); ++ oldinfo->fbcon_par = NULL; ++ /* ++ If oldinfo and newinfo are driving the same hardware, ++ the fb_release() method of oldinfo may attempt to ++ restore the hardware state. This will leave the ++ newinfo in an undefined state. Thus, a call to ++ fb_set_par() may be needed for the newinfo. ++ */ ++ if (newinfo && newinfo->fbops->fb_set_par) { ++ ret = newinfo->fbops->fb_set_par(newinfo); + +- if (ret) +- printk(KERN_ERR "con2fb_release_oldinfo: " +- "detected unhandled fb_set_par error, " +- "error code %d\n", ret); +- } ++ if (ret) ++ printk(KERN_ERR "con2fb_release_oldinfo: " ++ "detected unhandled fb_set_par error, " ++ "error code %d\n", ret); + } + +- return err; ++ return 0; + } + + static void con2fb_init_display(struct vc_data *vc, struct fb_info *info, +@@ -928,7 +935,6 @@ static const char *fbcon_startup(void) + struct fbcon_display *p = &fb_display[fg_console]; + struct vc_data *vc = vc_cons[fg_console].d; + const struct font_desc *font = NULL; +- struct module *owner; + struct fb_info *info = NULL; + struct fbcon_ops *ops; + int rows, cols; +@@ -947,17 +953,12 @@ static const char *fbcon_startup(void) + if (!info) + return NULL; + +- owner = info->fbops->owner; +- if (!try_module_get(owner)) ++ if (fbcon_open(info)) + return NULL; +- if (info->fbops->fb_open && info->fbops->fb_open(info, 0)) { +- module_put(owner); +- return NULL; +- } + + ops = kzalloc(sizeof(struct fbcon_ops), GFP_KERNEL); + if (!ops) { +- module_put(owner); ++ fbcon_release(info); + return NULL; + } + +@@ -3387,10 +3388,6 @@ static void fbcon_exit(void) + } + + if (mapped) { +- if (info->fbops->fb_release) +- info->fbops->fb_release(info, 0); +- module_put(info->fbops->owner); +- + if (info->fbcon_par) { + struct fbcon_ops *ops = info->fbcon_par; + +@@ -3400,6 +3397,8 @@ static void fbcon_exit(void) + kfree(info->fbcon_par); + info->fbcon_par = NULL; + } ++ ++ fbcon_release(info); + } + } + } +-- +2.39.5 + diff --git a/queue-5.15/fbcon-move-console_lock-for-register-unlink-unregist.patch b/queue-5.15/fbcon-move-console_lock-for-register-unlink-unregist.patch new file mode 100644 index 0000000000..3da24881e3 --- /dev/null +++ b/queue-5.15/fbcon-move-console_lock-for-register-unlink-unregist.patch @@ -0,0 +1,195 @@ +From 1f6a3677cb84e9a94f803e4e847b3ecad77a3ed2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 5 Apr 2022 23:03:32 +0200 +Subject: fbcon: Move console_lock for register/unlink/unregister + +From: Daniel Vetter <daniel.vetter@ffwll.ch> + +[ Upstream commit 6e7da3af008b72520f5318507f455f344b27f022 ] + +Ideally console_lock becomes an implementation detail of fbcon.c and +doesn't show up anywhere in fbmem.c. We're still pretty far from that, +but at least the register/unregister code is there now. + +With this the do_fb_ioctl() handler is the only code in fbmem.c still +calling console_lock(). + +Acked-by: Sam Ravnborg <sam@ravnborg.org> +Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> +Cc: Daniel Vetter <daniel@ffwll.ch> +Cc: Thomas Zimmermann <tzimmermann@suse.de> +Cc: Du Cheng <ducheng2@gmail.com> +Cc: Claudio Suarez <cssk@net-c.es> +Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> +Cc: Matthew Wilcox <willy@infradead.org> +Cc: Sam Ravnborg <sam@ravnborg.org> +Cc: Zheyu Ma <zheyuma97@gmail.com> +Cc: Guenter Roeck <linux@roeck-us.net> +Cc: Alex Deucher <alexander.deucher@amd.com> +Cc: Zhen Lei <thunder.leizhen@huawei.com> +Cc: Xiyu Yang <xiyuyang19@fudan.edu.cn> +Link: https://patchwork.freedesktop.org/patch/msgid/20220405210335.3434130-15-daniel.vetter@ffwll.ch +Stable-dep-of: 17186f1f90d3 ("fbdev: Fix do_register_framebuffer to prevent null-ptr-deref in fb_videomode_to_var") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/video/fbdev/core/fbcon.c | 33 ++++++++++++++++++++++++++------ + drivers/video/fbdev/core/fbmem.c | 23 ++-------------------- + 2 files changed, 29 insertions(+), 27 deletions(-) + +diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c +index 072a264ae380b..a67f982fe2ec0 100644 +--- a/drivers/video/fbdev/core/fbcon.c ++++ b/drivers/video/fbdev/core/fbcon.c +@@ -2823,10 +2823,12 @@ void fbcon_fb_unbind(struct fb_info *info) + int i, new_idx = -1, ret = 0; + int idx = info->node; + +- WARN_CONSOLE_UNLOCKED(); ++ console_lock(); + +- if (!fbcon_has_console_bind) ++ if (!fbcon_has_console_bind) { ++ console_unlock(); + return; ++ } + + for (i = first_fb_vc; i <= last_fb_vc; i++) { + if (con2fb_map[i] != idx && +@@ -2866,6 +2868,8 @@ void fbcon_fb_unbind(struct fb_info *info) + } + fbcon_unbind(); + } ++ ++ console_unlock(); + } + + /* called with console_lock held */ +@@ -2873,10 +2877,12 @@ void fbcon_fb_unregistered(struct fb_info *info) + { + int i, idx; + +- WARN_CONSOLE_UNLOCKED(); ++ console_lock(); + +- if (deferred_takeover) ++ if (deferred_takeover) { ++ console_unlock(); + return; ++ } + + idx = info->node; + for (i = first_fb_vc; i <= last_fb_vc; i++) { +@@ -2905,6 +2911,7 @@ void fbcon_fb_unregistered(struct fb_info *info) + + if (!num_registered_fb) + do_unregister_con_driver(&fb_con); ++ console_unlock(); + } + + void fbcon_remap_all(struct fb_info *info) +@@ -2962,19 +2969,27 @@ static inline void fbcon_select_primary(struct fb_info *info) + } + #endif /* CONFIG_FRAMEBUFFER_DETECT_PRIMARY */ + ++static bool lockless_register_fb; ++module_param_named_unsafe(lockless_register_fb, lockless_register_fb, bool, 0400); ++MODULE_PARM_DESC(lockless_register_fb, ++ "Lockless framebuffer registration for debugging [default=off]"); ++ + /* called with console_lock held */ + int fbcon_fb_registered(struct fb_info *info) + { + int ret = 0, i, idx; + +- WARN_CONSOLE_UNLOCKED(); ++ if (!lockless_register_fb) ++ console_lock(); ++ else ++ atomic_inc(&ignore_console_lock_warning); + + idx = info->node; + fbcon_select_primary(info); + + if (deferred_takeover) { + pr_info("fbcon: Deferring console take-over\n"); +- return 0; ++ goto out; + } + + if (info_idx == -1) { +@@ -2994,6 +3009,12 @@ int fbcon_fb_registered(struct fb_info *info) + } + } + ++out: ++ if (!lockless_register_fb) ++ console_unlock(); ++ else ++ atomic_dec(&ignore_console_lock_warning); ++ + return ret; + } + +diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c +index f4253ec8a6409..5e8ee360f6ba2 100644 +--- a/drivers/video/fbdev/core/fbmem.c ++++ b/drivers/video/fbdev/core/fbmem.c +@@ -1620,14 +1620,9 @@ static void do_remove_conflicting_framebuffers(struct apertures_struct *a, + } + } + +-static bool lockless_register_fb; +-module_param_named_unsafe(lockless_register_fb, lockless_register_fb, bool, 0400); +-MODULE_PARM_DESC(lockless_register_fb, +- "Lockless framebuffer registration for debugging [default=off]"); +- + static int do_register_framebuffer(struct fb_info *fb_info) + { +- int i, ret; ++ int i; + struct fb_videomode mode; + + if (fb_check_foreignness(fb_info)) +@@ -1696,17 +1691,7 @@ static int do_register_framebuffer(struct fb_info *fb_info) + } + #endif + +- if (!lockless_register_fb) +- console_lock(); +- else +- atomic_inc(&ignore_console_lock_warning); +- ret = fbcon_fb_registered(fb_info); +- +- if (!lockless_register_fb) +- console_unlock(); +- else +- atomic_dec(&ignore_console_lock_warning); +- return ret; ++ return fbcon_fb_registered(fb_info); + } + + static void unbind_console(struct fb_info *fb_info) +@@ -1716,9 +1701,7 @@ static void unbind_console(struct fb_info *fb_info) + if (WARN_ON(i < 0 || i >= FB_MAX || registered_fb[i] != fb_info)) + return; + +- console_lock(); + fbcon_fb_unbind(fb_info); +- console_unlock(); + } + + static void unlink_framebuffer(struct fb_info *fb_info) +@@ -1758,9 +1741,7 @@ static void do_unregister_framebuffer(struct fb_info *fb_info) + fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); + } + #endif +- console_lock(); + fbcon_fb_unregistered(fb_info); +- console_unlock(); + + /* this may free fb info */ + put_fb_info(fb_info); +-- +2.39.5 + diff --git a/queue-5.15/fbcon-move-more-common-code-into-fb_open.patch b/queue-5.15/fbcon-move-more-common-code-into-fb_open.patch new file mode 100644 index 0000000000..9e5dc281af --- /dev/null +++ b/queue-5.15/fbcon-move-more-common-code-into-fb_open.patch @@ -0,0 +1,178 @@ +From bbeee6fbede2e3a3967af4884b2c2c8b31c26507 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 5 Apr 2022 23:03:29 +0200 +Subject: fbcon: move more common code into fb_open() + +From: Daniel Vetter <daniel.vetter@ffwll.ch> + +[ Upstream commit d443d93864726ad68c0a741d1e7b03934a9af143 ] + +No idea why con2fb_acquire_newinfo() initializes much less than +fbcon_startup(), but so be it. From a quick look most of the +un-initialized stuff should be fairly harmless, but who knows. + +Note that the error handling for the con2fb_acquire_newinfo() failure +case was very strange: Callers updated con2fb_map to the new value +before calling this function, but upon error con2fb_acquire_newinfo +reset it to the old value. Since I removed the call to fbcon_release +anyway that strange error path was sticking out like a sore thumb, +hence I removed it. Which also allows us to remove the oldidx +parameter from that function. + +v2: Explain what's going on with oldidx and error paths (Sam) + +v3: Drop unused variable (0day) + +v4: Rebased over bisect fix in previous patch, unchagend end result. + +Acked-by: Sam Ravnborg <sam@ravnborg.org> (v2) +Acked-by: Thomas Zimmermann <tzimmermann@suse.de> +Cc: kernel test robot <lkp@intel.com> +Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> +Cc: Daniel Vetter <daniel@ffwll.ch> +Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> +Cc: Thomas Zimmermann <tzimmermann@suse.de> +Cc: Claudio Suarez <cssk@net-c.es> +Cc: Du Cheng <ducheng2@gmail.com> +Link: https://patchwork.freedesktop.org/patch/msgid/20220405210335.3434130-12-daniel.vetter@ffwll.ch +Stable-dep-of: 17186f1f90d3 ("fbdev: Fix do_register_framebuffer to prevent null-ptr-deref in fb_videomode_to_var") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/video/fbdev/core/fbcon.c | 75 +++++++++++++------------------- + 1 file changed, 30 insertions(+), 45 deletions(-) + +diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c +index 2a230a6335a81..734b8f3f81b24 100644 +--- a/drivers/video/fbdev/core/fbcon.c ++++ b/drivers/video/fbdev/core/fbcon.c +@@ -691,8 +691,18 @@ static int fbcon_invalid_charcount(struct fb_info *info, unsigned charcount) + + #endif /* CONFIG_MISC_TILEBLITTING */ + ++static void fbcon_release(struct fb_info *info) ++{ ++ if (info->fbops->fb_release) ++ info->fbops->fb_release(info, 0); ++ ++ module_put(info->fbops->owner); ++} ++ + static int fbcon_open(struct fb_info *info) + { ++ struct fbcon_ops *ops; ++ + if (!try_module_get(info->fbops->owner)) + return -ENODEV; + +@@ -702,48 +712,31 @@ static int fbcon_open(struct fb_info *info) + return -ENODEV; + } + +- return 0; +-} ++ ops = kzalloc(sizeof(struct fbcon_ops), GFP_KERNEL); ++ if (!ops) { ++ fbcon_release(info); ++ return -ENOMEM; ++ } + +-static void fbcon_release(struct fb_info *info) +-{ +- if (info->fbops->fb_release) +- info->fbops->fb_release(info, 0); ++ INIT_DELAYED_WORK(&ops->cursor_work, fb_flashcursor); ++ ops->info = info; ++ info->fbcon_par = ops; ++ ops->cur_blink_jiffies = HZ / 5; + +- module_put(info->fbops->owner); ++ return 0; + } + + static int con2fb_acquire_newinfo(struct vc_data *vc, struct fb_info *info, +- int unit, int oldidx) ++ int unit) + { +- struct fbcon_ops *ops = NULL; + int err; + + err = fbcon_open(info); + if (err) + return err; + +- if (!err) { +- ops = kzalloc(sizeof(struct fbcon_ops), GFP_KERNEL); +- if (!ops) +- err = -ENOMEM; +- } +- +- if (!err) { +- INIT_DELAYED_WORK(&ops->cursor_work, fb_flashcursor); +- +- ops->cur_blink_jiffies = HZ / 5; +- ops->info = info; +- info->fbcon_par = ops; +- +- if (vc) +- set_blitting_type(vc, info); +- } +- +- if (err) { +- con2fb_map[unit] = oldidx; +- fbcon_release(info); +- } ++ if (vc) ++ set_blitting_type(vc, info); + + return err; + } +@@ -854,9 +847,11 @@ static int set_con2fb_map(int unit, int newidx, int user) + + found = search_fb_in_map(newidx); + +- con2fb_map[unit] = newidx; +- if (!err && !found) +- err = con2fb_acquire_newinfo(vc, info, unit, oldidx); ++ if (!err && !found) { ++ err = con2fb_acquire_newinfo(vc, info, unit); ++ if (!err) ++ con2fb_map[unit] = newidx; ++ } + + /* + * If old fb is not mapped to any of the consoles, +@@ -956,20 +951,10 @@ static const char *fbcon_startup(void) + if (fbcon_open(info)) + return NULL; + +- ops = kzalloc(sizeof(struct fbcon_ops), GFP_KERNEL); +- if (!ops) { +- fbcon_release(info); +- return NULL; +- } +- +- INIT_DELAYED_WORK(&ops->cursor_work, fb_flashcursor); +- ++ ops = info->fbcon_par; + ops->currcon = -1; + ops->graphics = 1; + ops->cur_rotate = -1; +- ops->cur_blink_jiffies = HZ / 5; +- ops->info = info; +- info->fbcon_par = ops; + + p->con_rotate = initial_rotation; + if (p->con_rotate == -1) +@@ -1037,7 +1022,7 @@ static void fbcon_init(struct vc_data *vc, int init) + return; + + if (!info->fbcon_par) +- con2fb_acquire_newinfo(vc, info, vc->vc_num, -1); ++ con2fb_acquire_newinfo(vc, info, vc->vc_num); + + /* If we are not the first console on this + fb, copy the font from that console */ +-- +2.39.5 + diff --git a/queue-5.15/fbcon-use-delayed-work-for-cursor.patch b/queue-5.15/fbcon-use-delayed-work-for-cursor.patch new file mode 100644 index 0000000000..9cd16227ff --- /dev/null +++ b/queue-5.15/fbcon-use-delayed-work-for-cursor.patch @@ -0,0 +1,302 @@ +From 5d4b0d384bdfa97b0e09d8f5bc550bcc29d5ca07 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 5 Apr 2022 23:03:24 +0200 +Subject: fbcon: Use delayed work for cursor + +From: Daniel Vetter <daniel.vetter@ffwll.ch> + +[ Upstream commit 3b0fb6ab25dda03f6077bf8fce9407bb0d4db6ea ] + +Allows us to delete a bunch of hand-rolled stuff using a timer plus a +separate work). Also to simplify the code we initialize the +cursor_work completely when we allocate the fbcon_ops structure, +instead of trying to cope with console re-initialization. + +The motiviation here is that fbcon code stops using the fb_info.queue, +which helps with locking issues around cleanup and all that in a later +patch. + +Also note that this allows us to ditch the hand-rolled work cleanup in +fbcon_exit - we already call fbcon_del_cursor_timer, which takes care +of everything. Plus this was racy anyway. + +v2: +- Only INIT_DELAYED_WORK when kzalloc succeeded (Tetsuo) +- Explain that we replace both the timer and a work with the combined + delayed_work (Javier) + +Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> +Acked-by: Thomas Zimmermann <tzimmermann@suse.de> +Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> +Cc: Daniel Vetter <daniel@ffwll.ch> +Cc: Claudio Suarez <cssk@net-c.es> +Cc: Du Cheng <ducheng2@gmail.com> +Cc: Thomas Zimmermann <tzimmermann@suse.de> +Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> +Link: https://patchwork.freedesktop.org/patch/msgid/20220405210335.3434130-7-daniel.vetter@ffwll.ch +Stable-dep-of: 17186f1f90d3 ("fbdev: Fix do_register_framebuffer to prevent null-ptr-deref in fb_videomode_to_var") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/video/fbdev/core/fbcon.c | 85 +++++++++++++------------------- + drivers/video/fbdev/core/fbcon.h | 4 +- + 2 files changed, 35 insertions(+), 54 deletions(-) + +diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c +index 805a4745abd86..abea89d101626 100644 +--- a/drivers/video/fbdev/core/fbcon.c ++++ b/drivers/video/fbdev/core/fbcon.c +@@ -357,8 +357,8 @@ static int get_color(struct vc_data *vc, struct fb_info *info, + + static void fb_flashcursor(struct work_struct *work) + { +- struct fb_info *info = container_of(work, struct fb_info, queue); +- struct fbcon_ops *ops = info->fbcon_par; ++ struct fbcon_ops *ops = container_of(work, struct fbcon_ops, cursor_work.work); ++ struct fb_info *info; + struct vc_data *vc = NULL; + int c; + int mode; +@@ -371,7 +371,10 @@ static void fb_flashcursor(struct work_struct *work) + if (ret == 0) + return; + +- if (ops && ops->currcon != -1) ++ /* protected by console_lock */ ++ info = ops->info; ++ ++ if (ops->currcon != -1) + vc = vc_cons[ops->currcon].d; + + if (!vc || !con_is_visible(vc) || +@@ -387,42 +390,25 @@ static void fb_flashcursor(struct work_struct *work) + ops->cursor(vc, info, mode, get_color(vc, info, c, 1), + get_color(vc, info, c, 0)); + console_unlock(); +-} + +-static void cursor_timer_handler(struct timer_list *t) +-{ +- struct fbcon_ops *ops = from_timer(ops, t, cursor_timer); +- struct fb_info *info = ops->info; +- +- queue_work(system_power_efficient_wq, &info->queue); +- mod_timer(&ops->cursor_timer, jiffies + ops->cur_blink_jiffies); ++ queue_delayed_work(system_power_efficient_wq, &ops->cursor_work, ++ ops->cur_blink_jiffies); + } + +-static void fbcon_add_cursor_timer(struct fb_info *info) ++static void fbcon_add_cursor_work(struct fb_info *info) + { + struct fbcon_ops *ops = info->fbcon_par; + +- if ((!info->queue.func || info->queue.func == fb_flashcursor) && +- !(ops->flags & FBCON_FLAGS_CURSOR_TIMER) && +- !fbcon_cursor_noblink) { +- if (!info->queue.func) +- INIT_WORK(&info->queue, fb_flashcursor); +- +- timer_setup(&ops->cursor_timer, cursor_timer_handler, 0); +- mod_timer(&ops->cursor_timer, jiffies + ops->cur_blink_jiffies); +- ops->flags |= FBCON_FLAGS_CURSOR_TIMER; +- } ++ if (!fbcon_cursor_noblink) ++ queue_delayed_work(system_power_efficient_wq, &ops->cursor_work, ++ ops->cur_blink_jiffies); + } + +-static void fbcon_del_cursor_timer(struct fb_info *info) ++static void fbcon_del_cursor_work(struct fb_info *info) + { + struct fbcon_ops *ops = info->fbcon_par; + +- if (info->queue.func == fb_flashcursor && +- ops->flags & FBCON_FLAGS_CURSOR_TIMER) { +- del_timer_sync(&ops->cursor_timer); +- ops->flags &= ~FBCON_FLAGS_CURSOR_TIMER; +- } ++ cancel_delayed_work_sync(&ops->cursor_work); + } + + #ifndef MODULE +@@ -726,6 +712,8 @@ static int con2fb_acquire_newinfo(struct vc_data *vc, struct fb_info *info, + } + + if (!err) { ++ INIT_DELAYED_WORK(&ops->cursor_work, fb_flashcursor); ++ + ops->cur_blink_jiffies = HZ / 5; + ops->info = info; + info->fbcon_par = ops; +@@ -760,7 +748,7 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo, + } + + if (!err) { +- fbcon_del_cursor_timer(oldinfo); ++ fbcon_del_cursor_work(oldinfo); + kfree(ops->cursor_state.mask); + kfree(ops->cursor_data); + kfree(ops->cursor_src); +@@ -876,7 +864,7 @@ static int set_con2fb_map(int unit, int newidx, int user) + logo_shown != FBCON_LOGO_DONTSHOW); + + if (!found) +- fbcon_add_cursor_timer(info); ++ fbcon_add_cursor_work(info); + con2fb_map_boot[unit] = newidx; + con2fb_init_display(vc, info, unit, show_logo); + } +@@ -973,6 +961,8 @@ static const char *fbcon_startup(void) + return NULL; + } + ++ INIT_DELAYED_WORK(&ops->cursor_work, fb_flashcursor); ++ + ops->currcon = -1; + ops->graphics = 1; + ops->cur_rotate = -1; +@@ -1013,7 +1003,7 @@ static const char *fbcon_startup(void) + info->var.yres, + info->var.bits_per_pixel); + +- fbcon_add_cursor_timer(info); ++ fbcon_add_cursor_work(info); + return display_desc; + } + +@@ -1199,7 +1189,7 @@ static void fbcon_deinit(struct vc_data *vc) + goto finished; + + if (con_is_visible(vc)) +- fbcon_del_cursor_timer(info); ++ fbcon_del_cursor_work(info); + + ops->flags &= ~FBCON_FLAGS_INIT; + finished: +@@ -1326,9 +1316,9 @@ static void fbcon_cursor(struct vc_data *vc, int mode) + return; + + if (vc->vc_cursor_type & CUR_SW) +- fbcon_del_cursor_timer(info); ++ fbcon_del_cursor_work(info); + else +- fbcon_add_cursor_timer(info); ++ fbcon_add_cursor_work(info); + + ops->cursor_flash = (mode == CM_ERASE) ? 0 : 1; + +@@ -2134,14 +2124,14 @@ static int fbcon_switch(struct vc_data *vc) + } + + if (old_info != info) +- fbcon_del_cursor_timer(old_info); ++ fbcon_del_cursor_work(old_info); + } + + if (fbcon_is_inactive(vc, info) || + ops->blank_state != FB_BLANK_UNBLANK) +- fbcon_del_cursor_timer(info); ++ fbcon_del_cursor_work(info); + else +- fbcon_add_cursor_timer(info); ++ fbcon_add_cursor_work(info); + + set_blitting_type(vc, info); + ops->cursor_reset = 1; +@@ -2249,9 +2239,9 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) + + if (mode_switch || fbcon_is_inactive(vc, info) || + ops->blank_state != FB_BLANK_UNBLANK) +- fbcon_del_cursor_timer(info); ++ fbcon_del_cursor_work(info); + else +- fbcon_add_cursor_timer(info); ++ fbcon_add_cursor_work(info); + + return 0; + } +@@ -3241,7 +3231,7 @@ static ssize_t show_cursor_blink(struct device *device, + if (!ops) + goto err; + +- blink = (ops->flags & FBCON_FLAGS_CURSOR_TIMER) ? 1 : 0; ++ blink = delayed_work_pending(&ops->cursor_work); + err: + console_unlock(); + return snprintf(buf, PAGE_SIZE, "%d\n", blink); +@@ -3270,10 +3260,10 @@ static ssize_t store_cursor_blink(struct device *device, + + if (blink) { + fbcon_cursor_noblink = 0; +- fbcon_add_cursor_timer(info); ++ fbcon_add_cursor_work(info); + } else { + fbcon_cursor_noblink = 1; +- fbcon_del_cursor_timer(info); ++ fbcon_del_cursor_work(info); + } + + err: +@@ -3386,15 +3376,9 @@ static void fbcon_exit(void) + #endif + + for_each_registered_fb(i) { +- int pending = 0; +- + mapped = 0; + info = registered_fb[i]; + +- if (info->queue.func) +- pending = cancel_work_sync(&info->queue); +- pr_debug("fbcon: %s pending work\n", (pending ? "canceled" : "no")); +- + for (j = first_fb_vc; j <= last_fb_vc; j++) { + if (con2fb_map[j] == i) { + mapped = 1; +@@ -3410,15 +3394,12 @@ static void fbcon_exit(void) + if (info->fbcon_par) { + struct fbcon_ops *ops = info->fbcon_par; + +- fbcon_del_cursor_timer(info); ++ fbcon_del_cursor_work(info); + kfree(ops->cursor_src); + kfree(ops->cursor_state.mask); + kfree(info->fbcon_par); + info->fbcon_par = NULL; + } +- +- if (info->queue.func == fb_flashcursor) +- info->queue.func = NULL; + } + } + } +diff --git a/drivers/video/fbdev/core/fbcon.h b/drivers/video/fbdev/core/fbcon.h +index 3e1ec454b8aa3..a709e5796ef7e 100644 +--- a/drivers/video/fbdev/core/fbcon.h ++++ b/drivers/video/fbdev/core/fbcon.h +@@ -14,11 +14,11 @@ + #include <linux/types.h> + #include <linux/vt_buffer.h> + #include <linux/vt_kern.h> ++#include <linux/workqueue.h> + + #include <asm/io.h> + + #define FBCON_FLAGS_INIT 1 +-#define FBCON_FLAGS_CURSOR_TIMER 2 + + /* + * This is the interface between the low-level console driver and the +@@ -68,7 +68,7 @@ struct fbcon_ops { + int (*update_start)(struct fb_info *info); + int (*rotate_font)(struct fb_info *info, struct vc_data *vc); + struct fb_var_screeninfo var; /* copy of the current fb_var_screeninfo */ +- struct timer_list cursor_timer; /* Cursor timer */ ++ struct delayed_work cursor_work; /* Cursor timer */ + struct fb_cursor cursor_state; + struct fbcon_display *p; + struct fb_info *info; +-- +2.39.5 + diff --git a/queue-5.15/fbcon-use-lock_fb_info-in-fbcon_open-release.patch b/queue-5.15/fbcon-use-lock_fb_info-in-fbcon_open-release.patch new file mode 100644 index 0000000000..074fe97d5c --- /dev/null +++ b/queue-5.15/fbcon-use-lock_fb_info-in-fbcon_open-release.patch @@ -0,0 +1,108 @@ +From aad0fd8c1c0ea7e5b79ea269223efddf5c73720a Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 5 Apr 2022 23:03:30 +0200 +Subject: fbcon: use lock_fb_info in fbcon_open/release + +From: Daniel Vetter <daniel.vetter@ffwll.ch> + +[ Upstream commit 04933a294dacca3aaa480889d53e6195778d4578 ] + +Now we get to the real motiviation, because fbmem.c insists that +that's the right lock for these. + +Ofc fbcon.c has a lot more places where it probably should call +lock_fb_info(). But looking at fbmem.c at least most of these seem to +be protected by console_lock() too, which is probably what papers over +any issues. + +Note that this means we're shuffling around a bit the locking sections +for some of the console takeover and unbind paths, but not all: +- console binding/unbinding from the console layer never with +lock_fb_info +- unbind (as opposed to unlink) never bother with lock_fb_info + +Also the real serialization against set_par and set_pan are still +doing by wrapping the entire ioctl code in console_lock(). So this +shuffling shouldn't be worse than what we had from a "can you trigger +races?" pov, but it's at least clearer. + +Acked-by: Sam Ravnborg <sam@ravnborg.org> +Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> +Cc: Daniel Vetter <daniel@ffwll.ch> +Cc: Claudio Suarez <cssk@net-c.es> +Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> +Cc: Thomas Zimmermann <tzimmermann@suse.de> +Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Cc: Du Cheng <ducheng2@gmail.com> +Cc: Sam Ravnborg <sam@ravnborg.org> +Cc: Matthew Wilcox <willy@infradead.org> +Cc: William Kucharski <william.kucharski@oracle.com> +Cc: Alex Deucher <alexander.deucher@amd.com> +Cc: Zheyu Ma <zheyuma97@gmail.com> +Cc: Zhen Lei <thunder.leizhen@huawei.com> +Cc: Xiyu Yang <xiyuyang19@fudan.edu.cn> +Link: https://patchwork.freedesktop.org/patch/msgid/20220405210335.3434130-13-daniel.vetter@ffwll.ch +Stable-dep-of: 17186f1f90d3 ("fbdev: Fix do_register_framebuffer to prevent null-ptr-deref in fb_videomode_to_var") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/video/fbdev/core/fbcon.c | 5 +++++ + drivers/video/fbdev/core/fbmem.c | 4 ---- + 2 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c +index 734b8f3f81b24..072a264ae380b 100644 +--- a/drivers/video/fbdev/core/fbcon.c ++++ b/drivers/video/fbdev/core/fbcon.c +@@ -693,8 +693,10 @@ static int fbcon_invalid_charcount(struct fb_info *info, unsigned charcount) + + static void fbcon_release(struct fb_info *info) + { ++ lock_fb_info(info); + if (info->fbops->fb_release) + info->fbops->fb_release(info, 0); ++ unlock_fb_info(info); + + module_put(info->fbops->owner); + } +@@ -706,11 +708,14 @@ static int fbcon_open(struct fb_info *info) + if (!try_module_get(info->fbops->owner)) + return -ENODEV; + ++ lock_fb_info(info); + if (info->fbops->fb_open && + info->fbops->fb_open(info, 0)) { ++ unlock_fb_info(info); + module_put(info->fbops->owner); + return -ENODEV; + } ++ unlock_fb_info(info); + + ops = kzalloc(sizeof(struct fbcon_ops), GFP_KERNEL); + if (!ops) { +diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c +index d938c31e8f90a..f4253ec8a6409 100644 +--- a/drivers/video/fbdev/core/fbmem.c ++++ b/drivers/video/fbdev/core/fbmem.c +@@ -1700,9 +1700,7 @@ static int do_register_framebuffer(struct fb_info *fb_info) + console_lock(); + else + atomic_inc(&ignore_console_lock_warning); +- lock_fb_info(fb_info); + ret = fbcon_fb_registered(fb_info); +- unlock_fb_info(fb_info); + + if (!lockless_register_fb) + console_unlock(); +@@ -1719,9 +1717,7 @@ static void unbind_console(struct fb_info *fb_info) + return; + + console_lock(); +- lock_fb_info(fb_info); + fbcon_fb_unbind(fb_info); +- unlock_fb_info(fb_info); + console_unlock(); + } + +-- +2.39.5 + diff --git a/queue-5.15/fbdev-fix-do_register_framebuffer-to-prevent-null-pt.patch b/queue-5.15/fbdev-fix-do_register_framebuffer-to-prevent-null-pt.patch new file mode 100644 index 0000000000..f78fbe3d86 --- /dev/null +++ b/queue-5.15/fbdev-fix-do_register_framebuffer-to-prevent-null-pt.patch @@ -0,0 +1,112 @@ +From 717d77b6fe020171b16ba65269413b40ff77bec7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Mon, 28 Apr 2025 18:34:06 +0300 +Subject: fbdev: Fix do_register_framebuffer to prevent null-ptr-deref in + fb_videomode_to_var + +From: Murad Masimov <m.masimov@mt-integration.ru> + +[ Upstream commit 17186f1f90d34fa701e4f14e6818305151637b9e ] + +If fb_add_videomode() in do_register_framebuffer() fails to allocate +memory for fb_videomode, it will later lead to a null-ptr dereference in +fb_videomode_to_var(), as the fb_info is registered while not having the +mode in modelist that is expected to be there, i.e. the one that is +described in fb_info->var. + +================================================================ +general protection fault, probably for non-canonical address 0xdffffc0000000001: 0000 [#1] PREEMPT SMP KASAN NOPTI +KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f] +CPU: 1 PID: 30371 Comm: syz-executor.1 Not tainted 5.10.226-syzkaller #0 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014 +RIP: 0010:fb_videomode_to_var+0x24/0x610 drivers/video/fbdev/core/modedb.c:901 +Call Trace: + display_to_var+0x3a/0x7c0 drivers/video/fbdev/core/fbcon.c:929 + fbcon_resize+0x3e2/0x8f0 drivers/video/fbdev/core/fbcon.c:2071 + resize_screen drivers/tty/vt/vt.c:1176 [inline] + vc_do_resize+0x53a/0x1170 drivers/tty/vt/vt.c:1263 + fbcon_modechanged+0x3ac/0x6e0 drivers/video/fbdev/core/fbcon.c:2720 + fbcon_update_vcs+0x43/0x60 drivers/video/fbdev/core/fbcon.c:2776 + do_fb_ioctl+0x6d2/0x740 drivers/video/fbdev/core/fbmem.c:1128 + fb_ioctl+0xe7/0x150 drivers/video/fbdev/core/fbmem.c:1203 + vfs_ioctl fs/ioctl.c:48 [inline] + __do_sys_ioctl fs/ioctl.c:753 [inline] + __se_sys_ioctl fs/ioctl.c:739 [inline] + __x64_sys_ioctl+0x19a/0x210 fs/ioctl.c:739 + do_syscall_64+0x33/0x40 arch/x86/entry/common.c:46 + entry_SYSCALL_64_after_hwframe+0x67/0xd1 +================================================================ + +Even though fbcon_init() checks beforehand if fb_match_mode() in +var_to_display() fails, it can not prevent the panic because fbcon_init() +does not return error code. Considering this and the comment in the code +about fb_match_mode() returning NULL - "This should not happen" - it is +better to prevent registering the fb_info if its mode was not set +successfully. Also move fb_add_videomode() closer to the beginning of +do_register_framebuffer() to avoid having to do the cleanup on fail. + +Found by Linux Verification Center (linuxtesting.org) with Syzkaller. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Cc: stable@vger.kernel.org +Signed-off-by: Murad Masimov <m.masimov@mt-integration.ru> +Signed-off-by: Helge Deller <deller@gmx.de> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/video/fbdev/core/fbmem.c | 18 +++++++++++------- + 1 file changed, 11 insertions(+), 7 deletions(-) + +diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c +index 5e8ee360f6ba2..a8d6bd465ffe4 100644 +--- a/drivers/video/fbdev/core/fbmem.c ++++ b/drivers/video/fbdev/core/fbmem.c +@@ -1622,7 +1622,7 @@ static void do_remove_conflicting_framebuffers(struct apertures_struct *a, + + static int do_register_framebuffer(struct fb_info *fb_info) + { +- int i; ++ int i, err = 0; + struct fb_videomode mode; + + if (fb_check_foreignness(fb_info)) +@@ -1635,10 +1635,18 @@ static int do_register_framebuffer(struct fb_info *fb_info) + if (num_registered_fb == FB_MAX) + return -ENXIO; + +- num_registered_fb++; + for (i = 0 ; i < FB_MAX; i++) + if (!registered_fb[i]) + break; ++ ++ if (!fb_info->modelist.prev || !fb_info->modelist.next) ++ INIT_LIST_HEAD(&fb_info->modelist); ++ ++ fb_var_to_videomode(&mode, &fb_info->var); ++ err = fb_add_videomode(&mode, &fb_info->modelist); ++ if (err < 0) ++ return err; ++ + fb_info->node = i; + refcount_set(&fb_info->count, 1); + mutex_init(&fb_info->lock); +@@ -1671,16 +1679,12 @@ static int do_register_framebuffer(struct fb_info *fb_info) + if (!fb_info->pixmap.blit_y) + fb_info->pixmap.blit_y = ~(u32)0; + +- if (!fb_info->modelist.prev || !fb_info->modelist.next) +- INIT_LIST_HEAD(&fb_info->modelist); +- + if (fb_info->skip_vt_switch) + pm_vt_switch_required(fb_info->dev, false); + else + pm_vt_switch_required(fb_info->dev, true); + +- fb_var_to_videomode(&mode, &fb_info->var); +- fb_add_videomode(&mode, &fb_info->modelist); ++ num_registered_fb++; + registered_fb[i] = fb_info; + + #ifdef CONFIG_GUMSTIX_AM200EPD +-- +2.39.5 + diff --git a/queue-5.15/fs-jfs-consolidate-sanity-checking-in-dbmount.patch b/queue-5.15/fs-jfs-consolidate-sanity-checking-in-dbmount.patch new file mode 100644 index 0000000000..6e2464c9cb --- /dev/null +++ b/queue-5.15/fs-jfs-consolidate-sanity-checking-in-dbmount.patch @@ -0,0 +1,81 @@ +From 4fa4e51a748bca922fce94f839a3828a7fbba5e9 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 65a94b0121742..d668a04a71d71 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.15/hwmon-pmbus-max34440-fix-support-for-max34451.patch b/queue-5.15/hwmon-pmbus-max34440-fix-support-for-max34451.patch new file mode 100644 index 0000000000..d7964df076 --- /dev/null +++ b/queue-5.15/hwmon-pmbus-max34440-fix-support-for-max34451.patch @@ -0,0 +1,144 @@ +From fdc800283b8e32a0d501dfaa05c7392b1ed22b26 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 ea7609058a12f..91359647d1e78 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.15/iio-pressure-zpa2326-use-aligned_s64-for-the-timesta.patch b/queue-5.15/iio-pressure-zpa2326-use-aligned_s64-for-the-timesta.patch new file mode 100644 index 0000000000..bcbe3364f6 --- /dev/null +++ b/queue-5.15/iio-pressure-zpa2326-use-aligned_s64-for-the-timesta.patch @@ -0,0 +1,36 @@ +From a70f1c62e85b4bbaff153b8492acf7df6e6e9366 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 50f3338778daf..741c95899e4ef 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.15/jfs-validate-ag-parameters-in-dbmount-to-prevent-cra.patch b/queue-5.15/jfs-validate-ag-parameters-in-dbmount-to-prevent-cra.patch new file mode 100644 index 0000000000..9769494997 --- /dev/null +++ b/queue-5.15/jfs-validate-ag-parameters-in-dbmount-to-prevent-cra.patch @@ -0,0 +1,78 @@ +From 381fbe8668937535d79b3a3d879cdac5b4039dd3 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 d668a04a71d71..cfb81bf5881ed 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.15/ksmbd-allow-a-filename-to-contain-special-characters.patch b/queue-5.15/ksmbd-allow-a-filename-to-contain-special-characters.patch new file mode 100644 index 0000000000..abb5166c25 --- /dev/null +++ b/queue-5.15/ksmbd-allow-a-filename-to-contain-special-characters.patch @@ -0,0 +1,109 @@ +From c80a515fdf8b39dd41ad59f74316e41080d7c351 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 27 May 2025 11:23:01 +0900 +Subject: ksmbd: allow a filename to contain special characters on SMB3.1.1 + posix extension + +From: Namjae Jeon <linkinjeon@kernel.org> + +[ Upstream commit dc3e0f17f74558e8a2fce00608855f050de10230 ] + +If client send SMB2_CREATE_POSIX_CONTEXT to ksmbd, Allow a filename +to contain special characters. + +Reported-by: Philipp Kerling <pkerling@casix.org> +Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> +Signed-off-by: Steve French <stfrench@microsoft.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + fs/ksmbd/smb2pdu.c | 53 +++++++++++++++++++++++----------------------- + 1 file changed, 27 insertions(+), 26 deletions(-) + +diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c +index b21601c0a457c..76334a983cd25 100644 +--- a/fs/ksmbd/smb2pdu.c ++++ b/fs/ksmbd/smb2pdu.c +@@ -2679,7 +2679,7 @@ int smb2_open(struct ksmbd_work *work) + int req_op_level = 0, open_flags = 0, may_flags = 0, file_info = 0; + int rc = 0; + int contxt_cnt = 0, query_disk_id = 0; +- int maximal_access_ctxt = 0, posix_ctxt = 0; ++ bool maximal_access_ctxt = false, posix_ctxt = false; + int s_type = 0; + int next_off = 0; + char *name = NULL; +@@ -2706,6 +2706,27 @@ int smb2_open(struct ksmbd_work *work) + return create_smb2_pipe(work); + } + ++ if (req->CreateContextsOffset && tcon->posix_extensions) { ++ context = smb2_find_context_vals(req, SMB2_CREATE_TAG_POSIX, 16); ++ if (IS_ERR(context)) { ++ rc = PTR_ERR(context); ++ goto err_out2; ++ } else if (context) { ++ struct create_posix *posix = (struct create_posix *)context; ++ ++ if (le16_to_cpu(context->DataOffset) + ++ le32_to_cpu(context->DataLength) < ++ sizeof(struct create_posix) - 4) { ++ rc = -EINVAL; ++ goto err_out2; ++ } ++ ksmbd_debug(SMB, "get posix context\n"); ++ ++ posix_mode = le32_to_cpu(posix->Mode); ++ posix_ctxt = true; ++ } ++ } ++ + if (req->NameLength) { + if ((req->CreateOptions & FILE_DIRECTORY_FILE_LE) && + *(char *)req->Buffer == '\\') { +@@ -2737,9 +2758,11 @@ int smb2_open(struct ksmbd_work *work) + goto err_out2; + } + +- rc = ksmbd_validate_filename(name); +- if (rc < 0) +- goto err_out2; ++ if (posix_ctxt == false) { ++ rc = ksmbd_validate_filename(name); ++ if (rc < 0) ++ goto err_out2; ++ } + + if (ksmbd_share_veto_filename(share, name)) { + rc = -ENOENT; +@@ -2854,28 +2877,6 @@ int smb2_open(struct ksmbd_work *work) + rc = -EBADF; + goto err_out2; + } +- +- if (tcon->posix_extensions) { +- context = smb2_find_context_vals(req, +- SMB2_CREATE_TAG_POSIX, 16); +- if (IS_ERR(context)) { +- rc = PTR_ERR(context); +- goto err_out2; +- } else if (context) { +- struct create_posix *posix = +- (struct create_posix *)context; +- if (le16_to_cpu(context->DataOffset) + +- le32_to_cpu(context->DataLength) < +- sizeof(struct create_posix) - 4) { +- rc = -EINVAL; +- goto err_out2; +- } +- ksmbd_debug(SMB, "get posix context\n"); +- +- posix_mode = le32_to_cpu(posix->Mode); +- posix_ctxt = 1; +- } +- } + } + + if (ksmbd_override_fsids(work)) { +-- +2.39.5 + diff --git a/queue-5.15/leds-multicolor-fix-intensity-setting-while-sw-blink.patch b/queue-5.15/leds-multicolor-fix-intensity-setting-while-sw-blink.patch new file mode 100644 index 0000000000..242c8ebbfa --- /dev/null +++ b/queue-5.15/leds-multicolor-fix-intensity-setting-while-sw-blink.patch @@ -0,0 +1,48 @@ +From 9507b3c44db59079ce414991674354e17c648dac 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 ec62a48116135..e0785935f4ba6 100644 +--- a/drivers/leds/led-class-multicolor.c ++++ b/drivers/leds/led-class-multicolor.c +@@ -61,7 +61,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.15/mailbox-not-protect-module_put-with-spin_lock_irqsav.patch b/queue-5.15/mailbox-not-protect-module_put-with-spin_lock_irqsav.patch new file mode 100644 index 0000000000..ff6a78edd1 --- /dev/null +++ b/queue-5.15/mailbox-not-protect-module_put-with-spin_lock_irqsav.patch @@ -0,0 +1,38 @@ +From 12b7337b82c647f96f4f6ec198aef68e48b5ada7 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.15/md-md-bitmap-fix-dm-raid-max_write_behind-setting.patch b/queue-5.15/md-md-bitmap-fix-dm-raid-max_write_behind-setting.patch new file mode 100644 index 0000000000..1a08bdf44f --- /dev/null +++ b/queue-5.15/md-md-bitmap-fix-dm-raid-max_write_behind-setting.patch @@ -0,0 +1,36 @@ +From c8bcba63c271197435344d8be2f6fb501adeb69b 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 b26e22dd9ba2e..cb84a4ab8d70f 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.15/media-davinci-vpif-fix-memory-leak-in-probe-error-pa.patch b/queue-5.15/media-davinci-vpif-fix-memory-leak-in-probe-error-pa.patch new file mode 100644 index 0000000000..7e20e4b5e0 --- /dev/null +++ b/queue-5.15/media-davinci-vpif-fix-memory-leak-in-probe-error-pa.patch @@ -0,0 +1,52 @@ +From 71eccbb07f9473d20ce795742a32a144860ba176 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Wed, 16 Apr 2025 23:51:19 +0300 +Subject: media: davinci: vpif: Fix memory leak in probe error path + +From: Dmitry Nikiforov <Dm1tryNk@yandex.ru> + +[ Upstream commit 024bf40edf1155e7a587f0ec46294049777d9b02 ] + +If an error occurs during the initialization of `pdev_display`, +the allocated platform device `pdev_capture` is not released properly, +leading to a memory leak. + +Adjust error path handling to fix the leak. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 43acb728bbc4 ("media: davinci: vpif: fix use-after-free on driver unbind") +Cc: stable@vger.kernel.org +Signed-off-by: Dmitry Nikiforov <Dm1tryNk@yandex.ru> +Reviewed-by: Johan Hovold <johan@kernel.org> +Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/media/platform/davinci/vpif.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/media/platform/davinci/vpif.c b/drivers/media/platform/davinci/vpif.c +index 8ffc01c606d0c..a59a059008cf8 100644 +--- a/drivers/media/platform/davinci/vpif.c ++++ b/drivers/media/platform/davinci/vpif.c +@@ -503,7 +503,7 @@ static int vpif_probe(struct platform_device *pdev) + pdev_display = kzalloc(sizeof(*pdev_display), GFP_KERNEL); + if (!pdev_display) { + ret = -ENOMEM; +- goto err_put_pdev_capture; ++ goto err_del_pdev_capture; + } + + pdev_display->name = "vpif_display"; +@@ -526,6 +526,8 @@ static int vpif_probe(struct platform_device *pdev) + + err_put_pdev_display: + platform_device_put(pdev_display); ++err_del_pdev_capture: ++ platform_device_del(pdev_capture); + err_put_pdev_capture: + platform_device_put(pdev_capture); + err_put_rpm: +-- +2.39.5 + diff --git a/queue-5.15/media-imx-jpeg-drop-the-first-error-frames.patch b/queue-5.15/media-imx-jpeg-drop-the-first-error-frames.patch new file mode 100644 index 0000000000..644f0dd9f8 --- /dev/null +++ b/queue-5.15/media-imx-jpeg-drop-the-first-error-frames.patch @@ -0,0 +1,59 @@ +From 075b9944d07d0055d43634f283564214affe35fb Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Mon, 21 Apr 2025 15:06:12 +0800 +Subject: media: imx-jpeg: Drop the first error frames + +From: Ming Qian <ming.qian@oss.nxp.com> + +[ Upstream commit d52b9b7e2f10d22a49468128540533e8d76910cd ] + +When an output buffer contains error frame header, +v4l2_jpeg_parse_header() will return error, then driver will mark this +buffer and a capture buffer done with error flag in device_run(). + +But if the error occurs in the first frames, before setup the capture +queue, there is no chance to schedule device_run(), and there may be no +capture to mark error. + +So we need to drop this buffer with error flag, and make the decoding +can continue. + +Fixes: 2db16c6ed72c ("media: imx-jpeg: Add V4L2 driver for i.MX8 JPEG Encoder/Decoder") +Cc: stable@vger.kernel.org +Signed-off-by: Ming Qian <ming.qian@oss.nxp.com> +Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> +Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> +Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/media/platform/imx-jpeg/mxc-jpeg.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/imx-jpeg/mxc-jpeg.c +index 059e45aa03b7f..2ab03444f742a 100644 +--- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c ++++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c +@@ -1450,9 +1450,19 @@ static void mxc_jpeg_buf_queue(struct vb2_buffer *vb) + jpeg_src_buf = vb2_to_mxc_buf(vb); + jpeg_src_buf->jpeg_parse_error = false; + ret = mxc_jpeg_parse(ctx, vb); +- if (ret) ++ if (ret) { + jpeg_src_buf->jpeg_parse_error = true; + ++ /* ++ * if the capture queue is not setup, the device_run() won't be scheduled, ++ * need to drop the error buffer, so that the decoding can continue ++ */ ++ if (!vb2_is_streaming(v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx))) { ++ v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); ++ return; ++ } ++ } ++ + end: + v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); + } +-- +2.39.5 + diff --git a/queue-5.15/media-omap3isp-use-sgtable-based-scatterlist-wrapper.patch b/queue-5.15/media-omap3isp-use-sgtable-based-scatterlist-wrapper.patch new file mode 100644 index 0000000000..fe2410b4f6 --- /dev/null +++ b/queue-5.15/media-omap3isp-use-sgtable-based-scatterlist-wrapper.patch @@ -0,0 +1,79 @@ +From 19a68660cc87761bc396cc5445aa476e220e7611 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 108b5e9f82cb0..ee966f8ee0103 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 68cf68dbcace2..dc496ca9748a6 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.15/mfd-max14577-fix-wakeup-source-leaks-on-device-unbin.patch b/queue-5.15/mfd-max14577-fix-wakeup-source-leaks-on-device-unbin.patch new file mode 100644 index 0000000000..d97b9e76a8 --- /dev/null +++ b/queue-5.15/mfd-max14577-fix-wakeup-source-leaks-on-device-unbin.patch @@ -0,0 +1,35 @@ +From ed5972efcc55f8d5c4d75327035b80707310fcd1 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.15/nfsv4-always-set-nlink-even-if-the-server-doesn-t-su.patch b/queue-5.15/nfsv4-always-set-nlink-even-if-the-server-doesn-t-su.patch new file mode 100644 index 0000000000..2077d3d1da --- /dev/null +++ b/queue-5.15/nfsv4-always-set-nlink-even-if-the-server-doesn-t-su.patch @@ -0,0 +1,41 @@ +From 3f30fe6bc840e377dd0ecf128396e1cffb375221 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Sun, 4 May 2025 20:57:04 +0800 +Subject: NFSv4: Always set NLINK even if the server doesn't support it + +From: Han Young <hanyang.tony@bytedance.com> + +[ Upstream commit 3a3065352f73381d3a1aa0ccab44aec3a5a9b365 ] + +fattr4_numlinks is a recommended attribute, so the client should emulate +it even if the server doesn't support it. In decode_attr_nlink function +in nfs4xdr.c, nlink is initialized to 1. However, this default value +isn't set to the inode due to the check in nfs_fhget. + +So if the server doesn't support numlinks, inode's nlink will be zero, +the mount will fail with error "Stale file handle". Set the nlink to 1 +if the server doesn't support it. + +Signed-off-by: Han Young <hanyang.tony@bytedance.com> +Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + fs/nfs/inode.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c +index 09922258f5a11..28c24079c57a8 100644 +--- a/fs/nfs/inode.c ++++ b/fs/nfs/inode.c +@@ -567,6 +567,8 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st + set_nlink(inode, fattr->nlink); + else if (fattr_supported & NFS_ATTR_FATTR_NLINK) + nfs_set_cache_invalid(inode, NFS_INO_INVALID_NLINK); ++ else ++ set_nlink(inode, 1); + if (fattr->valid & NFS_ATTR_FATTR_OWNER) + inode->i_uid = fattr->uid; + else if (fattr_supported & NFS_ATTR_FATTR_OWNER) +-- +2.39.5 + diff --git a/queue-5.15/nfsv4.2-fix-listxattr-to-return-selinux-security-lab.patch b/queue-5.15/nfsv4.2-fix-listxattr-to-return-selinux-security-lab.patch new file mode 100644 index 0000000000..2fb38153d2 --- /dev/null +++ b/queue-5.15/nfsv4.2-fix-listxattr-to-return-selinux-security-lab.patch @@ -0,0 +1,56 @@ +From 8b3951e94fe4874c947b06c8d01d664ecabdc924 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 e4b3f25bb8e48..9d4e4146efef0 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -10528,7 +10528,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); +@@ -10551,8 +10551,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.15/ovl-check-for-null-d_inode-in-ovl_dentry_upper.patch b/queue-5.15/ovl-check-for-null-d_inode-in-ovl_dentry_upper.patch new file mode 100644 index 0000000000..6c173dc88a --- /dev/null +++ b/queue-5.15/ovl-check-for-null-d_inode-in-ovl_dentry_upper.patch @@ -0,0 +1,68 @@ +From 19724f9e23dc2bb734c662ad061f884b0d93f03d 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 8a9980ab2ad8f..74abba466f19b 100644 +--- a/fs/overlayfs/util.c ++++ b/fs/overlayfs/util.c +@@ -215,7 +215,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.15/platform-x86-ideapad-laptop-use-usleep_range-for-ec-.patch b/queue-5.15/platform-x86-ideapad-laptop-use-usleep_range-for-ec-.patch new file mode 100644 index 0000000000..1917a5abd2 --- /dev/null +++ b/queue-5.15/platform-x86-ideapad-laptop-use-usleep_range-for-ec-.patch @@ -0,0 +1,127 @@ +From 3764f3ca5065946882a8e7f3385ea3cbe236368c Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Mon, 26 May 2025 04:18:07 +0800 +Subject: platform/x86: ideapad-laptop: use usleep_range() for EC polling +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Rong Zhang <i@rong.moe> + +[ Upstream commit 5808c34216954cd832bd4b8bc52dfa287049122b ] + +It was reported that ideapad-laptop sometimes causes some recent (since +2024) Lenovo ThinkBook models shut down when: + - suspending/resuming + - closing/opening the lid + - (dis)connecting a charger + - reading/writing some sysfs properties, e.g., fan_mode, touchpad + - pressing down some Fn keys, e.g., Brightness Up/Down (Fn+F5/F6) + - (seldom) loading the kmod + +The issue has existed since the launch day of such models, and there +have been some out-of-tree workarounds (see Link:) for the issue. One +disables some functionalities, while another one simply shortens +IDEAPAD_EC_TIMEOUT. The disabled functionalities have read_ec_data() in +their call chains, which calls schedule() between each poll. + +It turns out that these models suffer from the indeterminacy of +schedule() because of their low tolerance for being polled too +frequently. Sometimes schedule() returns too soon due to the lack of +ready tasks, causing the margin between two polls to be too short. +In this case, the command is somehow aborted, and too many subsequent +polls (they poll for "nothing!") may eventually break the state machine +in the EC, resulting in a hard shutdown. This explains why shortening +IDEAPAD_EC_TIMEOUT works around the issue - it reduces the total number +of polls sent to the EC. + +Even when it doesn't lead to a shutdown, frequent polls may also disturb +the ongoing operation and notably delay (+ 10-20ms) the availability of +EC response. This phenomenon is unlikely to be exclusive to the models +mentioned above, so dropping the schedule() manner should also slightly +improve the responsiveness of various models. + +Fix these issues by migrating to usleep_range(150, 300). The interval is +chosen to add some margin to the minimal 50us and considering EC +responses are usually available after 150-2500us based on my test. It +should be enough to fix these issues on all models subject to the EC bug +without introducing latency on other models. + +Tested on ThinkBook 14 G7+ ASP and solved both issues. No regression was +introduced in the test on a model without the EC bug (ThinkBook X IMH, +thanks Eric). + +Link: https://github.com/ty2/ideapad-laptop-tb2024g6plus/commit/6c5db18c9e8109873c2c90a7d2d7f552148f7ad4 +Link: https://github.com/ferstar/ideapad-laptop-tb/commit/42d1e68e5009529d31bd23f978f636f79c023e80 +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218771 +Fixes: 6a09f21dd1e2 ("ideapad: add ACPI helpers") +Cc: stable@vger.kernel.org +Tested-by: Felix Yan <felixonmars@archlinux.org> +Tested-by: Eric Long <i@hack3r.moe> +Tested-by: Jianfei Zhang <zhangjianfei3@gmail.com> +Tested-by: Mingcong Bai <jeffbai@aosc.io> +Tested-by: Minh Le <minhld139@gmail.com> +Tested-by: Sicheng Zhu <Emmet_Z@outlook.com> +Signed-off-by: Rong Zhang <i@rong.moe> +Link: https://lore.kernel.org/r/20250525201833.37939-1-i@rong.moe +Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> +Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/platform/x86/ideapad-laptop.c | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c +index e75b09a144a32..7c655ace4fdc2 100644 +--- a/drivers/platform/x86/ideapad-laptop.c ++++ b/drivers/platform/x86/ideapad-laptop.c +@@ -13,6 +13,7 @@ + #include <linux/bitops.h> + #include <linux/bug.h> + #include <linux/debugfs.h> ++#include <linux/delay.h> + #include <linux/device.h> + #include <linux/dmi.h> + #include <linux/fb.h> +@@ -158,6 +159,20 @@ MODULE_PARM_DESC(no_bt_rfkill, "No rfkill for bluetooth."); + */ + #define IDEAPAD_EC_TIMEOUT 200 /* in ms */ + ++/* ++ * Some models (e.g., ThinkBook since 2024) have a low tolerance for being ++ * polled too frequently. Doing so may break the state machine in the EC, ++ * resulting in a hard shutdown. ++ * ++ * It is also observed that frequent polls may disturb the ongoing operation ++ * and notably delay the availability of EC response. ++ * ++ * These values are used as the delay before the first poll and the interval ++ * between subsequent polls to solve the above issues. ++ */ ++#define IDEAPAD_EC_POLL_MIN_US 150 ++#define IDEAPAD_EC_POLL_MAX_US 300 ++ + static int eval_int(acpi_handle handle, const char *name, unsigned long *res) + { + unsigned long long result; +@@ -263,7 +278,7 @@ static int read_ec_data(acpi_handle handle, unsigned long cmd, unsigned long *da + end_jiffies = jiffies + msecs_to_jiffies(IDEAPAD_EC_TIMEOUT) + 1; + + while (time_before(jiffies, end_jiffies)) { +- schedule(); ++ usleep_range(IDEAPAD_EC_POLL_MIN_US, IDEAPAD_EC_POLL_MAX_US); + + err = eval_vpcr(handle, 1, &val); + if (err) +@@ -294,7 +309,7 @@ static int write_ec_cmd(acpi_handle handle, unsigned long cmd, unsigned long dat + end_jiffies = jiffies + msecs_to_jiffies(IDEAPAD_EC_TIMEOUT) + 1; + + while (time_before(jiffies, end_jiffies)) { +- schedule(); ++ usleep_range(IDEAPAD_EC_POLL_MIN_US, IDEAPAD_EC_POLL_MAX_US); + + err = eval_vpcr(handle, 1, &val); + if (err) +-- +2.39.5 + diff --git a/queue-5.15/regulator-add-devm-helpers-for-get-and-enable.patch b/queue-5.15/regulator-add-devm-helpers-for-get-and-enable.patch new file mode 100644 index 0000000000..5d1b74ffd5 --- /dev/null +++ b/queue-5.15/regulator-add-devm-helpers-for-get-and-enable.patch @@ -0,0 +1,283 @@ +From 25cfa5112db5e8a67f5c2594214f8a6a17734e77 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 32823a87fd409..3265e75e97ab4 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 61f922e6fe353..a1fce0f27ce16 100644 +--- a/include/linux/regulator/consumer.h ++++ b/include/linux/regulator/consumer.h +@@ -203,6 +203,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); + +@@ -240,12 +242,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, +@@ -350,6 +355,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) + { +@@ -371,6 +387,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, +@@ -461,6 +481,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.15/regulator-core-allow-drivers-to-define-their-init-da.patch b/queue-5.15/regulator-core-allow-drivers-to-define-their-init-da.patch new file mode 100644 index 0000000000..452aa83e7e --- /dev/null +++ b/queue-5.15/regulator-core-allow-drivers-to-define-their-init-da.patch @@ -0,0 +1,110 @@ +From 73db36d8a44c4fe76143ec6b17bda1effa86c8de 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 9113233f41cd1..32823a87fd409 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 bbf6590a6dec2..61f922e6fe353 100644 +--- a/include/linux/regulator/consumer.h ++++ b/include/linux/regulator/consumer.h +@@ -240,6 +240,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.15/revert-iommu-amd-prevent-binding-other-pci-drivers-t.patch b/queue-5.15/revert-iommu-amd-prevent-binding-other-pci-drivers-t.patch new file mode 100644 index 0000000000..66b190269e --- /dev/null +++ b/queue-5.15/revert-iommu-amd-prevent-binding-other-pci-drivers-t.patch @@ -0,0 +1,60 @@ +From 941edc8cdffaac06c9f8339aead66417cec250fe 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 b6ee83b81d32c..625ff2486982d 100644 +--- a/drivers/iommu/amd/init.c ++++ b/drivers/iommu/amd/init.c +@@ -1870,9 +1870,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.15/series b/queue-5.15/series new file mode 100644 index 0000000000..ac1a2531e0 --- /dev/null +++ b/queue-5.15/series @@ -0,0 +1,58 @@ +cifs-fix-cifs_query_path_info-for-windows-nt-servers.patch +nfsv4-always-set-nlink-even-if-the-server-doesn-t-su.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 +ksmbd-allow-a-filename-to-contain-special-characters.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 +coresight-only-check-bottom-two-claim-bits.patch +usb-dwc2-also-exit-clock_gating-when-stopping-udc-wh.patch +usb-potential-integer-overflow-in-usbg_make_tpg.patch +tty-serial-uartlite-register-uart-driver-in-init.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 +alsa-usb-audio-add-a-quirk-for-lenovo-thinkpad-thund.patch +ceph-fix-possible-integer-overflow-in-ceph_zero_obje.patch +ovl-check-for-null-d_inode-in-ovl_dentry_upper.patch +fs-jfs-consolidate-sanity-checking-in-dbmount.patch +jfs-validate-ag-parameters-in-dbmount-to-prevent-cra.patch +media-davinci-vpif-fix-memory-leak-in-probe-error-pa.patch +media-omap3isp-use-sgtable-based-scatterlist-wrapper.patch +clk-ti-am43xx-add-clkctrl-data-for-am43xx-adc1.patch +media-imx-jpeg-drop-the-first-error-frames.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 +f2fs-don-t-over-report-free-space-or-inodes-in-statv.patch +fbcon-use-delayed-work-for-cursor.patch +fbcon-extract-fbcon_open-release-helpers.patch +fbcon-move-more-common-code-into-fb_open.patch +fbcon-use-lock_fb_info-in-fbcon_open-release.patch +fbcon-move-console_lock-for-register-unlink-unregist.patch +fbdev-fix-do_register_framebuffer-to-prevent-null-pt.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 +fbcon-delete-a-few-unneeded-forward-decl.patch +tty-vt-consolemap-rename-and-document-struct-uni_pag.patch +vgacon-switch-vgacon_scrolldelta-and-vgacon_restore_.patch +vgacon-remove-unneeded-forward-declarations.patch +tty-vt-make-init-parameter-of-consw-con_init-a-bool.patch +tty-vt-sanitize-arguments-of-consw-con_clear.patch +tty-vt-make-consw-con_switch-return-a-bool.patch +dummycon-trigger-redraw-when-switching-consoles-with.patch +platform-x86-ideapad-laptop-use-usleep_range-for-ec-.patch diff --git a/queue-5.15/tty-serial-uartlite-register-uart-driver-in-init.patch b/queue-5.15/tty-serial-uartlite-register-uart-driver-in-init.patch new file mode 100644 index 0000000000..081d717b4d --- /dev/null +++ b/queue-5.15/tty-serial-uartlite-register-uart-driver-in-init.patch @@ -0,0 +1,101 @@ +From b56104ce4ae3bcd08e9d41be01d8cc77153f428b Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Mon, 31 Mar 2025 18:06:19 +0200 +Subject: tty: serial: uartlite: register uart driver in init + +From: Jakub Lewalski <jakub.lewalski@nokia.com> + +[ Upstream commit 6bd697b5fc39fd24e2aa418c7b7d14469f550a93 ] + +When two instances of uart devices are probing, a concurrency race can +occur. If one thread calls uart_register_driver function, which first +allocates and assigns memory to 'uart_state' member of uart_driver +structure, the other instance can bypass uart driver registration and +call ulite_assign. This calls uart_add_one_port, which expects the uart +driver to be fully initialized. This leads to a kernel panic due to a +null pointer dereference: + +[ 8.143581] BUG: kernel NULL pointer dereference, address: 00000000000002b8 +[ 8.156982] #PF: supervisor write access in kernel mode +[ 8.156984] #PF: error_code(0x0002) - not-present page +[ 8.156986] PGD 0 P4D 0 +... +[ 8.180668] RIP: 0010:mutex_lock+0x19/0x30 +[ 8.188624] Call Trace: +[ 8.188629] ? __die_body.cold+0x1a/0x1f +[ 8.195260] ? page_fault_oops+0x15c/0x290 +[ 8.209183] ? __irq_resolve_mapping+0x47/0x80 +[ 8.209187] ? exc_page_fault+0x64/0x140 +[ 8.209190] ? asm_exc_page_fault+0x22/0x30 +[ 8.209196] ? mutex_lock+0x19/0x30 +[ 8.223116] uart_add_one_port+0x60/0x440 +[ 8.223122] ? proc_tty_register_driver+0x43/0x50 +[ 8.223126] ? tty_register_driver+0x1ca/0x1e0 +[ 8.246250] ulite_probe+0x357/0x4b0 [uartlite] + +To prevent it, move uart driver registration in to init function. This +will ensure that uart_driver is always registered when probe function +is called. + +Signed-off-by: Jakub Lewalski <jakub.lewalski@nokia.com> +Signed-off-by: Elodie Decerle <elodie.decerle@nokia.com> +Link: https://lore.kernel.org/r/20250331160732.2042-1-elodie.decerle@nokia.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/tty/serial/uartlite.c | 25 ++++++++++++------------- + 1 file changed, 12 insertions(+), 13 deletions(-) + +diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c +index 36871cebd6a0f..0345eaf969630 100644 +--- a/drivers/tty/serial/uartlite.c ++++ b/drivers/tty/serial/uartlite.c +@@ -808,16 +808,6 @@ static int ulite_probe(struct platform_device *pdev) + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + +- if (!ulite_uart_driver.state) { +- dev_dbg(&pdev->dev, "uartlite: calling uart_register_driver()\n"); +- ret = uart_register_driver(&ulite_uart_driver); +- if (ret < 0) { +- dev_err(&pdev->dev, "Failed to register driver\n"); +- clk_disable_unprepare(pdata->clk); +- return ret; +- } +- } +- + ret = ulite_assign(&pdev->dev, id, res->start, irq, pdata); + + pm_runtime_mark_last_busy(&pdev->dev); +@@ -859,16 +849,25 @@ static struct platform_driver ulite_platform_driver = { + + static int __init ulite_init(void) + { ++ int ret; ++ ++ pr_debug("uartlite: calling uart_register_driver()\n"); ++ ret = uart_register_driver(&ulite_uart_driver); ++ if (ret) ++ return ret; + + pr_debug("uartlite: calling platform_driver_register()\n"); +- return platform_driver_register(&ulite_platform_driver); ++ ret = platform_driver_register(&ulite_platform_driver); ++ if (ret) ++ uart_unregister_driver(&ulite_uart_driver); ++ ++ return ret; + } + + static void __exit ulite_exit(void) + { + platform_driver_unregister(&ulite_platform_driver); +- if (ulite_uart_driver.state) +- uart_unregister_driver(&ulite_uart_driver); ++ uart_unregister_driver(&ulite_uart_driver); + } + + module_init(ulite_init); +-- +2.39.5 + diff --git a/queue-5.15/tty-vt-consolemap-rename-and-document-struct-uni_pag.patch b/queue-5.15/tty-vt-consolemap-rename-and-document-struct-uni_pag.patch new file mode 100644 index 0000000000..49c2eacab6 --- /dev/null +++ b/queue-5.15/tty-vt-consolemap-rename-and-document-struct-uni_pag.patch @@ -0,0 +1,242 @@ +From 7bc0695353e5925cd16dfbff9178b27fc1098271 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Tue, 7 Jun 2022 12:49:12 +0200 +Subject: tty/vt: consolemap: rename and document struct uni_pagedir + +From: Jiri Slaby <jslaby@suse.cz> + +[ Upstream commit 4173f018aae16b6496d292c234b858241f85254f ] + +struct uni_pagedir contains 32 unicode page directories, so the name of +the structure is a bit misleading. Rename the structure to uni_pagedict, +so it looks like this: +struct uni_pagedict + -> 32 page dirs + -> 32 rows + -> 64 glyphs + +Signed-off-by: Jiri Slaby <jslaby@suse.cz> +Link: https://lore.kernel.org/r/20220607104946.18710-2-jslaby@suse.cz +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Stable-dep-of: 03bcbbb3995b ("dummycon: Trigger redraw when switching consoles with deferred takeover") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/tty/vt/consolemap.c | 47 ++++++++++++++++++++-------------- + drivers/video/console/vgacon.c | 4 +-- + include/linux/console_struct.h | 6 ++--- + 3 files changed, 33 insertions(+), 24 deletions(-) + +diff --git a/drivers/tty/vt/consolemap.c b/drivers/tty/vt/consolemap.c +index d815ac98b39e3..32fa4df121dab 100644 +--- a/drivers/tty/vt/consolemap.c ++++ b/drivers/tty/vt/consolemap.c +@@ -186,17 +186,26 @@ static unsigned short translations[][256] = { + + static int inv_translate[MAX_NR_CONSOLES]; + +-struct uni_pagedir { +- u16 **uni_pgdir[32]; ++/** ++ * struct uni_pagedict -- unicode directory ++ * ++ * @uni_pgdir: 32*32*64 table with glyphs ++ * @refcount: reference count of this structure ++ * @sum: checksum ++ * @inverse_translations: best-effort inverse mapping ++ * @inverse_trans_unicode: best-effort inverse mapping to unicode ++ */ ++struct uni_pagedict { ++ u16 **uni_pgdir[32]; + unsigned long refcount; + unsigned long sum; + unsigned char *inverse_translations[4]; + u16 *inverse_trans_unicode; + }; + +-static struct uni_pagedir *dflt; ++static struct uni_pagedict *dflt; + +-static void set_inverse_transl(struct vc_data *conp, struct uni_pagedir *p, int i) ++static void set_inverse_transl(struct vc_data *conp, struct uni_pagedict *p, int i) + { + int j, glyph; + unsigned short *t = translations[i]; +@@ -221,7 +230,7 @@ static void set_inverse_transl(struct vc_data *conp, struct uni_pagedir *p, int + } + + static void set_inverse_trans_unicode(struct vc_data *conp, +- struct uni_pagedir *p) ++ struct uni_pagedict *p) + { + int i, j, k, glyph; + u16 **p1, *p2; +@@ -270,7 +279,7 @@ unsigned short *set_translate(int m, struct vc_data *vc) + */ + u16 inverse_translate(const struct vc_data *conp, int glyph, int use_unicode) + { +- struct uni_pagedir *p; ++ struct uni_pagedict *p; + int m; + if (glyph < 0 || glyph >= MAX_GLYPH) + return 0; +@@ -297,7 +306,7 @@ EXPORT_SYMBOL_GPL(inverse_translate); + static void update_user_maps(void) + { + int i; +- struct uni_pagedir *p, *q = NULL; ++ struct uni_pagedict *p, *q = NULL; + + for (i = 0; i < MAX_NR_CONSOLES; i++) { + if (!vc_cons_allocated(i)) +@@ -393,7 +402,7 @@ int con_get_trans_new(ushort __user * arg) + extern u8 dfont_unicount[]; /* Defined in console_defmap.c */ + extern u16 dfont_unitable[]; + +-static void con_release_unimap(struct uni_pagedir *p) ++static void con_release_unimap(struct uni_pagedict *p) + { + u16 **p1; + int i, j; +@@ -419,7 +428,7 @@ static void con_release_unimap(struct uni_pagedir *p) + /* Caller must hold the console lock */ + void con_free_unimap(struct vc_data *vc) + { +- struct uni_pagedir *p; ++ struct uni_pagedict *p; + + p = *vc->vc_uni_pagedir_loc; + if (!p) +@@ -431,10 +440,10 @@ void con_free_unimap(struct vc_data *vc) + kfree(p); + } + +-static int con_unify_unimap(struct vc_data *conp, struct uni_pagedir *p) ++static int con_unify_unimap(struct vc_data *conp, struct uni_pagedict *p) + { + int i, j, k; +- struct uni_pagedir *q; ++ struct uni_pagedict *q; + + for (i = 0; i < MAX_NR_CONSOLES; i++) { + if (!vc_cons_allocated(i)) +@@ -472,7 +481,7 @@ static int con_unify_unimap(struct vc_data *conp, struct uni_pagedir *p) + } + + static int +-con_insert_unipair(struct uni_pagedir *p, u_short unicode, u_short fontpos) ++con_insert_unipair(struct uni_pagedict *p, u_short unicode, u_short fontpos) + { + int i, n; + u16 **p1, *p2; +@@ -503,7 +512,7 @@ con_insert_unipair(struct uni_pagedir *p, u_short unicode, u_short fontpos) + /* Caller must hold the lock */ + static int con_do_clear_unimap(struct vc_data *vc) + { +- struct uni_pagedir *p, *q; ++ struct uni_pagedict *p, *q; + + p = *vc->vc_uni_pagedir_loc; + if (!p || --p->refcount) { +@@ -536,7 +545,7 @@ int con_clear_unimap(struct vc_data *vc) + int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list) + { + int err = 0, err1, i; +- struct uni_pagedir *p, *q; ++ struct uni_pagedict *p, *q; + struct unipair *unilist, *plist; + + if (!ct) +@@ -569,7 +578,7 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list) + + /* + * Since refcount was > 1, con_clear_unimap() allocated a +- * a new uni_pagedir for this vc. Re: p != q ++ * a new uni_pagedict for this vc. Re: p != q + */ + q = *vc->vc_uni_pagedir_loc; + +@@ -660,7 +669,7 @@ int con_set_default_unimap(struct vc_data *vc) + { + int i, j, err = 0, err1; + u16 *q; +- struct uni_pagedir *p; ++ struct uni_pagedict *p; + + if (dflt) { + p = *vc->vc_uni_pagedir_loc; +@@ -714,7 +723,7 @@ EXPORT_SYMBOL(con_set_default_unimap); + */ + int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc) + { +- struct uni_pagedir *q; ++ struct uni_pagedict *q; + + if (!*src_vc->vc_uni_pagedir_loc) + return -EINVAL; +@@ -739,7 +748,7 @@ int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct, struct uni + int i, j, k, ret = 0; + ushort ect; + u16 **p1, *p2; +- struct uni_pagedir *p; ++ struct uni_pagedict *p; + struct unipair *unilist; + + unilist = kvmalloc_array(ct, sizeof(struct unipair), GFP_KERNEL); +@@ -810,7 +819,7 @@ conv_uni_to_pc(struct vc_data *conp, long ucs) + { + int h; + u16 **p1, *p2; +- struct uni_pagedir *p; ++ struct uni_pagedict *p; + + /* Only 16-bit codes supported at this time */ + if (ucs > 0xffff) +diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c +index 63a6944ebb190..7bce5a174f388 100644 +--- a/drivers/video/console/vgacon.c ++++ b/drivers/video/console/vgacon.c +@@ -75,7 +75,7 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines); + static int vgacon_set_origin(struct vc_data *c); + static void vgacon_save_screen(struct vc_data *c); + static void vgacon_invert_region(struct vc_data *c, u16 * p, int count); +-static struct uni_pagedir *vgacon_uni_pagedir; ++static struct uni_pagedict *vgacon_uni_pagedir; + static int vgacon_refcount; + + /* Description of the hardware situation */ +@@ -363,7 +363,7 @@ static const char *vgacon_startup(void) + + static void vgacon_init(struct vc_data *c, int init) + { +- struct uni_pagedir *p; ++ struct uni_pagedict *p; + + /* + * We cannot be loaded as a module, therefore init will be 1 +diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h +index d5b9c8d40c18e..f75033f0277fc 100644 +--- a/include/linux/console_struct.h ++++ b/include/linux/console_struct.h +@@ -17,7 +17,7 @@ + #include <linux/vt.h> + #include <linux/workqueue.h> + +-struct uni_pagedir; ++struct uni_pagedict; + struct uni_screen; + + #define NPAR 16 +@@ -157,8 +157,8 @@ struct vc_data { + unsigned int vc_bell_duration; /* Console bell duration */ + unsigned short vc_cur_blink_ms; /* Cursor blink duration */ + struct vc_data **vc_display_fg; /* [!] Ptr to var holding fg console for this display */ +- struct uni_pagedir *vc_uni_pagedir; +- struct uni_pagedir **vc_uni_pagedir_loc; /* [!] Location of uni_pagedir variable for this console */ ++ struct uni_pagedict *vc_uni_pagedir; ++ struct uni_pagedict **vc_uni_pagedir_loc; /* [!] Location of uni_pagedict variable for this console */ + struct uni_screen *vc_uni_screen; /* unicode screen content */ + /* additional information is in vt_kern.h */ + }; +-- +2.39.5 + diff --git a/queue-5.15/tty-vt-make-consw-con_switch-return-a-bool.patch b/queue-5.15/tty-vt-make-consw-con_switch-return-a-bool.patch new file mode 100644 index 0000000000..13d887c01a --- /dev/null +++ b/queue-5.15/tty-vt-make-consw-con_switch-return-a-bool.patch @@ -0,0 +1,193 @@ +From 9dd9ae6e5ddba349d059fc020672b4ad2c7c00a5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Mon, 22 Jan 2024 12:03:44 +0100 +Subject: tty: vt: make consw::con_switch() return a bool + +From: Jiri Slaby (SUSE) <jirislaby@kernel.org> + +[ Upstream commit 8d5cc8eed738e3202379722295c626cba0849785 ] + +The non-zero (true) return value from consw::con_switch() means a redraw +is needed. So make this return type a bool explicitly instead of int. +The latter might imply that -Eerrors are expected. They are not. + +And document the hook. + +Signed-off-by: "Jiri Slaby (SUSE)" <jirislaby@kernel.org> +Cc: Helge Deller <deller@gmx.de> +Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com> +Cc: Daniel Vetter <daniel@ffwll.ch> +Cc: linux-fbdev@vger.kernel.org +Cc: dri-devel@lists.freedesktop.org +Cc: linux-parisc@vger.kernel.org +Tested-by: Helge Deller <deller@gmx.de> # parisc STI console +Link: https://lore.kernel.org/r/20240122110401.7289-31-jirislaby@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Stable-dep-of: 03bcbbb3995b ("dummycon: Trigger redraw when switching consoles with deferred takeover") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/tty/vt/vt.c | 2 +- + drivers/video/console/dummycon.c | 4 ++-- + drivers/video/console/mdacon.c | 4 ++-- + drivers/video/console/newport_con.c | 4 ++-- + drivers/video/console/sticon.c | 4 ++-- + drivers/video/console/vgacon.c | 4 ++-- + drivers/video/fbdev/core/fbcon.c | 6 +++--- + include/linux/console.h | 4 +++- + 8 files changed, 17 insertions(+), 15 deletions(-) + +diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c +index 765db5a7d5f52..a6e0c803e96ec 100644 +--- a/drivers/tty/vt/vt.c ++++ b/drivers/tty/vt/vt.c +@@ -1014,7 +1014,7 @@ void redraw_screen(struct vc_data *vc, int is_switch) + } + + if (redraw) { +- int update; ++ bool update; + int old_was_color = vc->vc_can_do_color; + + set_origin(vc); +diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c +index 6918014b02408..d701f2b51f5b1 100644 +--- a/drivers/video/console/dummycon.c ++++ b/drivers/video/console/dummycon.c +@@ -119,9 +119,9 @@ static bool dummycon_scroll(struct vc_data *vc, unsigned int top, + return false; + } + +-static int dummycon_switch(struct vc_data *vc) ++static bool dummycon_switch(struct vc_data *vc) + { +- return 0; ++ return false; + } + + /* +diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c +index 1ddbb6cd5b0ca..26b41a8f36c87 100644 +--- a/drivers/video/console/mdacon.c ++++ b/drivers/video/console/mdacon.c +@@ -454,9 +454,9 @@ static void mdacon_clear(struct vc_data *c, unsigned int y, unsigned int x, + scr_memsetw(dest, eattr, width * 2); + } + +-static int mdacon_switch(struct vc_data *c) ++static bool mdacon_switch(struct vc_data *c) + { +- return 1; /* redrawing needed */ ++ return true; /* redrawing needed */ + } + + static int mdacon_blank(struct vc_data *c, int blank, int mode_switch) +diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c +index 5dac00c825946..1ebb18bf10983 100644 +--- a/drivers/video/console/newport_con.c ++++ b/drivers/video/console/newport_con.c +@@ -462,7 +462,7 @@ static void newport_cursor(struct vc_data *vc, int mode) + } + } + +-static int newport_switch(struct vc_data *vc) ++static bool newport_switch(struct vc_data *vc) + { + static int logo_drawn = 0; + +@@ -476,7 +476,7 @@ static int newport_switch(struct vc_data *vc) + } + } + +- return 1; ++ return true; + } + + static int newport_blank(struct vc_data *c, int blank, int mode_switch) +diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c +index 58e983b18f1f4..6b82194a8ef36 100644 +--- a/drivers/video/console/sticon.c ++++ b/drivers/video/console/sticon.c +@@ -309,9 +309,9 @@ static void sticon_clear(struct vc_data *conp, unsigned int sy, unsigned int sx, + conp->vc_video_erase_char, font_data[conp->vc_num]); + } + +-static int sticon_switch(struct vc_data *conp) ++static bool sticon_switch(struct vc_data *conp) + { +- return 1; /* needs refreshing */ ++ return true; /* needs refreshing */ + } + + static int sticon_blank(struct vc_data *c, int blank, int mode_switch) +diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c +index 54d79edbe85e1..448aede31b946 100644 +--- a/drivers/video/console/vgacon.c ++++ b/drivers/video/console/vgacon.c +@@ -616,7 +616,7 @@ static int vgacon_doresize(struct vc_data *c, + return 0; + } + +-static int vgacon_switch(struct vc_data *c) ++static bool vgacon_switch(struct vc_data *c) + { + int x = c->vc_cols * VGA_FONTWIDTH; + int y = c->vc_rows * c->vc_cell_height; +@@ -645,7 +645,7 @@ static int vgacon_switch(struct vc_data *c) + vgacon_doresize(c, c->vc_cols, c->vc_rows); + } + +- return 0; /* Redrawing not needed */ ++ return false; /* Redrawing not needed */ + } + + static void vga_set_palette(struct vc_data *vc, const unsigned char *table) +diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c +index 7467b7a27ce2f..1ce767de96c11 100644 +--- a/drivers/video/fbdev/core/fbcon.c ++++ b/drivers/video/fbdev/core/fbcon.c +@@ -2043,7 +2043,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width, + return 0; + } + +-static int fbcon_switch(struct vc_data *vc) ++static bool fbcon_switch(struct vc_data *vc) + { + struct fb_info *info, *old_info = NULL; + struct fbcon_ops *ops; +@@ -2166,9 +2166,9 @@ static int fbcon_switch(struct vc_data *vc) + vc->vc_origin + vc->vc_size_row * vc->vc_top, + vc->vc_size_row * (vc->vc_bottom - + vc->vc_top) / 2); +- return 0; ++ return false; + } +- return 1; ++ return true; + } + + static void fbcon_generic_blank(struct vc_data *vc, struct fb_info *info, +diff --git a/include/linux/console.h b/include/linux/console.h +index bd7f3a6a64cd0..e2862542a162d 100644 +--- a/include/linux/console.h ++++ b/include/linux/console.h +@@ -40,6 +40,8 @@ enum vc_intensity; + * @con_scroll: move lines from @top to @bottom in direction @dir by @lines. + * Return true if no generic handling should be done. + * Invoked by csi_M and printing to the console. ++ * @con_switch: notifier about the console switch; it is supposed to return ++ * true if a redraw is needed. + * @con_set_palette: sets the palette of the console to @table (optional) + * @con_scrolldelta: the contents of the console should be scrolled by @lines. + * Invoked by user. (optional) +@@ -58,7 +60,7 @@ struct consw { + bool (*con_scroll)(struct vc_data *vc, unsigned int top, + unsigned int bottom, enum con_scroll dir, + unsigned int lines); +- int (*con_switch)(struct vc_data *vc); ++ bool (*con_switch)(struct vc_data *vc); + int (*con_blank)(struct vc_data *vc, int blank, int mode_switch); + int (*con_font_set)(struct vc_data *vc, struct console_font *font, + unsigned int flags); +-- +2.39.5 + diff --git a/queue-5.15/tty-vt-make-init-parameter-of-consw-con_init-a-bool.patch b/queue-5.15/tty-vt-make-init-parameter-of-consw-con_init-a-bool.patch new file mode 100644 index 0000000000..42c6815f33 --- /dev/null +++ b/queue-5.15/tty-vt-make-init-parameter-of-consw-con_init-a-bool.patch @@ -0,0 +1,190 @@ +From 4795e5b506771b3b468dddf33ecdd2a91b3eb256 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Mon, 22 Jan 2024 12:03:34 +0100 +Subject: tty: vt: make init parameter of consw::con_init() a bool + +From: Jiri Slaby (SUSE) <jirislaby@kernel.org> + +[ Upstream commit dae3e6b6180f1a2394b984c596d39ed2c57d25fe ] + +The 'init' parameter of consw::con_init() is true for the first call of +the hook on a particular console. So make the parameter a bool. + +And document the hook. + +Signed-off-by: "Jiri Slaby (SUSE)" <jirislaby@kernel.org> +Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> +Cc: Helge Deller <deller@gmx.de> +Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com> +Cc: Daniel Vetter <daniel@ffwll.ch> +Cc: linux-fbdev@vger.kernel.org +Cc: dri-devel@lists.freedesktop.org +Cc: linux-parisc@vger.kernel.org +Tested-by: Helge Deller <deller@gmx.de> # parisc STI console +Link: https://lore.kernel.org/r/20240122110401.7289-21-jirislaby@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Stable-dep-of: 03bcbbb3995b ("dummycon: Trigger redraw when switching consoles with deferred takeover") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/tty/vt/vt.c | 8 ++++---- + drivers/video/console/dummycon.c | 2 +- + drivers/video/console/mdacon.c | 2 +- + drivers/video/console/newport_con.c | 2 +- + drivers/video/console/sticon.c | 2 +- + drivers/video/console/vgacon.c | 4 ++-- + drivers/video/fbdev/core/fbcon.c | 2 +- + include/linux/console.h | 4 +++- + 8 files changed, 14 insertions(+), 12 deletions(-) + +diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c +index bd125ea5c51f4..0e3d7d8f5e75a 100644 +--- a/drivers/tty/vt/vt.c ++++ b/drivers/tty/vt/vt.c +@@ -1050,7 +1050,7 @@ int vc_cons_allocated(unsigned int i) + return (i < MAX_NR_CONSOLES && vc_cons[i].d); + } + +-static void visual_init(struct vc_data *vc, int num, int init) ++static void visual_init(struct vc_data *vc, int num, bool init) + { + /* ++Geert: vc->vc_sw->con_init determines console size */ + if (vc->vc_sw) +@@ -1134,7 +1134,7 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */ + vc->port.ops = &vc_port_ops; + INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK); + +- visual_init(vc, currcons, 1); ++ visual_init(vc, currcons, true); + + if (!*vc->vc_uni_pagedir_loc) + con_set_default_unimap(vc); +@@ -3521,7 +3521,7 @@ static int __init con_init(void) + vc_cons[currcons].d = vc = kzalloc(sizeof(struct vc_data), GFP_NOWAIT); + INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK); + tty_port_init(&vc->port); +- visual_init(vc, currcons, 1); ++ visual_init(vc, currcons, true); + /* Assuming vc->vc_{cols,rows,screenbuf_size} are sane here. */ + vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT); + vc_init(vc, vc->vc_rows, vc->vc_cols, +@@ -3692,7 +3692,7 @@ static int do_bind_con_driver(const struct consw *csw, int first, int last, + old_was_color = vc->vc_can_do_color; + vc->vc_sw->con_deinit(vc); + vc->vc_origin = (unsigned long)vc->vc_screenbuf; +- visual_init(vc, i, 0); ++ visual_init(vc, i, false); + set_origin(vc); + update_attr(vc); + +diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c +index f1711b2f9ff05..9a19eb72a18b9 100644 +--- a/drivers/video/console/dummycon.c ++++ b/drivers/video/console/dummycon.c +@@ -97,7 +97,7 @@ static const char *dummycon_startup(void) + return "dummy device"; + } + +-static void dummycon_init(struct vc_data *vc, int init) ++static void dummycon_init(struct vc_data *vc, bool init) + { + vc->vc_can_do_color = 1; + if (init) { +diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c +index ef29b321967f0..c5b255c968794 100644 +--- a/drivers/video/console/mdacon.c ++++ b/drivers/video/console/mdacon.c +@@ -352,7 +352,7 @@ static const char *mdacon_startup(void) + return "MDA-2"; + } + +-static void mdacon_init(struct vc_data *c, int init) ++static void mdacon_init(struct vc_data *c, bool init) + { + c->vc_complement_mask = 0x0800; /* reverse video */ + c->vc_display_fg = &mda_display_fg; +diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c +index d9c682ae03926..4b7161a81b2f6 100644 +--- a/drivers/video/console/newport_con.c ++++ b/drivers/video/console/newport_con.c +@@ -324,7 +324,7 @@ static const char *newport_startup(void) + return NULL; + } + +-static void newport_init(struct vc_data *vc, int init) ++static void newport_init(struct vc_data *vc, bool init) + { + int cols, rows; + +diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c +index f304163e87e99..10302df885147 100644 +--- a/drivers/video/console/sticon.c ++++ b/drivers/video/console/sticon.c +@@ -272,7 +272,7 @@ static int sticon_font_set(struct vc_data *vc, struct console_font *font, + return sticon_set_font(vc, font); + } + +-static void sticon_init(struct vc_data *c, int init) ++static void sticon_init(struct vc_data *c, bool init) + { + struct sti_struct *sti = sticon_sti; + int vc_cols, vc_rows; +diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c +index 9bfe451050209..a9777fd38ad92 100644 +--- a/drivers/video/console/vgacon.c ++++ b/drivers/video/console/vgacon.c +@@ -353,7 +353,7 @@ static const char *vgacon_startup(void) + return display_desc; + } + +-static void vgacon_init(struct vc_data *c, int init) ++static void vgacon_init(struct vc_data *c, bool init) + { + struct uni_pagedict *p; + +@@ -370,7 +370,7 @@ static void vgacon_init(struct vc_data *c, int init) + c->vc_scan_lines = vga_scan_lines; + c->vc_font.height = c->vc_cell_height = vga_video_font_height; + +- /* set dimensions manually if init != 0 since vc_resize() will fail */ ++ /* set dimensions manually if init is true since vc_resize() will fail */ + if (init) { + c->vc_cols = vga_video_num_columns; + c->vc_rows = vga_video_num_lines; +diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c +index a3af7aacfaf11..f47dbba972fbb 100644 +--- a/drivers/video/fbdev/core/fbcon.c ++++ b/drivers/video/fbdev/core/fbcon.c +@@ -983,7 +983,7 @@ static const char *fbcon_startup(void) + return display_desc; + } + +-static void fbcon_init(struct vc_data *vc, int init) ++static void fbcon_init(struct vc_data *vc, bool init) + { + struct fb_info *info; + struct fbcon_ops *ops; +diff --git a/include/linux/console.h b/include/linux/console.h +index a97f277cfdfa3..9258cb8e0841e 100644 +--- a/include/linux/console.h ++++ b/include/linux/console.h +@@ -34,6 +34,8 @@ enum vc_intensity; + /** + * struct consw - callbacks for consoles + * ++ * @con_init: initialize the console on @vc. @init is true for the very first ++ * call on this @vc. + * @con_scroll: move lines from @top to @bottom in direction @dir by @lines. + * Return true if no generic handling should be done. + * Invoked by csi_M and printing to the console. +@@ -44,7 +46,7 @@ enum vc_intensity; + struct consw { + struct module *owner; + const char *(*con_startup)(void); +- void (*con_init)(struct vc_data *vc, int init); ++ void (*con_init)(struct vc_data *vc, bool init); + void (*con_deinit)(struct vc_data *vc); + void (*con_clear)(struct vc_data *vc, int sy, int sx, int height, + int width); +-- +2.39.5 + diff --git a/queue-5.15/tty-vt-sanitize-arguments-of-consw-con_clear.patch b/queue-5.15/tty-vt-sanitize-arguments-of-consw-con_clear.patch new file mode 100644 index 0000000000..ff3f26fb72 --- /dev/null +++ b/queue-5.15/tty-vt-sanitize-arguments-of-consw-con_clear.patch @@ -0,0 +1,313 @@ +From 68914630d09ed6e78a359d0824b3e49eab1322af Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Mon, 22 Jan 2024 12:03:35 +0100 +Subject: tty: vt: sanitize arguments of consw::con_clear() + +From: Jiri Slaby (SUSE) <jirislaby@kernel.org> + +[ Upstream commit 559f01a0ee6d924c6fec3eaf6a5b078b15e71070 ] + +In consw::con_clear(): +* Height is always 1, so drop it. +* Offsets and width are always unsigned values, so re-type them as such. + +This needs a new __fbcon_clear() in the fbcon code to still handle +height which might not be 1 when called internally. + +Note that tests for negative count/width are left in place -- they are +taken care of in the next patches. + +And document the hook. + +Signed-off-by: "Jiri Slaby (SUSE)" <jirislaby@kernel.org> +Cc: Helge Deller <deller@gmx.de> +Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com> +Cc: Daniel Vetter <daniel@ffwll.ch> +Cc: linux-fbdev@vger.kernel.org +Cc: dri-devel@lists.freedesktop.org +Cc: linux-parisc@vger.kernel.org +Tested-by: Helge Deller <deller@gmx.de> # parisc STI console +Link: https://lore.kernel.org/r/20240122110401.7289-22-jirislaby@kernel.org +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Stable-dep-of: 03bcbbb3995b ("dummycon: Trigger redraw when switching consoles with deferred takeover") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/tty/vt/vt.c | 2 +- + drivers/video/console/dummycon.c | 4 ++-- + drivers/video/console/mdacon.c | 15 +++++--------- + drivers/video/console/newport_con.c | 6 +++--- + drivers/video/console/sticon.c | 8 ++++---- + drivers/video/console/vgacon.c | 4 ++-- + drivers/video/fbdev/core/fbcon.c | 32 +++++++++++++++++------------ + include/linux/console.h | 5 +++-- + 8 files changed, 39 insertions(+), 37 deletions(-) + +diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c +index 0e3d7d8f5e75a..765db5a7d5f52 100644 +--- a/drivers/tty/vt/vt.c ++++ b/drivers/tty/vt/vt.c +@@ -1628,7 +1628,7 @@ static void csi_X(struct vc_data *vc, unsigned int vpar) + vc_uniscr_clear_line(vc, vc->state.x, count); + scr_memsetw((unsigned short *)vc->vc_pos, vc->vc_video_erase_char, 2 * count); + if (con_should_update(vc)) +- vc->vc_sw->con_clear(vc, vc->state.y, vc->state.x, 1, count); ++ vc->vc_sw->con_clear(vc, vc->state.y, vc->state.x, count); + vc->vc_need_wrap = 0; + } + +diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c +index 9a19eb72a18b9..6918014b02408 100644 +--- a/drivers/video/console/dummycon.c ++++ b/drivers/video/console/dummycon.c +@@ -108,8 +108,8 @@ static void dummycon_init(struct vc_data *vc, bool init) + } + + static void dummycon_deinit(struct vc_data *vc) { } +-static void dummycon_clear(struct vc_data *vc, int sy, int sx, int height, +- int width) { } ++static void dummycon_clear(struct vc_data *vc, unsigned int sy, unsigned int sx, ++ unsigned int width) { } + static void dummycon_cursor(struct vc_data *vc, int mode) { } + + static bool dummycon_scroll(struct vc_data *vc, unsigned int top, +diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c +index c5b255c968794..1ddbb6cd5b0ca 100644 +--- a/drivers/video/console/mdacon.c ++++ b/drivers/video/console/mdacon.c +@@ -442,23 +442,18 @@ static void mdacon_putcs(struct vc_data *c, const unsigned short *s, + } + } + +-static void mdacon_clear(struct vc_data *c, int y, int x, +- int height, int width) ++static void mdacon_clear(struct vc_data *c, unsigned int y, unsigned int x, ++ unsigned int width) + { + u16 *dest = mda_addr(x, y); + u16 eattr = mda_convert_attr(c->vc_video_erase_char); + +- if (width <= 0 || height <= 0) ++ if (width <= 0) + return; + +- if (x==0 && width==mda_num_columns) { +- scr_memsetw(dest, eattr, height*width*2); +- } else { +- for (; height > 0; height--, dest+=mda_num_columns) +- scr_memsetw(dest, eattr, width*2); +- } ++ scr_memsetw(dest, eattr, width * 2); + } +- ++ + static int mdacon_switch(struct vc_data *c) + { + return 1; /* redrawing needed */ +diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c +index 4b7161a81b2f6..5dac00c825946 100644 +--- a/drivers/video/console/newport_con.c ++++ b/drivers/video/console/newport_con.c +@@ -346,12 +346,12 @@ static void newport_deinit(struct vc_data *c) + } + } + +-static void newport_clear(struct vc_data *vc, int sy, int sx, int height, +- int width) ++static void newport_clear(struct vc_data *vc, unsigned int sy, unsigned int sx, ++ unsigned int width) + { + int xend = ((sx + width) << 3) - 1; + int ystart = ((sy << 4) + topscan) & 0x3ff; +- int yend = (((sy + height) << 4) + topscan - 1) & 0x3ff; ++ int yend = (((sy + 1) << 4) + topscan - 1) & 0x3ff; + + if (logo_active) + return; +diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c +index 10302df885147..58e983b18f1f4 100644 +--- a/drivers/video/console/sticon.c ++++ b/drivers/video/console/sticon.c +@@ -299,13 +299,13 @@ static void sticon_deinit(struct vc_data *c) + sticon_set_def_font(i, NULL); + } + +-static void sticon_clear(struct vc_data *conp, int sy, int sx, int height, +- int width) ++static void sticon_clear(struct vc_data *conp, unsigned int sy, unsigned int sx, ++ unsigned int width) + { +- if (!height || !width) ++ if (!width) + return; + +- sti_clear(sticon_sti, sy, sx, height, width, ++ sti_clear(sticon_sti, sy, sx, 1, width, + conp->vc_video_erase_char, font_data[conp->vc_num]); + } + +diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c +index a9777fd38ad92..54d79edbe85e1 100644 +--- a/drivers/video/console/vgacon.c ++++ b/drivers/video/console/vgacon.c +@@ -1187,8 +1187,8 @@ static bool vgacon_scroll(struct vc_data *c, unsigned int t, unsigned int b, + * The console `switch' structure for the VGA based console + */ + +-static void vgacon_clear(struct vc_data *vc, int sy, int sx, int height, +- int width) { } ++static void vgacon_clear(struct vc_data *vc, unsigned int sy, unsigned int sx, ++ unsigned int width) { } + static void vgacon_putc(struct vc_data *vc, int c, int ypos, int xpos) { } + static void vgacon_putcs(struct vc_data *vc, const unsigned short *s, + int count, int ypos, int xpos) { } +diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c +index f47dbba972fbb..7467b7a27ce2f 100644 +--- a/drivers/video/fbdev/core/fbcon.c ++++ b/drivers/video/fbdev/core/fbcon.c +@@ -1210,8 +1210,8 @@ static void fbcon_deinit(struct vc_data *vc) + * restriction is simplicity & efficiency at the moment. + */ + +-static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height, +- int width) ++static void __fbcon_clear(struct vc_data *vc, unsigned int sy, unsigned int sx, ++ unsigned int height, unsigned int width) + { + struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + struct fbcon_ops *ops = info->fbcon_par; +@@ -1250,6 +1250,12 @@ static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height, + ops->clear(vc, info, real_y(p, sy), sx, height, width, fg, bg); + } + ++static void fbcon_clear(struct vc_data *vc, unsigned int sy, unsigned int sx, ++ unsigned int width) ++{ ++ __fbcon_clear(vc, sy, sx, 1, width); ++} ++ + static void fbcon_putcs(struct vc_data *vc, const unsigned short *s, + int count, int ypos, int xpos) + { +@@ -1673,7 +1679,7 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b, + case SCROLL_MOVE: + fbcon_redraw_blit(vc, info, p, t, b - t - count, + count); +- fbcon_clear(vc, b - count, 0, count, vc->vc_cols); ++ __fbcon_clear(vc, b - count, 0, count, vc->vc_cols); + scr_memsetw((unsigned short *) (vc->vc_origin + + vc->vc_size_row * + (b - count)), +@@ -1696,7 +1702,7 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b, + b - t - count, vc->vc_cols); + else + goto redraw_up; +- fbcon_clear(vc, b - count, 0, count, vc->vc_cols); ++ __fbcon_clear(vc, b - count, 0, count, vc->vc_cols); + break; + + case SCROLL_PAN_REDRAW: +@@ -1714,7 +1720,7 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b, + vc->vc_rows - b, b); + } else + fbcon_redraw_move(vc, p, t + count, b - t - count, t); +- fbcon_clear(vc, b - count, 0, count, vc->vc_cols); ++ __fbcon_clear(vc, b - count, 0, count, vc->vc_cols); + break; + + case SCROLL_PAN_MOVE: +@@ -1737,14 +1743,14 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b, + b - t - count, vc->vc_cols); + else + goto redraw_up; +- fbcon_clear(vc, b - count, 0, count, vc->vc_cols); ++ __fbcon_clear(vc, b - count, 0, count, vc->vc_cols); + break; + + case SCROLL_REDRAW: + redraw_up: + fbcon_redraw(vc, p, t, b - t - count, + count * vc->vc_cols); +- fbcon_clear(vc, b - count, 0, count, vc->vc_cols); ++ __fbcon_clear(vc, b - count, 0, count, vc->vc_cols); + scr_memsetw((unsigned short *) (vc->vc_origin + + vc->vc_size_row * + (b - count)), +@@ -1761,7 +1767,7 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b, + case SCROLL_MOVE: + fbcon_redraw_blit(vc, info, p, b - 1, b - t - count, + -count); +- fbcon_clear(vc, t, 0, count, vc->vc_cols); ++ __fbcon_clear(vc, t, 0, count, vc->vc_cols); + scr_memsetw((unsigned short *) (vc->vc_origin + + vc->vc_size_row * + t), +@@ -1784,7 +1790,7 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b, + b - t - count, vc->vc_cols); + else + goto redraw_down; +- fbcon_clear(vc, t, 0, count, vc->vc_cols); ++ __fbcon_clear(vc, t, 0, count, vc->vc_cols); + break; + + case SCROLL_PAN_MOVE: +@@ -1806,7 +1812,7 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b, + b - t - count, vc->vc_cols); + else + goto redraw_down; +- fbcon_clear(vc, t, 0, count, vc->vc_cols); ++ __fbcon_clear(vc, t, 0, count, vc->vc_cols); + break; + + case SCROLL_PAN_REDRAW: +@@ -1823,14 +1829,14 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b, + fbcon_redraw_move(vc, p, count, t, 0); + } else + fbcon_redraw_move(vc, p, t, b - t - count, t + count); +- fbcon_clear(vc, t, 0, count, vc->vc_cols); ++ __fbcon_clear(vc, t, 0, count, vc->vc_cols); + break; + + case SCROLL_REDRAW: + redraw_down: + fbcon_redraw(vc, p, b - 1, b - t - count, + -count * vc->vc_cols); +- fbcon_clear(vc, t, 0, count, vc->vc_cols); ++ __fbcon_clear(vc, t, 0, count, vc->vc_cols); + scr_memsetw((unsigned short *) (vc->vc_origin + + vc->vc_size_row * + t), +@@ -2175,7 +2181,7 @@ static void fbcon_generic_blank(struct vc_data *vc, struct fb_info *info, + + oldc = vc->vc_video_erase_char; + vc->vc_video_erase_char &= charmask; +- fbcon_clear(vc, 0, 0, vc->vc_rows, vc->vc_cols); ++ __fbcon_clear(vc, 0, 0, vc->vc_rows, vc->vc_cols); + vc->vc_video_erase_char = oldc; + } + } +diff --git a/include/linux/console.h b/include/linux/console.h +index 9258cb8e0841e..bd7f3a6a64cd0 100644 +--- a/include/linux/console.h ++++ b/include/linux/console.h +@@ -36,6 +36,7 @@ enum vc_intensity; + * + * @con_init: initialize the console on @vc. @init is true for the very first + * call on this @vc. ++ * @con_clear: erase @count characters at [@x, @y] on @vc. @count >= 1. + * @con_scroll: move lines from @top to @bottom in direction @dir by @lines. + * Return true if no generic handling should be done. + * Invoked by csi_M and printing to the console. +@@ -48,8 +49,8 @@ struct consw { + const char *(*con_startup)(void); + void (*con_init)(struct vc_data *vc, bool init); + void (*con_deinit)(struct vc_data *vc); +- void (*con_clear)(struct vc_data *vc, int sy, int sx, int height, +- int width); ++ void (*con_clear)(struct vc_data *vc, unsigned int y, ++ unsigned int x, unsigned int count); + void (*con_putc)(struct vc_data *vc, int c, int ypos, int xpos); + void (*con_putcs)(struct vc_data *vc, const unsigned short *s, + int count, int ypos, int xpos); +-- +2.39.5 + diff --git a/queue-5.15/uio_hv_generic-align-ring-size-to-system-page.patch b/queue-5.15/uio_hv_generic-align-ring-size-to-system-page.patch new file mode 100644 index 0000000000..c7e9c81955 --- /dev/null +++ b/queue-5.15/uio_hv_generic-align-ring-size-to-system-page.patch @@ -0,0 +1,41 @@ +From efb2dcd0f249a4344459fb86687f659930e0413f 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 db8a450b5a19b..865a5b289e0a5 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.15/uio_hv_generic-query-the-ringbuffer-size-for-device.patch b/queue-5.15/uio_hv_generic-query-the-ringbuffer-size-for-device.patch new file mode 100644 index 0000000000..0e1e756dab --- /dev/null +++ b/queue-5.15/uio_hv_generic-query-the-ringbuffer-size-for-device.patch @@ -0,0 +1,56 @@ +From c894da74c14c39b60fb91e24d874a06aa81ffc06 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 9daa1afbf9dbf..db8a450b5a19b 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.15/um-add-cmpxchg8b_emu-and-checksum-functions-to-asm-p.patch b/queue-5.15/um-add-cmpxchg8b_emu-and-checksum-functions-to-asm-p.patch new file mode 100644 index 0000000000..2d81c2ec53 --- /dev/null +++ b/queue-5.15/um-add-cmpxchg8b_emu-and-checksum-functions-to-asm-p.patch @@ -0,0 +1,55 @@ +From 326abf98af6def5132cb53ac78cf44374b197e5a 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.15/usb-add-checks-for-snprintf-calls-in-usb_alloc_dev.patch b/queue-5.15/usb-add-checks-for-snprintf-calls-in-usb_alloc_dev.patch new file mode 100644 index 0000000000..1b91a68f36 --- /dev/null +++ b/queue-5.15/usb-add-checks-for-snprintf-calls-in-usb_alloc_dev.patch @@ -0,0 +1,72 @@ +From 208b49a411d28a4d4f8d19a67b0ef71812e84941 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 ec8e003f59415..a16e7ebb7f953 100644 +--- a/drivers/usb/core/usb.c ++++ b/drivers/usb/core/usb.c +@@ -750,15 +750,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 + +@@ -767,6 +768,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.15/usb-cdc-wdm-avoid-setting-wdm_read-for-zlp-s.patch b/queue-5.15/usb-cdc-wdm-avoid-setting-wdm_read-for-zlp-s.patch new file mode 100644 index 0000000000..e0a511fc37 --- /dev/null +++ b/queue-5.15/usb-cdc-wdm-avoid-setting-wdm_read-for-zlp-s.patch @@ -0,0 +1,114 @@ +From 5a31d8b28769f062c206e0b6ad8d6aa86633c3a6 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 a4be6dba756b3..4b5cf1a5e30d8 100644 +--- a/drivers/usb/class/cdc-wdm.c ++++ b/drivers/usb/class/cdc-wdm.c +@@ -92,7 +92,6 @@ struct wdm_device { + u16 wMaxCommand; + u16 wMaxPacketSize; + __le16 inum; +- int reslength; + int length; + int read; + int count; +@@ -214,6 +213,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); +@@ -222,18 +226,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); +@@ -585,15 +589,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); + } +@@ -1015,7 +1010,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.15/usb-common-usb-conn-gpio-use-a-unique-name-for-usb-c.patch b/queue-5.15/usb-common-usb-conn-gpio-use-a-unique-name-for-usb-c.patch new file mode 100644 index 0000000000..3b40817f4a --- /dev/null +++ b/queue-5.15/usb-common-usb-conn-gpio-use-a-unique-name-for-usb-c.patch @@ -0,0 +1,93 @@ +From 8c4b3e51b71d1e9198ebcaef9b7d26dfd9f69f7e 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 521c95935d4c3..9691a1c8d8b0e 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); + } +@@ -292,6 +308,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.15/usb-dwc2-also-exit-clock_gating-when-stopping-udc-wh.patch b/queue-5.15/usb-dwc2-also-exit-clock_gating-when-stopping-udc-wh.patch new file mode 100644 index 0000000000..e41ae6a6ef --- /dev/null +++ b/queue-5.15/usb-dwc2-also-exit-clock_gating-when-stopping-udc-wh.patch @@ -0,0 +1,47 @@ +From 5d6b85a8756cd6d9f584795af3136234ff15539e Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Thu, 17 Apr 2025 19:40:17 +0200 +Subject: usb: dwc2: also exit clock_gating when stopping udc while suspended + +From: Michael Grzeschik <m.grzeschik@pengutronix.de> + +[ Upstream commit af076a41f8a28faf9ceb9dd2d88aef2c202ef39a ] + +It is possible that the gadget will be disabled, while the udc is +suspended. When enabling the udc in that case, the clock gating +will not be enabled again. Leaving the phy unclocked. Even when the +udc is not enabled, connecting this powered but not clocked phy leads +to enumeration errors on the host side. + +To ensure that the clock gating will be in an valid state, we ensure +that the clock gating will be enabled before stopping the udc. + +Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de> +Acked-by: Minas Harutyunyan <hminas@synopsys.com> +Link: https://lore.kernel.org/r/20250417-dwc2_clock_gating-v1-1-8ea7c4d53d73@pengutronix.de +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/usb/dwc2/gadget.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c +index 7d8523398e191..525d1d0cfc249 100644 +--- a/drivers/usb/dwc2/gadget.c ++++ b/drivers/usb/dwc2/gadget.c +@@ -4602,6 +4602,12 @@ static int dwc2_hsotg_udc_stop(struct usb_gadget *gadget) + if (!hsotg) + return -ENODEV; + ++ /* Exit clock gating when driver is stopped. */ ++ if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_NONE && ++ hsotg->bus_suspended && !hsotg->params.no_clock_gating) { ++ dwc2_gadget_exit_clock_gating(hsotg, 0); ++ } ++ + /* all endpoints should be shutdown */ + for (ep = 1; ep < hsotg->num_of_eps; ep++) { + if (hsotg->eps_in[ep]) +-- +2.39.5 + diff --git a/queue-5.15/usb-potential-integer-overflow-in-usbg_make_tpg.patch b/queue-5.15/usb-potential-integer-overflow-in-usbg_make_tpg.patch new file mode 100644 index 0000000000..d262593894 --- /dev/null +++ b/queue-5.15/usb-potential-integer-overflow-in-usbg_make_tpg.patch @@ -0,0 +1,53 @@ +From 227c3796f4241cbf4405089c3febb0eb07a402bc 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 934e4b2a049ff..de54b0143894f 100644 +--- a/drivers/usb/gadget/function/f_tcm.c ++++ b/drivers/usb/gadget/function/f_tcm.c +@@ -1321,14 +1321,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.15/usb-typec-displayport-receive-dp-status-update-nak-r.patch b/queue-5.15/usb-typec-displayport-receive-dp-status-update-nak-r.patch new file mode 100644 index 0000000000..63a179ff88 --- /dev/null +++ b/queue-5.15/usb-typec-displayport-receive-dp-status-update-nak-r.patch @@ -0,0 +1,56 @@ +From 537924287367daad854e816569ccea65b24745c2 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 97a912f0c4eed..c76b872535d17 100644 +--- a/drivers/usb/typec/altmodes/displayport.c ++++ b/drivers/usb/typec/altmodes/displayport.c +@@ -298,6 +298,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.15/vgacon-remove-unneeded-forward-declarations.patch b/queue-5.15/vgacon-remove-unneeded-forward-declarations.patch new file mode 100644 index 0000000000..016d2c9b8a --- /dev/null +++ b/queue-5.15/vgacon-remove-unneeded-forward-declarations.patch @@ -0,0 +1,47 @@ +From cac2ff90a438e8ca9b86bb9abc7b9d601a4d1831 Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Wed, 12 Jul 2023 10:59:37 +0200 +Subject: vgacon: remove unneeded forward declarations + +From: Jiri Slaby (SUSE) <jirislaby@kernel.org> + +[ Upstream commit 6ceed69cde8fe4a78fe50d62d7a88a5c1eed4709 ] + +Most of the forward declarations in vgacon are not needed. Drop them. + +Signed-off-by: "Jiri Slaby (SUSE)" <jirislaby@kernel.org> +Cc: Helge Deller <deller@gmx.de> +Cc: linux-fbdev@vger.kernel.org +Cc: dri-devel@lists.freedesktop.org +Signed-off-by: Helge Deller <deller@gmx.de> +Stable-dep-of: 03bcbbb3995b ("dummycon: Trigger redraw when switching consoles with deferred takeover") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/video/console/vgacon.c | 10 +--------- + 1 file changed, 1 insertion(+), 9 deletions(-) + +diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c +index b2180fd183307..9bfe451050209 100644 +--- a/drivers/video/console/vgacon.c ++++ b/drivers/video/console/vgacon.c +@@ -65,16 +65,8 @@ static struct vgastate vgastate; + * Interface used by the world + */ + +-static const char *vgacon_startup(void); +-static void vgacon_init(struct vc_data *c, int init); +-static void vgacon_deinit(struct vc_data *c); +-static void vgacon_cursor(struct vc_data *c, int mode); +-static int vgacon_switch(struct vc_data *c); +-static int vgacon_blank(struct vc_data *c, int blank, int mode_switch); +-static void vgacon_scrolldelta(struct vc_data *c, int lines); + static int vgacon_set_origin(struct vc_data *c); +-static void vgacon_save_screen(struct vc_data *c); +-static void vgacon_invert_region(struct vc_data *c, u16 * p, int count); ++ + static struct uni_pagedict *vgacon_uni_pagedir; + static int vgacon_refcount; + +-- +2.39.5 + diff --git a/queue-5.15/vgacon-switch-vgacon_scrolldelta-and-vgacon_restore_.patch b/queue-5.15/vgacon-switch-vgacon_scrolldelta-and-vgacon_restore_.patch new file mode 100644 index 0000000000..39a505ee03 --- /dev/null +++ b/queue-5.15/vgacon-switch-vgacon_scrolldelta-and-vgacon_restore_.patch @@ -0,0 +1,56 @@ +From 61e5147b93d4134d997e3d2cd6cdb47b885ab77b Mon Sep 17 00:00:00 2001 +From: Sasha Levin <sashal@kernel.org> +Date: Wed, 12 Jul 2023 10:59:36 +0200 +Subject: vgacon: switch vgacon_scrolldelta() and vgacon_restore_screen() + +From: Jiri Slaby (SUSE) <jirislaby@kernel.org> + +[ Upstream commit 03b89a08484a88fb9e0604cab2b3eb0c2f265c74 ] + +Switch vgacon_scrolldelta() and vgacon_restore_screen() positions, so +that the former is not needed to be forward-declared. + +Signed-off-by: "Jiri Slaby (SUSE)" <jirislaby@kernel.org> +Cc: Helge Deller <deller@gmx.de> +Cc: linux-fbdev@vger.kernel.org +Cc: dri-devel@lists.freedesktop.org +Signed-off-by: Helge Deller <deller@gmx.de> +Stable-dep-of: 03bcbbb3995b ("dummycon: Trigger redraw when switching consoles with deferred takeover") +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + drivers/video/console/vgacon.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c +index 7bce5a174f388..b2180fd183307 100644 +--- a/drivers/video/console/vgacon.c ++++ b/drivers/video/console/vgacon.c +@@ -163,12 +163,6 @@ static inline void vga_set_mem_top(struct vc_data *c) + write_vga(12, (c->vc_visible_origin - vga_vram_base) / 2); + } + +-static void vgacon_restore_screen(struct vc_data *c) +-{ +- if (c->vc_origin != c->vc_visible_origin) +- vgacon_scrolldelta(c, 0); +-} +- + static void vgacon_scrolldelta(struct vc_data *c, int lines) + { + vc_scrolldelta_helper(c, lines, vga_rolled_over, (void *)vga_vram_base, +@@ -176,6 +170,12 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) + vga_set_mem_top(c); + } + ++static void vgacon_restore_screen(struct vc_data *c) ++{ ++ if (c->vc_origin != c->vc_visible_origin) ++ vgacon_scrolldelta(c, 0); ++} ++ + static const char *vgacon_startup(void) + { + const char *display_desc = NULL; +-- +2.39.5 + |