From: Greg Kroah-Hartman Date: Fri, 6 Dec 2024 12:25:58 +0000 (+0100) Subject: 5.10-stable patches X-Git-Tag: v6.6.64~23 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2d66feef6622168fce129a239f6f76f49cce3f88;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: i3c-master-fix-miss-free-init_dyn_addr-at-i3c_master_put_i3c_addrs.patch pci-keystone-add-link-up-check-to-ks_pcie_other_map_bus.patch scsi-ufs-exynos-fix-hibern8-notify-callbacks.patch util_macros.h-fix-rework-find_closest-macros.patch --- diff --git a/queue-5.10/i3c-master-fix-miss-free-init_dyn_addr-at-i3c_master_put_i3c_addrs.patch b/queue-5.10/i3c-master-fix-miss-free-init_dyn_addr-at-i3c_master_put_i3c_addrs.patch new file mode 100644 index 00000000000..5dca037afe0 --- /dev/null +++ b/queue-5.10/i3c-master-fix-miss-free-init_dyn_addr-at-i3c_master_put_i3c_addrs.patch @@ -0,0 +1,38 @@ +From 3082990592f7c6d7510a9133afa46e31bbe26533 Mon Sep 17 00:00:00 2001 +From: Frank Li +Date: Tue, 1 Oct 2024 12:26:08 -0400 +Subject: i3c: master: Fix miss free init_dyn_addr at i3c_master_put_i3c_addrs() + +From: Frank Li + +commit 3082990592f7c6d7510a9133afa46e31bbe26533 upstream. + +if (dev->boardinfo && dev->boardinfo->init_dyn_addr) + ^^^ here check "init_dyn_addr" + i3c_bus_set_addr_slot_status(&master->bus, dev->info.dyn_addr, ...) + ^^^^ + free "dyn_addr" +Fix copy/paste error "dyn_addr" by replacing it with "init_dyn_addr". + +Cc: stable@kernel.org +Fixes: 3a379bbcea0a ("i3c: Add core I3C infrastructure") +Reviewed-by: Miquel Raynal +Signed-off-by: Frank Li +Link: https://lore.kernel.org/r/20241001162608.224039-1-Frank.Li@nxp.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Greg Kroah-Hartman +--- + drivers/i3c/master.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/i3c/master.c ++++ b/drivers/i3c/master.c +@@ -1285,7 +1285,7 @@ static void i3c_master_put_i3c_addrs(str + I3C_ADDR_SLOT_FREE); + + if (dev->boardinfo && dev->boardinfo->init_dyn_addr) +- i3c_bus_set_addr_slot_status(&master->bus, dev->info.dyn_addr, ++ i3c_bus_set_addr_slot_status(&master->bus, dev->boardinfo->init_dyn_addr, + I3C_ADDR_SLOT_FREE); + } + diff --git a/queue-5.10/pci-keystone-add-link-up-check-to-ks_pcie_other_map_bus.patch b/queue-5.10/pci-keystone-add-link-up-check-to-ks_pcie_other_map_bus.patch new file mode 100644 index 00000000000..8558e7ce8d1 --- /dev/null +++ b/queue-5.10/pci-keystone-add-link-up-check-to-ks_pcie_other_map_bus.patch @@ -0,0 +1,52 @@ +From 9e9ec8d8692a6f64d81ef67d4fb6255af6be684b Mon Sep 17 00:00:00 2001 +From: Kishon Vijay Abraham I +Date: Fri, 24 May 2024 16:27:14 +0530 +Subject: PCI: keystone: Add link up check to ks_pcie_other_map_bus() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Kishon Vijay Abraham I + +commit 9e9ec8d8692a6f64d81ef67d4fb6255af6be684b upstream. + +K2G forwards the error triggered by a link-down state (e.g., no connected +endpoint device) on the system bus for PCI configuration transactions; +these errors are reported as an SError at system level, which is fatal and +hangs the system. + +So, apply fix similar to how it was done in the DesignWare Core driver +commit 15b23906347c ("PCI: dwc: Add link up check in dw_child_pcie_ops.map_bus()"). + +Fixes: 10a797c6e54a ("PCI: dwc: keystone: Use pci_ops for config space accessors") +Link: https://lore.kernel.org/r/20240524105714.191642-3-s-vadapalli@ti.com +Signed-off-by: Kishon Vijay Abraham I +Signed-off-by: Siddharth Vadapalli +[kwilczynski: commit log, added tag for stable releases] +Signed-off-by: Krzysztof Wilczyński +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/dwc/pci-keystone.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/drivers/pci/controller/dwc/pci-keystone.c ++++ b/drivers/pci/controller/dwc/pci-keystone.c +@@ -446,6 +446,17 @@ static void __iomem *ks_pcie_other_map_b + struct keystone_pcie *ks_pcie = to_keystone_pcie(pci); + u32 reg; + ++ /* ++ * Checking whether the link is up here is a last line of defense ++ * against platforms that forward errors on the system bus as ++ * SError upon PCI configuration transactions issued when the link ++ * is down. This check is racy by definition and does not stop ++ * the system from triggering an SError if the link goes down ++ * after this check is performed. ++ */ ++ if (!dw_pcie_link_up(pci)) ++ return NULL; ++ + reg = CFG_BUS(bus->number) | CFG_DEVICE(PCI_SLOT(devfn)) | + CFG_FUNC(PCI_FUNC(devfn)); + if (!pci_is_root_bus(bus->parent)) diff --git a/queue-5.10/scsi-ufs-exynos-fix-hibern8-notify-callbacks.patch b/queue-5.10/scsi-ufs-exynos-fix-hibern8-notify-callbacks.patch new file mode 100644 index 00000000000..882beb87341 --- /dev/null +++ b/queue-5.10/scsi-ufs-exynos-fix-hibern8-notify-callbacks.patch @@ -0,0 +1,87 @@ +From ceef938bbf8b93ba3a218b4adc244cde94b582aa Mon Sep 17 00:00:00 2001 +From: Peter Griffin +Date: Thu, 31 Oct 2024 15:00:31 +0000 +Subject: scsi: ufs: exynos: Fix hibern8 notify callbacks + +From: Peter Griffin + +commit ceef938bbf8b93ba3a218b4adc244cde94b582aa upstream. + +v1 of the patch which introduced the ufshcd_vops_hibern8_notify() +callback used a bool instead of an enum. In v2 this was updated to an +enum based on the review feedback in [1]. + +ufs-exynos hibernate calls have always been broken upstream as it +follows the v1 bool implementation. + +Link: https://patchwork.kernel.org/project/linux-scsi/patch/001f01d23994$719997c0$54ccc740$@samsung.com/ [1] +Fixes: 55f4b1f73631 ("scsi: ufs: ufs-exynos: Add UFS host support for Exynos SoCs") +Signed-off-by: Peter Griffin +Link: https://lore.kernel.org/r/20241031150033.3440894-13-peter.griffin@linaro.org +Cc: stable@vger.kernel.org +Reviewed-by: Tudor Ambarus +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/ufs/ufs-exynos.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/drivers/scsi/ufs/ufs-exynos.c ++++ b/drivers/scsi/ufs/ufs-exynos.c +@@ -1051,12 +1051,12 @@ static void exynos_ufs_dev_hw_reset(stru + hci_writel(ufs, 1 << 0, HCI_GPIO_OUT); + } + +-static void exynos_ufs_pre_hibern8(struct ufs_hba *hba, u8 enter) ++static void exynos_ufs_pre_hibern8(struct ufs_hba *hba, enum uic_cmd_dme cmd) + { + struct exynos_ufs *ufs = ufshcd_get_variant(hba); + struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr; + +- if (!enter) { ++ if (cmd == UIC_CMD_DME_HIBER_EXIT) { + if (ufs->opts & EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL) + exynos_ufs_disable_auto_ctrl_hcc(ufs); + exynos_ufs_ungate_clks(ufs); +@@ -1084,11 +1084,11 @@ static void exynos_ufs_pre_hibern8(struc + } + } + +-static void exynos_ufs_post_hibern8(struct ufs_hba *hba, u8 enter) ++static void exynos_ufs_post_hibern8(struct ufs_hba *hba, enum uic_cmd_dme cmd) + { + struct exynos_ufs *ufs = ufshcd_get_variant(hba); + +- if (!enter) { ++ if (cmd == UIC_CMD_DME_HIBER_EXIT) { + u32 cur_mode = 0; + u32 pwrmode; + +@@ -1107,7 +1107,7 @@ static void exynos_ufs_post_hibern8(stru + + if (!(ufs->opts & EXYNOS_UFS_OPT_SKIP_CONNECTION_ESTAB)) + exynos_ufs_establish_connt(ufs); +- } else { ++ } else if (cmd == UIC_CMD_DME_HIBER_ENTER) { + ufs->entry_hibern8_t = ktime_get(); + exynos_ufs_gate_clks(ufs); + if (ufs->opts & EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL) +@@ -1176,15 +1176,15 @@ static int exynos_ufs_pwr_change_notify( + } + + static void exynos_ufs_hibern8_notify(struct ufs_hba *hba, +- enum uic_cmd_dme enter, ++ enum uic_cmd_dme cmd, + enum ufs_notify_change_status notify) + { + switch ((u8)notify) { + case PRE_CHANGE: +- exynos_ufs_pre_hibern8(hba, enter); ++ exynos_ufs_pre_hibern8(hba, cmd); + break; + case POST_CHANGE: +- exynos_ufs_post_hibern8(hba, enter); ++ exynos_ufs_post_hibern8(hba, cmd); + break; + } + } diff --git a/queue-5.10/series b/queue-5.10/series index 38c48f82d83..a765ca2318e 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -315,3 +315,7 @@ octeontx2-pf-fix-out-of-bounds-read-in-otx2_get_fecparam.patch quota-flush-quota_release_work-upon-quota-writeback.patch btrfs-ref-verify-fix-use-after-free-after-invalid-re.patch ad7780-fix-division-by-zero-in-ad7780_write_raw.patch +util_macros.h-fix-rework-find_closest-macros.patch +scsi-ufs-exynos-fix-hibern8-notify-callbacks.patch +i3c-master-fix-miss-free-init_dyn_addr-at-i3c_master_put_i3c_addrs.patch +pci-keystone-add-link-up-check-to-ks_pcie_other_map_bus.patch diff --git a/queue-5.10/util_macros.h-fix-rework-find_closest-macros.patch b/queue-5.10/util_macros.h-fix-rework-find_closest-macros.patch new file mode 100644 index 00000000000..1d5946f5c97 --- /dev/null +++ b/queue-5.10/util_macros.h-fix-rework-find_closest-macros.patch @@ -0,0 +1,188 @@ +From bc73b4186736341ab5cd2c199da82db6e1134e13 Mon Sep 17 00:00:00 2001 +From: Alexandru Ardelean +Date: Tue, 5 Nov 2024 16:54:05 +0200 +Subject: util_macros.h: fix/rework find_closest() macros + +From: Alexandru Ardelean + +commit bc73b4186736341ab5cd2c199da82db6e1134e13 upstream. + +A bug was found in the find_closest() (find_closest_descending() is also +affected after some testing), where for certain values with small +progressions, the rounding (done by averaging 2 values) causes an +incorrect index to be returned. The rounding issues occur for +progressions of 1, 2 and 3. It goes away when the progression/interval +between two values is 4 or larger. + +It's particularly bad for progressions of 1. For example if there's an +array of 'a = { 1, 2, 3 }', using 'find_closest(2, a ...)' would return 0 +(the index of '1'), rather than returning 1 (the index of '2'). This +means that for exact values (with a progression of 1), find_closest() will +misbehave and return the index of the value smaller than the one we're +searching for. + +For progressions of 2 and 3, the exact values are obtained correctly; but +values aren't approximated correctly (as one would expect). Starting with +progressions of 4, all seems to be good (one gets what one would expect). + +While one could argue that 'find_closest()' should not be used for arrays +with progressions of 1 (i.e. '{1, 2, 3, ...}', the macro should still +behave correctly. + +The bug was found while testing the 'drivers/iio/adc/ad7606.c', +specifically the oversampling feature. +For reference, the oversampling values are listed as: + static const unsigned int ad7606_oversampling_avail[7] = { + 1, 2, 4, 8, 16, 32, 64, + }; + +When doing: + 1. $ echo 1 > /sys/bus/iio/devices/iio\:device0/oversampling_ratio + $ cat /sys/bus/iio/devices/iio\:device0/oversampling_ratio + 1 # this is fine + 2. $ echo 2 > /sys/bus/iio/devices/iio\:device0/oversampling_ratio + $ cat /sys/bus/iio/devices/iio\:device0/oversampling_ratio + 1 # this is wrong; 2 should be returned here + 3. $ echo 3 > /sys/bus/iio/devices/iio\:device0/oversampling_ratio + $ cat /sys/bus/iio/devices/iio\:device0/oversampling_ratio + 2 # this is fine + 4. $ echo 4 > /sys/bus/iio/devices/iio\:device0/oversampling_ratio + $ cat /sys/bus/iio/devices/iio\:device0/oversampling_ratio + 4 # this is fine +And from here-on, the values are as correct (one gets what one would +expect.) + +While writing a kunit test for this bug, a peculiar issue was found for the +array in the 'drivers/hwmon/ina2xx.c' & 'drivers/iio/adc/ina2xx-adc.c' +drivers. While running the kunit test (for 'ina226_avg_tab' from these +drivers): + * idx = find_closest([-1 to 2], ina226_avg_tab, ARRAY_SIZE(ina226_avg_tab)); + This returns idx == 0, so value. + * idx = find_closest(3, ina226_avg_tab, ARRAY_SIZE(ina226_avg_tab)); + This returns idx == 0, value 1; and now one could argue whether 3 is + closer to 4 or to 1. This quirk only appears for value '3' in this + array, but it seems to be a another rounding issue. + * And from 4 onwards the 'find_closest'() works fine (one gets what one + would expect). + +This change reworks the find_closest() macros to also check the difference +between the left and right elements when 'x'. If the distance to the right +is smaller (than the distance to the left), the index is incremented by 1. +This also makes redundant the need for using the DIV_ROUND_CLOSEST() macro. + +In order to accommodate for any mix of negative + positive values, the +internal variables '__fc_x', '__fc_mid_x', '__fc_left' & '__fc_right' are +forced to 'long' type. This also addresses any potential bugs/issues with +'x' being of an unsigned type. In those situations any comparison between +signed & unsigned would be promoted to a comparison between 2 unsigned +numbers; this is especially annoying when '__fc_left' & '__fc_right' +underflow. + +The find_closest_descending() macro was also reworked and duplicated from +the find_closest(), and it is being iterated in reverse. The main reason +for this is to get the same indices as 'find_closest()' (but in reverse). +The comparison for '__fc_right < __fc_left' favors going the array in +ascending order. +For example for array '{ 1024, 512, 256, 128, 64, 16, 4, 1 }' and x = 3, we +get: + __fc_mid_x = 2 + __fc_left = -1 + __fc_right = -2 + Then '__fc_right < __fc_left' evaluates to true and '__fc_i++' becomes 7 + which is not quite incorrect, but 3 is closer to 4 than to 1. + +This change has been validated with the kunit from the next patch. + +Link: https://lkml.kernel.org/r/20241105145406.554365-1-aardelean@baylibre.com +Fixes: 95d119528b0b ("util_macros.h: add find_closest() macro") +Signed-off-by: Alexandru Ardelean +Cc: Bartosz Golaszewski +Cc: Greg Kroah-Hartman +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/util_macros.h | 56 +++++++++++++++++++++++++++++++------------- + 1 file changed, 40 insertions(+), 16 deletions(-) + +--- a/include/linux/util_macros.h ++++ b/include/linux/util_macros.h +@@ -2,19 +2,6 @@ + #ifndef _LINUX_HELPER_MACROS_H_ + #define _LINUX_HELPER_MACROS_H_ + +-#define __find_closest(x, a, as, op) \ +-({ \ +- typeof(as) __fc_i, __fc_as = (as) - 1; \ +- typeof(x) __fc_x = (x); \ +- typeof(*a) const *__fc_a = (a); \ +- for (__fc_i = 0; __fc_i < __fc_as; __fc_i++) { \ +- if (__fc_x op DIV_ROUND_CLOSEST(__fc_a[__fc_i] + \ +- __fc_a[__fc_i + 1], 2)) \ +- break; \ +- } \ +- (__fc_i); \ +-}) +- + /** + * find_closest - locate the closest element in a sorted array + * @x: The reference value. +@@ -23,8 +10,27 @@ + * @as: Size of 'a'. + * + * Returns the index of the element closest to 'x'. ++ * Note: If using an array of negative numbers (or mixed positive numbers), ++ * then be sure that 'x' is of a signed-type to get good results. + */ +-#define find_closest(x, a, as) __find_closest(x, a, as, <=) ++#define find_closest(x, a, as) \ ++({ \ ++ typeof(as) __fc_i, __fc_as = (as) - 1; \ ++ long __fc_mid_x, __fc_x = (x); \ ++ long __fc_left, __fc_right; \ ++ typeof(*a) const *__fc_a = (a); \ ++ for (__fc_i = 0; __fc_i < __fc_as; __fc_i++) { \ ++ __fc_mid_x = (__fc_a[__fc_i] + __fc_a[__fc_i + 1]) / 2; \ ++ if (__fc_x <= __fc_mid_x) { \ ++ __fc_left = __fc_x - __fc_a[__fc_i]; \ ++ __fc_right = __fc_a[__fc_i + 1] - __fc_x; \ ++ if (__fc_right < __fc_left) \ ++ __fc_i++; \ ++ break; \ ++ } \ ++ } \ ++ (__fc_i); \ ++}) + + /** + * find_closest_descending - locate the closest element in a sorted array +@@ -34,9 +40,27 @@ + * @as: Size of 'a'. + * + * Similar to find_closest() but 'a' is expected to be sorted in descending +- * order. ++ * order. The iteration is done in reverse order, so that the comparison ++ * of '__fc_right' & '__fc_left' also works for unsigned numbers. + */ +-#define find_closest_descending(x, a, as) __find_closest(x, a, as, >=) ++#define find_closest_descending(x, a, as) \ ++({ \ ++ typeof(as) __fc_i, __fc_as = (as) - 1; \ ++ long __fc_mid_x, __fc_x = (x); \ ++ long __fc_left, __fc_right; \ ++ typeof(*a) const *__fc_a = (a); \ ++ for (__fc_i = __fc_as; __fc_i >= 1; __fc_i--) { \ ++ __fc_mid_x = (__fc_a[__fc_i] + __fc_a[__fc_i - 1]) / 2; \ ++ if (__fc_x <= __fc_mid_x) { \ ++ __fc_left = __fc_x - __fc_a[__fc_i]; \ ++ __fc_right = __fc_a[__fc_i - 1] - __fc_x; \ ++ if (__fc_right < __fc_left) \ ++ __fc_i--; \ ++ break; \ ++ } \ ++ } \ ++ (__fc_i); \ ++}) + + /** + * is_insidevar - check if the @ptr points inside the @var memory range.