From: Greg Kroah-Hartman Date: Fri, 21 Jul 2023 07:01:00 +0000 (+0200) Subject: 6.1-stable patches X-Git-Tag: v5.15.121~56 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b2aed4934b7ae3170e24be9b710ba530e15d0828;p=thirdparty%2Fkernel%2Fstable-queue.git 6.1-stable patches added patches: md-raid0-add-discard-support-for-the-original-layout.patch mfd-pm8008-fix-module-autoloading.patch misc-pci_endpoint_test-free-irqs-before-removing-the-device.patch misc-pci_endpoint_test-re-init-completion-for-every-test.patch --- diff --git a/queue-6.1/md-raid0-add-discard-support-for-the-original-layout.patch b/queue-6.1/md-raid0-add-discard-support-for-the-original-layout.patch new file mode 100644 index 00000000000..9bd28210168 --- /dev/null +++ b/queue-6.1/md-raid0-add-discard-support-for-the-original-layout.patch @@ -0,0 +1,203 @@ +From e836007089ba8fdf24e636ef2b007651fb4582e6 Mon Sep 17 00:00:00 2001 +From: Jason Baron +Date: Fri, 23 Jun 2023 14:05:23 -0400 +Subject: md/raid0: add discard support for the 'original' layout + +From: Jason Baron + +commit e836007089ba8fdf24e636ef2b007651fb4582e6 upstream. + +We've found that using raid0 with the 'original' layout and discard +enabled with different disk sizes (such that at least two zones are +created) can result in data corruption. This is due to the fact that +the discard handling in 'raid0_handle_discard()' assumes the 'alternate' +layout. We've seen this corruption using ext4 but other filesystems are +likely susceptible as well. + +More specifically, while multiple zones are necessary to create the +corruption, the corruption may not occur with multiple zones if they +layout in such a way the layout matches what the 'alternate' layout +would have produced. Thus, not all raid0 devices with the 'original' +layout, different size disks and discard enabled will encounter this +corruption. + +The 3.14 kernel inadvertently changed the raid0 disk layout for different +size disks. Thus, running a pre-3.14 kernel and post-3.14 kernel on the +same raid0 array could corrupt data. This lead to the creation of the +'original' layout (to match the pre-3.14 layout) and the 'alternate' layout +(to match the post 3.14 layout) in the 5.4 kernel time frame and an option +to tell the kernel which layout to use (since it couldn't be autodetected). +However, when the 'original' layout was added back to 5.4 discard support +for the 'original' layout was not added leading this issue. + +I've been able to reliably reproduce the corruption with the following +test case: + +1. create raid0 array with different size disks using original layout +2. mkfs +3. mount -o discard +4. create lots of files +5. remove 1/2 the files +6. fstrim -a (or just the mount point for the raid0 array) +7. umount +8. fsck -fn /dev/md0 (spews all sorts of corruptions) + +Let's fix this by adding proper discard support to the 'original' layout. +The fix 'maps' the 'original' layout disks to the order in which they are +read/written such that we can compare the disks in the same way that the +current 'alternate' layout does. A 'disk_shift' field is added to +'struct strip_zone'. This could be computed on the fly in +raid0_handle_discard() but by adding this field, we save some computation +in the discard path. + +Note we could also potentially fix this by re-ordering the disks in the +zones that follow the first one, and then always read/writing them using +the 'alternate' layout. However, that is seen as a more substantial change, +and we are attempting the least invasive fix at this time to remedy the +corruption. + +I've verified the change using the reproducer mentioned above. Typically, +the corruption is seen after less than 3 iterations, while the patch has +run 500+ iterations. + +Cc: NeilBrown +Cc: Song Liu +Fixes: c84a1372df92 ("md/raid0: avoid RAID0 data corruption due to layout confusion.") +Cc: stable@vger.kernel.org +Signed-off-by: Jason Baron +Signed-off-by: Song Liu +Link: https://lore.kernel.org/r/20230623180523.1901230-1-jbaron@akamai.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/raid0.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++------- + drivers/md/raid0.h | 1 + 2 files changed, 55 insertions(+), 8 deletions(-) + +--- a/drivers/md/raid0.c ++++ b/drivers/md/raid0.c +@@ -270,6 +270,18 @@ static int create_strip_zones(struct mdd + goto abort; + } + ++ if (conf->layout == RAID0_ORIG_LAYOUT) { ++ for (i = 1; i < conf->nr_strip_zones; i++) { ++ sector_t first_sector = conf->strip_zone[i-1].zone_end; ++ ++ sector_div(first_sector, mddev->chunk_sectors); ++ zone = conf->strip_zone + i; ++ /* disk_shift is first disk index used in the zone */ ++ zone->disk_shift = sector_div(first_sector, ++ zone->nb_dev); ++ } ++ } ++ + pr_debug("md/raid0:%s: done.\n", mdname(mddev)); + *private_conf = conf; + +@@ -431,6 +443,20 @@ exit_acct_set: + return ret; + } + ++/* ++ * Convert disk_index to the disk order in which it is read/written. ++ * For example, if we have 4 disks, they are numbered 0,1,2,3. If we ++ * write the disks starting at disk 3, then the read/write order would ++ * be disk 3, then 0, then 1, and then disk 2 and we want map_disk_shift() ++ * to map the disks as follows 0,1,2,3 => 1,2,3,0. So disk 0 would map ++ * to 1, 1 to 2, 2 to 3, and 3 to 0. That way we can compare disks in ++ * that 'output' space to understand the read/write disk ordering. ++ */ ++static int map_disk_shift(int disk_index, int num_disks, int disk_shift) ++{ ++ return ((disk_index + num_disks - disk_shift) % num_disks); ++} ++ + static void raid0_handle_discard(struct mddev *mddev, struct bio *bio) + { + struct r0conf *conf = mddev->private; +@@ -444,7 +470,9 @@ static void raid0_handle_discard(struct + sector_t end_disk_offset; + unsigned int end_disk_index; + unsigned int disk; ++ sector_t orig_start, orig_end; + ++ orig_start = start; + zone = find_zone(conf, &start); + + if (bio_end_sector(bio) > zone->zone_end) { +@@ -458,6 +486,7 @@ static void raid0_handle_discard(struct + } else + end = bio_end_sector(bio); + ++ orig_end = end; + if (zone != conf->strip_zone) + end = end - zone[-1].zone_end; + +@@ -469,13 +498,26 @@ static void raid0_handle_discard(struct + last_stripe_index = end; + sector_div(last_stripe_index, stripe_size); + +- start_disk_index = (int)(start - first_stripe_index * stripe_size) / +- mddev->chunk_sectors; ++ /* In the first zone the original and alternate layouts are the same */ ++ if ((conf->layout == RAID0_ORIG_LAYOUT) && (zone != conf->strip_zone)) { ++ sector_div(orig_start, mddev->chunk_sectors); ++ start_disk_index = sector_div(orig_start, zone->nb_dev); ++ start_disk_index = map_disk_shift(start_disk_index, ++ zone->nb_dev, ++ zone->disk_shift); ++ sector_div(orig_end, mddev->chunk_sectors); ++ end_disk_index = sector_div(orig_end, zone->nb_dev); ++ end_disk_index = map_disk_shift(end_disk_index, ++ zone->nb_dev, zone->disk_shift); ++ } else { ++ start_disk_index = (int)(start - first_stripe_index * stripe_size) / ++ mddev->chunk_sectors; ++ end_disk_index = (int)(end - last_stripe_index * stripe_size) / ++ mddev->chunk_sectors; ++ } + start_disk_offset = ((int)(start - first_stripe_index * stripe_size) % + mddev->chunk_sectors) + + first_stripe_index * mddev->chunk_sectors; +- end_disk_index = (int)(end - last_stripe_index * stripe_size) / +- mddev->chunk_sectors; + end_disk_offset = ((int)(end - last_stripe_index * stripe_size) % + mddev->chunk_sectors) + + last_stripe_index * mddev->chunk_sectors; +@@ -483,18 +525,22 @@ static void raid0_handle_discard(struct + for (disk = 0; disk < zone->nb_dev; disk++) { + sector_t dev_start, dev_end; + struct md_rdev *rdev; ++ int compare_disk; ++ ++ compare_disk = map_disk_shift(disk, zone->nb_dev, ++ zone->disk_shift); + +- if (disk < start_disk_index) ++ if (compare_disk < start_disk_index) + dev_start = (first_stripe_index + 1) * + mddev->chunk_sectors; +- else if (disk > start_disk_index) ++ else if (compare_disk > start_disk_index) + dev_start = first_stripe_index * mddev->chunk_sectors; + else + dev_start = start_disk_offset; + +- if (disk < end_disk_index) ++ if (compare_disk < end_disk_index) + dev_end = (last_stripe_index + 1) * mddev->chunk_sectors; +- else if (disk > end_disk_index) ++ else if (compare_disk > end_disk_index) + dev_end = last_stripe_index * mddev->chunk_sectors; + else + dev_end = end_disk_offset; +--- a/drivers/md/raid0.h ++++ b/drivers/md/raid0.h +@@ -6,6 +6,7 @@ struct strip_zone { + sector_t zone_end; /* Start of the next zone (in sectors) */ + sector_t dev_start; /* Zone offset in real dev (in sectors) */ + int nb_dev; /* # of devices attached to the zone */ ++ int disk_shift; /* start disk for the original layout */ + }; + + /* Linux 3.14 (20d0189b101) made an unintended change to diff --git a/queue-6.1/mfd-pm8008-fix-module-autoloading.patch b/queue-6.1/mfd-pm8008-fix-module-autoloading.patch new file mode 100644 index 00000000000..cb9a9a2e03d --- /dev/null +++ b/queue-6.1/mfd-pm8008-fix-module-autoloading.patch @@ -0,0 +1,33 @@ +From d420c9886f5369697047b880221789bf0054e438 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Fri, 26 May 2023 11:16:45 +0200 +Subject: mfd: pm8008: Fix module autoloading + +From: Johan Hovold + +commit d420c9886f5369697047b880221789bf0054e438 upstream. + +Add the missing module device table alias to that the driver can be +autoloaded when built as a module. + +Cc: stable@vger.kernel.org # 5.14 +Fixes: 6b149f3310a4 ("mfd: pm8008: Add driver for QCOM PM8008 PMIC") +Signed-off-by: Johan Hovold +Reviewed-by: Konrad Dybcio +Signed-off-by: Lee Jones +Link: https://lore.kernel.org/r/20230526091646.17318-2-johan+linaro@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mfd/qcom-pm8008.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/mfd/qcom-pm8008.c ++++ b/drivers/mfd/qcom-pm8008.c +@@ -233,6 +233,7 @@ static const struct of_device_id pm8008_ + { .compatible = "qcom,pm8008", }, + { }, + }; ++MODULE_DEVICE_TABLE(of, pm8008_match); + + static struct i2c_driver pm8008_mfd_driver = { + .driver = { diff --git a/queue-6.1/misc-pci_endpoint_test-free-irqs-before-removing-the-device.patch b/queue-6.1/misc-pci_endpoint_test-free-irqs-before-removing-the-device.patch new file mode 100644 index 00000000000..46bebc831d7 --- /dev/null +++ b/queue-6.1/misc-pci_endpoint_test-free-irqs-before-removing-the-device.patch @@ -0,0 +1,50 @@ +From f61b7634a3249d12b9daa36ffbdb9965b6f24c6c Mon Sep 17 00:00:00 2001 +From: Damien Le Moal +Date: Sat, 15 Apr 2023 11:35:39 +0900 +Subject: misc: pci_endpoint_test: Free IRQs before removing the device + +From: Damien Le Moal + +commit f61b7634a3249d12b9daa36ffbdb9965b6f24c6c upstream. + +In pci_endpoint_test_remove(), freeing the IRQs after removing the device +creates a small race window for IRQs to be received with the test device +memory already released, causing the IRQ handler to access invalid memory, +resulting in an oops. + +Free the device IRQs before removing the device to avoid this issue. + +Link: https://lore.kernel.org/r/20230415023542.77601-15-dlemoal@kernel.org +Fixes: e03327122e2c ("pci_endpoint_test: Add 2 ioctl commands") +Signed-off-by: Damien Le Moal +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Bjorn Helgaas +Reviewed-by: Manivannan Sadhasivam +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/misc/pci_endpoint_test.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/misc/pci_endpoint_test.c ++++ b/drivers/misc/pci_endpoint_test.c +@@ -937,6 +937,9 @@ static void pci_endpoint_test_remove(str + if (id < 0) + return; + ++ pci_endpoint_test_release_irq(test); ++ pci_endpoint_test_free_irq_vectors(test); ++ + misc_deregister(&test->miscdev); + kfree(misc_device->name); + kfree(test->name); +@@ -946,9 +949,6 @@ static void pci_endpoint_test_remove(str + pci_iounmap(pdev, test->bar[bar]); + } + +- pci_endpoint_test_release_irq(test); +- pci_endpoint_test_free_irq_vectors(test); +- + pci_release_regions(pdev); + pci_disable_device(pdev); + } diff --git a/queue-6.1/misc-pci_endpoint_test-re-init-completion-for-every-test.patch b/queue-6.1/misc-pci_endpoint_test-re-init-completion-for-every-test.patch new file mode 100644 index 00000000000..59138f07ab3 --- /dev/null +++ b/queue-6.1/misc-pci_endpoint_test-re-init-completion-for-every-test.patch @@ -0,0 +1,44 @@ +From fb620ae73b70c2f57b9d3e911fc24c024ba2324f Mon Sep 17 00:00:00 2001 +From: Damien Le Moal +Date: Sat, 15 Apr 2023 11:35:40 +0900 +Subject: misc: pci_endpoint_test: Re-init completion for every test + +From: Damien Le Moal + +commit fb620ae73b70c2f57b9d3e911fc24c024ba2324f upstream. + +The irq_raised completion used to detect the end of a test case is +initialized when the test device is probed, but never reinitialized again +before a test case. As a result, the irq_raised completion synchronization +is effective only for the first ioctl test case executed. Any subsequent +call to wait_for_completion() by another ioctl() call will immediately +return, potentially too early, leading to false positive failures. + +Fix this by reinitializing the irq_raised completion before starting a new +ioctl() test command. + +Link: https://lore.kernel.org/r/20230415023542.77601-16-dlemoal@kernel.org +Fixes: 2c156ac71c6b ("misc: Add host side PCI driver for PCI test function device") +Signed-off-by: Damien Le Moal +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Bjorn Helgaas +Reviewed-by: Manivannan Sadhasivam +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/misc/pci_endpoint_test.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/misc/pci_endpoint_test.c ++++ b/drivers/misc/pci_endpoint_test.c +@@ -728,6 +728,10 @@ static long pci_endpoint_test_ioctl(stru + struct pci_dev *pdev = test->pdev; + + mutex_lock(&test->mutex); ++ ++ reinit_completion(&test->irq_raised); ++ test->last_irq = -ENODATA; ++ + switch (cmd) { + case PCITEST_BAR: + bar = arg; diff --git a/queue-6.1/series b/queue-6.1/series index 3f603a28721..9f9ed128a61 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -129,3 +129,7 @@ pci-rockchip-add-poll-and-timeout-to-wait-for-phy-plls-to-be-locked.patch pci-rockchip-fix-legacy-irq-generation-for-rk3399-pcie-endpoint-core.patch pci-rockchip-use-u32-variable-to-access-32-bit-registers.patch pci-rockchip-set-address-alignment-for-endpoint-mode.patch +misc-pci_endpoint_test-free-irqs-before-removing-the-device.patch +misc-pci_endpoint_test-re-init-completion-for-every-test.patch +mfd-pm8008-fix-module-autoloading.patch +md-raid0-add-discard-support-for-the-original-layout.patch