From: Sasha Levin Date: Fri, 23 Feb 2024 17:44:26 +0000 (-0500) Subject: Fixes for 5.15 X-Git-Tag: v4.19.308~88 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4a5c49e519503c465c5de82db59c0efeaa1631bb;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.15 Signed-off-by: Sasha Levin --- diff --git a/queue-5.15/ahci-add-43-bit-dma-address-quirk-for-asmedia-asm106.patch b/queue-5.15/ahci-add-43-bit-dma-address-quirk-for-asmedia-asm106.patch new file mode 100644 index 00000000000..aa8e8ea70d4 --- /dev/null +++ b/queue-5.15/ahci-add-43-bit-dma-address-quirk-for-asmedia-asm106.patch @@ -0,0 +1,159 @@ +From 99f29150b3cafcb11aae51f7631607eb299a2aa5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 Jan 2024 17:04:01 +0200 +Subject: ahci: add 43-bit DMA address quirk for ASMedia ASM1061 controllers + +From: Lennert Buytenhek + +[ Upstream commit 20730e9b277873deeb6637339edcba64468f3da3 ] + +With one of the on-board ASM1061 AHCI controllers (1b21:0612) on an +ASUSTeK Pro WS WRX80E-SAGE SE WIFI mainboard, a controller hang was +observed that was immediately preceded by the following kernel +messages: + +ahci 0000:28:00.0: Using 64-bit DMA addresses +ahci 0000:28:00.0: AMD-Vi: Event logged [IO_PAGE_FAULT domain=0x0035 address=0x7fffff00000 flags=0x0000] +ahci 0000:28:00.0: AMD-Vi: Event logged [IO_PAGE_FAULT domain=0x0035 address=0x7fffff00300 flags=0x0000] +ahci 0000:28:00.0: AMD-Vi: Event logged [IO_PAGE_FAULT domain=0x0035 address=0x7fffff00380 flags=0x0000] +ahci 0000:28:00.0: AMD-Vi: Event logged [IO_PAGE_FAULT domain=0x0035 address=0x7fffff00400 flags=0x0000] +ahci 0000:28:00.0: AMD-Vi: Event logged [IO_PAGE_FAULT domain=0x0035 address=0x7fffff00680 flags=0x0000] +ahci 0000:28:00.0: AMD-Vi: Event logged [IO_PAGE_FAULT domain=0x0035 address=0x7fffff00700 flags=0x0000] + +The first message is produced by code in drivers/iommu/dma-iommu.c +which is accompanied by the following comment that seems to apply: + + /* + * Try to use all the 32-bit PCI addresses first. The original SAC vs. + * DAC reasoning loses relevance with PCIe, but enough hardware and + * firmware bugs are still lurking out there that it's safest not to + * venture into the 64-bit space until necessary. + * + * If your device goes wrong after seeing the notice then likely either + * its driver is not setting DMA masks accurately, the hardware has + * some inherent bug in handling >32-bit addresses, or not all the + * expected address bits are wired up between the device and the IOMMU. + */ + +Asking the ASM1061 on a discrete PCIe card to DMA from I/O virtual +address 0xffffffff00000000 produces the following I/O page faults: + +vfio-pci 0000:07:00.0: AMD-Vi: Event logged [IO_PAGE_FAULT domain=0x0021 address=0x7ff00000000 flags=0x0010] +vfio-pci 0000:07:00.0: AMD-Vi: Event logged [IO_PAGE_FAULT domain=0x0021 address=0x7ff00000500 flags=0x0010] + +Note that the upper 21 bits of the logged DMA address are zero. (When +asking a different PCIe device in the same PCIe slot to DMA to the +same I/O virtual address, we do see all the upper 32 bits of the DMA +address as 1, so this is not an issue with the chipset or IOMMU +configuration on the test system.) + +Also, hacking libahci to always set the upper 21 bits of all DMA +addresses to 1 produces no discernible effect on the behavior of the +ASM1061, and mkfs/mount/scrub/etc work as without this hack. + +This all strongly suggests that the ASM1061 has a 43 bit DMA address +limit, and this commit therefore adds a quirk to deal with this limit. + +This issue probably applies to (some of) the other supported ASMedia +parts as well, but we limit it to the PCI IDs known to refer to +ASM1061 parts, as that's the only part we know for sure to be affected +by this issue at this point. + +Link: https://lore.kernel.org/linux-ide/ZaZ2PIpEId-rl6jv@wantstofly.org/ +Signed-off-by: Lennert Buytenhek +[cassel: drop date from error messages in commit log] +Signed-off-by: Niklas Cassel +Signed-off-by: Sasha Levin +--- + drivers/ata/ahci.c | 29 +++++++++++++++++++++++------ + drivers/ata/ahci.h | 1 + + 2 files changed, 24 insertions(+), 6 deletions(-) + +diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c +index 56fcb1dec6af8..b0a8aac008bae 100644 +--- a/drivers/ata/ahci.c ++++ b/drivers/ata/ahci.c +@@ -49,6 +49,7 @@ enum { + enum board_ids { + /* board IDs by feature in alphabetical order */ + board_ahci, ++ board_ahci_43bit_dma, + board_ahci_ign_iferr, + board_ahci_low_power, + board_ahci_no_debounce_delay, +@@ -129,6 +130,13 @@ static const struct ata_port_info ahci_port_info[] = { + .udma_mask = ATA_UDMA6, + .port_ops = &ahci_ops, + }, ++ [board_ahci_43bit_dma] = { ++ AHCI_HFLAGS (AHCI_HFLAG_43BIT_ONLY), ++ .flags = AHCI_FLAG_COMMON, ++ .pio_mask = ATA_PIO4, ++ .udma_mask = ATA_UDMA6, ++ .port_ops = &ahci_ops, ++ }, + [board_ahci_ign_iferr] = { + AHCI_HFLAGS (AHCI_HFLAG_IGN_IRQ_IF_ERR), + .flags = AHCI_FLAG_COMMON, +@@ -598,11 +606,11 @@ static const struct pci_device_id ahci_pci_tbl[] = { + { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */ + { PCI_VDEVICE(PROMISE, 0x3781), board_ahci }, /* FastTrak TX8660 ahci-mode */ + +- /* Asmedia */ ++ /* ASMedia */ + { PCI_VDEVICE(ASMEDIA, 0x0601), board_ahci }, /* ASM1060 */ + { PCI_VDEVICE(ASMEDIA, 0x0602), board_ahci }, /* ASM1060 */ +- { PCI_VDEVICE(ASMEDIA, 0x0611), board_ahci }, /* ASM1061 */ +- { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci }, /* ASM1062 */ ++ { PCI_VDEVICE(ASMEDIA, 0x0611), board_ahci_43bit_dma }, /* ASM1061 */ ++ { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci_43bit_dma }, /* ASM1061/1062 */ + { PCI_VDEVICE(ASMEDIA, 0x0621), board_ahci }, /* ASM1061R */ + { PCI_VDEVICE(ASMEDIA, 0x0622), board_ahci }, /* ASM1062R */ + +@@ -955,11 +963,20 @@ static int ahci_pci_device_resume(struct device *dev) + + #endif /* CONFIG_PM */ + +-static int ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac) ++static int ahci_configure_dma_masks(struct pci_dev *pdev, ++ struct ahci_host_priv *hpriv) + { +- const int dma_bits = using_dac ? 64 : 32; ++ int dma_bits; + int rc; + ++ if (hpriv->cap & HOST_CAP_64) { ++ dma_bits = 64; ++ if (hpriv->flags & AHCI_HFLAG_43BIT_ONLY) ++ dma_bits = 43; ++ } else { ++ dma_bits = 32; ++ } ++ + /* + * If the device fixup already set the dma_mask to some non-standard + * value, don't extend it here. This happens on STA2X11, for example. +@@ -1937,7 +1954,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) + ahci_gtf_filter_workaround(host); + + /* initialize adapter */ +- rc = ahci_configure_dma_masks(pdev, hpriv->cap & HOST_CAP_64); ++ rc = ahci_configure_dma_masks(pdev, hpriv); + if (rc) + return rc; + +diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h +index dcc2d92cf6b62..69557e602e2ea 100644 +--- a/drivers/ata/ahci.h ++++ b/drivers/ata/ahci.h +@@ -244,6 +244,7 @@ enum { + AHCI_HFLAG_IGN_NOTSUPP_POWER_ON = BIT(27), /* ignore -EOPNOTSUPP + from phy_power_on() */ + AHCI_HFLAG_NO_SXS = BIT(28), /* SXS not supported */ ++ AHCI_HFLAG_43BIT_ONLY = BIT(29), /* 43bit DMA addr limit */ + + /* ap->flags bits */ + +-- +2.43.0 + diff --git a/queue-5.15/ahci-asm1166-correct-count-of-reported-ports.patch b/queue-5.15/ahci-asm1166-correct-count-of-reported-ports.patch new file mode 100644 index 00000000000..edf240cc7b3 --- /dev/null +++ b/queue-5.15/ahci-asm1166-correct-count-of-reported-ports.patch @@ -0,0 +1,52 @@ +From 40efe31f8bc495590b6e02d8df001388b5c33e87 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Jan 2024 19:30:02 +0100 +Subject: ahci: asm1166: correct count of reported ports + +From: Conrad Kostecki + +[ Upstream commit 0077a504e1a4468669fd2e011108db49133db56e ] + +The ASM1166 SATA host controller always reports wrongly, +that it has 32 ports. But in reality, it only has six ports. + +This seems to be a hardware issue, as all tested ASM1166 +SATA host controllers reports such high count of ports. + +Example output: ahci 0000:09:00.0: AHCI 0001.0301 +32 slots 32 ports 6 Gbps 0xffffff3f impl SATA mode. + +By adjusting the port_map, the count is limited to six ports. + +New output: ahci 0000:09:00.0: AHCI 0001.0301 +32 slots 32 ports 6 Gbps 0x3f impl SATA mode. + +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=211873 +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218346 +Signed-off-by: Conrad Kostecki +Reviewed-by: Hans de Goede +Signed-off-by: Niklas Cassel +Signed-off-by: Sasha Levin +--- + drivers/ata/ahci.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c +index 3147b2e6cd8c9..56fcb1dec6af8 100644 +--- a/drivers/ata/ahci.c ++++ b/drivers/ata/ahci.c +@@ -658,6 +658,11 @@ MODULE_PARM_DESC(mobile_lpm_policy, "Default LPM policy for mobile chipsets"); + static void ahci_pci_save_initial_config(struct pci_dev *pdev, + struct ahci_host_priv *hpriv) + { ++ if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && pdev->device == 0x1166) { ++ dev_info(&pdev->dev, "ASM1166 has only six ports\n"); ++ hpriv->saved_port_map = 0x3f; ++ } ++ + if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361) { + dev_info(&pdev->dev, "JMB361 has only one port\n"); + hpriv->force_port_map = 1; +-- +2.43.0 + diff --git a/queue-5.15/alsa-usb-audio-check-presence-of-valid-altsetting-co.patch b/queue-5.15/alsa-usb-audio-check-presence-of-valid-altsetting-co.patch new file mode 100644 index 00000000000..76d1d31fd19 --- /dev/null +++ b/queue-5.15/alsa-usb-audio-check-presence-of-valid-altsetting-co.patch @@ -0,0 +1,86 @@ +From 22513dc3318c6792cf3643b6567e361f5773baf3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Jan 2024 15:12:54 +0300 +Subject: ALSA: usb-audio: Check presence of valid altsetting control + +From: Alexander Tsoy + +[ Upstream commit 346f59d1e8ed0eed41c80e1acb657e484c308e6a ] + +Many devices with a single alternate setting do not have a Valid +Alternate Setting Control and validation performed by +validate_sample_rate_table_v2v3() doesn't work on them and is not +really needed. So check the presense of control before sending +altsetting validation requests. + +MOTU Microbook IIc is suffering the most without this check. It +takes up to 40 seconds to bootup due to how slow it switches +sampling rates: + +[ 2659.164824] usb 3-2: New USB device found, idVendor=07fd, idProduct=0004, bcdDevice= 0.60 +[ 2659.164827] usb 3-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0 +[ 2659.164829] usb 3-2: Product: MicroBook IIc +[ 2659.164830] usb 3-2: Manufacturer: MOTU +[ 2659.166204] usb 3-2: Found last interface = 3 +[ 2679.322298] usb 3-2: No valid sample rate available for 1:1, assuming a firmware bug +[ 2679.322306] usb 3-2: 1:1: add audio endpoint 0x3 +[ 2679.322321] usb 3-2: Creating new data endpoint #3 +[ 2679.322552] usb 3-2: 1:1 Set sample rate 96000, clock 1 +[ 2684.362250] usb 3-2: 2:1: cannot get freq (v2/v3): err -110 +[ 2694.444700] usb 3-2: No valid sample rate available for 2:1, assuming a firmware bug +[ 2694.444707] usb 3-2: 2:1: add audio endpoint 0x84 +[ 2694.444721] usb 3-2: Creating new data endpoint #84 +[ 2699.482103] usb 3-2: 2:1 Set sample rate 96000, clock 1 + +Signed-off-by: Alexander Tsoy +Link: https://lore.kernel.org/r/20240129121254.3454481-1-alexander@tsoy.me +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/usb/format.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/sound/usb/format.c b/sound/usb/format.c +index ab5fed9f55b60..3b45d0ee76938 100644 +--- a/sound/usb/format.c ++++ b/sound/usb/format.c +@@ -470,9 +470,11 @@ static int validate_sample_rate_table_v2v3(struct snd_usb_audio *chip, + int clock) + { + struct usb_device *dev = chip->dev; ++ struct usb_host_interface *alts; + unsigned int *table; + unsigned int nr_rates; + int i, err; ++ u32 bmControls; + + /* performing the rate verification may lead to unexpected USB bus + * behavior afterwards by some unknown reason. Do this only for the +@@ -481,6 +483,24 @@ static int validate_sample_rate_table_v2v3(struct snd_usb_audio *chip, + if (!(chip->quirk_flags & QUIRK_FLAG_VALIDATE_RATES)) + return 0; /* don't perform the validation as default */ + ++ alts = snd_usb_get_host_interface(chip, fp->iface, fp->altsetting); ++ if (!alts) ++ return 0; ++ ++ if (fp->protocol == UAC_VERSION_3) { ++ struct uac3_as_header_descriptor *as = snd_usb_find_csint_desc( ++ alts->extra, alts->extralen, NULL, UAC_AS_GENERAL); ++ bmControls = le32_to_cpu(as->bmControls); ++ } else { ++ struct uac2_as_header_descriptor *as = snd_usb_find_csint_desc( ++ alts->extra, alts->extralen, NULL, UAC_AS_GENERAL); ++ bmControls = as->bmControls; ++ } ++ ++ if (!uac_v2v3_control_is_readable(bmControls, ++ UAC2_AS_VAL_ALT_SETTINGS)) ++ return 0; ++ + table = kcalloc(fp->nr_rates, sizeof(*table), GFP_KERNEL); + if (!table) + return -ENOMEM; +-- +2.43.0 + diff --git a/queue-5.15/alsa-usb-audio-ignore-clock-selector-errors-for-sing.patch b/queue-5.15/alsa-usb-audio-ignore-clock-selector-errors-for-sing.patch new file mode 100644 index 00000000000..eb405dff54c --- /dev/null +++ b/queue-5.15/alsa-usb-audio-ignore-clock-selector-errors-for-sing.patch @@ -0,0 +1,68 @@ +From 4257b7734805bd247e54653442df0c8e5ad9211c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 1 Feb 2024 14:53:08 +0300 +Subject: ALSA: usb-audio: Ignore clock selector errors for single connection + +From: Alexander Tsoy + +[ Upstream commit eaa1b01fe709d6a236a9cec74813e0400601fd23 ] + +For devices with multiple clock sources connected to a selector, we need +to check what a clock selector control request has returned. This is +needed to ensure that a requested clock source is indeed selected and for +autoclock feature to work. + +For devices with single clock source connected, if we get an error there +is nothing else we can do about it. We can't skip clock selector setup as +it is required by some devices. So lets just ignore error in this case. + +This should fix various buggy Mackie devices: + +[ 649.109785] usb 1-1.3: parse_audio_format_rates_v2v3(): unable to find clock source (clock -32) +[ 649.111946] usb 1-1.3: parse_audio_format_rates_v2v3(): unable to find clock source (clock -32) +[ 649.113822] usb 1-1.3: parse_audio_format_rates_v2v3(): unable to find clock source (clock -32) + +There is also interesting info from the Windows documentation [1] (this +is probably why manufacturers dont't even test this feature): + +"The USB Audio 2.0 driver doesn't support clock selection. The driver +uses the Clock Source Entity, which is selected by default and never +issues a Clock Selector Control SET CUR request." + +Link: https://learn.microsoft.com/en-us/windows-hardware/drivers/audio/usb-2-0-audio-drivers [1] +Link: https://bugzilla.kernel.org/show_bug.cgi?id=217314 +Link: https://bugzilla.kernel.org/show_bug.cgi?id=218175 +Link: https://bugzilla.kernel.org/show_bug.cgi?id=218342 +Signed-off-by: Alexander Tsoy +Link: https://lore.kernel.org/r/20240201115308.17838-1-alexander@tsoy.me +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/usb/clock.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/sound/usb/clock.c b/sound/usb/clock.c +index ccca9efa7d33f..970e14ff54d14 100644 +--- a/sound/usb/clock.c ++++ b/sound/usb/clock.c +@@ -328,8 +328,16 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip, + if (chip->quirk_flags & QUIRK_FLAG_SKIP_CLOCK_SELECTOR) + return ret; + err = uac_clock_selector_set_val(chip, entity_id, cur); +- if (err < 0) ++ if (err < 0) { ++ if (pins == 1) { ++ usb_audio_dbg(chip, ++ "%s(): selector returned an error, " ++ "assuming a firmware bug, id %d, ret %d\n", ++ __func__, clock_id, err); ++ return ret; ++ } + return err; ++ } + } + + if (!validate || ret > 0 || !chip->autoclock) +-- +2.43.0 + diff --git a/queue-5.15/asoc-sunxi-sun4i-spdif-add-support-for-allwinner-h61.patch b/queue-5.15/asoc-sunxi-sun4i-spdif-add-support-for-allwinner-h61.patch new file mode 100644 index 00000000000..1b9b10ad7ae --- /dev/null +++ b/queue-5.15/asoc-sunxi-sun4i-spdif-add-support-for-allwinner-h61.patch @@ -0,0 +1,45 @@ +From 7ee81b2140a39954a95761c60fa71e01b0608e08 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 28 Jan 2024 00:32:43 +0800 +Subject: ASoC: sunxi: sun4i-spdif: Add support for Allwinner H616 + +From: Chen-Yu Tsai + +[ Upstream commit 0adf963b8463faa44653e22e56ce55f747e68868 ] + +The SPDIF hardware block found in the H616 SoC has the same layout as +the one found in the H6 SoC, except that it is missing the receiver +side. + +Since the driver currently only supports the transmit function, support +for the H616 is identical to what is currently done for the H6. + +Signed-off-by: Chen-Yu Tsai +Reviewed-by: Andre Przywara +Reviewed-by: Jernej Skrabec +Link: https://msgid.link/r/20240127163247.384439-4-wens@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/sunxi/sun4i-spdif.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/sound/soc/sunxi/sun4i-spdif.c b/sound/soc/sunxi/sun4i-spdif.c +index a10949bf0ca1e..dd8d13f3fd121 100644 +--- a/sound/soc/sunxi/sun4i-spdif.c ++++ b/sound/soc/sunxi/sun4i-spdif.c +@@ -464,6 +464,11 @@ static const struct of_device_id sun4i_spdif_of_match[] = { + .compatible = "allwinner,sun50i-h6-spdif", + .data = &sun50i_h6_spdif_quirks, + }, ++ { ++ .compatible = "allwinner,sun50i-h616-spdif", ++ /* Essentially the same as the H6, but without RX */ ++ .data = &sun50i_h6_spdif_quirks, ++ }, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, sun4i_spdif_of_match); +-- +2.43.0 + diff --git a/queue-5.15/dmaengine-fsl-qdma-increase-size-of-irq_name.patch b/queue-5.15/dmaengine-fsl-qdma-increase-size-of-irq_name.patch new file mode 100644 index 00000000000..1cbca58e32c --- /dev/null +++ b/queue-5.15/dmaengine-fsl-qdma-increase-size-of-irq_name.patch @@ -0,0 +1,48 @@ +From 5424cd2bdf7f1f3269814d8f205767ce4613923e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 19 Jan 2024 18:10:44 +0530 +Subject: dmaengine: fsl-qdma: increase size of 'irq_name' +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Vinod Koul + +[ Upstream commit 6386f6c995b3ab91c72cfb76e4465553c555a8da ] + +We seem to have hit warnings of 'output may be truncated' which is fixed +by increasing the size of 'irq_name' + +drivers/dma/fsl-qdma.c: In function ‘fsl_qdma_irq_init’: +drivers/dma/fsl-qdma.c:824:46: error: ‘%d’ directive writing between 1 and 11 bytes into a region of size 10 [-Werror=format-overflow=] + 824 | sprintf(irq_name, "qdma-queue%d", i); + | ^~ +drivers/dma/fsl-qdma.c:824:35: note: directive argument in the range [-2147483641, 2147483646] + 824 | sprintf(irq_name, "qdma-queue%d", i); + | ^~~~~~~~~~~~~~ +drivers/dma/fsl-qdma.c:824:17: note: ‘sprintf’ output between 12 and 22 bytes into a destination of size 20 + 824 | sprintf(irq_name, "qdma-queue%d", i); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/dma/fsl-qdma.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/dma/fsl-qdma.c b/drivers/dma/fsl-qdma.c +index 69385f32e2756..f383f219ed008 100644 +--- a/drivers/dma/fsl-qdma.c ++++ b/drivers/dma/fsl-qdma.c +@@ -805,7 +805,7 @@ fsl_qdma_irq_init(struct platform_device *pdev, + int i; + int cpu; + int ret; +- char irq_name[20]; ++ char irq_name[32]; + + fsl_qdma->error_irq = + platform_get_irq_byname(pdev, "qdma-error"); +-- +2.43.0 + diff --git a/queue-5.15/dmaengine-shdma-increase-size-of-dev_id.patch b/queue-5.15/dmaengine-shdma-increase-size-of-dev_id.patch new file mode 100644 index 00000000000..7f9f39e79b1 --- /dev/null +++ b/queue-5.15/dmaengine-shdma-increase-size-of-dev_id.patch @@ -0,0 +1,53 @@ +From d9053aa8b9a5afc23087a3b5af4ec3794e5c6a5a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 19 Jan 2024 18:10:44 +0530 +Subject: dmaengine: shdma: increase size of 'dev_id' +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Vinod Koul + +[ Upstream commit 404290240827c3bb5c4e195174a8854eef2f89ac ] + +We seem to have hit warnings of 'output may be truncated' which is fixed +by increasing the size of 'dev_id' + +drivers/dma/sh/shdmac.c: In function ‘sh_dmae_probe’: +drivers/dma/sh/shdmac.c:541:34: error: ‘%d’ directive output may be truncated writing between 1 and 10 bytes into a region of size 9 [-Werror=format-truncation=] + 541 | "sh-dmae%d.%d", pdev->id, id); + | ^~ +In function ‘sh_dmae_chan_probe’, + inlined from ‘sh_dmae_probe’ at drivers/dma/sh/shdmac.c:845:9: +drivers/dma/sh/shdmac.c:541:26: note: directive argument in the range [0, 2147483647] + 541 | "sh-dmae%d.%d", pdev->id, id); + | ^~~~~~~~~~~~~~ +drivers/dma/sh/shdmac.c:541:26: note: directive argument in the range [0, 19] +drivers/dma/sh/shdmac.c:540:17: note: ‘snprintf’ output between 11 and 21 bytes into a destination of size 16 + 540 | snprintf(sh_chan->dev_id, sizeof(sh_chan->dev_id), + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 541 | "sh-dmae%d.%d", pdev->id, id); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/dma/sh/shdma.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/dma/sh/shdma.h b/drivers/dma/sh/shdma.h +index 9c121a4b33ad8..f97d80343aea4 100644 +--- a/drivers/dma/sh/shdma.h ++++ b/drivers/dma/sh/shdma.h +@@ -25,7 +25,7 @@ struct sh_dmae_chan { + const struct sh_dmae_slave_config *config; /* Slave DMA configuration */ + int xmit_shift; /* log_2(bytes_per_xfer) */ + void __iomem *base; +- char dev_id[16]; /* unique name per DMAC of channel */ ++ char dev_id[32]; /* unique name per DMAC of channel */ + int pm_error; + dma_addr_t slave_addr; + }; +-- +2.43.0 + diff --git a/queue-5.15/dmaengine-ti-edma-add-some-null-pointer-checks-to-th.patch b/queue-5.15/dmaengine-ti-edma-add-some-null-pointer-checks-to-th.patch new file mode 100644 index 00000000000..d7092013ba1 --- /dev/null +++ b/queue-5.15/dmaengine-ti-edma-add-some-null-pointer-checks-to-th.patch @@ -0,0 +1,52 @@ +From 6be67ab3fa9dd2f6fea7050317a27577e15b12d0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Jan 2024 11:19:29 +0800 +Subject: dmaengine: ti: edma: Add some null pointer checks to the edma_probe + +From: Kunwu Chan + +[ Upstream commit 6e2276203ac9ff10fc76917ec9813c660f627369 ] + +devm_kasprintf() returns a pointer to dynamically allocated memory +which can be NULL upon failure. Ensure the allocation was successful +by checking the pointer validity. + +Signed-off-by: Kunwu Chan +Link: https://lore.kernel.org/r/20240118031929.192192-1-chentao@kylinos.cn +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/dma/ti/edma.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/dma/ti/edma.c b/drivers/dma/ti/edma.c +index a1adc8d91fd8d..69292d4a0c441 100644 +--- a/drivers/dma/ti/edma.c ++++ b/drivers/dma/ti/edma.c +@@ -2462,6 +2462,11 @@ static int edma_probe(struct platform_device *pdev) + if (irq > 0) { + irq_name = devm_kasprintf(dev, GFP_KERNEL, "%s_ccint", + dev_name(dev)); ++ if (!irq_name) { ++ ret = -ENOMEM; ++ goto err_disable_pm; ++ } ++ + ret = devm_request_irq(dev, irq, dma_irq_handler, 0, irq_name, + ecc); + if (ret) { +@@ -2478,6 +2483,11 @@ static int edma_probe(struct platform_device *pdev) + if (irq > 0) { + irq_name = devm_kasprintf(dev, GFP_KERNEL, "%s_ccerrint", + dev_name(dev)); ++ if (!irq_name) { ++ ret = -ENOMEM; ++ goto err_disable_pm; ++ } ++ + ret = devm_request_irq(dev, irq, dma_ccerr_handler, 0, irq_name, + ecc); + if (ret) { +-- +2.43.0 + diff --git a/queue-5.15/drm-amdgpu-reset-gpu-for-s3-suspend-abort-case.patch b/queue-5.15/drm-amdgpu-reset-gpu-for-s3-suspend-abort-case.patch new file mode 100644 index 00000000000..acd06bf5bf0 --- /dev/null +++ b/queue-5.15/drm-amdgpu-reset-gpu-for-s3-suspend-abort-case.patch @@ -0,0 +1,63 @@ +From 48960f363cc1ee0bdc319bcab54603f063a9ed1f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 17 Jan 2024 13:39:37 +0800 +Subject: drm/amdgpu: reset gpu for s3 suspend abort case + +From: Prike Liang + +[ Upstream commit 6ef82ac664bb9568ca3956e0d9c9c478e25077ff ] + +In the s3 suspend abort case some type of gfx9 power +rail not turn off from FCH side and this will put the +GPU in an unknown power status, so let's reset the gpu +to a known good power state before reinitialize gpu +device. + +Signed-off-by: Prike Liang +Acked-by: Alex Deucher +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/soc15.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c +index e8c0e77e1b018..6a3486f52d698 100644 +--- a/drivers/gpu/drm/amd/amdgpu/soc15.c ++++ b/drivers/gpu/drm/amd/amdgpu/soc15.c +@@ -1490,10 +1490,32 @@ static int soc15_common_suspend(void *handle) + return soc15_common_hw_fini(adev); + } + ++static bool soc15_need_reset_on_resume(struct amdgpu_device *adev) ++{ ++ u32 sol_reg; ++ ++ sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); ++ ++ /* Will reset for the following suspend abort cases. ++ * 1) Only reset limit on APU side, dGPU hasn't checked yet. ++ * 2) S3 suspend abort and TOS already launched. ++ */ ++ if (adev->flags & AMD_IS_APU && adev->in_s3 && ++ !adev->suspend_complete && ++ sol_reg) ++ return true; ++ ++ return false; ++} ++ + static int soc15_common_resume(void *handle) + { + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + ++ if (soc15_need_reset_on_resume(adev)) { ++ dev_info(adev->dev, "S3 suspend abort case, let's reset ASIC.\n"); ++ soc15_asic_reset(adev); ++ } + return soc15_common_hw_init(adev); + } + +-- +2.43.0 + diff --git a/queue-5.15/drm-amdgpu-skip-to-program-gfxdec-registers-for-susp.patch b/queue-5.15/drm-amdgpu-skip-to-program-gfxdec-registers-for-susp.patch new file mode 100644 index 00000000000..9add22d3bd6 --- /dev/null +++ b/queue-5.15/drm-amdgpu-skip-to-program-gfxdec-registers-for-susp.patch @@ -0,0 +1,79 @@ +From ce8b9ac93b5298946a4c0fa54e8fca16158f8a49 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Jan 2024 19:10:45 +0800 +Subject: drm/amdgpu: skip to program GFXDEC registers for suspend abort + +From: Prike Liang + +[ Upstream commit 93bafa32a6918154aa0caf9f66679a32c2431357 ] + +In the suspend abort cases, the gfx power rail doesn't turn off so +some GFXDEC registers/CSB can't reset to default value and at this +moment reinitialize GFXDEC/CSB will result in an unexpected error. +So let skip those program sequence for the suspend abort case. + +Signed-off-by: Prike Liang +Reviewed-by: Alex Deucher +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 ++ + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 ++ + drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 8 ++++++++ + 3 files changed, 12 insertions(+) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +index 1f1e7966beb51..dbef22f56482e 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +@@ -1045,6 +1045,8 @@ struct amdgpu_device { + bool in_s3; + bool in_s4; + bool in_s0ix; ++ /* indicate amdgpu suspension status */ ++ bool suspend_complete; + + atomic_t in_gpu_reset; + enum pp_mp1_state mp1_state; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +index deae92fde3b88..57943e9008710 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +@@ -2252,6 +2252,7 @@ static int amdgpu_pmops_suspend(struct device *dev) + struct drm_device *drm_dev = dev_get_drvdata(dev); + struct amdgpu_device *adev = drm_to_adev(drm_dev); + ++ adev->suspend_complete = false; + if (amdgpu_acpi_is_s0ix_active(adev)) + adev->in_s0ix = true; + else +@@ -2264,6 +2265,7 @@ static int amdgpu_pmops_suspend_noirq(struct device *dev) + struct drm_device *drm_dev = dev_get_drvdata(dev); + struct amdgpu_device *adev = drm_to_adev(drm_dev); + ++ adev->suspend_complete = true; + if (amdgpu_acpi_should_gpu_reset(adev)) + return amdgpu_asic_reset(adev); + +diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +index de1fab165041f..fb37c0d4b35b4 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +@@ -3268,6 +3268,14 @@ static int gfx_v9_0_cp_gfx_start(struct amdgpu_device *adev) + + gfx_v9_0_cp_gfx_enable(adev, true); + ++ /* Now only limit the quirk on the APU gfx9 series and already ++ * confirmed that the APU gfx10/gfx11 needn't such update. ++ */ ++ if (adev->flags & AMD_IS_APU && ++ adev->in_s3 && !adev->suspend_complete) { ++ DRM_INFO(" Will skip the CSB packet resubmit\n"); ++ return 0; ++ } + r = amdgpu_ring_alloc(ring, gfx_v9_0_get_csb_size(adev) + 4 + 3); + if (r) { + DRM_ERROR("amdgpu: cp failed to lock ring (%d).\n", r); +-- +2.43.0 + diff --git a/queue-5.15/efi-don-t-add-memblocks-for-soft-reserved-memory.patch b/queue-5.15/efi-don-t-add-memblocks-for-soft-reserved-memory.patch new file mode 100644 index 00000000000..f8665e207f0 --- /dev/null +++ b/queue-5.15/efi-don-t-add-memblocks-for-soft-reserved-memory.patch @@ -0,0 +1,59 @@ +From 4063f8a56608c11283d6aaf002f2f2e8f0f7246b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Feb 2024 10:07:04 -0800 +Subject: efi: Don't add memblocks for soft-reserved memory + +From: Andrew Bresticker + +[ Upstream commit 0bcff59ef7a652fcdc6d535554b63278c2406c8f ] + +Adding memblocks for soft-reserved regions prevents them from later being +hotplugged in by dax_kmem. + +Signed-off-by: Andrew Bresticker +Signed-off-by: Ard Biesheuvel +Signed-off-by: Sasha Levin +--- + drivers/firmware/efi/efi-init.c | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +diff --git a/drivers/firmware/efi/efi-init.c b/drivers/firmware/efi/efi-init.c +index b2c829e95bd14..4639ac6e4f9af 100644 +--- a/drivers/firmware/efi/efi-init.c ++++ b/drivers/firmware/efi/efi-init.c +@@ -141,15 +141,6 @@ static __init int is_usable_memory(efi_memory_desc_t *md) + case EFI_BOOT_SERVICES_DATA: + case EFI_CONVENTIONAL_MEMORY: + case EFI_PERSISTENT_MEMORY: +- /* +- * Special purpose memory is 'soft reserved', which means it +- * is set aside initially, but can be hotplugged back in or +- * be assigned to the dax driver after boot. +- */ +- if (efi_soft_reserve_enabled() && +- (md->attribute & EFI_MEMORY_SP)) +- return false; +- + /* + * According to the spec, these regions are no longer reserved + * after calling ExitBootServices(). However, we can only use +@@ -194,6 +185,16 @@ static __init void reserve_regions(void) + size = npages << PAGE_SHIFT; + + if (is_memory(md)) { ++ /* ++ * Special purpose memory is 'soft reserved', which ++ * means it is set aside initially. Don't add a memblock ++ * for it now so that it can be hotplugged back in or ++ * be assigned to the dax driver after boot. ++ */ ++ if (efi_soft_reserve_enabled() && ++ (md->attribute & EFI_MEMORY_SP)) ++ continue; ++ + early_init_dt_add_memory_arch(paddr, size); + + if (!is_usable_memory(md)) +-- +2.43.0 + diff --git a/queue-5.15/efi-runtime-fix-potential-overflow-of-soft-reserved-.patch b/queue-5.15/efi-runtime-fix-potential-overflow-of-soft-reserved-.patch new file mode 100644 index 00000000000..e347459d52b --- /dev/null +++ b/queue-5.15/efi-runtime-fix-potential-overflow-of-soft-reserved-.patch @@ -0,0 +1,49 @@ +From 0b95dd4c8047bd45ad2feaff81c20b71465a37e5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Feb 2024 10:07:03 -0800 +Subject: efi: runtime: Fix potential overflow of soft-reserved region size + +From: Andrew Bresticker + +[ Upstream commit de1034b38a346ef6be25fe8792f5d1e0684d5ff4 ] + +md_size will have been narrowed if we have >= 4GB worth of pages in a +soft-reserved region. + +Signed-off-by: Andrew Bresticker +Signed-off-by: Ard Biesheuvel +Signed-off-by: Sasha Levin +--- + drivers/firmware/efi/arm-runtime.c | 2 +- + drivers/firmware/efi/riscv-runtime.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/firmware/efi/arm-runtime.c b/drivers/firmware/efi/arm-runtime.c +index 3359ae2adf24b..9054c2852580d 100644 +--- a/drivers/firmware/efi/arm-runtime.c ++++ b/drivers/firmware/efi/arm-runtime.c +@@ -107,7 +107,7 @@ static int __init arm_enable_runtime_services(void) + efi_memory_desc_t *md; + + for_each_efi_memory_desc(md) { +- int md_size = md->num_pages << EFI_PAGE_SHIFT; ++ u64 md_size = md->num_pages << EFI_PAGE_SHIFT; + struct resource *res; + + if (!(md->attribute & EFI_MEMORY_SP)) +diff --git a/drivers/firmware/efi/riscv-runtime.c b/drivers/firmware/efi/riscv-runtime.c +index d28e715d2bcc8..6711e64eb0b16 100644 +--- a/drivers/firmware/efi/riscv-runtime.c ++++ b/drivers/firmware/efi/riscv-runtime.c +@@ -85,7 +85,7 @@ static int __init riscv_enable_runtime_services(void) + efi_memory_desc_t *md; + + for_each_efi_memory_desc(md) { +- int md_size = md->num_pages << EFI_PAGE_SHIFT; ++ u64 md_size = md->num_pages << EFI_PAGE_SHIFT; + struct resource *res; + + if (!(md->attribute & EFI_MEMORY_SP)) +-- +2.43.0 + diff --git a/queue-5.15/ext4-avoid-allocating-blocks-from-corrupted-group-in.patch b/queue-5.15/ext4-avoid-allocating-blocks-from-corrupted-group-in.patch new file mode 100644 index 00000000000..3a2a047f737 --- /dev/null +++ b/queue-5.15/ext4-avoid-allocating-blocks-from-corrupted-group-in.patch @@ -0,0 +1,65 @@ +From 901e97242c26729e7e8e49fa9b1089c10fafbced Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 4 Jan 2024 22:20:38 +0800 +Subject: ext4: avoid allocating blocks from corrupted group in + ext4_mb_try_best_found() + +From: Baokun Li + +[ Upstream commit 4530b3660d396a646aad91a787b6ab37cf604b53 ] + +Determine if the group block bitmap is corrupted before using ac_b_ex in +ext4_mb_try_best_found() to avoid allocating blocks from a group with a +corrupted block bitmap in the following concurrency and making the +situation worse. + +ext4_mb_regular_allocator + ext4_lock_group(sb, group) + ext4_mb_good_group + // check if the group bbitmap is corrupted + ext4_mb_complex_scan_group + // Scan group gets ac_b_ex but doesn't use it + ext4_unlock_group(sb, group) + ext4_mark_group_bitmap_corrupted(group) + // The block bitmap was corrupted during + // the group unlock gap. + ext4_mb_try_best_found + ext4_lock_group(ac->ac_sb, group) + ext4_mb_use_best_found + mb_mark_used + // Allocating blocks in block bitmap corrupted group + +Signed-off-by: Baokun Li +Reviewed-by: Jan Kara +Link: https://lore.kernel.org/r/20240104142040.2835097-7-libaokun1@huawei.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/mballoc.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index 48930df9ae565..3e4be376a479a 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -2197,6 +2197,9 @@ int ext4_mb_try_best_found(struct ext4_allocation_context *ac, + return err; + + ext4_lock_group(ac->ac_sb, group); ++ if (unlikely(EXT4_MB_GRP_BBITMAP_CORRUPT(e4b->bd_info))) ++ goto out; ++ + max = mb_find_extent(e4b, ex.fe_start, ex.fe_len, &ex); + + if (max > 0) { +@@ -2204,6 +2207,7 @@ int ext4_mb_try_best_found(struct ext4_allocation_context *ac, + ext4_mb_use_best_found(ac, e4b); + } + ++out: + ext4_unlock_group(ac->ac_sb, group); + ext4_mb_unload_buddy(e4b); + +-- +2.43.0 + diff --git a/queue-5.15/ext4-avoid-allocating-blocks-from-corrupted-group-in.patch-26613 b/queue-5.15/ext4-avoid-allocating-blocks-from-corrupted-group-in.patch-26613 new file mode 100644 index 00000000000..c7e4af1835e --- /dev/null +++ b/queue-5.15/ext4-avoid-allocating-blocks-from-corrupted-group-in.patch-26613 @@ -0,0 +1,54 @@ +From 18541a74ce692b43ba8022904112e1388e30e444 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 4 Jan 2024 22:20:39 +0800 +Subject: ext4: avoid allocating blocks from corrupted group in + ext4_mb_find_by_goal() + +From: Baokun Li + +[ Upstream commit 832698373a25950942c04a512daa652c18a9b513 ] + +Places the logic for checking if the group's block bitmap is corrupt under +the protection of the group lock to avoid allocating blocks from the group +with a corrupted block bitmap. + +Signed-off-by: Baokun Li +Reviewed-by: Jan Kara +Link: https://lore.kernel.org/r/20240104142040.2835097-8-libaokun1@huawei.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/mballoc.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index 3e4be376a479a..622f60d9e1c68 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -2236,12 +2236,10 @@ int ext4_mb_find_by_goal(struct ext4_allocation_context *ac, + if (err) + return err; + +- if (unlikely(EXT4_MB_GRP_BBITMAP_CORRUPT(e4b->bd_info))) { +- ext4_mb_unload_buddy(e4b); +- return 0; +- } +- + ext4_lock_group(ac->ac_sb, group); ++ if (unlikely(EXT4_MB_GRP_BBITMAP_CORRUPT(e4b->bd_info))) ++ goto out; ++ + max = mb_find_extent(e4b, ac->ac_g_ex.fe_start, + ac->ac_g_ex.fe_len, &ex); + ex.fe_logical = 0xDEADFA11; /* debug value */ +@@ -2274,6 +2272,7 @@ int ext4_mb_find_by_goal(struct ext4_allocation_context *ac, + ac->ac_b_ex = ex; + ext4_mb_use_best_found(ac, e4b); + } ++out: + ext4_unlock_group(ac->ac_sb, group); + ext4_mb_unload_buddy(e4b); + +-- +2.43.0 + diff --git a/queue-5.15/ext4-avoid-dividing-by-0-in-mb_update_avg_fragment_s.patch b/queue-5.15/ext4-avoid-dividing-by-0-in-mb_update_avg_fragment_s.patch new file mode 100644 index 00000000000..d632b6f81f9 --- /dev/null +++ b/queue-5.15/ext4-avoid-dividing-by-0-in-mb_update_avg_fragment_s.patch @@ -0,0 +1,38 @@ +From 19559be5d85e016f867b596f7fcd04c0f37c059d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 4 Jan 2024 22:20:37 +0800 +Subject: ext4: avoid dividing by 0 in mb_update_avg_fragment_size() when block + bitmap corrupt + +From: Baokun Li + +[ Upstream commit 993bf0f4c393b3667830918f9247438a8f6fdb5b ] + +Determine if bb_fragments is 0 instead of determining bb_free to eliminate +the risk of dividing by zero when the block bitmap is corrupted. + +Signed-off-by: Baokun Li +Reviewed-by: Jan Kara +Link: https://lore.kernel.org/r/20240104142040.2835097-6-libaokun1@huawei.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/mballoc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index 762c2f8b5b2a8..48930df9ae565 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -853,7 +853,7 @@ mb_update_avg_fragment_size(struct super_block *sb, struct ext4_group_info *grp) + { + struct ext4_sb_info *sbi = EXT4_SB(sb); + +- if (!test_opt2(sb, MB_OPTIMIZE_SCAN) || grp->bb_free == 0) ++ if (!test_opt2(sb, MB_OPTIMIZE_SCAN) || grp->bb_fragments == 0) + return; + + write_lock(&sbi->s_mb_rb_lock); +-- +2.43.0 + diff --git a/queue-5.15/ext4-correct-the-hole-length-returned-by-ext4_map_bl.patch b/queue-5.15/ext4-correct-the-hole-length-returned-by-ext4_map_bl.patch new file mode 100644 index 00000000000..c48e7d13f21 --- /dev/null +++ b/queue-5.15/ext4-correct-the-hole-length-returned-by-ext4_map_bl.patch @@ -0,0 +1,189 @@ +From 16bfdf2d610aff4ec02cf13035e017d3ca84756a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 27 Jan 2024 09:58:02 +0800 +Subject: ext4: correct the hole length returned by ext4_map_blocks() + +From: Zhang Yi + +[ Upstream commit 6430dea07e85958fa87d0276c0c4388dd51e630b ] + +In ext4_map_blocks(), if we can't find a range of mapping in the +extents cache, we are calling ext4_ext_map_blocks() to search the real +path and ext4_ext_determine_hole() to determine the hole range. But if +the querying range was partially or completely overlaped by a delalloc +extent, we can't find it in the real extent path, so the returned hole +length could be incorrect. + +Fortunately, ext4_ext_put_gap_in_cache() have already handle delalloc +extent, but it searches start from the expanded hole_start, doesn't +start from the querying range, so the delalloc extent found could not be +the one that overlaped the querying range, plus, it also didn't adjust +the hole length. Let's just remove ext4_ext_put_gap_in_cache(), handle +delalloc and insert adjusted hole extent in ext4_ext_determine_hole(). + +Signed-off-by: Zhang Yi +Suggested-by: Jan Kara +Reviewed-by: Jan Kara +Link: https://lore.kernel.org/r/20240127015825.1608160-4-yi.zhang@huaweicloud.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/extents.c | 111 +++++++++++++++++++++++++++++----------------- + 1 file changed, 70 insertions(+), 41 deletions(-) + +diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c +index 592be39e3d51f..cece004b32d5c 100644 +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -2227,7 +2227,7 @@ static int ext4_fill_es_cache_info(struct inode *inode, + + + /* +- * ext4_ext_determine_hole - determine hole around given block ++ * ext4_ext_find_hole - find hole around given block according to the given path + * @inode: inode we lookup in + * @path: path in extent tree to @lblk + * @lblk: pointer to logical block around which we want to determine hole +@@ -2239,9 +2239,9 @@ static int ext4_fill_es_cache_info(struct inode *inode, + * The function returns the length of a hole starting at @lblk. We update @lblk + * to the beginning of the hole if we managed to find it. + */ +-static ext4_lblk_t ext4_ext_determine_hole(struct inode *inode, +- struct ext4_ext_path *path, +- ext4_lblk_t *lblk) ++static ext4_lblk_t ext4_ext_find_hole(struct inode *inode, ++ struct ext4_ext_path *path, ++ ext4_lblk_t *lblk) + { + int depth = ext_depth(inode); + struct ext4_extent *ex; +@@ -2268,30 +2268,6 @@ static ext4_lblk_t ext4_ext_determine_hole(struct inode *inode, + return len; + } + +-/* +- * ext4_ext_put_gap_in_cache: +- * calculate boundaries of the gap that the requested block fits into +- * and cache this gap +- */ +-static void +-ext4_ext_put_gap_in_cache(struct inode *inode, ext4_lblk_t hole_start, +- ext4_lblk_t hole_len) +-{ +- struct extent_status es; +- +- ext4_es_find_extent_range(inode, &ext4_es_is_delayed, hole_start, +- hole_start + hole_len - 1, &es); +- if (es.es_len) { +- /* There's delayed extent containing lblock? */ +- if (es.es_lblk <= hole_start) +- return; +- hole_len = min(es.es_lblk - hole_start, hole_len); +- } +- ext_debug(inode, " -> %u:%u\n", hole_start, hole_len); +- ext4_es_insert_extent(inode, hole_start, hole_len, ~0, +- EXTENT_STATUS_HOLE); +-} +- + /* + * ext4_ext_rm_idx: + * removes index from the index block. +@@ -4064,6 +4040,69 @@ static int get_implied_cluster_alloc(struct super_block *sb, + return 0; + } + ++/* ++ * Determine hole length around the given logical block, first try to ++ * locate and expand the hole from the given @path, and then adjust it ++ * if it's partially or completely converted to delayed extents, insert ++ * it into the extent cache tree if it's indeed a hole, finally return ++ * the length of the determined extent. ++ */ ++static ext4_lblk_t ext4_ext_determine_insert_hole(struct inode *inode, ++ struct ext4_ext_path *path, ++ ext4_lblk_t lblk) ++{ ++ ext4_lblk_t hole_start, len; ++ struct extent_status es; ++ ++ hole_start = lblk; ++ len = ext4_ext_find_hole(inode, path, &hole_start); ++again: ++ ext4_es_find_extent_range(inode, &ext4_es_is_delayed, hole_start, ++ hole_start + len - 1, &es); ++ if (!es.es_len) ++ goto insert_hole; ++ ++ /* ++ * There's a delalloc extent in the hole, handle it if the delalloc ++ * extent is in front of, behind and straddle the queried range. ++ */ ++ if (lblk >= es.es_lblk + es.es_len) { ++ /* ++ * The delalloc extent is in front of the queried range, ++ * find again from the queried start block. ++ */ ++ len -= lblk - hole_start; ++ hole_start = lblk; ++ goto again; ++ } else if (in_range(lblk, es.es_lblk, es.es_len)) { ++ /* ++ * The delalloc extent containing lblk, it must have been ++ * added after ext4_map_blocks() checked the extent status ++ * tree, adjust the length to the delalloc extent's after ++ * lblk. ++ */ ++ len = es.es_lblk + es.es_len - lblk; ++ return len; ++ } else { ++ /* ++ * The delalloc extent is partially or completely behind ++ * the queried range, update hole length until the ++ * beginning of the delalloc extent. ++ */ ++ len = min(es.es_lblk - hole_start, len); ++ } ++ ++insert_hole: ++ /* Put just found gap into cache to speed up subsequent requests */ ++ ext_debug(inode, " -> %u:%u\n", hole_start, len); ++ ext4_es_insert_extent(inode, hole_start, len, ~0, EXTENT_STATUS_HOLE); ++ ++ /* Update hole_len to reflect hole size after lblk */ ++ if (hole_start != lblk) ++ len -= lblk - hole_start; ++ ++ return len; ++} + + /* + * Block allocation/map/preallocation routine for extents based files +@@ -4181,22 +4220,12 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, + * we couldn't try to create block if create flag is zero + */ + if ((flags & EXT4_GET_BLOCKS_CREATE) == 0) { +- ext4_lblk_t hole_start, hole_len; ++ ext4_lblk_t len; + +- hole_start = map->m_lblk; +- hole_len = ext4_ext_determine_hole(inode, path, &hole_start); +- /* +- * put just found gap into cache to speed up +- * subsequent requests +- */ +- ext4_ext_put_gap_in_cache(inode, hole_start, hole_len); ++ len = ext4_ext_determine_insert_hole(inode, path, map->m_lblk); + +- /* Update hole_len to reflect hole size after map->m_lblk */ +- if (hole_start != map->m_lblk) +- hole_len -= map->m_lblk - hole_start; + map->m_pblk = 0; +- map->m_len = min_t(unsigned int, map->m_len, hole_len); +- ++ map->m_len = min_t(unsigned int, map->m_len, len); + goto out; + } + +-- +2.43.0 + diff --git a/queue-5.15/fbdev-savage-error-out-if-pixclock-equals-zero.patch b/queue-5.15/fbdev-savage-error-out-if-pixclock-equals-zero.patch new file mode 100644 index 00000000000..eef55769e79 --- /dev/null +++ b/queue-5.15/fbdev-savage-error-out-if-pixclock-equals-zero.patch @@ -0,0 +1,45 @@ +From 633821a7393164761d6dac4d919484ffb6bafead Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Jan 2024 11:49:40 +0800 +Subject: fbdev: savage: Error out if pixclock equals zero + +From: Fullway Wang + +[ Upstream commit 04e5eac8f3ab2ff52fa191c187a46d4fdbc1e288 ] + +The userspace program could pass any values to the driver through +ioctl() interface. If the driver doesn't check the value of pixclock, +it may cause divide-by-zero error. + +Although pixclock is checked in savagefb_decode_var(), but it is not +checked properly in savagefb_probe(). Fix this by checking whether +pixclock is zero in the function savagefb_check_var() before +info->var.pixclock is used as the divisor. + +This is similar to CVE-2022-3061 in i740fb which was fixed by +commit 15cf0b8. + +Signed-off-by: Fullway Wang +Signed-off-by: Helge Deller +Signed-off-by: Sasha Levin +--- + drivers/video/fbdev/savage/savagefb_driver.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/video/fbdev/savage/savagefb_driver.c b/drivers/video/fbdev/savage/savagefb_driver.c +index 0ac750cc5ea13..94ebd8af50cf7 100644 +--- a/drivers/video/fbdev/savage/savagefb_driver.c ++++ b/drivers/video/fbdev/savage/savagefb_driver.c +@@ -868,6 +868,9 @@ static int savagefb_check_var(struct fb_var_screeninfo *var, + + DBG("savagefb_check_var"); + ++ if (!var->pixclock) ++ return -EINVAL; ++ + var->transp.offset = 0; + var->transp.length = 0; + switch (var->bits_per_pixel) { +-- +2.43.0 + diff --git a/queue-5.15/fbdev-sis-error-out-if-pixclock-equals-zero.patch b/queue-5.15/fbdev-sis-error-out-if-pixclock-equals-zero.patch new file mode 100644 index 00000000000..9381ac8beb6 --- /dev/null +++ b/queue-5.15/fbdev-sis-error-out-if-pixclock-equals-zero.patch @@ -0,0 +1,43 @@ +From 79153fdc7799d1cc699edbe984c9a7c22e0b4603 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Jan 2024 14:24:43 +0800 +Subject: fbdev: sis: Error out if pixclock equals zero + +From: Fullway Wang + +[ Upstream commit e421946be7d9bf545147bea8419ef8239cb7ca52 ] + +The userspace program could pass any values to the driver through +ioctl() interface. If the driver doesn't check the value of pixclock, +it may cause divide-by-zero error. + +In sisfb_check_var(), var->pixclock is used as a divisor to caculate +drate before it is checked against zero. Fix this by checking it +at the beginning. + +This is similar to CVE-2022-3061 in i740fb which was fixed by +commit 15cf0b8. + +Signed-off-by: Fullway Wang +Signed-off-by: Helge Deller +Signed-off-by: Sasha Levin +--- + drivers/video/fbdev/sis/sis_main.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/video/fbdev/sis/sis_main.c b/drivers/video/fbdev/sis/sis_main.c +index 266a5582f94d3..c6e21ba008953 100644 +--- a/drivers/video/fbdev/sis/sis_main.c ++++ b/drivers/video/fbdev/sis/sis_main.c +@@ -1474,6 +1474,8 @@ sisfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) + + vtotal = var->upper_margin + var->lower_margin + var->vsync_len; + ++ if (!var->pixclock) ++ return -EINVAL; + pixclock = var->pixclock; + + if((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) { +-- +2.43.0 + diff --git a/queue-5.15/firewire-core-send-bus-reset-promptly-on-gap-count-e.patch b/queue-5.15/firewire-core-send-bus-reset-promptly-on-gap-count-e.patch new file mode 100644 index 00000000000..1b974055da6 --- /dev/null +++ b/queue-5.15/firewire-core-send-bus-reset-promptly-on-gap-count-e.patch @@ -0,0 +1,129 @@ +From 32dba73f42f58a3a6101b9eed77866a4a434e739 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Feb 2024 08:01:17 +0900 +Subject: firewire: core: send bus reset promptly on gap count error + +From: Takashi Sakamoto + +[ Upstream commit 7ed4380009e96d9e9c605e12822e987b35b05648 ] + +If we are bus manager and the bus has inconsistent gap counts, send a +bus reset immediately instead of trying to read the root node's config +ROM first. Otherwise, we could spend a lot of time trying to read the +config ROM but never succeeding. + +This eliminates a 50+ second delay before the FireWire bus is usable after +a newly connected device is powered on in certain circumstances. + +The delay occurs if a gap count inconsistency occurs, we are not the root +node, and we become bus manager. One scenario that causes this is with a TI +XIO2213B OHCI, the first time a Sony DSR-25 is powered on after being +connected to the FireWire cable. In this configuration, the Linux box will +not receive the initial PHY configuration packet sent by the DSR-25 as IRM, +resulting in the DSR-25 having a gap count of 44 while the Linux box has a +gap count of 63. + +FireWire devices have a gap count parameter, which is set to 63 on power-up +and can be changed with a PHY configuration packet. This determines the +duration of the subaction and arbitration gaps. For reliable communication, +all nodes on a FireWire bus must have the same gap count. + +A node may have zero or more of the following roles: root node, bus manager +(BM), isochronous resource manager (IRM), and cycle master. Unless a root +node was forced with a PHY configuration packet, any node might become root +node after a bus reset. Only the root node can become cycle master. If the +root node is not cycle master capable, the BM or IRM should force a change +of root node. + +After a bus reset, each node sends a self-ID packet, which contains its +current gap count. A single bus reset does not change the gap count, but +two bus resets in a row will set the gap count to 63. Because a consistent +gap count is required for reliable communication, IEEE 1394a-2000 requires +that the bus manager generate a bus reset if it detects that the gap count +is inconsistent. + +When the gap count is inconsistent, build_tree() will notice this after the +self identification process. It will set card->gap_count to the invalid +value 0. If we become bus master, this will force bm_work() to send a bus +reset when it performs gap count optimization. + +After a bus reset, there is no bus manager. We will almost always try to +become bus manager. Once we become bus manager, we will first determine +whether the root node is cycle master capable. Then, we will determine if +the gap count should be changed. If either the root node or the gap count +should be changed, we will generate a bus reset. + +To determine if the root node is cycle master capable, we read its +configuration ROM. bm_work() will wait until we have finished trying to +read the configuration ROM. + +However, an inconsistent gap count can make this take a long time. +read_config_rom() will read the first few quadlets from the config ROM. Due +to the gap count inconsistency, eventually one of the reads will time out. +When read_config_rom() fails, fw_device_init() calls it again until +MAX_RETRIES is reached. This takes 50+ seconds. + +Once we give up trying to read the configuration ROM, bm_work() will wake +up, assume that the root node is not cycle master capable, and do a bus +reset. Hopefully, this will resolve the gap count inconsistency. + +This change makes bm_work() check for an inconsistent gap count before +waiting for the root node's configuration ROM. If the gap count is +inconsistent, bm_work() will immediately do a bus reset. This eliminates +the 50+ second delay and rapidly brings the bus to a working state. + +I considered that if the gap count is inconsistent, a PHY configuration +packet might not be successful, so it could be desirable to skip the PHY +configuration packet before the bus reset in this case. However, IEEE +1394a-2000 and IEEE 1394-2008 say that the bus manager may transmit a PHY +configuration packet before a bus reset when correcting a gap count error. +Since the standard endorses this, I decided it's safe to retain the PHY +configuration packet transmission. + +Normally, after a topology change, we will reset the bus a maximum of 5 +times to change the root node and perform gap count optimization. However, +if there is a gap count inconsistency, we must always generate a bus reset. +Otherwise the gap count inconsistency will persist and communication will +be unreliable. For that reason, if there is a gap count inconstency, we +generate a bus reset even if we already reached the 5 reset limit. + +Signed-off-by: Adam Goldman +Reference: https://sourceforge.net/p/linux1394/mailman/message/58727806/ +Signed-off-by: Takashi Sakamoto +Signed-off-by: Sasha Levin +--- + drivers/firewire/core-card.c | 18 +++++++++++++++++- + 1 file changed, 17 insertions(+), 1 deletion(-) + +diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c +index f3b3953cac834..be195ba834632 100644 +--- a/drivers/firewire/core-card.c ++++ b/drivers/firewire/core-card.c +@@ -429,7 +429,23 @@ static void bm_work(struct work_struct *work) + */ + card->bm_generation = generation; + +- if (root_device == NULL) { ++ if (card->gap_count == 0) { ++ /* ++ * If self IDs have inconsistent gap counts, do a ++ * bus reset ASAP. The config rom read might never ++ * complete, so don't wait for it. However, still ++ * send a PHY configuration packet prior to the ++ * bus reset. The PHY configuration packet might ++ * fail, but 1394-2008 8.4.5.2 explicitly permits ++ * it in this case, so it should be safe to try. ++ */ ++ new_root_id = local_id; ++ /* ++ * We must always send a bus reset if the gap count ++ * is inconsistent, so bypass the 5-reset limit. ++ */ ++ card->bm_retries = 0; ++ } else if (root_device == NULL) { + /* + * Either link_on is false, or we failed to read the + * config rom. In either case, pick another root. +-- +2.43.0 + diff --git a/queue-5.15/fs-ntfs3-add-null-ptr-dereference-checking-at-the-en.patch b/queue-5.15/fs-ntfs3-add-null-ptr-dereference-checking-at-the-en.patch new file mode 100644 index 00000000000..b8579eac80c --- /dev/null +++ b/queue-5.15/fs-ntfs3-add-null-ptr-dereference-checking-at-the-en.patch @@ -0,0 +1,61 @@ +From 3fb6d332d0603c455403b36f7d1784431a773dc5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Nov 2023 11:09:34 +0300 +Subject: fs/ntfs3: Add NULL ptr dereference checking at the end of + attr_allocate_frame() + +From: Konstantin Komarov + +[ Upstream commit aaab47f204aaf47838241d57bf8662c8840de60a ] + +It is preferable to exit through the out: label because +internal debugging functions are located there. + +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/attrib.c | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +diff --git a/fs/ntfs3/attrib.c b/fs/ntfs3/attrib.c +index 1d5ac2164d94f..64a6d255c4686 100644 +--- a/fs/ntfs3/attrib.c ++++ b/fs/ntfs3/attrib.c +@@ -1583,8 +1583,10 @@ int attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size, + le_b = NULL; + attr_b = ni_find_attr(ni, NULL, &le_b, ATTR_DATA, NULL, + 0, NULL, &mi_b); +- if (!attr_b) +- return -ENOENT; ++ if (!attr_b) { ++ err = -ENOENT; ++ goto out; ++ } + + attr = attr_b; + le = le_b; +@@ -1665,13 +1667,15 @@ int attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size, + ok: + run_truncate_around(run, vcn); + out: +- if (new_valid > data_size) +- new_valid = data_size; ++ if (attr_b) { ++ if (new_valid > data_size) ++ new_valid = data_size; + +- valid_size = le64_to_cpu(attr_b->nres.valid_size); +- if (new_valid != valid_size) { +- attr_b->nres.valid_size = cpu_to_le64(valid_size); +- mi_b->dirty = true; ++ valid_size = le64_to_cpu(attr_b->nres.valid_size); ++ if (new_valid != valid_size) { ++ attr_b->nres.valid_size = cpu_to_le64(valid_size); ++ mi_b->dirty = true; ++ } + } + + return err; +-- +2.43.0 + diff --git a/queue-5.15/fs-ntfs3-correct-function-is_rst_area_valid.patch b/queue-5.15/fs-ntfs3-correct-function-is_rst_area_valid.patch new file mode 100644 index 00000000000..b6af3c6b5b7 --- /dev/null +++ b/queue-5.15/fs-ntfs3-correct-function-is_rst_area_valid.patch @@ -0,0 +1,53 @@ +From 364cf2605426cf33e45a084e319d8cca82c283af Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Jan 2024 11:13:59 +0300 +Subject: fs/ntfs3: Correct function is_rst_area_valid + +From: Konstantin Komarov + +[ Upstream commit 1b7dd28e14c4728ae1a815605ca33ffb4ce1b309 ] + +Reported-by: Robert Morris +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/fslog.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c +index 8b95c06e5a4c5..6ba1357f3ed4c 100644 +--- a/fs/ntfs3/fslog.c ++++ b/fs/ntfs3/fslog.c +@@ -465,7 +465,7 @@ static inline bool is_rst_area_valid(const struct RESTART_HDR *rhdr) + { + const struct RESTART_AREA *ra; + u16 cl, fl, ul; +- u32 off, l_size, file_dat_bits, file_size_round; ++ u32 off, l_size, seq_bits; + u16 ro = le16_to_cpu(rhdr->ra_off); + u32 sys_page = le32_to_cpu(rhdr->sys_page_size); + +@@ -511,13 +511,15 @@ static inline bool is_rst_area_valid(const struct RESTART_HDR *rhdr) + /* Make sure the sequence number bits match the log file size. */ + l_size = le64_to_cpu(ra->l_size); + +- file_dat_bits = sizeof(u64) * 8 - le32_to_cpu(ra->seq_num_bits); +- file_size_round = 1u << (file_dat_bits + 3); +- if (file_size_round != l_size && +- (file_size_round < l_size || (file_size_round / 2) > l_size)) { +- return false; ++ seq_bits = sizeof(u64) * 8 + 3; ++ while (l_size) { ++ l_size >>= 1; ++ seq_bits -= 1; + } + ++ if (seq_bits != ra->seq_num_bits) ++ return false; ++ + /* The log page data offset and record header length must be quad-aligned. */ + if (!IS_ALIGNED(le16_to_cpu(ra->data_off), 8) || + !IS_ALIGNED(le16_to_cpu(ra->rec_hdr_len), 8)) +-- +2.43.0 + diff --git a/queue-5.15/fs-ntfs3-correct-hard-links-updating-when-dealing-wi.patch b/queue-5.15/fs-ntfs3-correct-hard-links-updating-when-dealing-wi.patch new file mode 100644 index 00000000000..11a88945c74 --- /dev/null +++ b/queue-5.15/fs-ntfs3-correct-hard-links-updating-when-dealing-wi.patch @@ -0,0 +1,45 @@ +From 3ef594a3ec6b53dc98a86e6fabfa938d91ff188f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Nov 2023 11:26:31 +0300 +Subject: fs/ntfs3: Correct hard links updating when dealing with DOS names + +From: Konstantin Komarov + +[ Upstream commit 1918c10e137eae266b8eb0ab1cc14421dcb0e3e2 ] + +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/record.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +diff --git a/fs/ntfs3/record.c b/fs/ntfs3/record.c +index 938fc286963f2..ac43e4a6d57d1 100644 +--- a/fs/ntfs3/record.c ++++ b/fs/ntfs3/record.c +@@ -509,8 +509,20 @@ bool mi_remove_attr(struct ntfs_inode *ni, struct mft_inode *mi, + return false; + + if (ni && is_attr_indexed(attr)) { +- le16_add_cpu(&ni->mi.mrec->hard_links, -1); +- ni->mi.dirty = true; ++ u16 links = le16_to_cpu(ni->mi.mrec->hard_links); ++ struct ATTR_FILE_NAME *fname = ++ attr->type != ATTR_NAME ? ++ NULL : ++ resident_data_ex(attr, ++ SIZEOF_ATTRIBUTE_FILENAME); ++ if (fname && fname->type == FILE_NAME_DOS) { ++ /* Do not decrease links count deleting DOS name. */ ++ } else if (!links) { ++ /* minor error. Not critical. */ ++ } else { ++ ni->mi.mrec->hard_links = cpu_to_le16(links - 1); ++ ni->mi.dirty = true; ++ } + } + + used -= asize; +-- +2.43.0 + diff --git a/queue-5.15/fs-ntfs3-disable-attr_list_entry-size-check.patch b/queue-5.15/fs-ntfs3-disable-attr_list_entry-size-check.patch new file mode 100644 index 00000000000..aedfd5d9e0f --- /dev/null +++ b/queue-5.15/fs-ntfs3-disable-attr_list_entry-size-check.patch @@ -0,0 +1,75 @@ +From e1458317f0dc2b5934080d742e00973b1838d388 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Dec 2023 13:59:43 +0300 +Subject: fs/ntfs3: Disable ATTR_LIST_ENTRY size check + +From: Konstantin Komarov + +[ Upstream commit 4cdfb6e7bc9c80142d33bf1d4653a73fa678ba56 ] + +The use of sizeof(struct ATTR_LIST_ENTRY) has been replaced with le_size(0) +due to alignment peculiarities on different platforms. + +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202312071005.g6YrbaIe-lkp@intel.com/ +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/attrlist.c | 8 ++++---- + fs/ntfs3/ntfs.h | 2 -- + 2 files changed, 4 insertions(+), 6 deletions(-) + +diff --git a/fs/ntfs3/attrlist.c b/fs/ntfs3/attrlist.c +index 0c6a68e71e7d4..723e49ec83ce7 100644 +--- a/fs/ntfs3/attrlist.c ++++ b/fs/ntfs3/attrlist.c +@@ -127,12 +127,13 @@ struct ATTR_LIST_ENTRY *al_enumerate(struct ntfs_inode *ni, + { + size_t off; + u16 sz; ++ const unsigned le_min_size = le_size(0); + + if (!le) { + le = ni->attr_list.le; + } else { + sz = le16_to_cpu(le->size); +- if (sz < sizeof(struct ATTR_LIST_ENTRY)) { ++ if (sz < le_min_size) { + /* Impossible 'cause we should not return such le. */ + return NULL; + } +@@ -141,7 +142,7 @@ struct ATTR_LIST_ENTRY *al_enumerate(struct ntfs_inode *ni, + + /* Check boundary. */ + off = PtrOffset(ni->attr_list.le, le); +- if (off + sizeof(struct ATTR_LIST_ENTRY) > ni->attr_list.size) { ++ if (off + le_min_size > ni->attr_list.size) { + /* The regular end of list. */ + return NULL; + } +@@ -149,8 +150,7 @@ struct ATTR_LIST_ENTRY *al_enumerate(struct ntfs_inode *ni, + sz = le16_to_cpu(le->size); + + /* Check le for errors. */ +- if (sz < sizeof(struct ATTR_LIST_ENTRY) || +- off + sz > ni->attr_list.size || ++ if (sz < le_min_size || off + sz > ni->attr_list.size || + sz < le->name_off + le->name_len * sizeof(short)) { + return NULL; + } +diff --git a/fs/ntfs3/ntfs.h b/fs/ntfs3/ntfs.h +index 8b580515b1d6e..ba26a465b3091 100644 +--- a/fs/ntfs3/ntfs.h ++++ b/fs/ntfs3/ntfs.h +@@ -521,8 +521,6 @@ struct ATTR_LIST_ENTRY { + + }; // sizeof(0x20) + +-static_assert(sizeof(struct ATTR_LIST_ENTRY) == 0x20); +- + static inline u32 le_size(u8 name_len) + { + return ALIGN(offsetof(struct ATTR_LIST_ENTRY, name) + +-- +2.43.0 + diff --git a/queue-5.15/fs-ntfs3-fix-detected-field-spanning-write-size-8-of.patch b/queue-5.15/fs-ntfs3-fix-detected-field-spanning-write-size-8-of.patch new file mode 100644 index 00000000000..901e3784518 --- /dev/null +++ b/queue-5.15/fs-ntfs3-fix-detected-field-spanning-write-size-8-of.patch @@ -0,0 +1,32 @@ +From ca5fc24002da2e5e746cccfcb8ac8fd01a635a26 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Nov 2023 11:47:30 +0300 +Subject: fs/ntfs3: Fix detected field-spanning write (size 8) of single field + "le->name" + +From: Konstantin Komarov + +[ Upstream commit d155617006ebc172a80d3eb013c4b867f9a8ada4 ] + +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/ntfs.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/ntfs3/ntfs.h b/fs/ntfs3/ntfs.h +index 0f38d558169a1..8b580515b1d6e 100644 +--- a/fs/ntfs3/ntfs.h ++++ b/fs/ntfs3/ntfs.h +@@ -517,7 +517,7 @@ struct ATTR_LIST_ENTRY { + __le64 vcn; // 0x08: Starting VCN of this attribute. + struct MFT_REF ref; // 0x10: MFT record number with attribute. + __le16 id; // 0x18: struct ATTRIB ID. +- __le16 name[3]; // 0x1A: Just to align. To get real name can use bNameOffset. ++ __le16 name[]; // 0x1A: Just to align. To get real name can use name_off. + + }; // sizeof(0x20) + +-- +2.43.0 + diff --git a/queue-5.15/fs-ntfs3-fix-oob-in-ntfs_listxattr.patch b/queue-5.15/fs-ntfs3-fix-oob-in-ntfs_listxattr.patch new file mode 100644 index 00000000000..c8abc77a942 --- /dev/null +++ b/queue-5.15/fs-ntfs3-fix-oob-in-ntfs_listxattr.patch @@ -0,0 +1,36 @@ +From 86ac74d7f940756ec1d10da54d84b9cffd7492ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 30 Dec 2023 17:00:03 +0800 +Subject: fs/ntfs3: Fix oob in ntfs_listxattr + +From: Edward Adam Davis + +[ Upstream commit 731ab1f9828800df871c5a7ab9ffe965317d3f15 ] + +The length of name cannot exceed the space occupied by ea. + +Reported-and-tested-by: syzbot+65e940cfb8f99a97aca7@syzkaller.appspotmail.com +Signed-off-by: Edward Adam Davis +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/xattr.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/fs/ntfs3/xattr.c b/fs/ntfs3/xattr.c +index 8e739023e3057..d0b75d7f58a7b 100644 +--- a/fs/ntfs3/xattr.c ++++ b/fs/ntfs3/xattr.c +@@ -217,6 +217,9 @@ static ssize_t ntfs_list_ea(struct ntfs_inode *ni, char *buffer, + if (!ea->name_len) + break; + ++ if (ea->name_len > ea_size) ++ break; ++ + if (buffer) { + /* Check if we can use field ea->name */ + if (off + ea_size > size) +-- +2.43.0 + diff --git a/queue-5.15/fs-ntfs3-improve-ntfs_dir_count.patch b/queue-5.15/fs-ntfs3-improve-ntfs_dir_count.patch new file mode 100644 index 00000000000..ccaf7637c39 --- /dev/null +++ b/queue-5.15/fs-ntfs3-improve-ntfs_dir_count.patch @@ -0,0 +1,62 @@ +From da9cd74e18fb8903eac1e68ca4473e20ea9cabf6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Nov 2023 11:24:33 +0300 +Subject: fs/ntfs3: Improve ntfs_dir_count + +From: Konstantin Komarov + +[ Upstream commit 6a799c928b78b14999b7705c4cca0f88e297fe96 ] + +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/dir.c | 10 +++------- + 1 file changed, 3 insertions(+), 7 deletions(-) + +diff --git a/fs/ntfs3/dir.c b/fs/ntfs3/dir.c +index c2fb76bb28f47..72cdfa8727d3c 100644 +--- a/fs/ntfs3/dir.c ++++ b/fs/ntfs3/dir.c +@@ -515,11 +515,9 @@ static int ntfs_dir_count(struct inode *dir, bool *is_empty, size_t *dirs, + struct INDEX_HDR *hdr; + const struct ATTR_FILE_NAME *fname; + u32 e_size, off, end; +- u64 vbo = 0; + size_t drs = 0, fles = 0, bit = 0; +- loff_t i_size = ni->vfs_inode.i_size; + struct indx_node *node = NULL; +- u8 index_bits = ni->dir.index_bits; ++ size_t max_indx = ni->vfs_inode.i_size >> ni->dir.index_bits; + + if (is_empty) + *is_empty = true; +@@ -563,7 +561,7 @@ static int ntfs_dir_count(struct inode *dir, bool *is_empty, size_t *dirs, + fles += 1; + } + +- if (vbo >= i_size) ++ if (bit >= max_indx) + goto out; + + err = indx_used_bit(&ni->dir, ni, &bit); +@@ -573,8 +571,7 @@ static int ntfs_dir_count(struct inode *dir, bool *is_empty, size_t *dirs, + if (bit == MINUS_ONE_T) + goto out; + +- vbo = (u64)bit << index_bits; +- if (vbo >= i_size) ++ if (bit >= max_indx) + goto out; + + err = indx_read(&ni->dir, ni, bit << ni->dir.idx2vbn_bits, +@@ -584,7 +581,6 @@ static int ntfs_dir_count(struct inode *dir, bool *is_empty, size_t *dirs, + + hdr = &node->index->ihdr; + bit += 1; +- vbo = (u64)bit << ni->dir.idx2vbn_bits; + } + + out: +-- +2.43.0 + diff --git a/queue-5.15/fs-ntfs3-modified-fix-directory-element-type-detecti.patch b/queue-5.15/fs-ntfs3-modified-fix-directory-element-type-detecti.patch new file mode 100644 index 00000000000..0e45c58a681 --- /dev/null +++ b/queue-5.15/fs-ntfs3-modified-fix-directory-element-type-detecti.patch @@ -0,0 +1,64 @@ +From 60f2348e2f041b9712065a8640c20811e7cdced6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Nov 2023 11:17:07 +0300 +Subject: fs/ntfs3: Modified fix directory element type detection + +From: Konstantin Komarov + +[ Upstream commit 22457c047ed971f2f2e33be593ddfabd9639a409 ] + +Unfortunately reparse attribute is used for many purposes (several dozens). +It is not possible here to know is this name symlink or not. +To get exactly the type of name we should to open inode (read mft). +getattr for opened file (fstat) correctly returns symlink. + +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/dir.c | 30 +++++++++++++++++++++++++----- + 1 file changed, 25 insertions(+), 5 deletions(-) + +diff --git a/fs/ntfs3/dir.c b/fs/ntfs3/dir.c +index d4d9f4ffb6d9a..c2fb76bb28f47 100644 +--- a/fs/ntfs3/dir.c ++++ b/fs/ntfs3/dir.c +@@ -309,11 +309,31 @@ static inline int ntfs_filldir(struct ntfs_sb_info *sbi, struct ntfs_inode *ni, + return 0; + } + +- /* NTFS: symlinks are "dir + reparse" or "file + reparse" */ +- if (fname->dup.fa & FILE_ATTRIBUTE_REPARSE_POINT) +- dt_type = DT_LNK; +- else +- dt_type = (fname->dup.fa & FILE_ATTRIBUTE_DIRECTORY) ? DT_DIR : DT_REG; ++ /* ++ * NTFS: symlinks are "dir + reparse" or "file + reparse" ++ * Unfortunately reparse attribute is used for many purposes (several dozens). ++ * It is not possible here to know is this name symlink or not. ++ * To get exactly the type of name we should to open inode (read mft). ++ * getattr for opened file (fstat) correctly returns symlink. ++ */ ++ dt_type = (fname->dup.fa & FILE_ATTRIBUTE_DIRECTORY) ? DT_DIR : DT_REG; ++ ++ /* ++ * It is not reliable to detect the type of name using duplicated information ++ * stored in parent directory. ++ * The only correct way to get the type of name - read MFT record and find ATTR_STD. ++ * The code below is not good idea. ++ * It does additional locks/reads just to get the type of name. ++ * Should we use additional mount option to enable branch below? ++ */ ++ if ((fname->dup.fa & FILE_ATTRIBUTE_REPARSE_POINT) && ++ ino != ni->mi.rno) { ++ struct inode *inode = ntfs_iget5(sbi->sb, &e->ref, NULL); ++ if (!IS_ERR_OR_NULL(inode)) { ++ dt_type = fs_umode_to_dtype(inode->i_mode); ++ iput(inode); ++ } ++ } + + return !dir_emit(ctx, (s8 *)name, name_len, ino, dt_type); + } +-- +2.43.0 + diff --git a/queue-5.15/fs-ntfs3-prevent-generic-message-attempt-to-access-b.patch b/queue-5.15/fs-ntfs3-prevent-generic-message-attempt-to-access-b.patch new file mode 100644 index 00000000000..1b0c75229a6 --- /dev/null +++ b/queue-5.15/fs-ntfs3-prevent-generic-message-attempt-to-access-b.patch @@ -0,0 +1,89 @@ +From d577c0e8eb0a02baad63de5dcba07aa140cdee33 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Jan 2024 11:03:21 +0300 +Subject: fs/ntfs3: Prevent generic message "attempt to access beyond end of + device" + +From: Konstantin Komarov + +[ Upstream commit 5ca87d01eba7bdfe9536a157ca33c1455bb8d16c ] + +It used in test environment. + +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/fsntfs.c | 24 ++++++++++++++++++++++++ + fs/ntfs3/ntfs_fs.h | 14 +------------- + 2 files changed, 25 insertions(+), 13 deletions(-) + +diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c +index 110690edbf621..1b082b7a67ee2 100644 +--- a/fs/ntfs3/fsntfs.c ++++ b/fs/ntfs3/fsntfs.c +@@ -981,6 +981,30 @@ static inline __le32 security_hash(const void *sd, size_t bytes) + return cpu_to_le32(hash); + } + ++/* ++ * simple wrapper for sb_bread_unmovable. ++ */ ++struct buffer_head *ntfs_bread(struct super_block *sb, sector_t block) ++{ ++ struct ntfs_sb_info *sbi = sb->s_fs_info; ++ struct buffer_head *bh; ++ ++ if (unlikely(block >= sbi->volume.blocks)) { ++ /* prevent generic message "attempt to access beyond end of device" */ ++ ntfs_err(sb, "try to read out of volume at offset 0x%llx", ++ (u64)block << sb->s_blocksize_bits); ++ return NULL; ++ } ++ ++ bh = sb_bread_unmovable(sb, block); ++ if (bh) ++ return bh; ++ ++ ntfs_err(sb, "failed to read volume at offset 0x%llx", ++ (u64)block << sb->s_blocksize_bits); ++ return NULL; ++} ++ + int ntfs_sb_read(struct super_block *sb, u64 lbo, size_t bytes, void *buffer) + { + struct block_device *bdev = sb->s_bdev; +diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h +index ffc8dfbb310ff..12a3b41d351c9 100644 +--- a/fs/ntfs3/ntfs_fs.h ++++ b/fs/ntfs3/ntfs_fs.h +@@ -581,6 +581,7 @@ bool check_index_header(const struct INDEX_HDR *hdr, size_t bytes); + int log_replay(struct ntfs_inode *ni, bool *initialized); + + /* Globals from fsntfs.c */ ++struct buffer_head *ntfs_bread(struct super_block *sb, sector_t block); + bool ntfs_fix_pre_write(struct NTFS_RECORD_HEADER *rhdr, size_t bytes); + int ntfs_fix_post_read(struct NTFS_RECORD_HEADER *rhdr, size_t bytes, + bool simple); +@@ -1011,19 +1012,6 @@ static inline u64 bytes_to_block(const struct super_block *sb, u64 size) + return (size + sb->s_blocksize - 1) >> sb->s_blocksize_bits; + } + +-static inline struct buffer_head *ntfs_bread(struct super_block *sb, +- sector_t block) +-{ +- struct buffer_head *bh = sb_bread_unmovable(sb, block); +- +- if (bh) +- return bh; +- +- ntfs_err(sb, "failed to read volume at offset 0x%llx", +- (u64)block << sb->s_blocksize_bits); +- return NULL; +-} +- + static inline struct ntfs_inode *ntfs_i(struct inode *inode) + { + return container_of(inode, struct ntfs_inode, vfs_inode); +-- +2.43.0 + diff --git a/queue-5.15/fs-ntfs3-print-warning-while-fixing-hard-links-count.patch b/queue-5.15/fs-ntfs3-print-warning-while-fixing-hard-links-count.patch new file mode 100644 index 00000000000..56c6a00681e --- /dev/null +++ b/queue-5.15/fs-ntfs3-print-warning-while-fixing-hard-links-count.patch @@ -0,0 +1,38 @@ +From 6a60a4537e362b3351d96bbcce40b9fd49c4049d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Nov 2023 11:34:24 +0300 +Subject: fs/ntfs3: Print warning while fixing hard links count + +From: Konstantin Komarov + +[ Upstream commit 85ba2a75faee759809a7e43b4c103ac59bac1026 ] + +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/inode.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c +index 176b04a5d1adb..0ff673bb4b2be 100644 +--- a/fs/ntfs3/inode.c ++++ b/fs/ntfs3/inode.c +@@ -402,7 +402,6 @@ static struct inode *ntfs_read_mft(struct inode *inode, + goto out; + + if (!is_match && name) { +- /* Reuse rec as buffer for ascii name. */ + err = -ENOENT; + goto out; + } +@@ -417,6 +416,7 @@ static struct inode *ntfs_read_mft(struct inode *inode, + + if (names != le16_to_cpu(rec->hard_links)) { + /* Correct minor error on the fly. Do not mark inode as dirty. */ ++ ntfs_inode_warn(inode, "Correct links count -> %u.", names); + rec->hard_links = cpu_to_le16(names); + ni->mi.dirty = true; + } +-- +2.43.0 + diff --git a/queue-5.15/fs-ntfs3-update-inode-i_size-after-success-write-int.patch b/queue-5.15/fs-ntfs3-update-inode-i_size-after-success-write-int.patch new file mode 100644 index 00000000000..ee71e17f70c --- /dev/null +++ b/queue-5.15/fs-ntfs3-update-inode-i_size-after-success-write-int.patch @@ -0,0 +1,33 @@ +From e1e7f51ab55c8780eec2ded1d5fe324ede153cbe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Jan 2024 10:30:09 +0300 +Subject: fs/ntfs3: Update inode->i_size after success write into compressed + file + +From: Konstantin Komarov + +[ Upstream commit d68968440b1a75dee05cfac7f368f1aa139e1911 ] + +Reported-by: Giovanni Santini +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/file.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c +index c526e0427f2bf..6d4f3431bc75a 100644 +--- a/fs/ntfs3/file.c ++++ b/fs/ntfs3/file.c +@@ -1090,6 +1090,8 @@ static ssize_t ntfs_compress_write(struct kiocb *iocb, struct iov_iter *from) + iocb->ki_pos += written; + if (iocb->ki_pos > ni->i_valid) + ni->i_valid = iocb->ki_pos; ++ if (iocb->ki_pos > i_size) ++ i_size_write(inode, iocb->ki_pos); + + return written; + } +-- +2.43.0 + diff --git a/queue-5.15/fs-ntfs3-use-non-movable-memory-for-ntfs3-mft-buffer.patch b/queue-5.15/fs-ntfs3-use-non-movable-memory-for-ntfs3-mft-buffer.patch new file mode 100644 index 00000000000..27398449742 --- /dev/null +++ b/queue-5.15/fs-ntfs3-use-non-movable-memory-for-ntfs3-mft-buffer.patch @@ -0,0 +1,79 @@ +From e94292d797c3181367daa4f86351fc36b8ac6c8f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Dec 2023 16:51:41 +0800 +Subject: fs/ntfs3: use non-movable memory for ntfs3 MFT buffer cache + +From: Ism Hong + +[ Upstream commit d6d33f03baa43d763fe094ca926eeae7d3421d07 ] + +Since the buffer cache for ntfs3 metadata is not released until the file +system is unmounted, allocating from the movable zone may result in cma +allocation failures. This is due to the page still being used by ntfs3, +leading to migration failures. + +To address this, this commit use sb_bread_umovable() instead of +sb_bread(). This change prevents allocation from the movable zone, +ensuring compatibility with scenarios where the buffer head is not +released until unmount. This patch is inspired by commit +a8ac900b8163("ext4: use non-movable memory for the ext4 superblock"). + +The issue is found when playing video files stored in NTFS on the +Android TV platform. During this process, the media parser reads the +video file, causing ntfs3 to allocate buffer cache from the CMA area. +Subsequently, the hardware decoder attempts to allocate memory from the +same CMA area. However, the page is still in use by ntfs3, resulting in +a migrate failure in alloc_contig_range(). + +The pinned page and allocating stacktrace reported by page owner shows +below: + +page:ffffffff00b68880 refcount:3 mapcount:0 mapping:ffffff80046aa828 + index:0xc0040 pfn:0x20fa4 + aops:def_blk_aops ino:0 + flags: 0x2020(active|private) + page dumped because: migration failure + page last allocated via order 0, migratetype Movable, + gfp_mask 0x108c48 + (GFP_NOFS|__GFP_NOFAIL|__GFP_HARDWALL|__GFP_MOVABLE), + page_owner tracks the page as allocated + prep_new_page + get_page_from_freelist + __alloc_pages_nodemask + pagecache_get_page + __getblk_gfp + __bread_gfp + ntfs_read_run_nb + ntfs_read_bh + mi_read + ntfs_iget5 + dir_search_u + ntfs_lookup + __lookup_slow + lookup_slow + walk_component + path_lookupat + +Signed-off-by: Ism Hong +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/ntfs_fs.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h +index 9812765000439..ffc8dfbb310ff 100644 +--- a/fs/ntfs3/ntfs_fs.h ++++ b/fs/ntfs3/ntfs_fs.h +@@ -1014,7 +1014,7 @@ static inline u64 bytes_to_block(const struct super_block *sb, u64 size) + static inline struct buffer_head *ntfs_bread(struct super_block *sb, + sector_t block) + { +- struct buffer_head *bh = sb_bread(sb, block); ++ struct buffer_head *bh = sb_bread_unmovable(sb, block); + + if (bh) + return bh; +-- +2.43.0 + diff --git a/queue-5.15/hwmon-coretemp-enlarge-per-package-core-count-limit.patch b/queue-5.15/hwmon-coretemp-enlarge-per-package-core-count-limit.patch new file mode 100644 index 00000000000..0ed0db5cdda --- /dev/null +++ b/queue-5.15/hwmon-coretemp-enlarge-per-package-core-count-limit.patch @@ -0,0 +1,43 @@ +From 01ce9f7a2fa0c7a621a0202888e133242f1d4736 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Feb 2024 17:21:36 +0800 +Subject: hwmon: (coretemp) Enlarge per package core count limit + +From: Zhang Rui + +[ Upstream commit 34cf8c657cf0365791cdc658ddbca9cc907726ce ] + +Currently, coretemp driver supports only 128 cores per package. +This loses some core temperature information on systems that have more +than 128 cores per package. + [ 58.685033] coretemp coretemp.0: Adding Core 128 failed + [ 58.692009] coretemp coretemp.0: Adding Core 129 failed + ... + +Enlarge the limitation to 512 because there are platforms with more than +256 cores per package. + +Signed-off-by: Zhang Rui +Link: https://lore.kernel.org/r/20240202092144.71180-4-rui.zhang@intel.com +Signed-off-by: Guenter Roeck +Signed-off-by: Sasha Levin +--- + drivers/hwmon/coretemp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c +index d67d972d18aa2..cbe2f874b5e2f 100644 +--- a/drivers/hwmon/coretemp.c ++++ b/drivers/hwmon/coretemp.c +@@ -40,7 +40,7 @@ MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius"); + + #define PKG_SYSFS_ATTR_NO 1 /* Sysfs attribute for package temp */ + #define BASE_SYSFS_ATTR_NO 2 /* Sysfs Base attr no for coretemp */ +-#define NUM_REAL_CORES 128 /* Number of Real cores per cpu */ ++#define NUM_REAL_CORES 512 /* Number of Real cores per cpu */ + #define CORETEMP_NAME_LENGTH 28 /* String Length of attrs */ + #define MAX_CORE_ATTRS 4 /* Maximum no of basic attrs */ + #define TOTAL_ATTRS (MAX_CORE_ATTRS + 1) +-- +2.43.0 + diff --git a/queue-5.15/input-i8042-add-fujitsu-lifebook-u728-to-i8042-quirk.patch b/queue-5.15/input-i8042-add-fujitsu-lifebook-u728-to-i8042-quirk.patch new file mode 100644 index 00000000000..1fde28c73a0 --- /dev/null +++ b/queue-5.15/input-i8042-add-fujitsu-lifebook-u728-to-i8042-quirk.patch @@ -0,0 +1,55 @@ +From f23074fb92a09a8f12db2f213e74c368cf51e96b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Feb 2024 10:28:59 -0800 +Subject: Input: i8042 - add Fujitsu Lifebook U728 to i8042 quirk table + +From: Szilard Fabian + +[ Upstream commit 4255447ad34c5c3785fcdcf76cfa0271d6e5ed39 ] + +Another Fujitsu-related patch. + +In the initial boot stage the integrated keyboard of Fujitsu Lifebook U728 +refuses to work and it's not possible to type for example a dm-crypt +passphrase without the help of an external keyboard. + +i8042.nomux kernel parameter resolves this issue but using that a PS/2 +mouse is detected. This input device is unused even when the i2c-hid-acpi +kernel module is blacklisted making the integrated ELAN touchpad +(04F3:3092) not working at all. + +So this notebook uses a hid-over-i2c touchpad which is managed by the +i2c_designware input driver. Since you can't find a PS/2 mouse port on this +computer and you can't connect a PS/2 mouse to it even with an official +port replicator I think it's safe to not use the PS/2 mouse port at all. + +Signed-off-by: Szilard Fabian +Link: https://lore.kernel.org/r/20240103014717.127307-2-szfabian@bluemarch.art +Signed-off-by: Dmitry Torokhov +Signed-off-by: Sasha Levin +--- + drivers/input/serio/i8042-acpipnpio.h | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/input/serio/i8042-acpipnpio.h b/drivers/input/serio/i8042-acpipnpio.h +index 359d1a287a78e..d4792950bcffd 100644 +--- a/drivers/input/serio/i8042-acpipnpio.h ++++ b/drivers/input/serio/i8042-acpipnpio.h +@@ -625,6 +625,14 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = { + }, + .driver_data = (void *)(SERIO_QUIRK_NOAUX) + }, ++ { ++ /* Fujitsu Lifebook U728 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U728"), ++ }, ++ .driver_data = (void *)(SERIO_QUIRK_NOAUX) ++ }, + { + /* Gigabyte M912 */ + .matches = { +-- +2.43.0 + diff --git a/queue-5.15/input-xpad-add-lenovo-legion-go-controllers.patch b/queue-5.15/input-xpad-add-lenovo-legion-go-controllers.patch new file mode 100644 index 00000000000..171b8ae53a2 --- /dev/null +++ b/queue-5.15/input-xpad-add-lenovo-legion-go-controllers.patch @@ -0,0 +1,69 @@ +From 25f774b407ee3ac165a7d09a26568b4358a0fab3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Jan 2024 13:34:16 -0800 +Subject: Input: xpad - add Lenovo Legion Go controllers + +From: Brenton Simpson + +[ Upstream commit 80441f76ee67002437db61f3b317ed80cce085d2 ] + +The Lenovo Legion Go is a handheld gaming system, similar to a Steam Deck. +It has a gamepad (including rear paddles), 3 gyroscopes, a trackpad, +volume buttons, a power button, and 2 LED ring lights. + +The Legion Go firmware presents these controls as a USB hub with various +devices attached. In its default state, the gamepad is presented as an +Xbox controller connected to this hub. (By holding a combination of +buttons, it can be changed to use the older DirectInput API.) + +This patch teaches the existing Xbox controller module `xpad` to bind to +the controller in the Legion Go, which enables support for the: + +- directional pad, +- analog sticks (including clicks), +- X, Y, A, B, +- start and select (or menu and capture), +- shoulder buttons, and +- rumble. + +The trackpad, touchscreen, volume controls, and power button are already +supported via existing kernel modules. Two of the face buttons, the +gyroscopes, rear paddles, and LEDs are not. + +After this patch lands, the Legion Go will be mostly functional in Linux, +out-of-the-box. The various components of the USB hub can be synthesized +into a single logical controller (including the additional buttons) in +userspace with [Handheld Daemon](https://github.com/hhd-dev/hhd), which +makes the Go fully functional. + +Signed-off-by: Brenton Simpson +Link: https://lore.kernel.org/r/20240118183546.418064-1-appsforartists@google.com +Signed-off-by: Dmitry Torokhov +Signed-off-by: Sasha Levin +--- + drivers/input/joystick/xpad.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c +index 1ff0d4e24fe68..f0b1dac938222 100644 +--- a/drivers/input/joystick/xpad.c ++++ b/drivers/input/joystick/xpad.c +@@ -276,6 +276,7 @@ static const struct xpad_device { + { 0x1689, 0xfd00, "Razer Onza Tournament Edition", 0, XTYPE_XBOX360 }, + { 0x1689, 0xfd01, "Razer Onza Classic Edition", 0, XTYPE_XBOX360 }, + { 0x1689, 0xfe00, "Razer Sabertooth", 0, XTYPE_XBOX360 }, ++ { 0x17ef, 0x6182, "Lenovo Legion Controller for Windows", 0, XTYPE_XBOX360 }, + { 0x1949, 0x041a, "Amazon Game Controller", 0, XTYPE_XBOX360 }, + { 0x1bad, 0x0002, "Harmonix Rock Band Guitar", 0, XTYPE_XBOX360 }, + { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, +@@ -464,6 +465,7 @@ static const struct usb_device_id xpad_table[] = { + XPAD_XBOX360_VENDOR(0x15e4), /* Numark X-Box 360 controllers */ + XPAD_XBOX360_VENDOR(0x162e), /* Joytech X-Box 360 controllers */ + XPAD_XBOX360_VENDOR(0x1689), /* Razer Onza */ ++ XPAD_XBOX360_VENDOR(0x17ef), /* Lenovo */ + XPAD_XBOX360_VENDOR(0x1949), /* Amazon controllers */ + XPAD_XBOX360_VENDOR(0x1bad), /* Harminix Rock Band Guitar and Drums */ + XPAD_XBOX360_VENDOR(0x20d6), /* PowerA Controllers */ +-- +2.43.0 + diff --git a/queue-5.15/mips-reserve-exception-vector-space-only-once.patch b/queue-5.15/mips-reserve-exception-vector-space-only-once.patch new file mode 100644 index 00000000000..556c69bd77b --- /dev/null +++ b/queue-5.15/mips-reserve-exception-vector-space-only-once.patch @@ -0,0 +1,45 @@ +From c4f1890c0ee3f11df46781614d6c609720d41aee Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Jan 2024 09:47:57 +0800 +Subject: MIPS: reserve exception vector space ONLY ONCE + +From: Huang Pei + +[ Upstream commit abcabb9e30a1f9a69c76776f8abffc31c377b542 ] + +"cpu_probe" is called both by BP and APs, but reserving exception vector +(like 0x0-0x1000) called by "cpu_probe" need once and calling on APs is +too late since memblock is unavailable at that time. + +So, reserve exception vector ONLY by BP. + +Suggested-by: Thomas Bogendoerfer +Signed-off-by: Huang Pei +Signed-off-by: Thomas Bogendoerfer +Signed-off-by: Sasha Levin +--- + arch/mips/kernel/traps.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c +index afb2c955d99ef..5c01a21a216b9 100644 +--- a/arch/mips/kernel/traps.c ++++ b/arch/mips/kernel/traps.c +@@ -2001,7 +2001,13 @@ unsigned long vi_handlers[64]; + + void reserve_exception_space(phys_addr_t addr, unsigned long size) + { +- memblock_reserve(addr, size); ++ /* ++ * reserve exception space on CPUs other than CPU0 ++ * is too late, since memblock is unavailable when APs ++ * up ++ */ ++ if (smp_processor_id() == 0) ++ memblock_reserve(addr, size); + } + + void __init *set_except_vector(int n, void *addr) +-- +2.43.0 + diff --git a/queue-5.15/netfilter-conntrack-check-sctp_cid_shutdown_ack-for-.patch b/queue-5.15/netfilter-conntrack-check-sctp_cid_shutdown_ack-for-.patch new file mode 100644 index 00000000000..c5c03187092 --- /dev/null +++ b/queue-5.15/netfilter-conntrack-check-sctp_cid_shutdown_ack-for-.patch @@ -0,0 +1,71 @@ +From f098db85088508adcb5ab8b028a97bf89931f457 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 Jan 2024 17:29:46 -0500 +Subject: netfilter: conntrack: check SCTP_CID_SHUTDOWN_ACK for vtag setting in + sctp_new + +From: Xin Long + +[ Upstream commit 6e348067ee4bc5905e35faa3a8fafa91c9124bc7 ] + +The annotation says in sctp_new(): "If it is a shutdown ack OOTB packet, we +expect a return shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8)". +However, it does not check SCTP_CID_SHUTDOWN_ACK before setting vtag[REPLY] +in the conntrack entry(ct). + +Because of that, if the ct in Router disappears for some reason in [1] +with the packet sequence like below: + + Client > Server: sctp (1) [INIT] [init tag: 3201533963] + Server > Client: sctp (1) [INIT ACK] [init tag: 972498433] + Client > Server: sctp (1) [COOKIE ECHO] + Server > Client: sctp (1) [COOKIE ACK] + Client > Server: sctp (1) [DATA] (B)(E) [TSN: 3075057809] + Server > Client: sctp (1) [SACK] [cum ack 3075057809] + Server > Client: sctp (1) [HB REQ] + (the ct in Router disappears somehow) <-------- [1] + Client > Server: sctp (1) [HB ACK] + Client > Server: sctp (1) [DATA] (B)(E) [TSN: 3075057810] + Client > Server: sctp (1) [DATA] (B)(E) [TSN: 3075057810] + Client > Server: sctp (1) [HB REQ] + Client > Server: sctp (1) [DATA] (B)(E) [TSN: 3075057810] + Client > Server: sctp (1) [HB REQ] + Client > Server: sctp (1) [ABORT] + +when processing HB ACK packet in Router it calls sctp_new() to initialize +the new ct with vtag[REPLY] set to HB_ACK packet's vtag. + +Later when sending DATA from Client, all the SACKs from Server will get +dropped in Router, as the SACK packet's vtag does not match vtag[REPLY] +in the ct. The worst thing is the vtag in this ct will never get fixed +by the upcoming packets from Server. + +This patch fixes it by checking SCTP_CID_SHUTDOWN_ACK before setting +vtag[REPLY] in the ct in sctp_new() as the annotation says. With this +fix, it will leave vtag[REPLY] in ct to 0 in the case above, and the +next HB REQ/ACK from Server is able to fix the vtag as its value is 0 +in nf_conntrack_sctp_packet(). + +Signed-off-by: Xin Long +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_conntrack_proto_sctp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c +index c94a9971d790c..7ffd698497f2a 100644 +--- a/net/netfilter/nf_conntrack_proto_sctp.c ++++ b/net/netfilter/nf_conntrack_proto_sctp.c +@@ -299,7 +299,7 @@ sctp_new(struct nf_conn *ct, const struct sk_buff *skb, + pr_debug("Setting vtag %x for secondary conntrack\n", + sh->vtag); + ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL] = sh->vtag; +- } else { ++ } else if (sch->type == SCTP_CID_SHUTDOWN_ACK) { + /* If it is a shutdown ack OOTB packet, we expect a return + shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */ + pr_debug("Setting vtag %x for new conn OOTB\n", +-- +2.43.0 + diff --git a/queue-5.15/nvme-fc-do-not-wait-in-vain-when-unloading-module.patch b/queue-5.15/nvme-fc-do-not-wait-in-vain-when-unloading-module.patch new file mode 100644 index 00000000000..93cc751a3c0 --- /dev/null +++ b/queue-5.15/nvme-fc-do-not-wait-in-vain-when-unloading-module.patch @@ -0,0 +1,145 @@ +From 408beebc78e246223b805730a2b76e88fa32c904 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 Jan 2024 09:51:01 +0100 +Subject: nvme-fc: do not wait in vain when unloading module + +From: Daniel Wagner + +[ Upstream commit 70fbfc47a392b98e5f8dba70c6efc6839205c982 ] + +The module exit path has race between deleting all controllers and +freeing 'left over IDs'. To prevent double free a synchronization +between nvme_delete_ctrl and ida_destroy has been added by the initial +commit. + +There is some logic around trying to prevent from hanging forever in +wait_for_completion, though it does not handling all cases. E.g. +blktests is able to reproduce the situation where the module unload +hangs forever. + +If we completely rely on the cleanup code executed from the +nvme_delete_ctrl path, all IDs will be freed eventually. This makes +calling ida_destroy unnecessary. We only have to ensure that all +nvme_delete_ctrl code has been executed before we leave +nvme_fc_exit_module. This is done by flushing the nvme_delete_wq +workqueue. + +While at it, remove the unused nvme_fc_wq workqueue too. + +Reviewed-by: Christoph Hellwig +Reviewed-by: Hannes Reinecke +Signed-off-by: Daniel Wagner +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/fc.c | 47 ++++++------------------------------------ + 1 file changed, 6 insertions(+), 41 deletions(-) + +diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c +index aa14ad963d910..8dfd317509aa6 100644 +--- a/drivers/nvme/host/fc.c ++++ b/drivers/nvme/host/fc.c +@@ -220,11 +220,6 @@ static LIST_HEAD(nvme_fc_lport_list); + static DEFINE_IDA(nvme_fc_local_port_cnt); + static DEFINE_IDA(nvme_fc_ctrl_cnt); + +-static struct workqueue_struct *nvme_fc_wq; +- +-static bool nvme_fc_waiting_to_unload; +-static DECLARE_COMPLETION(nvme_fc_unload_proceed); +- + /* + * These items are short-term. They will eventually be moved into + * a generic FC class. See comments in module init. +@@ -254,8 +249,6 @@ nvme_fc_free_lport(struct kref *ref) + /* remove from transport list */ + spin_lock_irqsave(&nvme_fc_lock, flags); + list_del(&lport->port_list); +- if (nvme_fc_waiting_to_unload && list_empty(&nvme_fc_lport_list)) +- complete(&nvme_fc_unload_proceed); + spin_unlock_irqrestore(&nvme_fc_lock, flags); + + ida_simple_remove(&nvme_fc_local_port_cnt, lport->localport.port_num); +@@ -3904,10 +3897,6 @@ static int __init nvme_fc_init_module(void) + { + int ret; + +- nvme_fc_wq = alloc_workqueue("nvme_fc_wq", WQ_MEM_RECLAIM, 0); +- if (!nvme_fc_wq) +- return -ENOMEM; +- + /* + * NOTE: + * It is expected that in the future the kernel will combine +@@ -3925,7 +3914,7 @@ static int __init nvme_fc_init_module(void) + ret = class_register(&fc_class); + if (ret) { + pr_err("couldn't register class fc\n"); +- goto out_destroy_wq; ++ return ret; + } + + /* +@@ -3949,8 +3938,6 @@ static int __init nvme_fc_init_module(void) + device_destroy(&fc_class, MKDEV(0, 0)); + out_destroy_class: + class_unregister(&fc_class); +-out_destroy_wq: +- destroy_workqueue(nvme_fc_wq); + + return ret; + } +@@ -3970,45 +3957,23 @@ nvme_fc_delete_controllers(struct nvme_fc_rport *rport) + spin_unlock(&rport->lock); + } + +-static void +-nvme_fc_cleanup_for_unload(void) ++static void __exit nvme_fc_exit_module(void) + { + struct nvme_fc_lport *lport; + struct nvme_fc_rport *rport; +- +- list_for_each_entry(lport, &nvme_fc_lport_list, port_list) { +- list_for_each_entry(rport, &lport->endp_list, endp_list) { +- nvme_fc_delete_controllers(rport); +- } +- } +-} +- +-static void __exit nvme_fc_exit_module(void) +-{ + unsigned long flags; +- bool need_cleanup = false; + + spin_lock_irqsave(&nvme_fc_lock, flags); +- nvme_fc_waiting_to_unload = true; +- if (!list_empty(&nvme_fc_lport_list)) { +- need_cleanup = true; +- nvme_fc_cleanup_for_unload(); +- } ++ list_for_each_entry(lport, &nvme_fc_lport_list, port_list) ++ list_for_each_entry(rport, &lport->endp_list, endp_list) ++ nvme_fc_delete_controllers(rport); + spin_unlock_irqrestore(&nvme_fc_lock, flags); +- if (need_cleanup) { +- pr_info("%s: waiting for ctlr deletes\n", __func__); +- wait_for_completion(&nvme_fc_unload_proceed); +- pr_info("%s: ctrl deletes complete\n", __func__); +- } ++ flush_workqueue(nvme_delete_wq); + + nvmf_unregister_transport(&nvme_fc_transport); + +- ida_destroy(&nvme_fc_local_port_cnt); +- ida_destroy(&nvme_fc_ctrl_cnt); +- + device_destroy(&fc_class, MKDEV(0, 0)); + class_unregister(&fc_class); +- destroy_workqueue(nvme_fc_wq); + } + + module_init(nvme_fc_init_module); +-- +2.43.0 + diff --git a/queue-5.15/nvmet-fc-abort-command-when-there-is-no-binding.patch b/queue-5.15/nvmet-fc-abort-command-when-there-is-no-binding.patch new file mode 100644 index 00000000000..d024c917ae8 --- /dev/null +++ b/queue-5.15/nvmet-fc-abort-command-when-there-is-no-binding.patch @@ -0,0 +1,51 @@ +From 95b962f2015319c0b86a222370af5f40f5dd005c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 Jan 2024 09:51:09 +0100 +Subject: nvmet-fc: abort command when there is no binding + +From: Daniel Wagner + +[ Upstream commit 3146345c2e9c2f661527054e402b0cfad80105a4 ] + +When the target port has not active port binding, there is no point in +trying to process the command as it has to fail anyway. Instead adding +checks to all commands abort the command early. + +Reviewed-by: Hannes Reinecke +Reviewed-by: Christoph Hellwig +Signed-off-by: Daniel Wagner +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/target/fc.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/nvme/target/fc.c b/drivers/nvme/target/fc.c +index 06d11bb7b944b..20d3013be08ab 100644 +--- a/drivers/nvme/target/fc.c ++++ b/drivers/nvme/target/fc.c +@@ -1101,6 +1101,9 @@ nvmet_fc_alloc_target_assoc(struct nvmet_fc_tgtport *tgtport, void *hosthandle) + int idx; + bool needrandom = true; + ++ if (!tgtport->pe) ++ return NULL; ++ + assoc = kzalloc(sizeof(*assoc), GFP_KERNEL); + if (!assoc) + return NULL; +@@ -2523,8 +2526,9 @@ nvmet_fc_handle_fcp_rqst(struct nvmet_fc_tgtport *tgtport, + + fod->req.cmd = &fod->cmdiubuf.sqe; + fod->req.cqe = &fod->rspiubuf.cqe; +- if (tgtport->pe) +- fod->req.port = tgtport->pe->port; ++ if (!tgtport->pe) ++ goto transport_error; ++ fod->req.port = tgtport->pe->port; + + /* clear any response payload */ + memset(&fod->rspiubuf, 0, sizeof(fod->rspiubuf)); +-- +2.43.0 + diff --git a/queue-5.15/nvmet-fc-avoid-deadlock-on-delete-association-path.patch b/queue-5.15/nvmet-fc-avoid-deadlock-on-delete-association-path.patch new file mode 100644 index 00000000000..bcceecf86b3 --- /dev/null +++ b/queue-5.15/nvmet-fc-avoid-deadlock-on-delete-association-path.patch @@ -0,0 +1,79 @@ +From 18072e1604fce2d43b9ae4714cfc833f5395ce34 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 Jan 2024 09:51:10 +0100 +Subject: nvmet-fc: avoid deadlock on delete association path + +From: Daniel Wagner + +[ Upstream commit 710c69dbaccdac312e32931abcb8499c1525d397 ] + +When deleting an association the shutdown path is deadlocking because we +try to flush the nvmet_wq nested. Avoid this by deadlock by deferring +the put work into its own work item. + +Reviewed-by: Christoph Hellwig +Signed-off-by: Daniel Wagner +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/target/fc.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/drivers/nvme/target/fc.c b/drivers/nvme/target/fc.c +index 20d3013be08ab..1ef075b159b9d 100644 +--- a/drivers/nvme/target/fc.c ++++ b/drivers/nvme/target/fc.c +@@ -111,6 +111,8 @@ struct nvmet_fc_tgtport { + struct nvmet_fc_port_entry *pe; + struct kref ref; + u32 max_sg_cnt; ++ ++ struct work_struct put_work; + }; + + struct nvmet_fc_port_entry { +@@ -248,6 +250,13 @@ static int nvmet_fc_tgt_a_get(struct nvmet_fc_tgt_assoc *assoc); + static void nvmet_fc_tgt_q_put(struct nvmet_fc_tgt_queue *queue); + static int nvmet_fc_tgt_q_get(struct nvmet_fc_tgt_queue *queue); + static void nvmet_fc_tgtport_put(struct nvmet_fc_tgtport *tgtport); ++static void nvmet_fc_put_tgtport_work(struct work_struct *work) ++{ ++ struct nvmet_fc_tgtport *tgtport = ++ container_of(work, struct nvmet_fc_tgtport, put_work); ++ ++ nvmet_fc_tgtport_put(tgtport); ++} + static int nvmet_fc_tgtport_get(struct nvmet_fc_tgtport *tgtport); + static void nvmet_fc_handle_fcp_rqst(struct nvmet_fc_tgtport *tgtport, + struct nvmet_fc_fcp_iod *fod); +@@ -359,7 +368,7 @@ __nvmet_fc_finish_ls_req(struct nvmet_fc_ls_req_op *lsop) + + if (!lsop->req_queued) { + spin_unlock_irqrestore(&tgtport->lock, flags); +- goto out_puttgtport; ++ goto out_putwork; + } + + list_del(&lsop->lsreq_list); +@@ -372,8 +381,8 @@ __nvmet_fc_finish_ls_req(struct nvmet_fc_ls_req_op *lsop) + (lsreq->rqstlen + lsreq->rsplen), + DMA_BIDIRECTIONAL); + +-out_puttgtport: +- nvmet_fc_tgtport_put(tgtport); ++out_putwork: ++ queue_work(nvmet_wq, &tgtport->put_work); + } + + static int +@@ -1404,6 +1413,7 @@ nvmet_fc_register_targetport(struct nvmet_fc_port_info *pinfo, + kref_init(&newrec->ref); + ida_init(&newrec->assoc_cnt); + newrec->max_sg_cnt = template->max_sgl_segments; ++ INIT_WORK(&newrec->put_work, nvmet_fc_put_tgtport_work); + + ret = nvmet_fc_alloc_ls_iodlist(newrec); + if (ret) { +-- +2.43.0 + diff --git a/queue-5.15/nvmet-fc-defer-cleanup-using-rcu-properly.patch b/queue-5.15/nvmet-fc-defer-cleanup-using-rcu-properly.patch new file mode 100644 index 00000000000..50fac890074 --- /dev/null +++ b/queue-5.15/nvmet-fc-defer-cleanup-using-rcu-properly.patch @@ -0,0 +1,276 @@ +From 43ae33ed169651cb6404d388469086befbeb9873 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 Jan 2024 09:51:04 +0100 +Subject: nvmet-fc: defer cleanup using RCU properly + +From: Daniel Wagner + +[ Upstream commit 4049dc96b8de7aeb3addcea039446e464726a525 ] + +When the target executes a disconnect and the host triggers a reconnect +immediately, the reconnect command still finds an existing association. + +The reconnect crashes later on because nvmet_fc_delete_target_assoc +blindly removes resources while the reconnect code wants to use it. + +To address this, nvmet_fc_find_target_assoc should not be able to +lookup an association which is being removed. The association list +is already under RCU lifetime management, so let's properly use it +and remove the association from the list and wait for a grace period +before cleaning up all. This means we also can drop the RCU management +on the queues, because this is now handled via the association itself. + +A second step split the execution context so that the initial disconnect +command can complete without running the reconnect code in the same +context. As usual, this is done by deferring the ->done to a workqueue. + +Reviewed-by: Christoph Hellwig +Reviewed-by: Hannes Reinecke +Signed-off-by: Daniel Wagner +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/target/fc.c | 83 ++++++++++++++++++---------------------- + 1 file changed, 37 insertions(+), 46 deletions(-) + +diff --git a/drivers/nvme/target/fc.c b/drivers/nvme/target/fc.c +index 80df50ed7e3aa..97f4ec37f36da 100644 +--- a/drivers/nvme/target/fc.c ++++ b/drivers/nvme/target/fc.c +@@ -165,7 +165,7 @@ struct nvmet_fc_tgt_assoc { + struct nvmet_fc_hostport *hostport; + struct nvmet_fc_ls_iod *rcv_disconn; + struct list_head a_list; +- struct nvmet_fc_tgt_queue __rcu *queues[NVMET_NR_QUEUES + 1]; ++ struct nvmet_fc_tgt_queue *queues[NVMET_NR_QUEUES + 1]; + struct kref ref; + struct work_struct del_work; + struct rcu_head rcu; +@@ -802,14 +802,11 @@ nvmet_fc_alloc_target_queue(struct nvmet_fc_tgt_assoc *assoc, + if (!queue) + return NULL; + +- if (!nvmet_fc_tgt_a_get(assoc)) +- goto out_free_queue; +- + queue->work_q = alloc_workqueue("ntfc%d.%d.%d", 0, 0, + assoc->tgtport->fc_target_port.port_num, + assoc->a_id, qid); + if (!queue->work_q) +- goto out_a_put; ++ goto out_free_queue; + + queue->qid = qid; + queue->sqsize = sqsize; +@@ -831,15 +828,13 @@ nvmet_fc_alloc_target_queue(struct nvmet_fc_tgt_assoc *assoc, + goto out_fail_iodlist; + + WARN_ON(assoc->queues[qid]); +- rcu_assign_pointer(assoc->queues[qid], queue); ++ assoc->queues[qid] = queue; + + return queue; + + out_fail_iodlist: + nvmet_fc_destroy_fcp_iodlist(assoc->tgtport, queue); + destroy_workqueue(queue->work_q); +-out_a_put: +- nvmet_fc_tgt_a_put(assoc); + out_free_queue: + kfree(queue); + return NULL; +@@ -852,12 +847,8 @@ nvmet_fc_tgt_queue_free(struct kref *ref) + struct nvmet_fc_tgt_queue *queue = + container_of(ref, struct nvmet_fc_tgt_queue, ref); + +- rcu_assign_pointer(queue->assoc->queues[queue->qid], NULL); +- + nvmet_fc_destroy_fcp_iodlist(queue->assoc->tgtport, queue); + +- nvmet_fc_tgt_a_put(queue->assoc); +- + destroy_workqueue(queue->work_q); + + kfree_rcu(queue, rcu); +@@ -969,7 +960,7 @@ nvmet_fc_find_target_queue(struct nvmet_fc_tgtport *tgtport, + rcu_read_lock(); + list_for_each_entry_rcu(assoc, &tgtport->assoc_list, a_list) { + if (association_id == assoc->association_id) { +- queue = rcu_dereference(assoc->queues[qid]); ++ queue = assoc->queues[qid]; + if (queue && + (!atomic_read(&queue->connected) || + !nvmet_fc_tgt_q_get(queue))) +@@ -1172,13 +1163,18 @@ nvmet_fc_target_assoc_free(struct kref *ref) + struct nvmet_fc_tgtport *tgtport = assoc->tgtport; + struct nvmet_fc_ls_iod *oldls; + unsigned long flags; ++ int i; ++ ++ for (i = NVMET_NR_QUEUES; i >= 0; i--) { ++ if (assoc->queues[i]) ++ nvmet_fc_delete_target_queue(assoc->queues[i]); ++ } + + /* Send Disconnect now that all i/o has completed */ + nvmet_fc_xmt_disconnect_assoc(assoc); + + nvmet_fc_free_hostport(assoc->hostport); + spin_lock_irqsave(&tgtport->lock, flags); +- list_del_rcu(&assoc->a_list); + oldls = assoc->rcv_disconn; + spin_unlock_irqrestore(&tgtport->lock, flags); + /* if pending Rcv Disconnect Association LS, send rsp now */ +@@ -1208,7 +1204,7 @@ static void + nvmet_fc_delete_target_assoc(struct nvmet_fc_tgt_assoc *assoc) + { + struct nvmet_fc_tgtport *tgtport = assoc->tgtport; +- struct nvmet_fc_tgt_queue *queue; ++ unsigned long flags; + int i, terminating; + + terminating = atomic_xchg(&assoc->terminating, 1); +@@ -1217,29 +1213,21 @@ nvmet_fc_delete_target_assoc(struct nvmet_fc_tgt_assoc *assoc) + if (terminating) + return; + ++ spin_lock_irqsave(&tgtport->lock, flags); ++ list_del_rcu(&assoc->a_list); ++ spin_unlock_irqrestore(&tgtport->lock, flags); + +- for (i = NVMET_NR_QUEUES; i >= 0; i--) { +- rcu_read_lock(); +- queue = rcu_dereference(assoc->queues[i]); +- if (!queue) { +- rcu_read_unlock(); +- continue; +- } ++ synchronize_rcu(); + +- if (!nvmet_fc_tgt_q_get(queue)) { +- rcu_read_unlock(); +- continue; +- } +- rcu_read_unlock(); +- nvmet_fc_delete_target_queue(queue); +- nvmet_fc_tgt_q_put(queue); ++ /* ensure all in-flight I/Os have been processed */ ++ for (i = NVMET_NR_QUEUES; i >= 0; i--) { ++ if (assoc->queues[i]) ++ flush_workqueue(assoc->queues[i]->work_q); + } + + dev_info(tgtport->dev, + "{%d:%d} Association deleted\n", + tgtport->fc_target_port.port_num, assoc->a_id); +- +- nvmet_fc_tgt_a_put(assoc); + } + + static struct nvmet_fc_tgt_assoc * +@@ -1492,9 +1480,8 @@ __nvmet_fc_free_assocs(struct nvmet_fc_tgtport *tgtport) + list_for_each_entry_rcu(assoc, &tgtport->assoc_list, a_list) { + if (!nvmet_fc_tgt_a_get(assoc)) + continue; +- if (!queue_work(nvmet_wq, &assoc->del_work)) +- /* already deleting - release local reference */ +- nvmet_fc_tgt_a_put(assoc); ++ queue_work(nvmet_wq, &assoc->del_work); ++ nvmet_fc_tgt_a_put(assoc); + } + rcu_read_unlock(); + } +@@ -1547,9 +1534,8 @@ nvmet_fc_invalidate_host(struct nvmet_fc_target_port *target_port, + continue; + assoc->hostport->invalid = 1; + noassoc = false; +- if (!queue_work(nvmet_wq, &assoc->del_work)) +- /* already deleting - release local reference */ +- nvmet_fc_tgt_a_put(assoc); ++ queue_work(nvmet_wq, &assoc->del_work); ++ nvmet_fc_tgt_a_put(assoc); + } + spin_unlock_irqrestore(&tgtport->lock, flags); + +@@ -1581,7 +1567,7 @@ nvmet_fc_delete_ctrl(struct nvmet_ctrl *ctrl) + + rcu_read_lock(); + list_for_each_entry_rcu(assoc, &tgtport->assoc_list, a_list) { +- queue = rcu_dereference(assoc->queues[0]); ++ queue = assoc->queues[0]; + if (queue && queue->nvme_sq.ctrl == ctrl) { + if (nvmet_fc_tgt_a_get(assoc)) + found_ctrl = true; +@@ -1593,9 +1579,8 @@ nvmet_fc_delete_ctrl(struct nvmet_ctrl *ctrl) + nvmet_fc_tgtport_put(tgtport); + + if (found_ctrl) { +- if (!queue_work(nvmet_wq, &assoc->del_work)) +- /* already deleting - release local reference */ +- nvmet_fc_tgt_a_put(assoc); ++ queue_work(nvmet_wq, &assoc->del_work); ++ nvmet_fc_tgt_a_put(assoc); + return; + } + +@@ -1625,6 +1610,8 @@ nvmet_fc_unregister_targetport(struct nvmet_fc_target_port *target_port) + /* terminate any outstanding associations */ + __nvmet_fc_free_assocs(tgtport); + ++ flush_workqueue(nvmet_wq); ++ + /* + * should terminate LS's as well. However, LS's will be generated + * at the tail end of association termination, so they likely don't +@@ -1870,9 +1857,6 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport, + sizeof(struct fcnvme_ls_disconnect_assoc_acc)), + FCNVME_LS_DISCONNECT_ASSOC); + +- /* release get taken in nvmet_fc_find_target_assoc */ +- nvmet_fc_tgt_a_put(assoc); +- + /* + * The rules for LS response says the response cannot + * go back until ABTS's have been sent for all outstanding +@@ -1887,8 +1871,6 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport, + assoc->rcv_disconn = iod; + spin_unlock_irqrestore(&tgtport->lock, flags); + +- nvmet_fc_delete_target_assoc(assoc); +- + if (oldls) { + dev_info(tgtport->dev, + "{%d:%d} Multiple Disconnect Association LS's " +@@ -1904,6 +1886,9 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport, + nvmet_fc_xmt_ls_rsp(tgtport, oldls); + } + ++ queue_work(nvmet_wq, &assoc->del_work); ++ nvmet_fc_tgt_a_put(assoc); ++ + return false; + } + +@@ -2902,6 +2887,9 @@ nvmet_fc_remove_port(struct nvmet_port *port) + + nvmet_fc_portentry_unbind(pe); + ++ /* terminate any outstanding associations */ ++ __nvmet_fc_free_assocs(pe->tgtport); ++ + kfree(pe); + } + +@@ -2933,6 +2921,9 @@ static int __init nvmet_fc_init_module(void) + + static void __exit nvmet_fc_exit_module(void) + { ++ /* ensure any shutdown operation, e.g. delete ctrls have finished */ ++ flush_workqueue(nvmet_wq); ++ + /* sanity check - all lports should be removed */ + if (!list_empty(&nvmet_fc_target_list)) + pr_warn("%s: targetport list not empty\n", __func__); +-- +2.43.0 + diff --git a/queue-5.15/nvmet-fc-hold-reference-on-hostport-match.patch b/queue-5.15/nvmet-fc-hold-reference-on-hostport-match.patch new file mode 100644 index 00000000000..9020a1d11a9 --- /dev/null +++ b/queue-5.15/nvmet-fc-hold-reference-on-hostport-match.patch @@ -0,0 +1,40 @@ +From f70345c57cab67d9b61acb464eacf3dae46d11fb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 Jan 2024 09:51:06 +0100 +Subject: nvmet-fc: hold reference on hostport match + +From: Daniel Wagner + +[ Upstream commit ca121a0f7515591dba0eb5532bfa7ace4dc153ce ] + +The hostport data structure is shared between the association, this why +we keep track of the users via a refcount. So we should not decrement +the refcount on a match and free the hostport several times. + +Reported by KASAN. + +Reviewed-by: Hannes Reinecke +Reviewed-by: Christoph Hellwig +Signed-off-by: Daniel Wagner +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/target/fc.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/nvme/target/fc.c b/drivers/nvme/target/fc.c +index 97f4ec37f36da..06d11bb7b944b 100644 +--- a/drivers/nvme/target/fc.c ++++ b/drivers/nvme/target/fc.c +@@ -1069,8 +1069,6 @@ nvmet_fc_alloc_hostport(struct nvmet_fc_tgtport *tgtport, void *hosthandle) + /* new allocation not needed */ + kfree(newhost); + newhost = match; +- /* no new allocation - release reference */ +- nvmet_fc_tgtport_put(tgtport); + } else { + newhost->tgtport = tgtport; + newhost->hosthandle = hosthandle; +-- +2.43.0 + diff --git a/queue-5.15/nvmet-fc-release-reference-on-target-port.patch b/queue-5.15/nvmet-fc-release-reference-on-target-port.patch new file mode 100644 index 00000000000..fa7f89f66be --- /dev/null +++ b/queue-5.15/nvmet-fc-release-reference-on-target-port.patch @@ -0,0 +1,45 @@ +From 3604707b062dd52a76f3657f768c28a30dd8b79a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 Jan 2024 09:51:03 +0100 +Subject: nvmet-fc: release reference on target port + +From: Daniel Wagner + +[ Upstream commit c691e6d7e13dab81ac8c7489c83b5dea972522a5 ] + +In case we return early out of __nvmet_fc_finish_ls_req() we still have +to release the reference on the target port. + +Reviewed-by: Hannes Reinecke +Reviewed-by: Christoph Hellwig +Signed-off-by: Daniel Wagner +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/target/fc.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/nvme/target/fc.c b/drivers/nvme/target/fc.c +index 00a2a591f5c1f..80df50ed7e3aa 100644 +--- a/drivers/nvme/target/fc.c ++++ b/drivers/nvme/target/fc.c +@@ -359,7 +359,7 @@ __nvmet_fc_finish_ls_req(struct nvmet_fc_ls_req_op *lsop) + + if (!lsop->req_queued) { + spin_unlock_irqrestore(&tgtport->lock, flags); +- return; ++ goto out_puttgtport; + } + + list_del(&lsop->lsreq_list); +@@ -372,6 +372,7 @@ __nvmet_fc_finish_ls_req(struct nvmet_fc_ls_req_op *lsop) + (lsreq->rqstlen + lsreq->rsplen), + DMA_BIDIRECTIONAL); + ++out_puttgtport: + nvmet_fc_tgtport_put(tgtport); + } + +-- +2.43.0 + diff --git a/queue-5.15/nvmet-fc-take-ref-count-on-tgtport-before-delete-ass.patch b/queue-5.15/nvmet-fc-take-ref-count-on-tgtport-before-delete-ass.patch new file mode 100644 index 00000000000..5796f674432 --- /dev/null +++ b/queue-5.15/nvmet-fc-take-ref-count-on-tgtport-before-delete-ass.patch @@ -0,0 +1,104 @@ +From 017111ccc9999643acf7098052294fa8756c365e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 Jan 2024 09:51:11 +0100 +Subject: nvmet-fc: take ref count on tgtport before delete assoc + +From: Daniel Wagner + +[ Upstream commit fe506a74589326183297d5abdda02d0c76ae5a8b ] + +We have to ensure that the tgtport is not going away +before be have remove all the associations. + +Reviewed-by: Christoph Hellwig +Signed-off-by: Daniel Wagner +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/target/fc.c | 31 +++++++++++++++++++++++-------- + 1 file changed, 23 insertions(+), 8 deletions(-) + +diff --git a/drivers/nvme/target/fc.c b/drivers/nvme/target/fc.c +index 1ef075b159b9d..d3ca59ae4c7af 100644 +--- a/drivers/nvme/target/fc.c ++++ b/drivers/nvme/target/fc.c +@@ -1092,13 +1092,28 @@ nvmet_fc_alloc_hostport(struct nvmet_fc_tgtport *tgtport, void *hosthandle) + } + + static void +-nvmet_fc_delete_assoc(struct work_struct *work) ++nvmet_fc_delete_assoc(struct nvmet_fc_tgt_assoc *assoc) ++{ ++ nvmet_fc_delete_target_assoc(assoc); ++ nvmet_fc_tgt_a_put(assoc); ++} ++ ++static void ++nvmet_fc_delete_assoc_work(struct work_struct *work) + { + struct nvmet_fc_tgt_assoc *assoc = + container_of(work, struct nvmet_fc_tgt_assoc, del_work); ++ struct nvmet_fc_tgtport *tgtport = assoc->tgtport; + +- nvmet_fc_delete_target_assoc(assoc); +- nvmet_fc_tgt_a_put(assoc); ++ nvmet_fc_delete_assoc(assoc); ++ nvmet_fc_tgtport_put(tgtport); ++} ++ ++static void ++nvmet_fc_schedule_delete_assoc(struct nvmet_fc_tgt_assoc *assoc) ++{ ++ nvmet_fc_tgtport_get(assoc->tgtport); ++ queue_work(nvmet_wq, &assoc->del_work); + } + + static struct nvmet_fc_tgt_assoc * +@@ -1132,7 +1147,7 @@ nvmet_fc_alloc_target_assoc(struct nvmet_fc_tgtport *tgtport, void *hosthandle) + assoc->a_id = idx; + INIT_LIST_HEAD(&assoc->a_list); + kref_init(&assoc->ref); +- INIT_WORK(&assoc->del_work, nvmet_fc_delete_assoc); ++ INIT_WORK(&assoc->del_work, nvmet_fc_delete_assoc_work); + atomic_set(&assoc->terminating, 0); + + while (needrandom) { +@@ -1491,7 +1506,7 @@ __nvmet_fc_free_assocs(struct nvmet_fc_tgtport *tgtport) + list_for_each_entry_rcu(assoc, &tgtport->assoc_list, a_list) { + if (!nvmet_fc_tgt_a_get(assoc)) + continue; +- queue_work(nvmet_wq, &assoc->del_work); ++ nvmet_fc_schedule_delete_assoc(assoc); + nvmet_fc_tgt_a_put(assoc); + } + rcu_read_unlock(); +@@ -1545,7 +1560,7 @@ nvmet_fc_invalidate_host(struct nvmet_fc_target_port *target_port, + continue; + assoc->hostport->invalid = 1; + noassoc = false; +- queue_work(nvmet_wq, &assoc->del_work); ++ nvmet_fc_schedule_delete_assoc(assoc); + nvmet_fc_tgt_a_put(assoc); + } + spin_unlock_irqrestore(&tgtport->lock, flags); +@@ -1590,7 +1605,7 @@ nvmet_fc_delete_ctrl(struct nvmet_ctrl *ctrl) + nvmet_fc_tgtport_put(tgtport); + + if (found_ctrl) { +- queue_work(nvmet_wq, &assoc->del_work); ++ nvmet_fc_schedule_delete_assoc(assoc); + nvmet_fc_tgt_a_put(assoc); + return; + } +@@ -1897,7 +1912,7 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport, + nvmet_fc_xmt_ls_rsp(tgtport, oldls); + } + +- queue_work(nvmet_wq, &assoc->del_work); ++ nvmet_fc_schedule_delete_assoc(assoc); + nvmet_fc_tgt_a_put(assoc); + + return false; +-- +2.43.0 + diff --git a/queue-5.15/nvmet-fcloop-swap-the-list_add_tail-arguments.patch b/queue-5.15/nvmet-fcloop-swap-the-list_add_tail-arguments.patch new file mode 100644 index 00000000000..13e26a4e4ba --- /dev/null +++ b/queue-5.15/nvmet-fcloop-swap-the-list_add_tail-arguments.patch @@ -0,0 +1,56 @@ +From ca370738f0e39dac6a821163d7350987f183cc0e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 Jan 2024 09:51:02 +0100 +Subject: nvmet-fcloop: swap the list_add_tail arguments + +From: Daniel Wagner + +[ Upstream commit dcfad4ab4d6733f2861cd241d8532a0004fc835a ] + +The first argument of list_add_tail function is the new element which +should be added to the list which is the second argument. Swap the +arguments to allow processing more than one element at a time. + +Reviewed-by: Christoph Hellwig +Reviewed-by: Hannes Reinecke +Signed-off-by: Daniel Wagner +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/target/fcloop.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/nvme/target/fcloop.c b/drivers/nvme/target/fcloop.c +index c780af36c1d4a..f5b8442b653db 100644 +--- a/drivers/nvme/target/fcloop.c ++++ b/drivers/nvme/target/fcloop.c +@@ -358,7 +358,7 @@ fcloop_h2t_ls_req(struct nvme_fc_local_port *localport, + if (!rport->targetport) { + tls_req->status = -ECONNREFUSED; + spin_lock(&rport->lock); +- list_add_tail(&rport->ls_list, &tls_req->ls_list); ++ list_add_tail(&tls_req->ls_list, &rport->ls_list); + spin_unlock(&rport->lock); + queue_work(nvmet_wq, &rport->ls_work); + return ret; +@@ -391,7 +391,7 @@ fcloop_h2t_xmt_ls_rsp(struct nvmet_fc_target_port *targetport, + if (remoteport) { + rport = remoteport->private; + spin_lock(&rport->lock); +- list_add_tail(&rport->ls_list, &tls_req->ls_list); ++ list_add_tail(&tls_req->ls_list, &rport->ls_list); + spin_unlock(&rport->lock); + queue_work(nvmet_wq, &rport->ls_work); + } +@@ -446,7 +446,7 @@ fcloop_t2h_ls_req(struct nvmet_fc_target_port *targetport, void *hosthandle, + if (!tport->remoteport) { + tls_req->status = -ECONNREFUSED; + spin_lock(&tport->lock); +- list_add_tail(&tport->ls_list, &tls_req->ls_list); ++ list_add_tail(&tls_req->ls_list, &tport->ls_list); + spin_unlock(&tport->lock); + queue_work(nvmet_wq, &tport->ls_work); + return ret; +-- +2.43.0 + diff --git a/queue-5.15/nvmet-tcp-fix-nvme-tcp-ida-memory-leak.patch b/queue-5.15/nvmet-tcp-fix-nvme-tcp-ida-memory-leak.patch new file mode 100644 index 00000000000..c94ed38d074 --- /dev/null +++ b/queue-5.15/nvmet-tcp-fix-nvme-tcp-ida-memory-leak.patch @@ -0,0 +1,36 @@ +From 5707db134973ecca83d86f9ce6e5d6a1cf017197 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Jan 2024 16:26:43 +0800 +Subject: nvmet-tcp: fix nvme tcp ida memory leak + +From: Guixin Liu + +[ Upstream commit 47c5dd66c1840524572dcdd956f4af2bdb6fbdff ] + +The nvmet_tcp_queue_ida should be destroy when the nvmet-tcp module +exit. + +Signed-off-by: Guixin Liu +Reviewed-by: Christoph Hellwig +Reviewed-by: Chaitanya Kulkarni +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/target/tcp.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c +index 4f2164a3f466b..8468a41322f25 100644 +--- a/drivers/nvme/target/tcp.c ++++ b/drivers/nvme/target/tcp.c +@@ -1884,6 +1884,7 @@ static void __exit nvmet_tcp_exit(void) + flush_workqueue(nvmet_wq); + + destroy_workqueue(nvmet_tcp_wq); ++ ida_destroy(&nvmet_tcp_queue_ida); + } + + module_init(nvmet_tcp_init); +-- +2.43.0 + diff --git a/queue-5.15/platform-x86-touchscreen_dmi-add-info-for-the-teclas.patch b/queue-5.15/platform-x86-touchscreen_dmi-add-info-for-the-teclas.patch new file mode 100644 index 00000000000..0f0dc9faca8 --- /dev/null +++ b/queue-5.15/platform-x86-touchscreen_dmi-add-info-for-the-teclas.patch @@ -0,0 +1,77 @@ +From ad05deaaf4c4f541853a07c666c3174ac4bd77d6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Jan 2024 17:53:08 +0800 +Subject: platform/x86: touchscreen_dmi: Add info for the TECLAST X16 Plus + tablet + +From: Phoenix Chen + +[ Upstream commit 1abdf288b0ef5606f76b6e191fa6df05330e3d7e ] + +Add touch screen info for TECLAST X16 Plus tablet. + +Signed-off-by: Phoenix Chen +Link: https://lore.kernel.org/r/20240126095308.5042-1-asbeltogf@gmail.com +Reviewed-by: Hans de Goede +Signed-off-by: Hans de Goede +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/touchscreen_dmi.c | 35 ++++++++++++++++++++++++++ + 1 file changed, 35 insertions(+) + +diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c +index f129e29b295d9..397283893f39f 100644 +--- a/drivers/platform/x86/touchscreen_dmi.c ++++ b/drivers/platform/x86/touchscreen_dmi.c +@@ -916,6 +916,32 @@ static const struct ts_dmi_data teclast_tbook11_data = { + .properties = teclast_tbook11_props, + }; + ++static const struct property_entry teclast_x16_plus_props[] = { ++ PROPERTY_ENTRY_U32("touchscreen-min-x", 8), ++ PROPERTY_ENTRY_U32("touchscreen-min-y", 14), ++ PROPERTY_ENTRY_U32("touchscreen-size-x", 1916), ++ PROPERTY_ENTRY_U32("touchscreen-size-y", 1264), ++ PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), ++ PROPERTY_ENTRY_STRING("firmware-name", "gsl3692-teclast-x16-plus.fw"), ++ PROPERTY_ENTRY_U32("silead,max-fingers", 10), ++ PROPERTY_ENTRY_BOOL("silead,home-button"), ++ { } ++}; ++ ++static const struct ts_dmi_data teclast_x16_plus_data = { ++ .embedded_fw = { ++ .name = "silead/gsl3692-teclast-x16-plus.fw", ++ .prefix = { 0xf0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00 }, ++ .length = 43560, ++ .sha256 = { 0x9d, 0xb0, 0x3d, 0xf1, 0x00, 0x3c, 0xb5, 0x25, ++ 0x62, 0x8a, 0xa0, 0x93, 0x4b, 0xe0, 0x4e, 0x75, ++ 0xd1, 0x27, 0xb1, 0x65, 0x3c, 0xba, 0xa5, 0x0f, ++ 0xcd, 0xb4, 0xbe, 0x00, 0xbb, 0xf6, 0x43, 0x29 }, ++ }, ++ .acpi_name = "MSSL1680:00", ++ .properties = teclast_x16_plus_props, ++}; ++ + static const struct property_entry teclast_x3_plus_props[] = { + PROPERTY_ENTRY_U32("touchscreen-size-x", 1980), + PROPERTY_ENTRY_U32("touchscreen-size-y", 1500), +@@ -1552,6 +1578,15 @@ const struct dmi_system_id touchscreen_dmi_table[] = { + DMI_MATCH(DMI_PRODUCT_SKU, "E5A6_A1"), + }, + }, ++ { ++ /* Teclast X16 Plus */ ++ .driver_data = (void *)&teclast_x16_plus_data, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), ++ DMI_MATCH(DMI_PRODUCT_SKU, "D3A5_A1"), ++ }, ++ }, + { + /* Teclast X3 Plus */ + .driver_data = (void *)&teclast_x3_plus_data, +-- +2.43.0 + diff --git a/queue-5.15/regulator-pwm-regulator-add-validity-checks-in-conti.patch b/queue-5.15/regulator-pwm-regulator-add-validity-checks-in-conti.patch new file mode 100644 index 00000000000..a5bb0bc594c --- /dev/null +++ b/queue-5.15/regulator-pwm-regulator-add-validity-checks-in-conti.patch @@ -0,0 +1,43 @@ +From 90bba3c22e672ad9c43f765c7d9358c885d20856 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 13 Jan 2024 23:46:26 +0100 +Subject: regulator: pwm-regulator: Add validity checks in continuous + .get_voltage +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Martin Blumenstingl + +[ Upstream commit c92688cac239794e4a1d976afa5203a4d3a2ac0e ] + +Continuous regulators can be configured to operate only in a certain +duty cycle range (for example from 0..91%). Add a check to error out if +the duty cycle translates to an unsupported (or out of range) voltage. + +Suggested-by: Uwe Kleine-König +Signed-off-by: Martin Blumenstingl +Link: https://msgid.link/r/20240113224628.377993-2-martin.blumenstingl@googlemail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/pwm-regulator.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/regulator/pwm-regulator.c b/drivers/regulator/pwm-regulator.c +index 7629476d94aeb..f4d9d9455dea6 100644 +--- a/drivers/regulator/pwm-regulator.c ++++ b/drivers/regulator/pwm-regulator.c +@@ -158,6 +158,9 @@ static int pwm_regulator_get_voltage(struct regulator_dev *rdev) + pwm_get_state(drvdata->pwm, &pstate); + + voltage = pwm_get_relative_duty_cycle(&pstate, duty_unit); ++ if (voltage < min(max_uV_duty, min_uV_duty) || ++ voltage > max(max_uV_duty, min_uV_duty)) ++ return -ENOTRECOVERABLE; + + /* + * The dutycycle for min_uV might be greater than the one for max_uV. +-- +2.43.0 + diff --git a/queue-5.15/scsi-lpfc-use-unsigned-type-for-num_sge.patch b/queue-5.15/scsi-lpfc-use-unsigned-type-for-num_sge.patch new file mode 100644 index 00000000000..c184e270f5d --- /dev/null +++ b/queue-5.15/scsi-lpfc-use-unsigned-type-for-num_sge.patch @@ -0,0 +1,80 @@ +From 82b5c9b0183976380e51209a8c0e5ce70525113f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Dec 2023 17:26:58 +0100 +Subject: scsi: lpfc: Use unsigned type for num_sge + +From: Hannes Reinecke + +[ Upstream commit d6c1b19153f92e95e5e1801d540e98771053afae ] + +LUNs going into "failed ready running" state observed on >1T and on even +numbers of size (2T, 4T, 6T, 8T and 10T). The issue occurs when DIF is +enabled at the host. + +The kernel logs: + + Cannot setup S/G List for HBAIO segs 1/1 SGL 512 SCSI 256: 3 0 + +The host lpfc driver is failing to setup scatter/gather list (protection +data) for the I/Os. + +The return type lpfc_bg_setup_sgl()/lpfc_bg_setup_sgl_prot() causes the +compiler to remove the most significant bit. Use an unsigned type instead. + +Signed-off-by: Hannes Reinecke +[dwagner: added commit message] +Signed-off-by: Daniel Wagner +Link: https://lore.kernel.org/r/20231220162658.12392-1-dwagner@suse.de +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/lpfc/lpfc_scsi.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c +index 4813adec0301d..6d1a3cbd6b3c4 100644 +--- a/drivers/scsi/lpfc/lpfc_scsi.c ++++ b/drivers/scsi/lpfc/lpfc_scsi.c +@@ -1983,7 +1983,7 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, + * + * Returns the number of SGEs added to the SGL. + **/ +-static int ++static uint32_t + lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc, + struct sli4_sge *sgl, int datasegcnt, + struct lpfc_io_buf *lpfc_cmd) +@@ -1991,8 +1991,8 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc, + struct scatterlist *sgde = NULL; /* s/g data entry */ + struct sli4_sge_diseed *diseed = NULL; + dma_addr_t physaddr; +- int i = 0, num_sge = 0, status; +- uint32_t reftag; ++ int i = 0, status; ++ uint32_t reftag, num_sge = 0; + uint8_t txop, rxop; + #ifdef CONFIG_SCSI_LPFC_DEBUG_FS + uint32_t rc; +@@ -2164,7 +2164,7 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc, + * + * Returns the number of SGEs added to the SGL. + **/ +-static int ++static uint32_t + lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, + struct sli4_sge *sgl, int datacnt, int protcnt, + struct lpfc_io_buf *lpfc_cmd) +@@ -2188,8 +2188,8 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, + uint32_t rc; + #endif + uint32_t checking = 1; +- uint32_t dma_offset = 0; +- int num_sge = 0, j = 2; ++ uint32_t dma_offset = 0, num_sge = 0; ++ int j = 2; + struct sli4_hybrid_sgl *sgl_xtra = NULL; + + sgpe = scsi_prot_sglist(sc); +-- +2.43.0 + diff --git a/queue-5.15/scsi-target-core-add-tmf-to-tmr_list-handling.patch b/queue-5.15/scsi-target-core-add-tmf-to-tmr_list-handling.patch new file mode 100644 index 00000000000..e3e45d4cdbd --- /dev/null +++ b/queue-5.15/scsi-target-core-add-tmf-to-tmr_list-handling.patch @@ -0,0 +1,88 @@ +From 56fb7019459a00d5b8f50ce4c2fb59d5cdcc6e1f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 Jan 2024 15:59:41 +0300 +Subject: scsi: target: core: Add TMF to tmr_list handling + +From: Dmitry Bogdanov + +[ Upstream commit 83ab68168a3d990d5ff39ab030ad5754cbbccb25 ] + +An abort that is responded to by iSCSI itself is added to tmr_list but does +not go to target core. A LUN_RESET that goes through tmr_list takes a +refcounter on the abort and waits for completion. However, the abort will +be never complete because it was not started in target core. + + Unable to locate ITT: 0x05000000 on CID: 0 + Unable to locate RefTaskTag: 0x05000000 on CID: 0. + wait_for_tasks: Stopping tmf LUN_RESET with tag 0x0 ref_task_tag 0x0 i_state 34 t_state ISTATE_PROCESSING refcnt 2 transport_state active,stop,fabric_stop + wait for tasks: tmf LUN_RESET with tag 0x0 ref_task_tag 0x0 i_state 34 t_state ISTATE_PROCESSING refcnt 2 transport_state active,stop,fabric_stop +... + INFO: task kworker/0:2:49 blocked for more than 491 seconds. + task:kworker/0:2 state:D stack: 0 pid: 49 ppid: 2 flags:0x00000800 + Workqueue: events target_tmr_work [target_core_mod] +Call Trace: + __switch_to+0x2c4/0x470 + _schedule+0x314/0x1730 + schedule+0x64/0x130 + schedule_timeout+0x168/0x430 + wait_for_completion+0x140/0x270 + target_put_cmd_and_wait+0x64/0xb0 [target_core_mod] + core_tmr_lun_reset+0x30/0xa0 [target_core_mod] + target_tmr_work+0xc8/0x1b0 [target_core_mod] + process_one_work+0x2d4/0x5d0 + worker_thread+0x78/0x6c0 + +To fix this, only add abort to tmr_list if it will be handled by target +core. + +Signed-off-by: Dmitry Bogdanov +Link: https://lore.kernel.org/r/20240111125941.8688-1-d.bogdanov@yadro.com +Reviewed-by: Mike Christie +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/target/target_core_device.c | 5 ----- + drivers/target/target_core_transport.c | 4 ++++ + 2 files changed, 4 insertions(+), 5 deletions(-) + +diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c +index 813de805f815a..d4185c1bed8a8 100644 +--- a/drivers/target/target_core_device.c ++++ b/drivers/target/target_core_device.c +@@ -147,7 +147,6 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd) + struct se_session *se_sess = se_cmd->se_sess; + struct se_node_acl *nacl = se_sess->se_node_acl; + struct se_tmr_req *se_tmr = se_cmd->se_tmr_req; +- unsigned long flags; + + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, se_cmd->orig_fe_lun); +@@ -178,10 +177,6 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd) + se_cmd->se_dev = rcu_dereference_raw(se_lun->lun_se_dev); + se_tmr->tmr_dev = rcu_dereference_raw(se_lun->lun_se_dev); + +- spin_lock_irqsave(&se_tmr->tmr_dev->se_tmr_lock, flags); +- list_add_tail(&se_tmr->tmr_list, &se_tmr->tmr_dev->dev_tmr_list); +- spin_unlock_irqrestore(&se_tmr->tmr_dev->se_tmr_lock, flags); +- + return 0; + } + EXPORT_SYMBOL(transport_lookup_tmr_lun); +diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c +index 72edf5bd75ee6..ac2d0e7d58ab7 100644 +--- a/drivers/target/target_core_transport.c ++++ b/drivers/target/target_core_transport.c +@@ -3568,6 +3568,10 @@ int transport_generic_handle_tmr( + unsigned long flags; + bool aborted = false; + ++ spin_lock_irqsave(&cmd->se_dev->se_tmr_lock, flags); ++ list_add_tail(&cmd->se_tmr_req->tmr_list, &cmd->se_dev->dev_tmr_list); ++ spin_unlock_irqrestore(&cmd->se_dev->se_tmr_lock, flags); ++ + spin_lock_irqsave(&cmd->t_state_lock, flags); + if (cmd->transport_state & CMD_T_ABORTED) { + aborted = true; +-- +2.43.0 + diff --git a/queue-5.15/series b/queue-5.15/series index fc76bdbd88d..5ecd06429c1 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -15,3 +15,59 @@ zonefs-improve-error-handling.patch x86-fpu-stop-relying-on-userspace-for-info-to-fault-in-xsave-buffer.patch sched-rt-fix-sysctl_sched_rr_timeslice-intial-value.patch sched-rt-disallow-writing-invalid-values-to-sched_rt_period_us.patch +xhci-fix-possible-null-pointer-deref-during-xhci-urb.patch +scsi-target-core-add-tmf-to-tmr_list-handling.patch +dmaengine-shdma-increase-size-of-dev_id.patch +dmaengine-fsl-qdma-increase-size-of-irq_name.patch +wifi-cfg80211-fix-missing-interfaces-when-dumping.patch +wifi-mac80211-fix-race-condition-on-enabling-fast-xm.patch +fbdev-savage-error-out-if-pixclock-equals-zero.patch +fbdev-sis-error-out-if-pixclock-equals-zero.patch +spi-hisi-sfc-v3xx-return-irq_none-if-no-interrupts-w.patch +ahci-asm1166-correct-count-of-reported-ports.patch +ahci-add-43-bit-dma-address-quirk-for-asmedia-asm106.patch +mips-reserve-exception-vector-space-only-once.patch +platform-x86-touchscreen_dmi-add-info-for-the-teclas.patch +ext4-avoid-dividing-by-0-in-mb_update_avg_fragment_s.patch +ext4-avoid-allocating-blocks-from-corrupted-group-in.patch +ext4-avoid-allocating-blocks-from-corrupted-group-in.patch-26613 +dmaengine-ti-edma-add-some-null-pointer-checks-to-th.patch +regulator-pwm-regulator-add-validity-checks-in-conti.patch +nvmet-tcp-fix-nvme-tcp-ida-memory-leak.patch +alsa-usb-audio-check-presence-of-valid-altsetting-co.patch +asoc-sunxi-sun4i-spdif-add-support-for-allwinner-h61.patch +spi-sh-msiof-avoid-integer-overflow-in-constants.patch +input-xpad-add-lenovo-legion-go-controllers.patch +netfilter-conntrack-check-sctp_cid_shutdown_ack-for-.patch +alsa-usb-audio-ignore-clock-selector-errors-for-sing.patch +nvme-fc-do-not-wait-in-vain-when-unloading-module.patch +nvmet-fcloop-swap-the-list_add_tail-arguments.patch +nvmet-fc-release-reference-on-target-port.patch +nvmet-fc-defer-cleanup-using-rcu-properly.patch +nvmet-fc-hold-reference-on-hostport-match.patch +nvmet-fc-abort-command-when-there-is-no-binding.patch +nvmet-fc-avoid-deadlock-on-delete-association-path.patch +nvmet-fc-take-ref-count-on-tgtport-before-delete-ass.patch +ext4-correct-the-hole-length-returned-by-ext4_map_bl.patch +input-i8042-add-fujitsu-lifebook-u728-to-i8042-quirk.patch +fs-ntfs3-modified-fix-directory-element-type-detecti.patch +fs-ntfs3-improve-ntfs_dir_count.patch +fs-ntfs3-correct-hard-links-updating-when-dealing-wi.patch +fs-ntfs3-print-warning-while-fixing-hard-links-count.patch +fs-ntfs3-fix-detected-field-spanning-write-size-8-of.patch +fs-ntfs3-add-null-ptr-dereference-checking-at-the-en.patch +fs-ntfs3-disable-attr_list_entry-size-check.patch +fs-ntfs3-use-non-movable-memory-for-ntfs3-mft-buffer.patch +fs-ntfs3-prevent-generic-message-attempt-to-access-b.patch +fs-ntfs3-correct-function-is_rst_area_valid.patch +fs-ntfs3-update-inode-i_size-after-success-write-int.patch +fs-ntfs3-fix-oob-in-ntfs_listxattr.patch +wifi-mac80211-adding-missing-drv_mgd_complete_tx-cal.patch +efi-runtime-fix-potential-overflow-of-soft-reserved-.patch +efi-don-t-add-memblocks-for-soft-reserved-memory.patch +hwmon-coretemp-enlarge-per-package-core-count-limit.patch +scsi-lpfc-use-unsigned-type-for-num_sge.patch +firewire-core-send-bus-reset-promptly-on-gap-count-e.patch +drm-amdgpu-skip-to-program-gfxdec-registers-for-susp.patch +drm-amdgpu-reset-gpu-for-s3-suspend-abort-case.patch +virtio-blk-ensure-no-requests-in-virtqueues-before-d.patch diff --git a/queue-5.15/spi-hisi-sfc-v3xx-return-irq_none-if-no-interrupts-w.patch b/queue-5.15/spi-hisi-sfc-v3xx-return-irq_none-if-no-interrupts-w.patch new file mode 100644 index 00000000000..d0f6e57d0f6 --- /dev/null +++ b/queue-5.15/spi-hisi-sfc-v3xx-return-irq_none-if-no-interrupts-w.patch @@ -0,0 +1,47 @@ +From dd3ac6c2e5ad9f3e295198c4b023f1a63d0c6bdd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Jan 2024 15:11:49 +0800 +Subject: spi: hisi-sfc-v3xx: Return IRQ_NONE if no interrupts were detected + +From: Devyn Liu + +[ Upstream commit de8b6e1c231a95abf95ad097b993d34b31458ec9 ] + +Return IRQ_NONE from the interrupt handler when no interrupt was +detected. Because an empty interrupt will cause a null pointer error: + + Unable to handle kernel NULL pointer dereference at virtual + address 0000000000000008 + Call trace: + complete+0x54/0x100 + hisi_sfc_v3xx_isr+0x2c/0x40 [spi_hisi_sfc_v3xx] + __handle_irq_event_percpu+0x64/0x1e0 + handle_irq_event+0x7c/0x1cc + +Signed-off-by: Devyn Liu +Link: https://msgid.link/r/20240123071149.917678-1-liudingyuan@huawei.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-hisi-sfc-v3xx.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/spi/spi-hisi-sfc-v3xx.c b/drivers/spi/spi-hisi-sfc-v3xx.c +index d3a23b1c2a4c5..61bf00dfe9c33 100644 +--- a/drivers/spi/spi-hisi-sfc-v3xx.c ++++ b/drivers/spi/spi-hisi-sfc-v3xx.c +@@ -377,6 +377,11 @@ static const struct spi_controller_mem_ops hisi_sfc_v3xx_mem_ops = { + static irqreturn_t hisi_sfc_v3xx_isr(int irq, void *data) + { + struct hisi_sfc_v3xx_host *host = data; ++ u32 reg; ++ ++ reg = readl(host->regbase + HISI_SFC_V3XX_INT_STAT); ++ if (!reg) ++ return IRQ_NONE; + + hisi_sfc_v3xx_disable_int(host); + +-- +2.43.0 + diff --git a/queue-5.15/spi-sh-msiof-avoid-integer-overflow-in-constants.patch b/queue-5.15/spi-sh-msiof-avoid-integer-overflow-in-constants.patch new file mode 100644 index 00000000000..1d696972c51 --- /dev/null +++ b/queue-5.15/spi-sh-msiof-avoid-integer-overflow-in-constants.patch @@ -0,0 +1,53 @@ +From be5b4721fe22c6476c9b7b415590d193d4746030 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Jan 2024 10:40:53 +0100 +Subject: spi: sh-msiof: avoid integer overflow in constants + +From: Wolfram Sang + +[ Upstream commit 6500ad28fd5d67d5ca0fee9da73c463090842440 ] + +cppcheck rightfully warned: + + drivers/spi/spi-sh-msiof.c:792:28: warning: Signed integer overflow for expression '7<<29'. [integerOverflow] + sh_msiof_write(p, SIFCTR, SIFCTR_TFWM_1 | SIFCTR_RFWM_1); + +Signed-off-by: Wolfram Sang +Reviewed-by: Geert Uytterhoeven +Link: https://msgid.link/r/20240130094053.10672-1-wsa+renesas@sang-engineering.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-sh-msiof.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c +index eb2c64e0a5f7c..b7b3ec76e2cbd 100644 +--- a/drivers/spi/spi-sh-msiof.c ++++ b/drivers/spi/spi-sh-msiof.c +@@ -137,14 +137,14 @@ struct sh_msiof_spi_priv { + + /* SIFCTR */ + #define SIFCTR_TFWM_MASK GENMASK(31, 29) /* Transmit FIFO Watermark */ +-#define SIFCTR_TFWM_64 (0 << 29) /* Transfer Request when 64 empty stages */ +-#define SIFCTR_TFWM_32 (1 << 29) /* Transfer Request when 32 empty stages */ +-#define SIFCTR_TFWM_24 (2 << 29) /* Transfer Request when 24 empty stages */ +-#define SIFCTR_TFWM_16 (3 << 29) /* Transfer Request when 16 empty stages */ +-#define SIFCTR_TFWM_12 (4 << 29) /* Transfer Request when 12 empty stages */ +-#define SIFCTR_TFWM_8 (5 << 29) /* Transfer Request when 8 empty stages */ +-#define SIFCTR_TFWM_4 (6 << 29) /* Transfer Request when 4 empty stages */ +-#define SIFCTR_TFWM_1 (7 << 29) /* Transfer Request when 1 empty stage */ ++#define SIFCTR_TFWM_64 (0UL << 29) /* Transfer Request when 64 empty stages */ ++#define SIFCTR_TFWM_32 (1UL << 29) /* Transfer Request when 32 empty stages */ ++#define SIFCTR_TFWM_24 (2UL << 29) /* Transfer Request when 24 empty stages */ ++#define SIFCTR_TFWM_16 (3UL << 29) /* Transfer Request when 16 empty stages */ ++#define SIFCTR_TFWM_12 (4UL << 29) /* Transfer Request when 12 empty stages */ ++#define SIFCTR_TFWM_8 (5UL << 29) /* Transfer Request when 8 empty stages */ ++#define SIFCTR_TFWM_4 (6UL << 29) /* Transfer Request when 4 empty stages */ ++#define SIFCTR_TFWM_1 (7UL << 29) /* Transfer Request when 1 empty stage */ + #define SIFCTR_TFUA_MASK GENMASK(26, 20) /* Transmit FIFO Usable Area */ + #define SIFCTR_TFUA_SHIFT 20 + #define SIFCTR_TFUA(i) ((i) << SIFCTR_TFUA_SHIFT) +-- +2.43.0 + diff --git a/queue-5.15/virtio-blk-ensure-no-requests-in-virtqueues-before-d.patch b/queue-5.15/virtio-blk-ensure-no-requests-in-virtqueues-before-d.patch new file mode 100644 index 00000000000..e96282dfb47 --- /dev/null +++ b/queue-5.15/virtio-blk-ensure-no-requests-in-virtqueues-before-d.patch @@ -0,0 +1,64 @@ +From e3aba688fc97a98d7871170681352b47789064e6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Jan 2024 16:52:50 +0800 +Subject: virtio-blk: Ensure no requests in virtqueues before deleting vqs. + +From: Yi Sun + +[ Upstream commit 4ce6e2db00de8103a0687fb0f65fd17124a51aaa ] + +Ensure no remaining requests in virtqueues before resetting vdev and +deleting virtqueues. Otherwise these requests will never be completed. +It may cause the system to become unresponsive. + +Function blk_mq_quiesce_queue() can ensure that requests have become +in_flight status, but it cannot guarantee that requests have been +processed by the device. Virtqueues should never be deleted before +all requests become complete status. + +Function blk_mq_freeze_queue() ensure that all requests in virtqueues +become complete status. And no requests can enter in virtqueues. + +Signed-off-by: Yi Sun +Reviewed-by: Stefan Hajnoczi +Link: https://lore.kernel.org/r/20240129085250.1550594-1-yi.sun@unisoc.com +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/virtio_blk.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c +index affeca0dbc7ea..7f73e7447ecb5 100644 +--- a/drivers/block/virtio_blk.c ++++ b/drivers/block/virtio_blk.c +@@ -989,14 +989,15 @@ static int virtblk_freeze(struct virtio_device *vdev) + { + struct virtio_blk *vblk = vdev->priv; + ++ /* Ensure no requests in virtqueues before deleting vqs. */ ++ blk_mq_freeze_queue(vblk->disk->queue); ++ + /* Ensure we don't receive any more interrupts */ + vdev->config->reset(vdev); + + /* Make sure no work handler is accessing the device. */ + flush_work(&vblk->config_work); + +- blk_mq_quiesce_queue(vblk->disk->queue); +- + vdev->config->del_vqs(vdev); + kfree(vblk->vqs); + +@@ -1014,7 +1015,7 @@ static int virtblk_restore(struct virtio_device *vdev) + + virtio_device_ready(vdev); + +- blk_mq_unquiesce_queue(vblk->disk->queue); ++ blk_mq_unfreeze_queue(vblk->disk->queue); + return 0; + } + #endif +-- +2.43.0 + diff --git a/queue-5.15/wifi-cfg80211-fix-missing-interfaces-when-dumping.patch b/queue-5.15/wifi-cfg80211-fix-missing-interfaces-when-dumping.patch new file mode 100644 index 00000000000..e97d4061f39 --- /dev/null +++ b/queue-5.15/wifi-cfg80211-fix-missing-interfaces-when-dumping.patch @@ -0,0 +1,71 @@ +From 3fe8e7b383354400e7133077d0d4a04cb6b243ce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Jan 2024 14:22:57 +0000 +Subject: wifi: cfg80211: fix missing interfaces when dumping + +From: Michal Kazior + +[ Upstream commit a6e4f85d3820d00694ed10f581f4c650445dbcda ] + +The nl80211_dump_interface() supports resumption +in case nl80211_send_iface() doesn't have the +resources to complete its work. + +The logic would store the progress as iteration +offsets for rdev and wdev loops. + +However the logic did not properly handle +resumption for non-last rdev. Assuming a system +with 2 rdevs, with 2 wdevs each, this could +happen: + + dump(cb=[0, 0]): + if_start=cb[1] (=0) + send rdev0.wdev0 -> ok + send rdev0.wdev1 -> yield + cb[1] = 1 + + dump(cb=[0, 1]): + if_start=cb[1] (=1) + send rdev0.wdev1 -> ok + // since if_start=1 the rdev0.wdev0 got skipped + // through if_idx < if_start + send rdev1.wdev1 -> ok + +The if_start needs to be reset back to 0 upon wdev +loop end. + +The problem is actually hard to hit on a desktop, +and even on most routers. The prerequisites for +this manifesting was: + - more than 1 wiphy + - a few handful of interfaces + - dump without rdev or wdev filter + +I was seeing this with 4 wiphys 9 interfaces each. +It'd miss 6 interfaces from the last wiphy +reported to userspace. + +Signed-off-by: Michal Kazior +Link: https://msgid.link/20240116142340.89678-1-kazikcz@gmail.com +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/wireless/nl80211.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c +index 82b93380afec4..4a8b701440ebd 100644 +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -3737,6 +3737,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback * + if_idx++; + } + ++ if_start = 0; + wp_idx++; + } + out: +-- +2.43.0 + diff --git a/queue-5.15/wifi-mac80211-adding-missing-drv_mgd_complete_tx-cal.patch b/queue-5.15/wifi-mac80211-adding-missing-drv_mgd_complete_tx-cal.patch new file mode 100644 index 00000000000..c81b0b4ad39 --- /dev/null +++ b/queue-5.15/wifi-mac80211-adding-missing-drv_mgd_complete_tx-cal.patch @@ -0,0 +1,35 @@ +From 7cc7e184c17dc1c34f5a9af98a33ce28e6a25a99 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 Jan 2024 16:48:23 +0100 +Subject: wifi: mac80211: adding missing drv_mgd_complete_tx() call + +From: Johannes Berg + +[ Upstream commit c042600c17d8c490279f0ae2baee29475fe8047d ] + +There's a call to drv_mgd_prepare_tx() and so there should +be one to drv_mgd_complete_tx(), but on this path it's not. +Add it. + +Link: https://msgid.link/20240131164824.2f0922a514e1.I5aac89b93bcead88c374187d70cad0599d29d2c8@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/mac80211/mlme.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c +index cc6d38a2e6d5a..5da0c2a2e293e 100644 +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -5923,6 +5923,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, + ieee80211_report_disconnect(sdata, frame_buf, + sizeof(frame_buf), true, + req->reason_code, false); ++ drv_mgd_complete_tx(sdata->local, sdata, &info); + return 0; + } + +-- +2.43.0 + diff --git a/queue-5.15/wifi-mac80211-fix-race-condition-on-enabling-fast-xm.patch b/queue-5.15/wifi-mac80211-fix-race-condition-on-enabling-fast-xm.patch new file mode 100644 index 00000000000..de4b1732bee --- /dev/null +++ b/queue-5.15/wifi-mac80211-fix-race-condition-on-enabling-fast-xm.patch @@ -0,0 +1,53 @@ +From 8e0b05368d1a56c4fee34ab9eed9221e5e8d9d53 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 4 Jan 2024 19:10:59 +0100 +Subject: wifi: mac80211: fix race condition on enabling fast-xmit + +From: Felix Fietkau + +[ Upstream commit bcbc84af1183c8cf3d1ca9b78540c2185cd85e7f ] + +fast-xmit must only be enabled after the sta has been uploaded to the driver, +otherwise it could end up passing the not-yet-uploaded sta via drv_tx calls +to the driver, leading to potential crashes because of uninitialized drv_priv +data. +Add a missing sta->uploaded check and re-check fast xmit after inserting a sta. + +Signed-off-by: Felix Fietkau +Link: https://msgid.link/20240104181059.84032-1-nbd@nbd.name +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/mac80211/sta_info.c | 2 ++ + net/mac80211/tx.c | 2 +- + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c +index e10bcfa20526d..f4deee1926e58 100644 +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -696,6 +696,8 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU) + if (ieee80211_vif_is_mesh(&sdata->vif)) + mesh_accept_plinks_update(sdata); + ++ ieee80211_check_fast_xmit(sta); ++ + return 0; + out_remove: + sta_info_hash_del(local, sta); +diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c +index 481b6b34797da..c4e6fbe4343ee 100644 +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -2965,7 +2965,7 @@ void ieee80211_check_fast_xmit(struct sta_info *sta) + sdata->vif.type == NL80211_IFTYPE_STATION) + goto out; + +- if (!test_sta_flag(sta, WLAN_STA_AUTHORIZED)) ++ if (!test_sta_flag(sta, WLAN_STA_AUTHORIZED) || !sta->uploaded) + goto out; + + if (test_sta_flag(sta, WLAN_STA_PS_STA) || +-- +2.43.0 + diff --git a/queue-5.15/xhci-fix-possible-null-pointer-deref-during-xhci-urb.patch b/queue-5.15/xhci-fix-possible-null-pointer-deref-during-xhci-urb.patch new file mode 100644 index 00000000000..0c88a106a24 --- /dev/null +++ b/queue-5.15/xhci-fix-possible-null-pointer-deref-during-xhci-urb.patch @@ -0,0 +1,98 @@ +From ed623a29a39d156867e55ce7070b77edc411766f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 1 Dec 2023 17:06:47 +0200 +Subject: xhci: fix possible null pointer deref during xhci urb enqueue + +From: Mathias Nyman + +[ Upstream commit e2e2aacf042f52854c92775b7800ba668e0bdfe4 ] + +There is a short gap between urb being submitted and actually added to the +endpoint queue (linked). If the device is disconnected during this time +then usb core is not yet aware of the pending urb, and device may be freed +just before xhci_urq_enqueue() continues, dereferencing the freed device. + +Freeing the device is protected by the xhci spinlock, so make sure we take +and keep the lock while checking that device exists, dereference it, and +add the urb to the queue. + +Remove the unnecessary URB check, usb core checks it before calling +xhci_urb_enqueue() + +Suggested-by: Kuen-Han Tsai +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20231201150647.1307406-20-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/host/xhci.c | 40 +++++++++++++++++++++++----------------- + 1 file changed, 23 insertions(+), 17 deletions(-) + +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index 5c9d3be136d2c..6c8c9cbcd05da 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -1644,24 +1644,7 @@ static int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag + struct urb_priv *urb_priv; + int num_tds; + +- if (!urb) +- return -EINVAL; +- ret = xhci_check_args(hcd, urb->dev, urb->ep, +- true, true, __func__); +- if (ret <= 0) +- return ret ? ret : -EINVAL; +- +- slot_id = urb->dev->slot_id; + ep_index = xhci_get_endpoint_index(&urb->ep->desc); +- ep_state = &xhci->devs[slot_id]->eps[ep_index].ep_state; +- +- if (!HCD_HW_ACCESSIBLE(hcd)) +- return -ESHUTDOWN; +- +- if (xhci->devs[slot_id]->flags & VDEV_PORT_ERROR) { +- xhci_dbg(xhci, "Can't queue urb, port error, link inactive\n"); +- return -ENODEV; +- } + + if (usb_endpoint_xfer_isoc(&urb->ep->desc)) + num_tds = urb->number_of_packets; +@@ -1700,12 +1683,35 @@ static int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag + + spin_lock_irqsave(&xhci->lock, flags); + ++ ret = xhci_check_args(hcd, urb->dev, urb->ep, ++ true, true, __func__); ++ if (ret <= 0) { ++ ret = ret ? ret : -EINVAL; ++ goto free_priv; ++ } ++ ++ slot_id = urb->dev->slot_id; ++ ++ if (!HCD_HW_ACCESSIBLE(hcd)) { ++ ret = -ESHUTDOWN; ++ goto free_priv; ++ } ++ ++ if (xhci->devs[slot_id]->flags & VDEV_PORT_ERROR) { ++ xhci_dbg(xhci, "Can't queue urb, port error, link inactive\n"); ++ ret = -ENODEV; ++ goto free_priv; ++ } ++ + if (xhci->xhc_state & XHCI_STATE_DYING) { + xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for non-responsive xHCI host.\n", + urb->ep->desc.bEndpointAddress, urb); + ret = -ESHUTDOWN; + goto free_priv; + } ++ ++ ep_state = &xhci->devs[slot_id]->eps[ep_index].ep_state; ++ + if (*ep_state & (EP_GETTING_STREAMS | EP_GETTING_NO_STREAMS)) { + xhci_warn(xhci, "WARN: Can't enqueue URB, ep in streams transition state %x\n", + *ep_state); +-- +2.43.0 +