From 3c8679fe9fba8d9c139199782eb1067f6e233d88 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Mon, 9 Sep 2024 20:36:19 -0400 Subject: [PATCH] Fixes for 6.6 Signed-off-by: Sasha Levin --- ...ix-memory-leaks-in-error-paths-of-pr.patch | 83 ++ ...eturn-an-error-if-acpi_processor_get.patch | 44 + ...n-get_cpu_for_acpi_id-against-missin.patch | 46 ++ ...move-get_cpu_for_acpi_id-to-a-header.patch | 82 ++ ...y-clear-sof-link-platform-name-upon-.patch | 47 ++ ...i-i2s-fix-lrclk-polarity-in-i2s-mode.patch | 272 ++++++ ...soc-tegra-fix-cbb-error-during-probe.patch | 92 +++ ...check-ata_qcflag_rtf_filled-before-u.patch | 81 ++ ...remove-redundant-sense_buffer-memset.patch | 51 ++ ...xfd-clarify-the-meaning-of-timestamp.patch | 296 +++++++ ...p251xfd_handle_rxif_ring_uinc-factor.patch | 108 +++ ...-add-workaround-for-erratum-ds800007.patch | 146 ++++ ...-prepare-to-workaround-broken-rx-fif.patch | 255 ++++++ ...550-don-t-park-the-usb-rcg-at-regist.patch | 106 +++ ...550-don-t-use-parking-clk_ops-for-qu.patch | 285 +++++++ ...-update-the-alpha-pll-type-for-gplls.patch | 101 +++ ...rfive-align-rsa-input-data-to-32-bit.patch | 86 ++ ...rfive-fix-nent-assignment-in-rsa-dec.patch | 57 ++ .../drm-amd-add-gfx12-swizzle-mode-defs.patch | 63 ++ ...e-gfx12-in-amdgpu_display_verify_siz.patch | 84 ++ ...ark-debug_fence_free-with-__maybe_un.patch | 59 ++ ...ark-debug_fence_init_onstack-with-__.patch | 58 ++ ...io-modepin-enable-module-autoloading.patch | 37 + ...o-rockchip-fix-of-node-leak-in-probe.patch | 38 + ...llocate-tagset-on-reset-if-necessary.patch | 43 + ...rnel-crash-if-commands-allocation-fa.patch | 48 ++ ...erpc-64e-define-mmu_pte_psize-static.patch | 38 + ...werpc-64e-remove-unused-ibm-htw-code.patch | 380 +++++++++ ...-split-out-nohash-book3e-64-bit-code.patch | 773 ++++++++++++++++++ ...rpc-vdso-don-t-discard-rela-sections.patch | 73 ++ ...trict-memory-size-because-of-linear-.patch | 41 + ...riscv-fix-toolchain-vector-detection.patch | 44 + queue-6.6/series | 36 + ...ouble-put-of-cfile-in-smb2_rename_pa.patch | 39 + ...l-pointer-dereference-in-ublk_ctrl_s.patch | 69 ++ ...e-scalability-of-workqueue-watchdog-.patch | 77 ++ ...chdog_touch-is-always-called-with-va.patch | 36 + 37 files changed, 4274 insertions(+) create mode 100644 queue-6.6/acpi-processor-fix-memory-leaks-in-error-paths-of-pr.patch create mode 100644 queue-6.6/acpi-processor-return-an-error-if-acpi_processor_get.patch create mode 100644 queue-6.6/arm64-acpi-harden-get_cpu_for_acpi_id-against-missin.patch create mode 100644 queue-6.6/arm64-acpi-move-get_cpu_for_acpi_id-to-a-header.patch create mode 100644 queue-6.6/asoc-sof-topology-clear-sof-link-platform-name-upon-.patch create mode 100644 queue-6.6/asoc-sunxi-sun4i-i2s-fix-lrclk-polarity-in-i2s-mode.patch create mode 100644 queue-6.6/asoc-tegra-fix-cbb-error-during-probe.patch create mode 100644 queue-6.6/ata-libata-scsi-check-ata_qcflag_rtf_filled-before-u.patch create mode 100644 queue-6.6/ata-libata-scsi-remove-redundant-sense_buffer-memset.patch create mode 100644 queue-6.6/can-mcp251xfd-clarify-the-meaning-of-timestamp.patch create mode 100644 queue-6.6/can-mcp251xfd-mcp251xfd_handle_rxif_ring_uinc-factor.patch create mode 100644 queue-6.6/can-mcp251xfd-rx-add-workaround-for-erratum-ds800007.patch create mode 100644 queue-6.6/can-mcp251xfd-rx-prepare-to-workaround-broken-rx-fif.patch create mode 100644 queue-6.6/clk-qcom-gcc-sm8550-don-t-park-the-usb-rcg-at-regist.patch create mode 100644 queue-6.6/clk-qcom-gcc-sm8550-don-t-use-parking-clk_ops-for-qu.patch create mode 100644 queue-6.6/clk-qcom-ipq9574-update-the-alpha-pll-type-for-gplls.patch create mode 100644 queue-6.6/crypto-starfive-align-rsa-input-data-to-32-bit.patch create mode 100644 queue-6.6/crypto-starfive-fix-nent-assignment-in-rsa-dec.patch create mode 100644 queue-6.6/drm-amd-add-gfx12-swizzle-mode-defs.patch create mode 100644 queue-6.6/drm-amdgpu-handle-gfx12-in-amdgpu_display_verify_siz.patch create mode 100644 queue-6.6/drm-i915-fence-mark-debug_fence_free-with-__maybe_un.patch create mode 100644 queue-6.6/drm-i915-fence-mark-debug_fence_init_onstack-with-__.patch create mode 100644 queue-6.6/gpio-modepin-enable-module-autoloading.patch create mode 100644 queue-6.6/gpio-rockchip-fix-of-node-leak-in-probe.patch create mode 100644 queue-6.6/nvme-pci-allocate-tagset-on-reset-if-necessary.patch create mode 100644 queue-6.6/nvmet-tcp-fix-kernel-crash-if-commands-allocation-fa.patch create mode 100644 queue-6.6/powerpc-64e-define-mmu_pte_psize-static.patch create mode 100644 queue-6.6/powerpc-64e-remove-unused-ibm-htw-code.patch create mode 100644 queue-6.6/powerpc-64e-split-out-nohash-book3e-64-bit-code.patch create mode 100644 queue-6.6/powerpc-vdso-don-t-discard-rela-sections.patch create mode 100644 queue-6.6/riscv-do-not-restrict-memory-size-because-of-linear-.patch create mode 100644 queue-6.6/riscv-fix-toolchain-vector-detection.patch create mode 100644 queue-6.6/smb-client-fix-double-put-of-cfile-in-smb2_rename_pa.patch create mode 100644 queue-6.6/ublk_drv-fix-null-pointer-dereference-in-ublk_ctrl_s.patch create mode 100644 queue-6.6/workqueue-improve-scalability-of-workqueue-watchdog-.patch create mode 100644 queue-6.6/workqueue-wq_watchdog_touch-is-always-called-with-va.patch diff --git a/queue-6.6/acpi-processor-fix-memory-leaks-in-error-paths-of-pr.patch b/queue-6.6/acpi-processor-fix-memory-leaks-in-error-paths-of-pr.patch new file mode 100644 index 00000000000..dba1f80d8ab --- /dev/null +++ b/queue-6.6/acpi-processor-fix-memory-leaks-in-error-paths-of-pr.patch @@ -0,0 +1,83 @@ +From 8476f48348420777ebd36484841bc8158bce1630 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 May 2024 14:34:32 +0100 +Subject: ACPI: processor: Fix memory leaks in error paths of processor_add() + +From: Jonathan Cameron + +[ Upstream commit 47ec9b417ed9b6b8ec2a941cd84d9de62adc358a ] + +If acpi_processor_get_info() returned an error, pr and the associated +pr->throttling.shared_cpu_map were leaked. + +The unwind code was in the wrong order wrt to setup, relying on +some unwind actions having no affect (clearing variables that were +never set etc). That makes it harder to reason about so reorder +and add appropriate labels to only undo what was actually set up +in the first place. + +Acked-by: Rafael J. Wysocki +Reviewed-by: Gavin Shan +Signed-off-by: Jonathan Cameron +Link: https://lore.kernel.org/r/20240529133446.28446-6-Jonathan.Cameron@huawei.com +Signed-off-by: Catalin Marinas +Signed-off-by: Sasha Levin +--- + drivers/acpi/acpi_processor.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c +index 5f760bc62219..7053f1b9fc1d 100644 +--- a/drivers/acpi/acpi_processor.c ++++ b/drivers/acpi/acpi_processor.c +@@ -415,7 +415,7 @@ static int acpi_processor_add(struct acpi_device *device, + + result = acpi_processor_get_info(device); + if (result) /* Processor is not physically present or unavailable */ +- return result; ++ goto err_clear_driver_data; + + BUG_ON(pr->id >= nr_cpu_ids); + +@@ -430,7 +430,7 @@ static int acpi_processor_add(struct acpi_device *device, + "BIOS reported wrong ACPI id %d for the processor\n", + pr->id); + /* Give up, but do not abort the namespace scan. */ +- goto err; ++ goto err_clear_driver_data; + } + /* + * processor_device_array is not cleared on errors to allow buggy BIOS +@@ -442,12 +442,12 @@ static int acpi_processor_add(struct acpi_device *device, + dev = get_cpu_device(pr->id); + if (!dev) { + result = -ENODEV; +- goto err; ++ goto err_clear_per_cpu; + } + + result = acpi_bind_one(dev, device); + if (result) +- goto err; ++ goto err_clear_per_cpu; + + pr->dev = dev; + +@@ -458,10 +458,11 @@ static int acpi_processor_add(struct acpi_device *device, + dev_err(dev, "Processor driver could not be attached\n"); + acpi_unbind_one(dev); + +- err: +- free_cpumask_var(pr->throttling.shared_cpu_map); +- device->driver_data = NULL; ++ err_clear_per_cpu: + per_cpu(processors, pr->id) = NULL; ++ err_clear_driver_data: ++ device->driver_data = NULL; ++ free_cpumask_var(pr->throttling.shared_cpu_map); + err_free_pr: + kfree(pr); + return result; +-- +2.43.0 + diff --git a/queue-6.6/acpi-processor-return-an-error-if-acpi_processor_get.patch b/queue-6.6/acpi-processor-return-an-error-if-acpi_processor_get.patch new file mode 100644 index 00000000000..89921e6a296 --- /dev/null +++ b/queue-6.6/acpi-processor-return-an-error-if-acpi_processor_get.patch @@ -0,0 +1,44 @@ +From fecad7e9f49b78c919c6dee9dc7841cb6cc32b9d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 May 2024 14:34:31 +0100 +Subject: ACPI: processor: Return an error if acpi_processor_get_info() fails + in processor_add() + +From: Jonathan Cameron + +[ Upstream commit fadf231f0a06a6748a7fc4a2c29ac9ef7bca6bfd ] + +Rafael observed [1] that returning 0 from processor_add() will result in +acpi_default_enumeration() being called which will attempt to create a +platform device, but that makes little sense when the processor is known +to be not available. So just return the error code from acpi_processor_get_info() +instead. + +Link: https://lore.kernel.org/all/CAJZ5v0iKU8ra9jR+EmgxbuNm=Uwx2m1-8vn_RAZ+aCiUVLe3Pw@mail.gmail.com/ [1] +Suggested-by: Rafael J. Wysocki +Acked-by: Rafael J. Wysocki +Reviewed-by: Gavin Shan +Signed-off-by: Jonathan Cameron +Link: https://lore.kernel.org/r/20240529133446.28446-5-Jonathan.Cameron@huawei.com +Signed-off-by: Catalin Marinas +Signed-off-by: Sasha Levin +--- + drivers/acpi/acpi_processor.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c +index 0f5218e361df..5f760bc62219 100644 +--- a/drivers/acpi/acpi_processor.c ++++ b/drivers/acpi/acpi_processor.c +@@ -415,7 +415,7 @@ static int acpi_processor_add(struct acpi_device *device, + + result = acpi_processor_get_info(device); + if (result) /* Processor is not physically present or unavailable */ +- return 0; ++ return result; + + BUG_ON(pr->id >= nr_cpu_ids); + +-- +2.43.0 + diff --git a/queue-6.6/arm64-acpi-harden-get_cpu_for_acpi_id-against-missin.patch b/queue-6.6/arm64-acpi-harden-get_cpu_for_acpi_id-against-missin.patch new file mode 100644 index 00000000000..d306c832b07 --- /dev/null +++ b/queue-6.6/arm64-acpi-harden-get_cpu_for_acpi_id-against-missin.patch @@ -0,0 +1,46 @@ +From 56e68fd0af2a34acf6517b9d4d820442c614f7b7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 May 2024 14:34:39 +0100 +Subject: arm64: acpi: Harden get_cpu_for_acpi_id() against missing CPU entry + +From: Jonathan Cameron + +[ Upstream commit 2488444274c70038eb6b686cba5f1ce48ebb9cdd ] + +In a review discussion of the changes to support vCPU hotplug where +a check was added on the GICC being enabled if was online, it was +noted that there is need to map back to the cpu and use that to index +into a cpumask. As such, a valid ID is needed. + +If an MPIDR check fails in acpi_map_gic_cpu_interface() it is possible +for the entry in cpu_madt_gicc[cpu] == NULL. This function would +then cause a NULL pointer dereference. Whilst a path to trigger +this has not been established, harden this caller against the +possibility. + +Reviewed-by: Gavin Shan +Signed-off-by: Jonathan Cameron +Link: https://lore.kernel.org/r/20240529133446.28446-13-Jonathan.Cameron@huawei.com +Signed-off-by: Catalin Marinas +Signed-off-by: Sasha Levin +--- + arch/arm64/include/asm/acpi.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h +index bc9a6656fc0c..a407f9cd549e 100644 +--- a/arch/arm64/include/asm/acpi.h ++++ b/arch/arm64/include/asm/acpi.h +@@ -124,7 +124,8 @@ static inline int get_cpu_for_acpi_id(u32 uid) + int cpu; + + for (cpu = 0; cpu < nr_cpu_ids; cpu++) +- if (uid == get_acpi_id_for_cpu(cpu)) ++ if (acpi_cpu_get_madt_gicc(cpu) && ++ uid == get_acpi_id_for_cpu(cpu)) + return cpu; + + return -EINVAL; +-- +2.43.0 + diff --git a/queue-6.6/arm64-acpi-move-get_cpu_for_acpi_id-to-a-header.patch b/queue-6.6/arm64-acpi-move-get_cpu_for_acpi_id-to-a-header.patch new file mode 100644 index 00000000000..e1791e25a6c --- /dev/null +++ b/queue-6.6/arm64-acpi-move-get_cpu_for_acpi_id-to-a-header.patch @@ -0,0 +1,82 @@ +From b72e13006aa037d1439d3f90c362413d58d694fb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 May 2024 14:34:38 +0100 +Subject: arm64: acpi: Move get_cpu_for_acpi_id() to a header + +From: James Morse + +[ Upstream commit 8d34b6f17b9ac93faa2791eb037dcb08bdf755de ] + +ACPI identifies CPUs by UID. get_cpu_for_acpi_id() maps the ACPI UID +to the Linux CPU number. + +The helper to retrieve this mapping is only available in arm64's NUMA +code. + +Move it to live next to get_acpi_id_for_cpu(). + +Signed-off-by: James Morse +Reviewed-by: Jonathan Cameron +Reviewed-by: Gavin Shan +Tested-by: Miguel Luis +Tested-by: Vishnu Pajjuri +Tested-by: Jianyong Wu +Signed-off-by: Russell King (Oracle) +Acked-by: Hanjun Guo +Signed-off-by: Jonathan Cameron +Reviewed-by: Lorenzo Pieralisi +Link: https://lore.kernel.org/r/20240529133446.28446-12-Jonathan.Cameron@huawei.com +Signed-off-by: Catalin Marinas +Signed-off-by: Sasha Levin +--- + arch/arm64/include/asm/acpi.h | 11 +++++++++++ + arch/arm64/kernel/acpi_numa.c | 11 ----------- + 2 files changed, 11 insertions(+), 11 deletions(-) + +diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h +index 6792a1f83f2a..bc9a6656fc0c 100644 +--- a/arch/arm64/include/asm/acpi.h ++++ b/arch/arm64/include/asm/acpi.h +@@ -119,6 +119,17 @@ static inline u32 get_acpi_id_for_cpu(unsigned int cpu) + return acpi_cpu_get_madt_gicc(cpu)->uid; + } + ++static inline int get_cpu_for_acpi_id(u32 uid) ++{ ++ int cpu; ++ ++ for (cpu = 0; cpu < nr_cpu_ids; cpu++) ++ if (uid == get_acpi_id_for_cpu(cpu)) ++ return cpu; ++ ++ return -EINVAL; ++} ++ + static inline void arch_fix_phys_package_id(int num, u32 slot) { } + void __init acpi_init_cpus(void); + int apei_claim_sea(struct pt_regs *regs); +diff --git a/arch/arm64/kernel/acpi_numa.c b/arch/arm64/kernel/acpi_numa.c +index ccbff21ce1fa..2465f291c7e1 100644 +--- a/arch/arm64/kernel/acpi_numa.c ++++ b/arch/arm64/kernel/acpi_numa.c +@@ -34,17 +34,6 @@ int __init acpi_numa_get_nid(unsigned int cpu) + return acpi_early_node_map[cpu]; + } + +-static inline int get_cpu_for_acpi_id(u32 uid) +-{ +- int cpu; +- +- for (cpu = 0; cpu < nr_cpu_ids; cpu++) +- if (uid == get_acpi_id_for_cpu(cpu)) +- return cpu; +- +- return -EINVAL; +-} +- + static int __init acpi_parse_gicc_pxm(union acpi_subtable_headers *header, + const unsigned long end) + { +-- +2.43.0 + diff --git a/queue-6.6/asoc-sof-topology-clear-sof-link-platform-name-upon-.patch b/queue-6.6/asoc-sof-topology-clear-sof-link-platform-name-upon-.patch new file mode 100644 index 00000000000..e3fe45a202e --- /dev/null +++ b/queue-6.6/asoc-sof-topology-clear-sof-link-platform-name-upon-.patch @@ -0,0 +1,47 @@ +From c963aa883ea3a8cf7425e1b24617ee12f2f60132 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Aug 2024 12:10:04 +0800 +Subject: ASoc: SOF: topology: Clear SOF link platform name upon unload + +From: Chen-Yu Tsai + +[ Upstream commit e0be875c5bf03a9676a6bfed9e0f1766922a7dbd ] + +The SOF topology loading function sets the device name for the platform +component link. This should be unset when unloading the topology, +otherwise a machine driver unbind/bind or reprobe would complain about +an invalid component as having both its component name and of_node set: + + mt8186_mt6366 sound: ASoC: Both Component name/of_node are set for AFE_SOF_DL1 + mt8186_mt6366 sound: error -EINVAL: Cannot register card + mt8186_mt6366 sound: probe with driver mt8186_mt6366 failed with error -22 + +This happens with machine drivers that set the of_node separately. + +Clear the SOF link platform name in the topology unload callback. + +Fixes: 311ce4fe7637 ("ASoC: SOF: Add support for loading topologies") +Signed-off-by: Chen-Yu Tsai +Link: https://patch.msgid.link/20240821041006.2618855-1-wenst@chromium.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/sof/topology.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c +index 7133ec13322b..cf1e63daad86 100644 +--- a/sound/soc/sof/topology.c ++++ b/sound/soc/sof/topology.c +@@ -2040,6 +2040,8 @@ static int sof_link_unload(struct snd_soc_component *scomp, struct snd_soc_dobj + if (!slink) + return 0; + ++ slink->link->platforms->name = NULL; ++ + kfree(slink->tuples); + list_del(&slink->list); + kfree(slink->hw_configs); +-- +2.43.0 + diff --git a/queue-6.6/asoc-sunxi-sun4i-i2s-fix-lrclk-polarity-in-i2s-mode.patch b/queue-6.6/asoc-sunxi-sun4i-i2s-fix-lrclk-polarity-in-i2s-mode.patch new file mode 100644 index 00000000000..077e9d7aa9c --- /dev/null +++ b/queue-6.6/asoc-sunxi-sun4i-i2s-fix-lrclk-polarity-in-i2s-mode.patch @@ -0,0 +1,272 @@ +From b065b7523b2dda0d6d9c1424888d4f6c0325719b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 1 Aug 2024 14:07:19 +0200 +Subject: ASoC: sunxi: sun4i-i2s: fix LRCLK polarity in i2s mode + +From: Matteo Martelli + +[ Upstream commit 3e83957e8dd7433a69116780d9bad217b00913ea ] + +This fixes the LRCLK polarity for sun8i-h3 and sun50i-h6 in i2s mode +which was wrongly inverted. + +The LRCLK was being set in reversed logic compared to the DAI format: +inverted LRCLK for SND_SOC_DAIFMT_IB_NF and SND_SOC_DAIFMT_NB_NF; normal +LRCLK for SND_SOC_DAIFMT_IB_IF and SND_SOC_DAIFMT_NB_IF. Such reversed +logic applies properly for DSP_A, DSP_B, LEFT_J and RIGHT_J modes but +not for I2S mode, for which the LRCLK signal results reversed to what +expected on the bus. The issue is due to a misinterpretation of the +LRCLK polarity bit of the H3 and H6 i2s controllers. Such bit in this +case does not mean "0 => normal" or "1 => inverted" according to the +expected bus operation, but it means "0 => frame starts on low edge" and +"1 => frame starts on high edge" (from the User Manuals). + +This commit fixes the LRCLK polarity by setting the LRCLK polarity bit +according to the selected bus mode and renames the LRCLK polarity bit +definition to avoid further confusion. + +Fixes: dd657eae8164 ("ASoC: sun4i-i2s: Fix the LRCK polarity") +Fixes: 73adf87b7a58 ("ASoC: sun4i-i2s: Add support for H6 I2S") +Signed-off-by: Matteo Martelli +Link: https://patch.msgid.link/20240801-asoc-fix-sun4i-i2s-v2-1-a8e4e9daa363@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/sunxi/sun4i-i2s.c | 143 ++++++++++++++++++------------------ + 1 file changed, 73 insertions(+), 70 deletions(-) + +diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c +index 5124b6c9ceb4..d1cb49d54f00 100644 +--- a/sound/soc/sunxi/sun4i-i2s.c ++++ b/sound/soc/sunxi/sun4i-i2s.c +@@ -100,8 +100,8 @@ + #define SUN8I_I2S_CTRL_MODE_PCM (0 << 4) + + #define SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK BIT(19) +-#define SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED (1 << 19) +-#define SUN8I_I2S_FMT0_LRCLK_POLARITY_NORMAL (0 << 19) ++#define SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH (1 << 19) ++#define SUN8I_I2S_FMT0_LRCLK_POLARITY_START_LOW (0 << 19) + #define SUN8I_I2S_FMT0_LRCK_PERIOD_MASK GENMASK(17, 8) + #define SUN8I_I2S_FMT0_LRCK_PERIOD(period) ((period - 1) << 8) + #define SUN8I_I2S_FMT0_BCLK_POLARITY_MASK BIT(7) +@@ -727,65 +727,37 @@ static int sun4i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s, + static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s, + unsigned int fmt) + { +- u32 mode, val; ++ u32 mode, lrclk_pol, bclk_pol, val; + u8 offset; + +- /* +- * DAI clock polarity +- * +- * The setup for LRCK contradicts the datasheet, but under a +- * scope it's clear that the LRCK polarity is reversed +- * compared to the expected polarity on the bus. +- */ +- switch (fmt & SND_SOC_DAIFMT_INV_MASK) { +- case SND_SOC_DAIFMT_IB_IF: +- /* Invert both clocks */ +- val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED; +- break; +- case SND_SOC_DAIFMT_IB_NF: +- /* Invert bit clock */ +- val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED | +- SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED; +- break; +- case SND_SOC_DAIFMT_NB_IF: +- /* Invert frame clock */ +- val = 0; +- break; +- case SND_SOC_DAIFMT_NB_NF: +- val = SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED; +- break; +- default: +- return -EINVAL; +- } +- +- regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG, +- SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK | +- SUN8I_I2S_FMT0_BCLK_POLARITY_MASK, +- val); +- + /* DAI Mode */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: ++ lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH; + mode = SUN8I_I2S_CTRL_MODE_PCM; + offset = 1; + break; + + case SND_SOC_DAIFMT_DSP_B: ++ lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH; + mode = SUN8I_I2S_CTRL_MODE_PCM; + offset = 0; + break; + + case SND_SOC_DAIFMT_I2S: ++ lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_LOW; + mode = SUN8I_I2S_CTRL_MODE_LEFT; + offset = 1; + break; + + case SND_SOC_DAIFMT_LEFT_J: ++ lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH; + mode = SUN8I_I2S_CTRL_MODE_LEFT; + offset = 0; + break; + + case SND_SOC_DAIFMT_RIGHT_J: ++ lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH; + mode = SUN8I_I2S_CTRL_MODE_RIGHT; + offset = 0; + break; +@@ -803,6 +775,35 @@ static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s, + SUN8I_I2S_TX_CHAN_OFFSET_MASK, + SUN8I_I2S_TX_CHAN_OFFSET(offset)); + ++ /* DAI clock polarity */ ++ bclk_pol = SUN8I_I2S_FMT0_BCLK_POLARITY_NORMAL; ++ ++ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { ++ case SND_SOC_DAIFMT_IB_IF: ++ /* Invert both clocks */ ++ lrclk_pol ^= SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK; ++ bclk_pol = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED; ++ break; ++ case SND_SOC_DAIFMT_IB_NF: ++ /* Invert bit clock */ ++ bclk_pol = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED; ++ break; ++ case SND_SOC_DAIFMT_NB_IF: ++ /* Invert frame clock */ ++ lrclk_pol ^= SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK; ++ break; ++ case SND_SOC_DAIFMT_NB_NF: ++ /* No inversion */ ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG, ++ SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK | ++ SUN8I_I2S_FMT0_BCLK_POLARITY_MASK, ++ lrclk_pol | bclk_pol); ++ + /* DAI clock master masks */ + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BP_FP: +@@ -834,65 +835,37 @@ static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s, + static int sun50i_h6_i2s_set_soc_fmt(const struct sun4i_i2s *i2s, + unsigned int fmt) + { +- u32 mode, val; ++ u32 mode, lrclk_pol, bclk_pol, val; + u8 offset; + +- /* +- * DAI clock polarity +- * +- * The setup for LRCK contradicts the datasheet, but under a +- * scope it's clear that the LRCK polarity is reversed +- * compared to the expected polarity on the bus. +- */ +- switch (fmt & SND_SOC_DAIFMT_INV_MASK) { +- case SND_SOC_DAIFMT_IB_IF: +- /* Invert both clocks */ +- val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED; +- break; +- case SND_SOC_DAIFMT_IB_NF: +- /* Invert bit clock */ +- val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED | +- SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED; +- break; +- case SND_SOC_DAIFMT_NB_IF: +- /* Invert frame clock */ +- val = 0; +- break; +- case SND_SOC_DAIFMT_NB_NF: +- val = SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED; +- break; +- default: +- return -EINVAL; +- } +- +- regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG, +- SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK | +- SUN8I_I2S_FMT0_BCLK_POLARITY_MASK, +- val); +- + /* DAI Mode */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: ++ lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH; + mode = SUN8I_I2S_CTRL_MODE_PCM; + offset = 1; + break; + + case SND_SOC_DAIFMT_DSP_B: ++ lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH; + mode = SUN8I_I2S_CTRL_MODE_PCM; + offset = 0; + break; + + case SND_SOC_DAIFMT_I2S: ++ lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_LOW; + mode = SUN8I_I2S_CTRL_MODE_LEFT; + offset = 1; + break; + + case SND_SOC_DAIFMT_LEFT_J: ++ lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH; + mode = SUN8I_I2S_CTRL_MODE_LEFT; + offset = 0; + break; + + case SND_SOC_DAIFMT_RIGHT_J: ++ lrclk_pol = SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH; + mode = SUN8I_I2S_CTRL_MODE_RIGHT; + offset = 0; + break; +@@ -910,6 +883,36 @@ static int sun50i_h6_i2s_set_soc_fmt(const struct sun4i_i2s *i2s, + SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK, + SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset)); + ++ /* DAI clock polarity */ ++ bclk_pol = SUN8I_I2S_FMT0_BCLK_POLARITY_NORMAL; ++ ++ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { ++ case SND_SOC_DAIFMT_IB_IF: ++ /* Invert both clocks */ ++ lrclk_pol ^= SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK; ++ bclk_pol = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED; ++ break; ++ case SND_SOC_DAIFMT_IB_NF: ++ /* Invert bit clock */ ++ bclk_pol = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED; ++ break; ++ case SND_SOC_DAIFMT_NB_IF: ++ /* Invert frame clock */ ++ lrclk_pol ^= SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK; ++ break; ++ case SND_SOC_DAIFMT_NB_NF: ++ /* No inversion */ ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG, ++ SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK | ++ SUN8I_I2S_FMT0_BCLK_POLARITY_MASK, ++ lrclk_pol | bclk_pol); ++ ++ + /* DAI clock master masks */ + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BP_FP: +-- +2.43.0 + diff --git a/queue-6.6/asoc-tegra-fix-cbb-error-during-probe.patch b/queue-6.6/asoc-tegra-fix-cbb-error-during-probe.patch new file mode 100644 index 00000000000..e7f1b117f94 --- /dev/null +++ b/queue-6.6/asoc-tegra-fix-cbb-error-during-probe.patch @@ -0,0 +1,92 @@ +From 4c12d6162b46478dab68654f8d458044f8e7722d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 Aug 2024 14:43:42 +0000 +Subject: ASoC: tegra: Fix CBB error during probe() + +From: Mohan Kumar + +[ Upstream commit 6781b962d97bc52715a8db8cc17278cc3c23ebe8 ] + +When Tegra audio drivers are built as part of the kernel image, +TIMEOUT_ERR is observed from cbb-fabric. Following is seen on +Jetson AGX Orin during boot: + +[ 8.012482] ************************************** +[ 8.017423] CPU:0, Error:cbb-fabric, Errmon:2 +[ 8.021922] Error Code : TIMEOUT_ERR +[ 8.025966] Overflow : Multiple TIMEOUT_ERR +[ 8.030644] +[ 8.032175] Error Code : TIMEOUT_ERR +[ 8.036217] MASTER_ID : CCPLEX +[ 8.039722] Address : 0x290a0a8 +[ 8.043318] Cache : 0x1 -- Bufferable +[ 8.047630] Protection : 0x2 -- Unprivileged, Non-Secure, Data Access +[ 8.054628] Access_Type : Write + +[ 8.106130] WARNING: CPU: 0 PID: 124 at drivers/soc/tegra/cbb/tegra234-cbb.c:604 tegra234_cbb_isr+0x134/0x178 + +[ 8.240602] Call trace: +[ 8.243126] tegra234_cbb_isr+0x134/0x178 +[ 8.247261] __handle_irq_event_percpu+0x60/0x238 +[ 8.252132] handle_irq_event+0x54/0xb8 + +These errors happen when MVC device, which is a child of AHUB +device, tries to access its device registers. This happens as +part of call tegra210_mvc_reset_vol_settings() in MVC device +probe(). + +The root cause of this problem is, the child MVC device gets +probed before the AHUB clock gets enabled. The AHUB clock is +enabled in runtime PM resume of parent AHUB device and due to +the wrong sequence of pm_runtime_enable() in AHUB driver, +runtime PM resume doesn't happen for AHUB device when MVC makes +register access. + +Fix this by calling pm_runtime_enable() for parent AHUB device +before of_platform_populate() in AHUB driver. This ensures that +clock becomes available when MVC makes register access. + +Fixes: 16e1bcc2caf4 ("ASoC: tegra: Add Tegra210 based AHUB driver") +Signed-off-by: Mohan Kumar +Signed-off-by: Ritu Chaudhary +Signed-off-by: Sameer Pujar +Link: https://patch.msgid.link/20240823144342.4123814-3-spujar@nvidia.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/tegra/tegra210_ahub.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/sound/soc/tegra/tegra210_ahub.c b/sound/soc/tegra/tegra210_ahub.c +index 3f114a2adfce..ab3c6b2544d2 100644 +--- a/sound/soc/tegra/tegra210_ahub.c ++++ b/sound/soc/tegra/tegra210_ahub.c +@@ -2,7 +2,7 @@ + // + // tegra210_ahub.c - Tegra210 AHUB driver + // +-// Copyright (c) 2020-2022, NVIDIA CORPORATION. All rights reserved. ++// Copyright (c) 2020-2024, NVIDIA CORPORATION. All rights reserved. + + #include + #include +@@ -1391,11 +1391,13 @@ static int tegra_ahub_probe(struct platform_device *pdev) + return err; + } + ++ pm_runtime_enable(&pdev->dev); ++ + err = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); +- if (err) ++ if (err) { ++ pm_runtime_disable(&pdev->dev); + return err; +- +- pm_runtime_enable(&pdev->dev); ++ } + + return 0; + } +-- +2.43.0 + diff --git a/queue-6.6/ata-libata-scsi-check-ata_qcflag_rtf_filled-before-u.patch b/queue-6.6/ata-libata-scsi-check-ata_qcflag_rtf_filled-before-u.patch new file mode 100644 index 00000000000..ffd8bdac417 --- /dev/null +++ b/queue-6.6/ata-libata-scsi-check-ata_qcflag_rtf_filled-before-u.patch @@ -0,0 +1,81 @@ +From d7b1d425d26e98eaa851318c5deabd4806c5d59a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 Jul 2024 02:47:35 +0000 +Subject: ata: libata-scsi: Check ATA_QCFLAG_RTF_FILLED before using result_tf + +From: Igor Pylypiv + +[ Upstream commit 816be86c7993d3c5832c3017c0056297e86f978c ] + +qc->result_tf contents are only valid when the ATA_QCFLAG_RTF_FILLED flag +is set. The ATA_QCFLAG_RTF_FILLED flag should be always set for commands +that failed or for commands that have the ATA_QCFLAG_RESULT_TF flag set. + +Reviewed-by: Hannes Reinecke +Reviewed-by: Damien Le Moal +Reviewed-by: Niklas Cassel +Signed-off-by: Igor Pylypiv +Link: https://lore.kernel.org/r/20240702024735.1152293-8-ipylypiv@google.com +Signed-off-by: Niklas Cassel +Signed-off-by: Sasha Levin +--- + drivers/ata/libata-scsi.c | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c +index 27e0c87236ac..c91f8746289f 100644 +--- a/drivers/ata/libata-scsi.c ++++ b/drivers/ata/libata-scsi.c +@@ -242,10 +242,17 @@ void ata_scsi_set_sense_information(struct ata_device *dev, + */ + static void ata_scsi_set_passthru_sense_fields(struct ata_queued_cmd *qc) + { ++ struct ata_device *dev = qc->dev; + struct scsi_cmnd *cmd = qc->scsicmd; + struct ata_taskfile *tf = &qc->result_tf; + unsigned char *sb = cmd->sense_buffer; + ++ if (!(qc->flags & ATA_QCFLAG_RTF_FILLED)) { ++ ata_dev_dbg(dev, ++ "missing result TF: can't set ATA PT sense fields\n"); ++ return; ++ } ++ + if ((sb[0] & 0x7f) >= 0x72) { + unsigned char *desc; + u8 len; +@@ -924,10 +931,17 @@ static void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, + */ + static void ata_gen_passthru_sense(struct ata_queued_cmd *qc) + { ++ struct ata_device *dev = qc->dev; + struct scsi_cmnd *cmd = qc->scsicmd; + struct ata_taskfile *tf = &qc->result_tf; + u8 sense_key, asc, ascq; + ++ if (!(qc->flags & ATA_QCFLAG_RTF_FILLED)) { ++ ata_dev_dbg(dev, ++ "missing result TF: can't generate ATA PT sense data\n"); ++ return; ++ } ++ + /* + * Use ata_to_sense_error() to map status register bits + * onto sense key, asc & ascq. +@@ -979,6 +993,13 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc) + ata_scsi_set_sense(dev, cmd, NOT_READY, 0x04, 0x21); + return; + } ++ ++ if (!(qc->flags & ATA_QCFLAG_RTF_FILLED)) { ++ ata_dev_dbg(dev, ++ "missing result TF: can't generate sense data\n"); ++ return; ++ } ++ + /* Use ata_to_sense_error() to map status register bits + * onto sense key, asc & ascq. + */ +-- +2.43.0 + diff --git a/queue-6.6/ata-libata-scsi-remove-redundant-sense_buffer-memset.patch b/queue-6.6/ata-libata-scsi-remove-redundant-sense_buffer-memset.patch new file mode 100644 index 00000000000..3629c5bd71d --- /dev/null +++ b/queue-6.6/ata-libata-scsi-remove-redundant-sense_buffer-memset.patch @@ -0,0 +1,51 @@ +From 0ba8d14a4da3911cc47823206f101e74af2b89d9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 Jul 2024 02:47:32 +0000 +Subject: ata: libata-scsi: Remove redundant sense_buffer memsets + +From: Igor Pylypiv + +[ Upstream commit 3f6d903b54a137e9e438d9c3b774b5d0432917bc ] + +SCSI layer clears sense_buffer in scsi_queue_rq() so there is no need for +libata to clear it again. + +Reviewed-by: Hannes Reinecke +Reviewed-by: Damien Le Moal +Reviewed-by: Niklas Cassel +Signed-off-by: Igor Pylypiv +Link: https://lore.kernel.org/r/20240702024735.1152293-5-ipylypiv@google.com +Signed-off-by: Niklas Cassel +Signed-off-by: Sasha Levin +--- + drivers/ata/libata-scsi.c | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c +index 277bf0e8ed09..27e0c87236ac 100644 +--- a/drivers/ata/libata-scsi.c ++++ b/drivers/ata/libata-scsi.c +@@ -926,11 +926,8 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc) + { + struct scsi_cmnd *cmd = qc->scsicmd; + struct ata_taskfile *tf = &qc->result_tf; +- unsigned char *sb = cmd->sense_buffer; + u8 sense_key, asc, ascq; + +- memset(sb, 0, SCSI_SENSE_BUFFERSIZE); +- + /* + * Use ata_to_sense_error() to map status register bits + * onto sense key, asc & ascq. +@@ -976,8 +973,6 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc) + u64 block; + u8 sense_key, asc, ascq; + +- memset(sb, 0, SCSI_SENSE_BUFFERSIZE); +- + if (ata_dev_disabled(dev)) { + /* Device disabled after error recovery */ + /* LOGICAL UNIT NOT READY, HARD RESET REQUIRED */ +-- +2.43.0 + diff --git a/queue-6.6/can-mcp251xfd-clarify-the-meaning-of-timestamp.patch b/queue-6.6/can-mcp251xfd-clarify-the-meaning-of-timestamp.patch new file mode 100644 index 00000000000..948ec6aff03 --- /dev/null +++ b/queue-6.6/can-mcp251xfd-clarify-the-meaning-of-timestamp.patch @@ -0,0 +1,296 @@ +From 0a789d4e09b508b6cd10847e720d149b985c5f24 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Jan 2023 11:48:16 +0100 +Subject: can: mcp251xfd: clarify the meaning of timestamp +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Marc Kleine-Budde + +[ Upstream commit e793c724b48ca8cae9693bc3be528e85284c126a ] + +The mcp251xfd chip is configured to provide a timestamp with each +received and transmitted CAN frame. The timestamp is derived from the +internal free-running timer, which can also be read from the TBC +register via SPI. The timer is 32 bits wide and is clocked by the +external oscillator (typically 20 or 40 MHz). + +To avoid confusion, we call this timestamp "timestamp_raw" or "ts_raw" +for short. + +Using the timecounter framework, the "ts_raw" is converted to 64 bit +nanoseconds since the epoch. This is what we call "timestamp". + +This is a preparation for the next patches which use the "timestamp" +to work around a bug where so far only the "ts_raw" is used. + +Tested-by: Stefan Althöfer +Tested-by: Thomas Kopp +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + .../net/can/spi/mcp251xfd/mcp251xfd-core.c | 28 +++++++++---------- + drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c | 2 +- + drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c | 2 +- + .../can/spi/mcp251xfd/mcp251xfd-timestamp.c | 22 ++++----------- + drivers/net/can/spi/mcp251xfd/mcp251xfd.h | 27 ++++++++++++++---- + 5 files changed, 43 insertions(+), 38 deletions(-) + +diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +index 1665f78abb5c..a9bafa96e2f9 100644 +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +@@ -2,7 +2,7 @@ + // + // mcp251xfd - Microchip MCP251xFD Family CAN controller driver + // +-// Copyright (c) 2019, 2020, 2021 Pengutronix, ++// Copyright (c) 2019, 2020, 2021, 2023 Pengutronix, + // Marc Kleine-Budde + // + // Based on: +@@ -867,18 +867,18 @@ static int mcp251xfd_get_berr_counter(const struct net_device *ndev, + + static struct sk_buff * + mcp251xfd_alloc_can_err_skb(struct mcp251xfd_priv *priv, +- struct can_frame **cf, u32 *timestamp) ++ struct can_frame **cf, u32 *ts_raw) + { + struct sk_buff *skb; + int err; + +- err = mcp251xfd_get_timestamp(priv, timestamp); ++ err = mcp251xfd_get_timestamp_raw(priv, ts_raw); + if (err) + return NULL; + + skb = alloc_can_err_skb(priv->ndev, cf); + if (skb) +- mcp251xfd_skb_set_timestamp(priv, skb, *timestamp); ++ mcp251xfd_skb_set_timestamp_raw(priv, skb, *ts_raw); + + return skb; + } +@@ -889,7 +889,7 @@ static int mcp251xfd_handle_rxovif(struct mcp251xfd_priv *priv) + struct mcp251xfd_rx_ring *ring; + struct sk_buff *skb; + struct can_frame *cf; +- u32 timestamp, rxovif; ++ u32 ts_raw, rxovif; + int err, i; + + stats->rx_over_errors++; +@@ -924,14 +924,14 @@ static int mcp251xfd_handle_rxovif(struct mcp251xfd_priv *priv) + return err; + } + +- skb = mcp251xfd_alloc_can_err_skb(priv, &cf, ×tamp); ++ skb = mcp251xfd_alloc_can_err_skb(priv, &cf, &ts_raw); + if (!skb) + return 0; + + cf->can_id |= CAN_ERR_CRTL; + cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; + +- err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp); ++ err = can_rx_offload_queue_timestamp(&priv->offload, skb, ts_raw); + if (err) + stats->rx_fifo_errors++; + +@@ -948,12 +948,12 @@ static int mcp251xfd_handle_txatif(struct mcp251xfd_priv *priv) + static int mcp251xfd_handle_ivmif(struct mcp251xfd_priv *priv) + { + struct net_device_stats *stats = &priv->ndev->stats; +- u32 bdiag1, timestamp; ++ u32 bdiag1, ts_raw; + struct sk_buff *skb; + struct can_frame *cf = NULL; + int err; + +- err = mcp251xfd_get_timestamp(priv, ×tamp); ++ err = mcp251xfd_get_timestamp_raw(priv, &ts_raw); + if (err) + return err; + +@@ -1035,8 +1035,8 @@ static int mcp251xfd_handle_ivmif(struct mcp251xfd_priv *priv) + if (!cf) + return 0; + +- mcp251xfd_skb_set_timestamp(priv, skb, timestamp); +- err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp); ++ mcp251xfd_skb_set_timestamp_raw(priv, skb, ts_raw); ++ err = can_rx_offload_queue_timestamp(&priv->offload, skb, ts_raw); + if (err) + stats->rx_fifo_errors++; + +@@ -1049,7 +1049,7 @@ static int mcp251xfd_handle_cerrif(struct mcp251xfd_priv *priv) + struct sk_buff *skb; + struct can_frame *cf = NULL; + enum can_state new_state, rx_state, tx_state; +- u32 trec, timestamp; ++ u32 trec, ts_raw; + int err; + + err = regmap_read(priv->map_reg, MCP251XFD_REG_TREC, &trec); +@@ -1079,7 +1079,7 @@ static int mcp251xfd_handle_cerrif(struct mcp251xfd_priv *priv) + /* The skb allocation might fail, but can_change_state() + * handles cf == NULL. + */ +- skb = mcp251xfd_alloc_can_err_skb(priv, &cf, ×tamp); ++ skb = mcp251xfd_alloc_can_err_skb(priv, &cf, &ts_raw); + can_change_state(priv->ndev, cf, tx_state, rx_state); + + if (new_state == CAN_STATE_BUS_OFF) { +@@ -1110,7 +1110,7 @@ static int mcp251xfd_handle_cerrif(struct mcp251xfd_priv *priv) + cf->data[7] = bec.rxerr; + } + +- err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp); ++ err = can_rx_offload_queue_timestamp(&priv->offload, skb, ts_raw); + if (err) + stats->rx_fifo_errors++; + +diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c +index 5d0fb1c454cd..a79e6c661ecc 100644 +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c +@@ -160,7 +160,7 @@ mcp251xfd_hw_rx_obj_to_skb(const struct mcp251xfd_priv *priv, + if (!(hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_RTR)) + memcpy(cfd->data, hw_rx_obj->data, cfd->len); + +- mcp251xfd_skb_set_timestamp(priv, skb, hw_rx_obj->ts); ++ mcp251xfd_skb_set_timestamp_raw(priv, skb, hw_rx_obj->ts); + } + + static int +diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c +index 5b0c7890d4b4..3886476a8f8e 100644 +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c +@@ -97,7 +97,7 @@ mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv, + tef_tail = mcp251xfd_get_tef_tail(priv); + skb = priv->can.echo_skb[tef_tail]; + if (skb) +- mcp251xfd_skb_set_timestamp(priv, skb, hw_tef_obj->ts); ++ mcp251xfd_skb_set_timestamp_raw(priv, skb, hw_tef_obj->ts); + stats->tx_bytes += + can_rx_offload_get_echo_skb_queue_timestamp(&priv->offload, + tef_tail, hw_tef_obj->ts, +diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-timestamp.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-timestamp.c +index 712e09186987..1db99aabe85c 100644 +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-timestamp.c ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-timestamp.c +@@ -2,7 +2,7 @@ + // + // mcp251xfd - Microchip MCP251xFD Family CAN controller driver + // +-// Copyright (c) 2021 Pengutronix, ++// Copyright (c) 2021, 2023 Pengutronix, + // Marc Kleine-Budde + // + +@@ -11,20 +11,20 @@ + + #include "mcp251xfd.h" + +-static u64 mcp251xfd_timestamp_read(const struct cyclecounter *cc) ++static u64 mcp251xfd_timestamp_raw_read(const struct cyclecounter *cc) + { + const struct mcp251xfd_priv *priv; +- u32 timestamp = 0; ++ u32 ts_raw = 0; + int err; + + priv = container_of(cc, struct mcp251xfd_priv, cc); +- err = mcp251xfd_get_timestamp(priv, ×tamp); ++ err = mcp251xfd_get_timestamp_raw(priv, &ts_raw); + if (err) + netdev_err(priv->ndev, + "Error %d while reading timestamp. HW timestamps may be inaccurate.", + err); + +- return timestamp; ++ return ts_raw; + } + + static void mcp251xfd_timestamp_work(struct work_struct *work) +@@ -39,21 +39,11 @@ static void mcp251xfd_timestamp_work(struct work_struct *work) + MCP251XFD_TIMESTAMP_WORK_DELAY_SEC * HZ); + } + +-void mcp251xfd_skb_set_timestamp(const struct mcp251xfd_priv *priv, +- struct sk_buff *skb, u32 timestamp) +-{ +- struct skb_shared_hwtstamps *hwtstamps = skb_hwtstamps(skb); +- u64 ns; +- +- ns = timecounter_cyc2time(&priv->tc, timestamp); +- hwtstamps->hwtstamp = ns_to_ktime(ns); +-} +- + void mcp251xfd_timestamp_init(struct mcp251xfd_priv *priv) + { + struct cyclecounter *cc = &priv->cc; + +- cc->read = mcp251xfd_timestamp_read; ++ cc->read = mcp251xfd_timestamp_raw_read; + cc->mask = CYCLECOUNTER_MASK(32); + cc->shift = 1; + cc->mult = clocksource_hz2mult(priv->can.clock.freq, cc->shift); +diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h +index 2e5cee6ad0c4..ae35845d4ce1 100644 +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h +@@ -2,7 +2,7 @@ + * + * mcp251xfd - Microchip MCP251xFD Family CAN controller driver + * +- * Copyright (c) 2019, 2020, 2021 Pengutronix, ++ * Copyright (c) 2019, 2020, 2021, 2023 Pengutronix, + * Marc Kleine-Budde + * Copyright (c) 2019 Martin Sperl + */ +@@ -812,10 +812,27 @@ mcp251xfd_spi_cmd_write(const struct mcp251xfd_priv *priv, + return data; + } + +-static inline int mcp251xfd_get_timestamp(const struct mcp251xfd_priv *priv, +- u32 *timestamp) ++static inline int mcp251xfd_get_timestamp_raw(const struct mcp251xfd_priv *priv, ++ u32 *ts_raw) + { +- return regmap_read(priv->map_reg, MCP251XFD_REG_TBC, timestamp); ++ return regmap_read(priv->map_reg, MCP251XFD_REG_TBC, ts_raw); ++} ++ ++static inline void mcp251xfd_skb_set_timestamp(struct sk_buff *skb, u64 ns) ++{ ++ struct skb_shared_hwtstamps *hwtstamps = skb_hwtstamps(skb); ++ ++ hwtstamps->hwtstamp = ns_to_ktime(ns); ++} ++ ++static inline ++void mcp251xfd_skb_set_timestamp_raw(const struct mcp251xfd_priv *priv, ++ struct sk_buff *skb, u32 ts_raw) ++{ ++ u64 ns; ++ ++ ns = timecounter_cyc2time(&priv->tc, ts_raw); ++ mcp251xfd_skb_set_timestamp(skb, ns); + } + + static inline u16 mcp251xfd_get_tef_obj_addr(u8 n) +@@ -936,8 +953,6 @@ void mcp251xfd_ring_free(struct mcp251xfd_priv *priv); + int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv); + int mcp251xfd_handle_rxif(struct mcp251xfd_priv *priv); + int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv); +-void mcp251xfd_skb_set_timestamp(const struct mcp251xfd_priv *priv, +- struct sk_buff *skb, u32 timestamp); + void mcp251xfd_timestamp_init(struct mcp251xfd_priv *priv); + void mcp251xfd_timestamp_stop(struct mcp251xfd_priv *priv); + +-- +2.43.0 + diff --git a/queue-6.6/can-mcp251xfd-mcp251xfd_handle_rxif_ring_uinc-factor.patch b/queue-6.6/can-mcp251xfd-mcp251xfd_handle_rxif_ring_uinc-factor.patch new file mode 100644 index 00000000000..429a5ac2d17 --- /dev/null +++ b/queue-6.6/can-mcp251xfd-mcp251xfd_handle_rxif_ring_uinc-factor.patch @@ -0,0 +1,108 @@ +From e2e5cebd9a70392b20b829170e31c271d8769998 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Jan 2023 20:25:48 +0100 +Subject: can: mcp251xfd: mcp251xfd_handle_rxif_ring_uinc(): factor out in + separate function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Marc Kleine-Budde + +[ Upstream commit d49184b7b585f9da7ee546b744525f62117019f6 ] + +This is a preparation patch. + +Sending the UINC messages followed by incrementing the tail pointer +will be called in more than one place in upcoming patches, so factor +this out into a separate function. + +Also make mcp251xfd_handle_rxif_ring_uinc() safe to be called with a +"len" of 0. + +Tested-by: Stefan Althöfer +Tested-by: Thomas Kopp +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c | 48 +++++++++++++------- + 1 file changed, 32 insertions(+), 16 deletions(-) + +diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c +index ced8d9c81f8c..5e2f39de88f3 100644 +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c +@@ -197,6 +197,37 @@ mcp251xfd_rx_obj_read(const struct mcp251xfd_priv *priv, + return err; + } + ++static int ++mcp251xfd_handle_rxif_ring_uinc(const struct mcp251xfd_priv *priv, ++ struct mcp251xfd_rx_ring *ring, ++ u8 len) ++{ ++ int offset; ++ int err; ++ ++ if (!len) ++ return 0; ++ ++ /* Increment the RX FIFO tail pointer 'len' times in a ++ * single SPI message. ++ * ++ * Note: ++ * Calculate offset, so that the SPI transfer ends on ++ * the last message of the uinc_xfer array, which has ++ * "cs_change == 0", to properly deactivate the chip ++ * select. ++ */ ++ offset = ARRAY_SIZE(ring->uinc_xfer) - len; ++ err = spi_sync_transfer(priv->spi, ++ ring->uinc_xfer + offset, len); ++ if (err) ++ return err; ++ ++ ring->tail += len; ++ ++ return 0; ++} ++ + static int + mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv *priv, + struct mcp251xfd_rx_ring *ring) +@@ -210,8 +241,6 @@ mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv *priv, + return err; + + while ((len = mcp251xfd_get_rx_linear_len(ring))) { +- int offset; +- + rx_tail = mcp251xfd_get_rx_tail(ring); + + err = mcp251xfd_rx_obj_read(priv, ring, hw_rx_obj, +@@ -227,22 +256,9 @@ mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv *priv, + return err; + } + +- /* Increment the RX FIFO tail pointer 'len' times in a +- * single SPI message. +- * +- * Note: +- * Calculate offset, so that the SPI transfer ends on +- * the last message of the uinc_xfer array, which has +- * "cs_change == 0", to properly deactivate the chip +- * select. +- */ +- offset = ARRAY_SIZE(ring->uinc_xfer) - len; +- err = spi_sync_transfer(priv->spi, +- ring->uinc_xfer + offset, len); ++ err = mcp251xfd_handle_rxif_ring_uinc(priv, ring, len); + if (err) + return err; +- +- ring->tail += len; + } + + return 0; +-- +2.43.0 + diff --git a/queue-6.6/can-mcp251xfd-rx-add-workaround-for-erratum-ds800007.patch b/queue-6.6/can-mcp251xfd-rx-add-workaround-for-erratum-ds800007.patch new file mode 100644 index 00000000000..1b618ba225b --- /dev/null +++ b/queue-6.6/can-mcp251xfd-rx-add-workaround-for-erratum-ds800007.patch @@ -0,0 +1,146 @@ +From 0c94a525e9837cd49d2b3031a6215faaf6d3e713 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Jan 2023 11:53:50 +0100 +Subject: can: mcp251xfd: rx: add workaround for erratum DS80000789E 6 of + mcp2518fd +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Marc Kleine-Budde + +[ Upstream commit 24436be590c6fbb05f6161b0dfba7d9da60214aa ] + +This patch tries to works around erratum DS80000789E 6 of the +mcp2518fd, the other variants of the chip family (mcp2517fd and +mcp251863) are probably also affected. + +In the bad case, the driver reads a too large head index. In the +original code, the driver always trusted the read value, which caused +old, already processed CAN frames or new, incompletely written CAN +frames to be (re-)processed. + +To work around this issue, keep a per FIFO timestamp [1] of the last +valid received CAN frame and compare against the timestamp of every +received CAN frame. If an old CAN frame is detected, abort the +iteration and mark the number of valid CAN frames as processed in the +chip by incrementing the FIFO's tail index. + +Further tests showed that this workaround can recognize old CAN +frames, but a small time window remains in which partially written CAN +frames [2] are not recognized but then processed. These CAN frames +have the correct data and time stamps, but the DLC has not yet been +updated. + +[1] As the raw timestamp overflows every 107 seconds (at the usual + clock rate of 40 MHz) convert it to nanoseconds with the + timecounter framework and use this to detect stale CAN frames. + +Link: https://lore.kernel.org/all/BL3PR11MB64844C1C95CA3BDADAE4D8CCFBC99@BL3PR11MB6484.namprd11.prod.outlook.com [2] +Reported-by: Stefan Althöfer +Closes: https://lore.kernel.org/all/FR0P281MB1966273C216630B120ABB6E197E89@FR0P281MB1966.DEUP281.PROD.OUTLOOK.COM +Tested-by: Stefan Althöfer +Tested-by: Thomas Kopp +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + .../net/can/spi/mcp251xfd/mcp251xfd-ring.c | 1 + + drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c | 32 +++++++++++++++++-- + drivers/net/can/spi/mcp251xfd/mcp251xfd.h | 3 ++ + 3 files changed, 33 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c +index 5f92aed62ff9..f72582d4d3e8 100644 +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c +@@ -206,6 +206,7 @@ mcp251xfd_ring_init_rx(struct mcp251xfd_priv *priv, u16 *base, u8 *fifo_nr) + int i, j; + + mcp251xfd_for_each_rx_ring(priv, rx_ring, i) { ++ rx_ring->last_valid = timecounter_read(&priv->tc); + rx_ring->head = 0; + rx_ring->tail = 0; + rx_ring->base = *base; +diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c +index a79e6c661ecc..fe897f3e4c12 100644 +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c +@@ -159,8 +159,6 @@ mcp251xfd_hw_rx_obj_to_skb(const struct mcp251xfd_priv *priv, + + if (!(hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_RTR)) + memcpy(cfd->data, hw_rx_obj->data, cfd->len); +- +- mcp251xfd_skb_set_timestamp_raw(priv, skb, hw_rx_obj->ts); + } + + static int +@@ -171,8 +169,26 @@ mcp251xfd_handle_rxif_one(struct mcp251xfd_priv *priv, + struct net_device_stats *stats = &priv->ndev->stats; + struct sk_buff *skb; + struct canfd_frame *cfd; ++ u64 timestamp; + int err; + ++ /* According to mcp2518fd erratum DS80000789E 6. the FIFOCI ++ * bits of a FIFOSTA register, here the RX FIFO head index ++ * might be corrupted and we might process past the RX FIFO's ++ * head into old CAN frames. ++ * ++ * Compare the timestamp of currently processed CAN frame with ++ * last valid frame received. Abort with -EBADMSG if an old ++ * CAN frame is detected. ++ */ ++ timestamp = timecounter_cyc2time(&priv->tc, hw_rx_obj->ts); ++ if (timestamp <= ring->last_valid) { ++ stats->rx_fifo_errors++; ++ ++ return -EBADMSG; ++ } ++ ring->last_valid = timestamp; ++ + if (hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_FDF) + skb = alloc_canfd_skb(priv->ndev, &cfd); + else +@@ -183,6 +199,7 @@ mcp251xfd_handle_rxif_one(struct mcp251xfd_priv *priv, + return 0; + } + ++ mcp251xfd_skb_set_timestamp(skb, timestamp); + mcp251xfd_hw_rx_obj_to_skb(priv, hw_rx_obj, skb); + err = can_rx_offload_queue_timestamp(&priv->offload, skb, hw_rx_obj->ts); + if (err) +@@ -265,7 +282,16 @@ mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv *priv, + err = mcp251xfd_handle_rxif_one(priv, ring, + (void *)hw_rx_obj + + i * ring->obj_size); +- if (err) ++ ++ /* -EBADMSG means we're affected by mcp2518fd ++ * erratum DS80000789E 6., i.e. the timestamp ++ * in the RX object is older that the last ++ * valid received CAN frame. Don't process any ++ * further and mark processed frames as good. ++ */ ++ if (err == -EBADMSG) ++ return mcp251xfd_handle_rxif_ring_uinc(priv, ring, i); ++ else if (err) + return err; + } + +diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h +index ae35845d4ce1..991662fbba42 100644 +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h +@@ -554,6 +554,9 @@ struct mcp251xfd_rx_ring { + unsigned int head; + unsigned int tail; + ++ /* timestamp of the last valid received CAN frame */ ++ u64 last_valid; ++ + u16 base; + u8 nr; + u8 fifo_nr; +-- +2.43.0 + diff --git a/queue-6.6/can-mcp251xfd-rx-prepare-to-workaround-broken-rx-fif.patch b/queue-6.6/can-mcp251xfd-rx-prepare-to-workaround-broken-rx-fif.patch new file mode 100644 index 00000000000..74301e18e66 --- /dev/null +++ b/queue-6.6/can-mcp251xfd-rx-prepare-to-workaround-broken-rx-fif.patch @@ -0,0 +1,255 @@ +From bb7f55b3b253cbee9d1dceadda3c75a5732e7a89 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Jan 2023 21:07:03 +0100 +Subject: can: mcp251xfd: rx: prepare to workaround broken RX FIFO head index + erratum +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Marc Kleine-Budde + +[ Upstream commit 85505e585637a737e4713c1386c30e37c325b82e ] + +This is a preparatory patch to work around erratum DS80000789E 6 of +the mcp2518fd, the other variants of the chip family (mcp2517fd and +mcp251863) are probably also affected. + +When handling the RX interrupt, the driver iterates over all pending +FIFOs (which are implemented as ring buffers in hardware) and reads +the FIFO header index from the RX FIFO STA register of the chip. + +In the bad case, the driver reads a too large head index. In the +original code, the driver always trusted the read value, which caused +old CAN frames that were already processed, or new, incompletely +written CAN frames to be (re-)processed. + +Instead of reading and trusting the head index, read the head index +and calculate the number of CAN frames that were supposedly received - +replace mcp251xfd_rx_ring_update() with mcp251xfd_get_rx_len(). + +The mcp251xfd_handle_rxif_ring() function reads the received CAN +frames from the chip, iterates over them and pushes them into the +network stack. Prepare that the iteration can be stopped if an old CAN +frame is detected. The actual code to detect old or incomplete frames +and abort will be added in the next patch. + +Link: https://lore.kernel.org/all/BL3PR11MB64844C1C95CA3BDADAE4D8CCFBC99@BL3PR11MB6484.namprd11.prod.outlook.com +Reported-by: Stefan Althöfer +Closes: https://lore.kernel.org/all/FR0P281MB1966273C216630B120ABB6E197E89@FR0P281MB1966.DEUP281.PROD.OUTLOOK.COM +Tested-by: Stefan Althöfer +Tested-by: Thomas Kopp +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + .../net/can/spi/mcp251xfd/mcp251xfd-ring.c | 2 + + drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c | 89 +++++++++++-------- + drivers/net/can/spi/mcp251xfd/mcp251xfd.h | 12 +-- + 3 files changed, 56 insertions(+), 47 deletions(-) + +diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c +index 3a941a71c78f..5f92aed62ff9 100644 +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c +@@ -523,6 +523,8 @@ int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv) + } + + rx_ring->obj_num = rx_obj_num; ++ rx_ring->obj_num_shift_to_u8 = BITS_PER_TYPE(rx_ring->obj_num_shift_to_u8) - ++ ilog2(rx_obj_num); + rx_ring->obj_size = rx_obj_size; + priv->rx[i] = rx_ring; + } +diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c +index 5e2f39de88f3..5d0fb1c454cd 100644 +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c +@@ -2,7 +2,7 @@ + // + // mcp251xfd - Microchip MCP251xFD Family CAN controller driver + // +-// Copyright (c) 2019, 2020, 2021 Pengutronix, ++// Copyright (c) 2019, 2020, 2021, 2023 Pengutronix, + // Marc Kleine-Budde + // + // Based on: +@@ -16,23 +16,14 @@ + + #include "mcp251xfd.h" + +-static inline int +-mcp251xfd_rx_head_get_from_chip(const struct mcp251xfd_priv *priv, +- const struct mcp251xfd_rx_ring *ring, +- u8 *rx_head, bool *fifo_empty) ++static inline bool mcp251xfd_rx_fifo_sta_empty(const u32 fifo_sta) + { +- u32 fifo_sta; +- int err; +- +- err = regmap_read(priv->map_reg, MCP251XFD_REG_FIFOSTA(ring->fifo_nr), +- &fifo_sta); +- if (err) +- return err; +- +- *rx_head = FIELD_GET(MCP251XFD_REG_FIFOSTA_FIFOCI_MASK, fifo_sta); +- *fifo_empty = !(fifo_sta & MCP251XFD_REG_FIFOSTA_TFNRFNIF); ++ return !(fifo_sta & MCP251XFD_REG_FIFOSTA_TFNRFNIF); ++} + +- return 0; ++static inline bool mcp251xfd_rx_fifo_sta_full(const u32 fifo_sta) ++{ ++ return fifo_sta & MCP251XFD_REG_FIFOSTA_TFERFFIF; + } + + static inline int +@@ -80,29 +71,49 @@ mcp251xfd_check_rx_tail(const struct mcp251xfd_priv *priv, + } + + static int +-mcp251xfd_rx_ring_update(const struct mcp251xfd_priv *priv, +- struct mcp251xfd_rx_ring *ring) ++mcp251xfd_get_rx_len(const struct mcp251xfd_priv *priv, ++ const struct mcp251xfd_rx_ring *ring, ++ u8 *len_p) + { +- u32 new_head; +- u8 chip_rx_head; +- bool fifo_empty; ++ const u8 shift = ring->obj_num_shift_to_u8; ++ u8 chip_head, tail, len; ++ u32 fifo_sta; + int err; + +- err = mcp251xfd_rx_head_get_from_chip(priv, ring, &chip_rx_head, +- &fifo_empty); +- if (err || fifo_empty) ++ err = regmap_read(priv->map_reg, MCP251XFD_REG_FIFOSTA(ring->fifo_nr), ++ &fifo_sta); ++ if (err) ++ return err; ++ ++ if (mcp251xfd_rx_fifo_sta_empty(fifo_sta)) { ++ *len_p = 0; ++ return 0; ++ } ++ ++ if (mcp251xfd_rx_fifo_sta_full(fifo_sta)) { ++ *len_p = ring->obj_num; ++ return 0; ++ } ++ ++ chip_head = FIELD_GET(MCP251XFD_REG_FIFOSTA_FIFOCI_MASK, fifo_sta); ++ ++ err = mcp251xfd_check_rx_tail(priv, ring); ++ if (err) + return err; ++ tail = mcp251xfd_get_rx_tail(ring); + +- /* chip_rx_head, is the next RX-Object filled by the HW. +- * The new RX head must be >= the old head. ++ /* First shift to full u8. The subtraction works on signed ++ * values, that keeps the difference steady around the u8 ++ * overflow. The right shift acts on len, which is an u8. + */ +- new_head = round_down(ring->head, ring->obj_num) + chip_rx_head; +- if (new_head <= ring->head) +- new_head += ring->obj_num; ++ BUILD_BUG_ON(sizeof(ring->obj_num) != sizeof(chip_head)); ++ BUILD_BUG_ON(sizeof(ring->obj_num) != sizeof(tail)); ++ BUILD_BUG_ON(sizeof(ring->obj_num) != sizeof(len)); + +- ring->head = new_head; ++ len = (chip_head << shift) - (tail << shift); ++ *len_p = len >> shift; + +- return mcp251xfd_check_rx_tail(priv, ring); ++ return 0; + } + + static void +@@ -208,6 +219,8 @@ mcp251xfd_handle_rxif_ring_uinc(const struct mcp251xfd_priv *priv, + if (!len) + return 0; + ++ ring->head += len; ++ + /* Increment the RX FIFO tail pointer 'len' times in a + * single SPI message. + * +@@ -233,22 +246,22 @@ mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv *priv, + struct mcp251xfd_rx_ring *ring) + { + struct mcp251xfd_hw_rx_obj_canfd *hw_rx_obj = ring->obj; +- u8 rx_tail, len; ++ u8 rx_tail, len, l; + int err, i; + +- err = mcp251xfd_rx_ring_update(priv, ring); ++ err = mcp251xfd_get_rx_len(priv, ring, &len); + if (err) + return err; + +- while ((len = mcp251xfd_get_rx_linear_len(ring))) { ++ while ((l = mcp251xfd_get_rx_linear_len(ring, len))) { + rx_tail = mcp251xfd_get_rx_tail(ring); + + err = mcp251xfd_rx_obj_read(priv, ring, hw_rx_obj, +- rx_tail, len); ++ rx_tail, l); + if (err) + return err; + +- for (i = 0; i < len; i++) { ++ for (i = 0; i < l; i++) { + err = mcp251xfd_handle_rxif_one(priv, ring, + (void *)hw_rx_obj + + i * ring->obj_size); +@@ -256,9 +269,11 @@ mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv *priv, + return err; + } + +- err = mcp251xfd_handle_rxif_ring_uinc(priv, ring, len); ++ err = mcp251xfd_handle_rxif_ring_uinc(priv, ring, l); + if (err) + return err; ++ ++ len -= l; + } + + return 0; +diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h +index 4628bf847bc9..2e5cee6ad0c4 100644 +--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h ++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h +@@ -558,6 +558,7 @@ struct mcp251xfd_rx_ring { + u8 nr; + u8 fifo_nr; + u8 obj_num; ++ u8 obj_num_shift_to_u8; + u8 obj_size; + + union mcp251xfd_write_reg_buf irq_enable_buf; +@@ -907,18 +908,9 @@ static inline u8 mcp251xfd_get_rx_tail(const struct mcp251xfd_rx_ring *ring) + return ring->tail & (ring->obj_num - 1); + } + +-static inline u8 mcp251xfd_get_rx_len(const struct mcp251xfd_rx_ring *ring) +-{ +- return ring->head - ring->tail; +-} +- + static inline u8 +-mcp251xfd_get_rx_linear_len(const struct mcp251xfd_rx_ring *ring) ++mcp251xfd_get_rx_linear_len(const struct mcp251xfd_rx_ring *ring, u8 len) + { +- u8 len; +- +- len = mcp251xfd_get_rx_len(ring); +- + return min_t(u8, len, ring->obj_num - mcp251xfd_get_rx_tail(ring)); + } + +-- +2.43.0 + diff --git a/queue-6.6/clk-qcom-gcc-sm8550-don-t-park-the-usb-rcg-at-regist.patch b/queue-6.6/clk-qcom-gcc-sm8550-don-t-park-the-usb-rcg-at-regist.patch new file mode 100644 index 00000000000..32a9e2dd421 --- /dev/null +++ b/queue-6.6/clk-qcom-gcc-sm8550-don-t-park-the-usb-rcg-at-regist.patch @@ -0,0 +1,106 @@ +From 6f77e927f029cd5c958341d30aa8285043fb6f5f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Aug 2024 16:36:27 -0700 +Subject: clk: qcom: gcc-sm8550: Don't park the USB RCG at registration time + +From: Stephen Boyd + +[ Upstream commit 7b6dfa1bbe7f727315d2e05a2fc8e4cfeb779156 ] + +Amit Pundir reports that audio and USB-C host mode stops working if the +gcc_usb30_prim_master_clk_src clk is registered and +clk_rcg2_shared_init() parks it on XO. Skip parking this clk at +registration time to fix those issues. + +Partially revert commit 01a0a6cc8cfd ("clk: qcom: Park shared RCGs upon +registration") by skipping the parking bit for this clk, but keep the +part where we cache the config register. That's still necessary to +figure out the true parent of the clk at registration time. + +Fixes: 01a0a6cc8cfd ("clk: qcom: Park shared RCGs upon registration") +Fixes: 929c75d57566 ("clk: qcom: gcc-sm8550: Mark RCGs shared where applicable") +Cc: Konrad Dybcio +Cc: Bjorn Andersson +Cc: Taniya Das +Reported-by: Amit Pundir +Closes: https://lore.kernel.org/CAMi1Hd1KQBE4kKUdAn8E5FV+BiKzuv+8FoyWQrrTHPDoYTuhgA@mail.gmail.com +Signed-off-by: Stephen Boyd +Link: https://lore.kernel.org/r/20240819233628.2074654-3-swboyd@chromium.org +Tested-by: Amit Pundir +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/clk-rcg.h | 1 + + drivers/clk/qcom/clk-rcg2.c | 30 ++++++++++++++++++++++++++++++ + drivers/clk/qcom/gcc-sm8550.c | 2 +- + 3 files changed, 32 insertions(+), 1 deletion(-) + +diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h +index e6d84c8c7989..84c497f361bc 100644 +--- a/drivers/clk/qcom/clk-rcg.h ++++ b/drivers/clk/qcom/clk-rcg.h +@@ -176,6 +176,7 @@ extern const struct clk_ops clk_byte2_ops; + extern const struct clk_ops clk_pixel_ops; + extern const struct clk_ops clk_gfx3d_ops; + extern const struct clk_ops clk_rcg2_shared_ops; ++extern const struct clk_ops clk_rcg2_shared_no_init_park_ops; + extern const struct clk_ops clk_dp_ops; + + struct clk_rcg_dfs_data { +diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c +index b9f2a29be927..461f54fe5e4f 100644 +--- a/drivers/clk/qcom/clk-rcg2.c ++++ b/drivers/clk/qcom/clk-rcg2.c +@@ -1182,6 +1182,36 @@ const struct clk_ops clk_rcg2_shared_ops = { + }; + EXPORT_SYMBOL_GPL(clk_rcg2_shared_ops); + ++static int clk_rcg2_shared_no_init_park(struct clk_hw *hw) ++{ ++ struct clk_rcg2 *rcg = to_clk_rcg2(hw); ++ ++ /* ++ * Read the config register so that the parent is properly mapped at ++ * registration time. ++ */ ++ regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &rcg->parked_cfg); ++ ++ return 0; ++} ++ ++/* ++ * Like clk_rcg2_shared_ops but skip the init so that the clk frequency is left ++ * unchanged at registration time. ++ */ ++const struct clk_ops clk_rcg2_shared_no_init_park_ops = { ++ .init = clk_rcg2_shared_no_init_park, ++ .enable = clk_rcg2_shared_enable, ++ .disable = clk_rcg2_shared_disable, ++ .get_parent = clk_rcg2_shared_get_parent, ++ .set_parent = clk_rcg2_shared_set_parent, ++ .recalc_rate = clk_rcg2_shared_recalc_rate, ++ .determine_rate = clk_rcg2_determine_rate, ++ .set_rate = clk_rcg2_shared_set_rate, ++ .set_rate_and_parent = clk_rcg2_shared_set_rate_and_parent, ++}; ++EXPORT_SYMBOL_GPL(clk_rcg2_shared_no_init_park_ops); ++ + /* Common APIs to be used for DFS based RCGR */ + static void clk_rcg2_dfs_populate_freq(struct clk_hw *hw, unsigned int l, + struct freq_tbl *f) +diff --git a/drivers/clk/qcom/gcc-sm8550.c b/drivers/clk/qcom/gcc-sm8550.c +index bf7b7c5d4606..eb3765c57b65 100644 +--- a/drivers/clk/qcom/gcc-sm8550.c ++++ b/drivers/clk/qcom/gcc-sm8550.c +@@ -1159,7 +1159,7 @@ static struct clk_rcg2 gcc_usb30_prim_master_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_shared_no_init_park_ops, + }, + }; + +-- +2.43.0 + diff --git a/queue-6.6/clk-qcom-gcc-sm8550-don-t-use-parking-clk_ops-for-qu.patch b/queue-6.6/clk-qcom-gcc-sm8550-don-t-use-parking-clk_ops-for-qu.patch new file mode 100644 index 00000000000..0d0edd2e719 --- /dev/null +++ b/queue-6.6/clk-qcom-gcc-sm8550-don-t-use-parking-clk_ops-for-qu.patch @@ -0,0 +1,285 @@ +From a3b4a42a75776e4375a924ecc57465e5c276e447 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Aug 2024 16:36:26 -0700 +Subject: clk: qcom: gcc-sm8550: Don't use parking clk_ops for QUPs + +From: Stephen Boyd + +[ Upstream commit d10eeb75168b84ed9559c58efe2756c2e0bc052a ] + +The QUPs aren't shared in a way that requires parking the RCG at an +always on parent in case some other entity turns on the clk. The +hardware is capable of setting a new frequency itself with the DFS mode, +so parking is unnecessary. Furthermore, there aren't any GDSCs for these +devices, so there isn't a possibility of the GDSC turning on the clks +for housekeeping purposes. + +This wasn't a problem to mark these clks shared until we started parking +shared RCGs at clk registration time in commit 01a0a6cc8cfd ("clk: qcom: +Park shared RCGs upon registration"). Parking at init is actually +harmful to the UART when earlycon is used. If the device is pumping out +data while the frequency changes you'll see garbage on the serial +console until the driver can probe and actually set a proper frequency. + +Revert the QUP part of commit 929c75d57566 ("clk: qcom: gcc-sm8550: Mark +RCGs shared where applicable") so that the QUPs don't get parked during +clk registration and break UART operations. + +Fixes: 01a0a6cc8cfd ("clk: qcom: Park shared RCGs upon registration") +Fixes: 929c75d57566 ("clk: qcom: gcc-sm8550: Mark RCGs shared where applicable") +Cc: Konrad Dybcio +Cc: Bjorn Andersson +Cc: Taniya Das +Reported-by: Amit Pundir +Closes: https://lore.kernel.org/CAMi1Hd1KQBE4kKUdAn8E5FV+BiKzuv+8FoyWQrrTHPDoYTuhgA@mail.gmail.com +Signed-off-by: Stephen Boyd +Link: https://lore.kernel.org/r/20240819233628.2074654-2-swboyd@chromium.org +Tested-by: Amit Pundir +Tested-by: Neil Armstrong # on SM8550-QRD +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/gcc-sm8550.c | 52 +++++++++++++++++------------------ + 1 file changed, 26 insertions(+), 26 deletions(-) + +diff --git a/drivers/clk/qcom/gcc-sm8550.c b/drivers/clk/qcom/gcc-sm8550.c +index b883dffe5f7a..bf7b7c5d4606 100644 +--- a/drivers/clk/qcom/gcc-sm8550.c ++++ b/drivers/clk/qcom/gcc-sm8550.c +@@ -536,7 +536,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s0_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }, + }; + +@@ -551,7 +551,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s1_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }, + }; + +@@ -566,7 +566,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s2_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }, + }; + +@@ -581,7 +581,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s3_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }, + }; + +@@ -596,7 +596,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s4_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }, + }; + +@@ -611,7 +611,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s5_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }, + }; + +@@ -626,7 +626,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s6_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }, + }; + +@@ -641,7 +641,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s7_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }, + }; + +@@ -656,7 +656,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s8_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }, + }; + +@@ -671,7 +671,7 @@ static struct clk_rcg2 gcc_qupv3_i2c_s9_clk_src = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }, + }; + +@@ -700,7 +700,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = { +@@ -717,7 +717,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = { +@@ -750,7 +750,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = { +@@ -767,7 +767,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = { +@@ -784,7 +784,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = { +@@ -801,7 +801,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = { +@@ -818,7 +818,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s6_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = { +@@ -835,7 +835,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s7_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = { +@@ -852,7 +852,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s0_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap2_s0_clk_src = { +@@ -869,7 +869,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s1_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap2_s1_clk_src = { +@@ -886,7 +886,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s2_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap2_s2_clk_src = { +@@ -903,7 +903,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s3_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap2_s3_clk_src = { +@@ -920,7 +920,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s4_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap2_s4_clk_src = { +@@ -937,7 +937,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s5_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap2_s5_clk_src = { +@@ -975,7 +975,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s6_clk_src_init = { + .parent_data = gcc_parent_data_8, + .num_parents = ARRAY_SIZE(gcc_parent_data_8), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap2_s6_clk_src = { +@@ -992,7 +992,7 @@ static struct clk_init_data gcc_qupv3_wrap2_s7_clk_src_init = { + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, +- .ops = &clk_rcg2_shared_ops, ++ .ops = &clk_rcg2_ops, + }; + + static struct clk_rcg2 gcc_qupv3_wrap2_s7_clk_src = { +-- +2.43.0 + diff --git a/queue-6.6/clk-qcom-ipq9574-update-the-alpha-pll-type-for-gplls.patch b/queue-6.6/clk-qcom-ipq9574-update-the-alpha-pll-type-for-gplls.patch new file mode 100644 index 00000000000..6255ce68676 --- /dev/null +++ b/queue-6.6/clk-qcom-ipq9574-update-the-alpha-pll-type-for-gplls.patch @@ -0,0 +1,101 @@ +From 6d90019599f844b1f26df6e8d551c316bfb713ac Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Aug 2024 11:41:05 +0530 +Subject: clk: qcom: ipq9574: Update the alpha PLL type for GPLLs + +From: devi priya + +[ Upstream commit 6357efe3abead68048729adf11a9363881657939 ] + +Update PLL offsets to DEFAULT_EVO to configure MDIO to 800MHz. + +The incorrect clock frequency leads to an incorrect MDIO clock. This, +in turn, affects the MDIO hardware configurations as the divider is +calculated from the MDIO clock frequency. If the clock frequency is +not as expected, the MDIO register fails due to the generation of an +incorrect MDIO frequency. + +This issue is critical as it results in incorrect MDIO configurations +and ultimately leads to the MDIO function not working. This results in +a complete feature failure affecting all Ethernet PHYs. Specifically, +Ethernet will not work on IPQ9574 due to this issue. + +Currently, the clock frequency is set to CLK_ALPHA_PLL_TYPE_DEFAULT. +However, this setting does not yield the expected clock frequency. +To rectify this, we need to change this to CLK_ALPHA_PLL_TYPE_DEFAULT_EVO. + +This modification ensures that the clock frequency aligns with our +expectations, thereby resolving the MDIO register failure and ensuring +the proper functioning of the Ethernet on IPQ9574. + +Fixes: d75b82cff488 ("clk: qcom: Add Global Clock Controller driver for IPQ9574") +Signed-off-by: devi priya +Signed-off-by: Amandeep Singh +Link: https://lore.kernel.org/r/20240806061105.2849944-1-quic_amansing@quicinc.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/gcc-ipq9574.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/clk/qcom/gcc-ipq9574.c b/drivers/clk/qcom/gcc-ipq9574.c +index f8b9a1e93bef..cdbbf2cc9c5d 100644 +--- a/drivers/clk/qcom/gcc-ipq9574.c ++++ b/drivers/clk/qcom/gcc-ipq9574.c +@@ -65,7 +65,7 @@ static const struct clk_parent_data gcc_sleep_clk_data[] = { + + static struct clk_alpha_pll gpll0_main = { + .offset = 0x20000, +- .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], ++ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr = { + .enable_reg = 0x0b000, + .enable_mask = BIT(0), +@@ -93,7 +93,7 @@ static struct clk_fixed_factor gpll0_out_main_div2 = { + + static struct clk_alpha_pll_postdiv gpll0 = { + .offset = 0x20000, +- .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], ++ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpll0", +@@ -107,7 +107,7 @@ static struct clk_alpha_pll_postdiv gpll0 = { + + static struct clk_alpha_pll gpll4_main = { + .offset = 0x22000, +- .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], ++ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr = { + .enable_reg = 0x0b000, + .enable_mask = BIT(2), +@@ -122,7 +122,7 @@ static struct clk_alpha_pll gpll4_main = { + + static struct clk_alpha_pll_postdiv gpll4 = { + .offset = 0x22000, +- .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], ++ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpll4", +@@ -136,7 +136,7 @@ static struct clk_alpha_pll_postdiv gpll4 = { + + static struct clk_alpha_pll gpll2_main = { + .offset = 0x21000, +- .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], ++ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .clkr = { + .enable_reg = 0x0b000, + .enable_mask = BIT(1), +@@ -151,7 +151,7 @@ static struct clk_alpha_pll gpll2_main = { + + static struct clk_alpha_pll_postdiv gpll2 = { + .offset = 0x21000, +- .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], ++ .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO], + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpll2", +-- +2.43.0 + diff --git a/queue-6.6/crypto-starfive-align-rsa-input-data-to-32-bit.patch b/queue-6.6/crypto-starfive-align-rsa-input-data-to-32-bit.patch new file mode 100644 index 00000000000..271b87c1c2d --- /dev/null +++ b/queue-6.6/crypto-starfive-align-rsa-input-data-to-32-bit.patch @@ -0,0 +1,86 @@ +From c84c7de31dd31b2cbe3adf0a2e396e1047fa9452 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Jun 2024 09:40:42 +0800 +Subject: crypto: starfive - Align rsa input data to 32-bit + +From: Jia Jie Ho + +[ Upstream commit 6aad7019f697ab0bed98eba737d19bd7f67713de ] + +Hardware expects RSA input plain/ciphertext to be 32-bit aligned. +Set fixed length for preallocated buffer to the maximum supported +keysize of the hardware and shift input text accordingly. + +Signed-off-by: Jia Jie Ho +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/starfive/jh7110-cryp.h | 3 ++- + drivers/crypto/starfive/jh7110-rsa.c | 12 ++++++++---- + 2 files changed, 10 insertions(+), 5 deletions(-) + +diff --git a/drivers/crypto/starfive/jh7110-cryp.h b/drivers/crypto/starfive/jh7110-cryp.h +index fe011d50473d..f386e9897896 100644 +--- a/drivers/crypto/starfive/jh7110-cryp.h ++++ b/drivers/crypto/starfive/jh7110-cryp.h +@@ -30,6 +30,7 @@ + #define MAX_KEY_SIZE SHA512_BLOCK_SIZE + #define STARFIVE_AES_IV_LEN AES_BLOCK_SIZE + #define STARFIVE_AES_CTR_LEN AES_BLOCK_SIZE ++#define STARFIVE_RSA_MAX_KEYSZ 256 + + union starfive_aes_csr { + u32 v; +@@ -217,7 +218,7 @@ struct starfive_cryp_request_ctx { + unsigned int digsize; + unsigned long in_sg_len; + unsigned char *adata; +- u8 rsa_data[] __aligned(sizeof(u32)); ++ u8 rsa_data[STARFIVE_RSA_MAX_KEYSZ] __aligned(sizeof(u32)); + }; + + struct starfive_cryp_dev *starfive_cryp_find_dev(struct starfive_cryp_ctx *ctx); +diff --git a/drivers/crypto/starfive/jh7110-rsa.c b/drivers/crypto/starfive/jh7110-rsa.c +index f31bbd825f88..fbc06f8ee95f 100644 +--- a/drivers/crypto/starfive/jh7110-rsa.c ++++ b/drivers/crypto/starfive/jh7110-rsa.c +@@ -37,7 +37,6 @@ + // A * A * R mod N ==> A + #define CRYPTO_CMD_AARN 0x7 + +-#define STARFIVE_RSA_MAX_KEYSZ 256 + #define STARFIVE_RSA_RESET 0x2 + + static inline int starfive_pka_wait_done(struct starfive_cryp_ctx *ctx) +@@ -91,7 +90,7 @@ static int starfive_rsa_montgomery_form(struct starfive_cryp_ctx *ctx, + { + struct starfive_cryp_dev *cryp = ctx->cryp; + struct starfive_cryp_request_ctx *rctx = ctx->rctx; +- int count = rctx->total / sizeof(u32) - 1; ++ int count = (ALIGN(rctx->total, 4) / 4) - 1; + int loop; + u32 temp; + u8 opsize; +@@ -274,12 +273,17 @@ static int starfive_rsa_enc_core(struct starfive_cryp_ctx *ctx, int enc) + struct starfive_cryp_dev *cryp = ctx->cryp; + struct starfive_cryp_request_ctx *rctx = ctx->rctx; + struct starfive_rsa_key *key = &ctx->rsa_key; +- int ret = 0; ++ int ret = 0, shift = 0; + + writel(STARFIVE_RSA_RESET, cryp->base + STARFIVE_PKA_CACR_OFFSET); + ++ if (!IS_ALIGNED(rctx->total, sizeof(u32))) { ++ shift = sizeof(u32) - (rctx->total & 0x3); ++ memset(rctx->rsa_data, 0, shift); ++ } ++ + rctx->total = sg_copy_to_buffer(rctx->in_sg, rctx->nents, +- rctx->rsa_data, rctx->total); ++ rctx->rsa_data + shift, rctx->total); + + if (enc) { + key->bitlen = key->e_bitlen; +-- +2.43.0 + diff --git a/queue-6.6/crypto-starfive-fix-nent-assignment-in-rsa-dec.patch b/queue-6.6/crypto-starfive-fix-nent-assignment-in-rsa-dec.patch new file mode 100644 index 00000000000..bc7b1882147 --- /dev/null +++ b/queue-6.6/crypto-starfive-fix-nent-assignment-in-rsa-dec.patch @@ -0,0 +1,57 @@ +From a4334a723769472c50893e63f03dc66fc08dda44 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Jun 2024 09:40:43 +0800 +Subject: crypto: starfive - Fix nent assignment in rsa dec + +From: Jia Jie Ho + +[ Upstream commit 8323c036789b8b4a61925fce439a89dba17b7f2f ] + +Missing src scatterlist nent assignment in rsa decrypt function. +Removing all unneeded assignment and use nents value from req->src +instead. + +Signed-off-by: Jia Jie Ho +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/starfive/jh7110-cryp.h | 1 - + drivers/crypto/starfive/jh7110-rsa.c | 3 +-- + 2 files changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/crypto/starfive/jh7110-cryp.h b/drivers/crypto/starfive/jh7110-cryp.h +index f386e9897896..607f70292b21 100644 +--- a/drivers/crypto/starfive/jh7110-cryp.h ++++ b/drivers/crypto/starfive/jh7110-cryp.h +@@ -213,7 +213,6 @@ struct starfive_cryp_request_ctx { + struct scatterlist *out_sg; + struct ahash_request ahash_fbk_req; + size_t total; +- size_t nents; + unsigned int blksize; + unsigned int digsize; + unsigned long in_sg_len; +diff --git a/drivers/crypto/starfive/jh7110-rsa.c b/drivers/crypto/starfive/jh7110-rsa.c +index fbc06f8ee95f..1db9a3d02848 100644 +--- a/drivers/crypto/starfive/jh7110-rsa.c ++++ b/drivers/crypto/starfive/jh7110-rsa.c +@@ -282,7 +282,7 @@ static int starfive_rsa_enc_core(struct starfive_cryp_ctx *ctx, int enc) + memset(rctx->rsa_data, 0, shift); + } + +- rctx->total = sg_copy_to_buffer(rctx->in_sg, rctx->nents, ++ rctx->total = sg_copy_to_buffer(rctx->in_sg, sg_nents(rctx->in_sg), + rctx->rsa_data + shift, rctx->total); + + if (enc) { +@@ -333,7 +333,6 @@ static int starfive_rsa_enc(struct akcipher_request *req) + rctx->in_sg = req->src; + rctx->out_sg = req->dst; + rctx->total = req->src_len; +- rctx->nents = sg_nents(rctx->in_sg); + ctx->rctx = rctx; + + return starfive_rsa_enc_core(ctx, 1); +-- +2.43.0 + diff --git a/queue-6.6/drm-amd-add-gfx12-swizzle-mode-defs.patch b/queue-6.6/drm-amd-add-gfx12-swizzle-mode-defs.patch new file mode 100644 index 00000000000..c584e5465c0 --- /dev/null +++ b/queue-6.6/drm-amd-add-gfx12-swizzle-mode-defs.patch @@ -0,0 +1,63 @@ +From b82fcd8d702fe9ef09528f84d66d302ed5e84f3b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 2 Feb 2024 14:00:27 -0500 +Subject: drm/amd: Add gfx12 swizzle mode defs + +From: Aurabindo Pillai + +[ Upstream commit 7ceb94e87bffff7c12b61eb29749e1d8ac976896 ] + +Add GFX12 swizzle mode definitions for use with DCN401 + +Signed-off-by: Aurabindo Pillai +Acked-by: Rodrigo Siqueira +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + include/uapi/drm/drm_fourcc.h | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h +index 8db7fd3f743e..fb3040677815 100644 +--- a/include/uapi/drm/drm_fourcc.h ++++ b/include/uapi/drm/drm_fourcc.h +@@ -1474,6 +1474,7 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier) + #define AMD_FMT_MOD_TILE_VER_GFX10 2 + #define AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS 3 + #define AMD_FMT_MOD_TILE_VER_GFX11 4 ++#define AMD_FMT_MOD_TILE_VER_GFX12 5 + + /* + * 64K_S is the same for GFX9/GFX10/GFX10_RBPLUS and hence has GFX9 as canonical +@@ -1484,6 +1485,8 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier) + /* + * 64K_D for non-32 bpp is the same for GFX9/GFX10/GFX10_RBPLUS and hence has + * GFX9 as canonical version. ++ * ++ * 64K_D_2D on GFX12 is identical to 64K_D on GFX11. + */ + #define AMD_FMT_MOD_TILE_GFX9_64K_D 10 + #define AMD_FMT_MOD_TILE_GFX9_64K_S_X 25 +@@ -1491,6 +1494,19 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier) + #define AMD_FMT_MOD_TILE_GFX9_64K_R_X 27 + #define AMD_FMT_MOD_TILE_GFX11_256K_R_X 31 + ++/* Gfx12 swizzle modes: ++ * 0 - LINEAR ++ * 1 - 256B_2D - 2D block dimensions ++ * 2 - 4KB_2D ++ * 3 - 64KB_2D ++ * 4 - 256KB_2D ++ * 5 - 4KB_3D - 3D block dimensions ++ * 6 - 64KB_3D ++ * 7 - 256KB_3D ++ */ ++#define AMD_FMT_MOD_TILE_GFX12_64K_2D 3 ++#define AMD_FMT_MOD_TILE_GFX12_256K_2D 4 ++ + #define AMD_FMT_MOD_DCC_BLOCK_64B 0 + #define AMD_FMT_MOD_DCC_BLOCK_128B 1 + #define AMD_FMT_MOD_DCC_BLOCK_256B 2 +-- +2.43.0 + diff --git a/queue-6.6/drm-amdgpu-handle-gfx12-in-amdgpu_display_verify_siz.patch b/queue-6.6/drm-amdgpu-handle-gfx12-in-amdgpu_display_verify_siz.patch new file mode 100644 index 00000000000..08eac7b450e --- /dev/null +++ b/queue-6.6/drm-amdgpu-handle-gfx12-in-amdgpu_display_verify_siz.patch @@ -0,0 +1,84 @@ +From 2ac02f4d4ef4c1ece373031d988f86e757b310c1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 1 Jun 2024 19:53:01 -0400 +Subject: drm/amdgpu: handle gfx12 in amdgpu_display_verify_sizes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Marek Olšák + +[ Upstream commit 8dd1426e2c80e32ac1995007330c8f95ffa28ebb ] + +It verified GFX9-11 swizzle modes on GFX12, which has undefined behavior. + +Signed-off-by: Marek Olšák +Acked-by: Alex Deucher +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 27 ++++++++++++++++++++- + include/uapi/drm/drm_fourcc.h | 2 ++ + 2 files changed, 28 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +index 82ad2b01f2e9..5fbb9caa7415 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +@@ -1033,6 +1033,30 @@ static int amdgpu_display_verify_sizes(struct amdgpu_framebuffer *rfb) + block_width = 256 / format_info->cpp[i]; + block_height = 1; + block_size_log2 = 8; ++ } else if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) >= AMD_FMT_MOD_TILE_VER_GFX12) { ++ int swizzle = AMD_FMT_MOD_GET(TILE, modifier); ++ ++ switch (swizzle) { ++ case AMD_FMT_MOD_TILE_GFX12_256B_2D: ++ block_size_log2 = 8; ++ break; ++ case AMD_FMT_MOD_TILE_GFX12_4K_2D: ++ block_size_log2 = 12; ++ break; ++ case AMD_FMT_MOD_TILE_GFX12_64K_2D: ++ block_size_log2 = 16; ++ break; ++ case AMD_FMT_MOD_TILE_GFX12_256K_2D: ++ block_size_log2 = 18; ++ break; ++ default: ++ drm_dbg_kms(rfb->base.dev, ++ "Gfx12 swizzle mode with unknown block size: %d\n", swizzle); ++ return -EINVAL; ++ } ++ ++ get_block_dimensions(block_size_log2, format_info->cpp[i], ++ &block_width, &block_height); + } else { + int swizzle = AMD_FMT_MOD_GET(TILE, modifier); + +@@ -1068,7 +1092,8 @@ static int amdgpu_display_verify_sizes(struct amdgpu_framebuffer *rfb) + return ret; + } + +- if (AMD_FMT_MOD_GET(DCC, modifier)) { ++ if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) <= AMD_FMT_MOD_TILE_VER_GFX11 && ++ AMD_FMT_MOD_GET(DCC, modifier)) { + if (AMD_FMT_MOD_GET(DCC_RETILE, modifier)) { + block_size_log2 = get_dcc_block_size(modifier, false, false); + get_block_dimensions(block_size_log2 + 8, format_info->cpp[0], +diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h +index fb3040677815..5eed091d4c29 100644 +--- a/include/uapi/drm/drm_fourcc.h ++++ b/include/uapi/drm/drm_fourcc.h +@@ -1504,6 +1504,8 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier) + * 6 - 64KB_3D + * 7 - 256KB_3D + */ ++#define AMD_FMT_MOD_TILE_GFX12_256B_2D 1 ++#define AMD_FMT_MOD_TILE_GFX12_4K_2D 2 + #define AMD_FMT_MOD_TILE_GFX12_64K_2D 3 + #define AMD_FMT_MOD_TILE_GFX12_256K_2D 4 + +-- +2.43.0 + diff --git a/queue-6.6/drm-i915-fence-mark-debug_fence_free-with-__maybe_un.patch b/queue-6.6/drm-i915-fence-mark-debug_fence_free-with-__maybe_un.patch new file mode 100644 index 00000000000..3949d49f9c1 --- /dev/null +++ b/queue-6.6/drm-i915-fence-mark-debug_fence_free-with-__maybe_un.patch @@ -0,0 +1,59 @@ +From 306b4aabb8c035d57e856aed581e7b7cb9f7952e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Aug 2024 18:58:38 +0300 +Subject: drm/i915/fence: Mark debug_fence_free() with __maybe_unused + +From: Andy Shevchenko + +[ Upstream commit f99999536128b14b5d765a9982763b5134efdd79 ] + +When debug_fence_free() is unused +(CONFIG_DRM_I915_SW_FENCE_DEBUG_OBJECTS=n), it prevents kernel builds +with clang, `make W=1` and CONFIG_WERROR=y: + +.../i915_sw_fence.c:118:20: error: unused function 'debug_fence_free' [-Werror,-Wunused-function] + 118 | static inline void debug_fence_free(struct i915_sw_fence *fence) + | ^~~~~~~~~~~~~~~~ + +Fix this by marking debug_fence_free() with __maybe_unused. + +See also commit 6863f5643dd7 ("kbuild: allow Clang to find unused static +inline functions for W=1 build"). + +Fixes: fc1584059d6c ("drm/i915: Integrate i915_sw_fence with debugobjects") +Signed-off-by: Andy Shevchenko +Reviewed-by: Jani Nikula +Link: https://patchwork.freedesktop.org/patch/msgid/20240829155950.1141978-3-andriy.shevchenko@linux.intel.com +Signed-off-by: Jani Nikula +(cherry picked from commit 8be4dce5ea6f2368cc25edc71989c4690fa66964) +Signed-off-by: Joonas Lahtinen +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/i915/i915_sw_fence.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c b/drivers/gpu/drm/i915/i915_sw_fence.c +index d4020ff3549a..1d4cc91c0e40 100644 +--- a/drivers/gpu/drm/i915/i915_sw_fence.c ++++ b/drivers/gpu/drm/i915/i915_sw_fence.c +@@ -77,7 +77,7 @@ static inline void debug_fence_destroy(struct i915_sw_fence *fence) + debug_object_destroy(fence, &i915_sw_fence_debug_descr); + } + +-static inline void debug_fence_free(struct i915_sw_fence *fence) ++static inline __maybe_unused void debug_fence_free(struct i915_sw_fence *fence) + { + debug_object_free(fence, &i915_sw_fence_debug_descr); + smp_wmb(); /* flush the change in state before reallocation */ +@@ -115,7 +115,7 @@ static inline void debug_fence_destroy(struct i915_sw_fence *fence) + { + } + +-static inline void debug_fence_free(struct i915_sw_fence *fence) ++static inline __maybe_unused void debug_fence_free(struct i915_sw_fence *fence) + { + } + +-- +2.43.0 + diff --git a/queue-6.6/drm-i915-fence-mark-debug_fence_init_onstack-with-__.patch b/queue-6.6/drm-i915-fence-mark-debug_fence_init_onstack-with-__.patch new file mode 100644 index 00000000000..5f9335e8833 --- /dev/null +++ b/queue-6.6/drm-i915-fence-mark-debug_fence_init_onstack-with-__.patch @@ -0,0 +1,58 @@ +From 13a6d4c7f105a5092c52df6e747925e263ebe167 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Aug 2024 18:58:37 +0300 +Subject: drm/i915/fence: Mark debug_fence_init_onstack() with __maybe_unused + +From: Andy Shevchenko + +[ Upstream commit fcd9e8afd546f6ced378d078345a89bf346d065e ] + +When debug_fence_init_onstack() is unused (CONFIG_DRM_I915_SELFTEST=n), +it prevents kernel builds with clang, `make W=1` and CONFIG_WERROR=y: + +.../i915_sw_fence.c:97:20: error: unused function 'debug_fence_init_onstack' [-Werror,-Wunused-function] + 97 | static inline void debug_fence_init_onstack(struct i915_sw_fence *fence) + | ^~~~~~~~~~~~~~~~~~~~~~~~ + +Fix this by marking debug_fence_init_onstack() with __maybe_unused. + +See also commit 6863f5643dd7 ("kbuild: allow Clang to find unused static +inline functions for W=1 build"). + +Fixes: 214707fc2ce0 ("drm/i915/selftests: Wrap a timer into a i915_sw_fence") +Signed-off-by: Andy Shevchenko +Reviewed-by: Jani Nikula +Link: https://patchwork.freedesktop.org/patch/msgid/20240829155950.1141978-2-andriy.shevchenko@linux.intel.com +Signed-off-by: Jani Nikula +(cherry picked from commit 5bf472058ffb43baf6a4cdfe1d7f58c4c194c688) +Signed-off-by: Joonas Lahtinen +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/i915/i915_sw_fence.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c b/drivers/gpu/drm/i915/i915_sw_fence.c +index 8a9aad523eec..d4020ff3549a 100644 +--- a/drivers/gpu/drm/i915/i915_sw_fence.c ++++ b/drivers/gpu/drm/i915/i915_sw_fence.c +@@ -51,7 +51,7 @@ static inline void debug_fence_init(struct i915_sw_fence *fence) + debug_object_init(fence, &i915_sw_fence_debug_descr); + } + +-static inline void debug_fence_init_onstack(struct i915_sw_fence *fence) ++static inline __maybe_unused void debug_fence_init_onstack(struct i915_sw_fence *fence) + { + debug_object_init_on_stack(fence, &i915_sw_fence_debug_descr); + } +@@ -94,7 +94,7 @@ static inline void debug_fence_init(struct i915_sw_fence *fence) + { + } + +-static inline void debug_fence_init_onstack(struct i915_sw_fence *fence) ++static inline __maybe_unused void debug_fence_init_onstack(struct i915_sw_fence *fence) + { + } + +-- +2.43.0 + diff --git a/queue-6.6/gpio-modepin-enable-module-autoloading.patch b/queue-6.6/gpio-modepin-enable-module-autoloading.patch new file mode 100644 index 00000000000..b0b4dd84165 --- /dev/null +++ b/queue-6.6/gpio-modepin-enable-module-autoloading.patch @@ -0,0 +1,37 @@ +From bdfc4fc4830a81c9c00c223491e54a2565dcc078 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Sep 2024 11:58:48 +0000 +Subject: gpio: modepin: Enable module autoloading + +From: Liao Chen + +[ Upstream commit a5135526426df5319d5f4bcd15ae57c45a97714b ] + +Add MODULE_DEVICE_TABLE(), so modules could be properly autoloaded based +on the alias from of_device_id table. + +Fixes: 7687a5b0ee93 ("gpio: modepin: Add driver support for modepin GPIO controller") +Signed-off-by: Liao Chen +Reviewed-by: Michal Simek +Link: https://lore.kernel.org/r/20240902115848.904227-1-liaochen4@huawei.com +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpio-zynqmp-modepin.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpio/gpio-zynqmp-modepin.c b/drivers/gpio/gpio-zynqmp-modepin.c +index a0d69387c153..2f3c9ebfa78d 100644 +--- a/drivers/gpio/gpio-zynqmp-modepin.c ++++ b/drivers/gpio/gpio-zynqmp-modepin.c +@@ -146,6 +146,7 @@ static const struct of_device_id modepin_platform_id[] = { + { .compatible = "xlnx,zynqmp-gpio-modepin", }, + { } + }; ++MODULE_DEVICE_TABLE(of, modepin_platform_id); + + static struct platform_driver modepin_platform_driver = { + .driver = { +-- +2.43.0 + diff --git a/queue-6.6/gpio-rockchip-fix-of-node-leak-in-probe.patch b/queue-6.6/gpio-rockchip-fix-of-node-leak-in-probe.patch new file mode 100644 index 00000000000..07c3451aa58 --- /dev/null +++ b/queue-6.6/gpio-rockchip-fix-of-node-leak-in-probe.patch @@ -0,0 +1,38 @@ +From 4ac663fa429b8dfa4570a35c82be326aca3e7c2d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 26 Aug 2024 17:08:32 +0200 +Subject: gpio: rockchip: fix OF node leak in probe() + +From: Krzysztof Kozlowski + +[ Upstream commit adad2e460e505a556f5ea6f0dc16fe95e62d5d76 ] + +Driver code is leaking OF node reference from of_get_parent() in +probe(). + +Fixes: 936ee2675eee ("gpio/rockchip: add driver for rockchip gpio") +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Heiko Stuebner +Reviewed-by: Shawn Lin +Link: https://lore.kernel.org/r/20240826150832.65657-1-krzysztof.kozlowski@linaro.org +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpio-rockchip.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c +index b35b9604413f..caeb3bdc78f8 100644 +--- a/drivers/gpio/gpio-rockchip.c ++++ b/drivers/gpio/gpio-rockchip.c +@@ -713,6 +713,7 @@ static int rockchip_gpio_probe(struct platform_device *pdev) + return -ENODEV; + + pctldev = of_pinctrl_get(pctlnp); ++ of_node_put(pctlnp); + if (!pctldev) + return -EPROBE_DEFER; + +-- +2.43.0 + diff --git a/queue-6.6/nvme-pci-allocate-tagset-on-reset-if-necessary.patch b/queue-6.6/nvme-pci-allocate-tagset-on-reset-if-necessary.patch new file mode 100644 index 00000000000..289451a3b2f --- /dev/null +++ b/queue-6.6/nvme-pci-allocate-tagset-on-reset-if-necessary.patch @@ -0,0 +1,43 @@ +From cf4ca3642d32cbbe78bf1034aaed7a7b39050316 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 26 Aug 2024 11:20:57 -0700 +Subject: nvme-pci: allocate tagset on reset if necessary + +From: Keith Busch + +[ Upstream commit 6f01bdbfef3b62955cf6503a8425d527b3a5cf94 ] + +If a drive is unable to create IO queues on the initial probe, a +subsequent reset will need to allocate the tagset if IO queue creation +is successful. Without this, blk_mq_update_nr_hw_queues will crash on a +bad pointer due to the invalid tagset. + +Fixes: eac3ef262941f62 ("nvme-pci: split the initial probe from the rest path") +Reviewed-by: Sagi Grimberg +Reviewed-by: Christoph Hellwig +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/pci.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 89e0798af780..7fc1ab4d9e7d 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -2471,6 +2471,12 @@ static unsigned int nvme_pci_nr_maps(struct nvme_dev *dev) + + static void nvme_pci_update_nr_queues(struct nvme_dev *dev) + { ++ if (!dev->ctrl.tagset) { ++ nvme_alloc_io_tag_set(&dev->ctrl, &dev->tagset, &nvme_mq_ops, ++ nvme_pci_nr_maps(dev), sizeof(struct nvme_iod)); ++ return; ++ } ++ + blk_mq_update_nr_hw_queues(&dev->tagset, dev->online_queues - 1); + /* free previously allocated queues that are no longer usable */ + nvme_free_queues(dev, dev->online_queues); +-- +2.43.0 + diff --git a/queue-6.6/nvmet-tcp-fix-kernel-crash-if-commands-allocation-fa.patch b/queue-6.6/nvmet-tcp-fix-kernel-crash-if-commands-allocation-fa.patch new file mode 100644 index 00000000000..af6c8ed596f --- /dev/null +++ b/queue-6.6/nvmet-tcp-fix-kernel-crash-if-commands-allocation-fa.patch @@ -0,0 +1,48 @@ +From 281c5c0e41765cdc44791e3332336739c0d682bd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Aug 2024 16:28:26 +0200 +Subject: nvmet-tcp: fix kernel crash if commands allocation fails + +From: Maurizio Lombardi + +[ Upstream commit 5572a55a6f830ee3f3a994b6b962a5c327d28cb3 ] + +If the commands allocation fails in nvmet_tcp_alloc_cmds() +the kernel crashes in nvmet_tcp_release_queue_work() because of +a NULL pointer dereference. + + nvmet: failed to install queue 0 cntlid 1 ret 6 + Unable to handle kernel NULL pointer dereference at + virtual address 0000000000000008 + +Fix the bug by setting queue->nr_cmds to zero in case +nvmet_tcp_alloc_cmd() fails. + +Fixes: 872d26a391da ("nvmet-tcp: add NVMe over TCP target driver") +Signed-off-by: Maurizio Lombardi +Reviewed-by: Christoph Hellwig +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/target/tcp.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c +index c65a1f4421f6..bd142aed20f4 100644 +--- a/drivers/nvme/target/tcp.c ++++ b/drivers/nvme/target/tcp.c +@@ -1859,8 +1859,10 @@ static u16 nvmet_tcp_install_queue(struct nvmet_sq *sq) + } + + queue->nr_cmds = sq->size * 2; +- if (nvmet_tcp_alloc_cmds(queue)) ++ if (nvmet_tcp_alloc_cmds(queue)) { ++ queue->nr_cmds = 0; + return NVME_SC_INTERNAL; ++ } + return 0; + } + +-- +2.43.0 + diff --git a/queue-6.6/powerpc-64e-define-mmu_pte_psize-static.patch b/queue-6.6/powerpc-64e-define-mmu_pte_psize-static.patch new file mode 100644 index 00000000000..27bf33f5815 --- /dev/null +++ b/queue-6.6/powerpc-64e-define-mmu_pte_psize-static.patch @@ -0,0 +1,38 @@ +From 9f5bea0c165045bd8bd6a50d9bc22581088e4f29 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 20 Aug 2024 14:42:38 +0200 +Subject: powerpc/64e: Define mmu_pte_psize static + +From: Christophe Leroy + +[ Upstream commit d92b5cc29c792f1d3f0aaa3b29dddfe816c03e88 ] + +mmu_pte_psize is only used in the tlb_64e.c, define it static. + +Fixes: 25d21ad6e799 ("powerpc: Add TLB management code for 64-bit Book3E") +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202408011256.1O99IB0s-lkp@intel.com/ +Signed-off-by: Christophe Leroy +Signed-off-by: Michael Ellerman +Link: https://msgid.link/beb30d280eaa5d857c38a0834b147dffd6b28aa9.1724157750.git.christophe.leroy@csgroup.eu +Signed-off-by: Sasha Levin +--- + arch/powerpc/mm/nohash/tlb_64e.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/powerpc/mm/nohash/tlb_64e.c b/arch/powerpc/mm/nohash/tlb_64e.c +index 1dcda261554c..b6af3ec4d001 100644 +--- a/arch/powerpc/mm/nohash/tlb_64e.c ++++ b/arch/powerpc/mm/nohash/tlb_64e.c +@@ -33,7 +33,7 @@ + * though this will probably be made common with other nohash + * implementations at some point + */ +-int mmu_pte_psize; /* Page size used for PTE pages */ ++static int mmu_pte_psize; /* Page size used for PTE pages */ + int mmu_vmemmap_psize; /* Page size used for the virtual mem map */ + int book3e_htw_mode; /* HW tablewalk? Value is PPC_HTW_* */ + unsigned long linear_map_top; /* Top of linear mapping */ +-- +2.43.0 + diff --git a/queue-6.6/powerpc-64e-remove-unused-ibm-htw-code.patch b/queue-6.6/powerpc-64e-remove-unused-ibm-htw-code.patch new file mode 100644 index 00000000000..0e04f1c25d5 --- /dev/null +++ b/queue-6.6/powerpc-64e-remove-unused-ibm-htw-code.patch @@ -0,0 +1,380 @@ +From 3e86587442166b6a746e49d83f70afca56019922 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 Jul 2024 15:51:13 +0200 +Subject: powerpc/64e: remove unused IBM HTW code + +From: Michael Ellerman + +[ Upstream commit 88715b6e5d529f4ef3830ad2a893e4624c6af0b8 ] + +Patch series "Reimplement huge pages without hugepd on powerpc (8xx, e500, +book3s/64)", v7. + +Unlike most architectures, powerpc 8xx HW requires a two-level pagetable +topology for all page sizes. So a leaf PMD-contig approach is not +feasible as such. + +Possible sizes on 8xx are 4k, 16k, 512k and 8M. + +First level (PGD/PMD) covers 4M per entry. For 8M pages, two PMD entries +must point to a single entry level-2 page table. Until now that was done +using hugepd. This series changes it to use standard page tables where +the entry is replicated 1024 times on each of the two pagetables refered +by the two associated PMD entries for that 8M page. + +For e500 and book3s/64 there are less constraints because it is not tied +to the HW assisted tablewalk like on 8xx, so it is easier to use leaf PMDs +(and PUDs). + +On e500 the supported page sizes are 4M, 16M, 64M, 256M and 1G. All at +PMD level on e500/32 (mpc85xx) and mix of PMD and PUD for e500/64. We +encode page size with 4 available bits in PTE entries. On e300/32 PGD +entries size is increases to 64 bits in order to allow leaf-PMD entries +because PTE are 64 bits on e500. + +On book3s/64 only the hash-4k mode is concerned. It supports 16M pages as +cont-PMD and 16G pages as cont-PUD. In other modes (radix-4k, radix-6k +and hash-64k) the sizes match with PMD and PUD sizes so that's just leaf +entries. The hash processing make things a bit more complex. To ease +things, __hash_page_huge() is modified to bail out when DIRTY or ACCESSED +bits are missing, leaving it to mm core to fix it. + +This patch (of 23): + +The nohash HTW_IBM (Hardware Table Walk) code is unused since support for +A2 was removed in commit fb5a515704d7 ("powerpc: Remove platforms/ wsp and +associated pieces") (2014). + +The remaining supported CPUs use either no HTW (data_tlb_miss_bolted), or +the e6500 HTW (data_tlb_miss_e6500). + +Link: https://lkml.kernel.org/r/cover.1719928057.git.christophe.leroy@csgroup.eu +Link: https://lkml.kernel.org/r/820dd1385ecc931f07b0d7a0fa827b1613917ab6.1719928057.git.christophe.leroy@csgroup.eu +Signed-off-by: Michael Ellerman +Signed-off-by: Christophe Leroy +Cc: Jason Gunthorpe +Cc: Nicholas Piggin +Cc: Oscar Salvador +Cc: Peter Xu +Signed-off-by: Andrew Morton +Stable-dep-of: d92b5cc29c79 ("powerpc/64e: Define mmu_pte_psize static") +Signed-off-by: Sasha Levin +--- + arch/powerpc/include/asm/nohash/mmu-e500.h | 3 +- + arch/powerpc/mm/nohash/tlb.c | 57 +----- + arch/powerpc/mm/nohash/tlb_low_64e.S | 195 --------------------- + 3 files changed, 2 insertions(+), 253 deletions(-) + +diff --git a/arch/powerpc/include/asm/nohash/mmu-e500.h b/arch/powerpc/include/asm/nohash/mmu-e500.h +index 6ddced0415cb..7dc24b8632d7 100644 +--- a/arch/powerpc/include/asm/nohash/mmu-e500.h ++++ b/arch/powerpc/include/asm/nohash/mmu-e500.h +@@ -303,8 +303,7 @@ extern unsigned long linear_map_top; + extern int book3e_htw_mode; + + #define PPC_HTW_NONE 0 +-#define PPC_HTW_IBM 1 +-#define PPC_HTW_E6500 2 ++#define PPC_HTW_E6500 1 + + /* + * 64-bit booke platforms don't load the tlb in the tlb miss handler code. +diff --git a/arch/powerpc/mm/nohash/tlb.c b/arch/powerpc/mm/nohash/tlb.c +index 5ffa0af4328a..a5bb87ec8578 100644 +--- a/arch/powerpc/mm/nohash/tlb.c ++++ b/arch/powerpc/mm/nohash/tlb.c +@@ -400,9 +400,8 @@ void tlb_flush_pgtable(struct mmu_gather *tlb, unsigned long address) + static void __init setup_page_sizes(void) + { + unsigned int tlb0cfg; +- unsigned int tlb0ps; + unsigned int eptcfg; +- int i, psize; ++ int psize; + + #ifdef CONFIG_PPC_E500 + unsigned int mmucfg = mfspr(SPRN_MMUCFG); +@@ -471,50 +470,6 @@ static void __init setup_page_sizes(void) + goto out; + } + #endif +- +- tlb0cfg = mfspr(SPRN_TLB0CFG); +- tlb0ps = mfspr(SPRN_TLB0PS); +- eptcfg = mfspr(SPRN_EPTCFG); +- +- /* Look for supported direct sizes */ +- for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { +- struct mmu_psize_def *def = &mmu_psize_defs[psize]; +- +- if (tlb0ps & (1U << (def->shift - 10))) +- def->flags |= MMU_PAGE_SIZE_DIRECT; +- } +- +- /* Indirect page sizes supported ? */ +- if ((tlb0cfg & TLBnCFG_IND) == 0 || +- (tlb0cfg & TLBnCFG_PT) == 0) +- goto out; +- +- book3e_htw_mode = PPC_HTW_IBM; +- +- /* Now, we only deal with one IND page size for each +- * direct size. Hopefully all implementations today are +- * unambiguous, but we might want to be careful in the +- * future. +- */ +- for (i = 0; i < 3; i++) { +- unsigned int ps, sps; +- +- sps = eptcfg & 0x1f; +- eptcfg >>= 5; +- ps = eptcfg & 0x1f; +- eptcfg >>= 5; +- if (!ps || !sps) +- continue; +- for (psize = 0; psize < MMU_PAGE_COUNT; psize++) { +- struct mmu_psize_def *def = &mmu_psize_defs[psize]; +- +- if (ps == (def->shift - 10)) +- def->flags |= MMU_PAGE_SIZE_INDIRECT; +- if (sps == (def->shift - 10)) +- def->ind = ps + 10; +- } +- } +- + out: + /* Cleanup array and print summary */ + pr_info("MMU: Supported page sizes\n"); +@@ -543,10 +498,6 @@ static void __init setup_mmu_htw(void) + */ + + switch (book3e_htw_mode) { +- case PPC_HTW_IBM: +- patch_exception(0x1c0, exc_data_tlb_miss_htw_book3e); +- patch_exception(0x1e0, exc_instruction_tlb_miss_htw_book3e); +- break; + #ifdef CONFIG_PPC_E500 + case PPC_HTW_E6500: + extlb_level_exc = EX_TLB_SIZE; +@@ -577,12 +528,6 @@ static void early_init_this_mmu(void) + mmu_pte_psize = MMU_PAGE_2M; + break; + +- case PPC_HTW_IBM: +- mas4 |= MAS4_INDD; +- mas4 |= BOOK3E_PAGESZ_1M << MAS4_TSIZED_SHIFT; +- mmu_pte_psize = MMU_PAGE_1M; +- break; +- + case PPC_HTW_NONE: + mas4 |= BOOK3E_PAGESZ_4K << MAS4_TSIZED_SHIFT; + mmu_pte_psize = mmu_virtual_psize; +diff --git a/arch/powerpc/mm/nohash/tlb_low_64e.S b/arch/powerpc/mm/nohash/tlb_low_64e.S +index 7e0b8fe1c279..b0eb3f7eaed1 100644 +--- a/arch/powerpc/mm/nohash/tlb_low_64e.S ++++ b/arch/powerpc/mm/nohash/tlb_low_64e.S +@@ -893,201 +893,6 @@ virt_page_table_tlb_miss_whacko_fault: + TLB_MISS_EPILOG_ERROR + b exc_data_storage_book3e + +- +-/************************************************************** +- * * +- * TLB miss handling for Book3E with hw page table support * +- * * +- **************************************************************/ +- +- +-/* Data TLB miss */ +- START_EXCEPTION(data_tlb_miss_htw) +- TLB_MISS_PROLOG +- +- /* Now we handle the fault proper. We only save DEAR in normal +- * fault case since that's the only interesting values here. +- * We could probably also optimize by not saving SRR0/1 in the +- * linear mapping case but I'll leave that for later +- */ +- mfspr r14,SPRN_ESR +- mfspr r16,SPRN_DEAR /* get faulting address */ +- srdi r11,r16,44 /* get region */ +- xoris r11,r11,0xc +- cmpldi cr0,r11,0 /* linear mapping ? */ +- beq tlb_load_linear /* yes -> go to linear map load */ +- cmpldi cr1,r11,1 /* vmalloc mapping ? */ +- +- /* We do the user/kernel test for the PID here along with the RW test +- */ +- srdi. r11,r16,60 /* Check for user region */ +- ld r15,PACAPGD(r13) /* Load user pgdir */ +- beq htw_tlb_miss +- +- /* XXX replace the RMW cycles with immediate loads + writes */ +-1: mfspr r10,SPRN_MAS1 +- rlwinm r10,r10,0,16,1 /* Clear TID */ +- mtspr SPRN_MAS1,r10 +- ld r15,PACA_KERNELPGD(r13) /* Load kernel pgdir */ +- beq+ cr1,htw_tlb_miss +- +- /* We got a crappy address, just fault with whatever DEAR and ESR +- * are here +- */ +- TLB_MISS_EPILOG_ERROR +- b exc_data_storage_book3e +- +-/* Instruction TLB miss */ +- START_EXCEPTION(instruction_tlb_miss_htw) +- TLB_MISS_PROLOG +- +- /* If we take a recursive fault, the second level handler may need +- * to know whether we are handling a data or instruction fault in +- * order to get to the right store fault handler. We provide that +- * info by keeping a crazy value for ESR in r14 +- */ +- li r14,-1 /* store to exception frame is done later */ +- +- /* Now we handle the fault proper. We only save DEAR in the non +- * linear mapping case since we know the linear mapping case will +- * not re-enter. We could indeed optimize and also not save SRR0/1 +- * in the linear mapping case but I'll leave that for later +- * +- * Faulting address is SRR0 which is already in r16 +- */ +- srdi r11,r16,44 /* get region */ +- xoris r11,r11,0xc +- cmpldi cr0,r11,0 /* linear mapping ? */ +- beq tlb_load_linear /* yes -> go to linear map load */ +- cmpldi cr1,r11,1 /* vmalloc mapping ? */ +- +- /* We do the user/kernel test for the PID here along with the RW test +- */ +- srdi. r11,r16,60 /* Check for user region */ +- ld r15,PACAPGD(r13) /* Load user pgdir */ +- beq htw_tlb_miss +- +- /* XXX replace the RMW cycles with immediate loads + writes */ +-1: mfspr r10,SPRN_MAS1 +- rlwinm r10,r10,0,16,1 /* Clear TID */ +- mtspr SPRN_MAS1,r10 +- ld r15,PACA_KERNELPGD(r13) /* Load kernel pgdir */ +- beq+ htw_tlb_miss +- +- /* We got a crappy address, just fault */ +- TLB_MISS_EPILOG_ERROR +- b exc_instruction_storage_book3e +- +- +-/* +- * This is the guts of the second-level TLB miss handler for direct +- * misses. We are entered with: +- * +- * r16 = virtual page table faulting address +- * r15 = PGD pointer +- * r14 = ESR +- * r13 = PACA +- * r12 = TLB exception frame in PACA +- * r11 = crap (free to use) +- * r10 = crap (free to use) +- * +- * It can be re-entered by the linear mapping miss handler. However, to +- * avoid too much complication, it will save/restore things for us +- */ +-htw_tlb_miss: +-#ifdef CONFIG_PPC_KUAP +- mfspr r10,SPRN_MAS1 +- rlwinm. r10,r10,0,0x3fff0000 +- beq- htw_tlb_miss_fault /* KUAP fault */ +-#endif +- /* Search if we already have a TLB entry for that virtual address, and +- * if we do, bail out. +- * +- * MAS1:IND should be already set based on MAS4 +- */ +- PPC_TLBSRX_DOT(0,R16) +- beq htw_tlb_miss_done +- +- /* Now, we need to walk the page tables. First check if we are in +- * range. +- */ +- rldicl. r10,r16,64-PGTABLE_EADDR_SIZE,PGTABLE_EADDR_SIZE+4 +- bne- htw_tlb_miss_fault +- +- /* Get the PGD pointer */ +- cmpldi cr0,r15,0 +- beq- htw_tlb_miss_fault +- +- /* Get to PGD entry */ +- rldicl r11,r16,64-(PGDIR_SHIFT-3),64-PGD_INDEX_SIZE-3 +- clrrdi r10,r11,3 +- ldx r15,r10,r15 +- cmpdi cr0,r15,0 +- bge htw_tlb_miss_fault +- +- /* Get to PUD entry */ +- rldicl r11,r16,64-(PUD_SHIFT-3),64-PUD_INDEX_SIZE-3 +- clrrdi r10,r11,3 +- ldx r15,r10,r15 +- cmpdi cr0,r15,0 +- bge htw_tlb_miss_fault +- +- /* Get to PMD entry */ +- rldicl r11,r16,64-(PMD_SHIFT-3),64-PMD_INDEX_SIZE-3 +- clrrdi r10,r11,3 +- ldx r15,r10,r15 +- cmpdi cr0,r15,0 +- bge htw_tlb_miss_fault +- +- /* Ok, we're all right, we can now create an indirect entry for +- * a 1M or 256M page. +- * +- * The last trick is now that because we use "half" pages for +- * the HTW (1M IND is 2K and 256M IND is 32K) we need to account +- * for an added LSB bit to the RPN. For 64K pages, there is no +- * problem as we already use 32K arrays (half PTE pages), but for +- * 4K page we need to extract a bit from the virtual address and +- * insert it into the "PA52" bit of the RPN. +- */ +- rlwimi r15,r16,32-9,20,20 +- /* Now we build the MAS: +- * +- * MAS 0 : Fully setup with defaults in MAS4 and TLBnCFG +- * MAS 1 : Almost fully setup +- * - PID already updated by caller if necessary +- * - TSIZE for now is base ind page size always +- * MAS 2 : Use defaults +- * MAS 3+7 : Needs to be done +- */ +- ori r10,r15,(BOOK3E_PAGESZ_4K << MAS3_SPSIZE_SHIFT) +- +- srdi r16,r10,32 +- mtspr SPRN_MAS3,r10 +- mtspr SPRN_MAS7,r16 +- +- tlbwe +- +-htw_tlb_miss_done: +- /* We don't bother with restoring DEAR or ESR since we know we are +- * level 0 and just going back to userland. They are only needed +- * if you are going to take an access fault +- */ +- TLB_MISS_EPILOG_SUCCESS +- rfi +- +-htw_tlb_miss_fault: +- /* We need to check if it was an instruction miss. We know this +- * though because r14 would contain -1 +- */ +- cmpdi cr0,r14,-1 +- beq 1f +- mtspr SPRN_DEAR,r16 +- mtspr SPRN_ESR,r14 +- TLB_MISS_EPILOG_ERROR +- b exc_data_storage_book3e +-1: TLB_MISS_EPILOG_ERROR +- b exc_instruction_storage_book3e +- + /* + * This is the guts of "any" level TLB miss handler for kernel linear + * mapping misses. We are entered with: +-- +2.43.0 + diff --git a/queue-6.6/powerpc-64e-split-out-nohash-book3e-64-bit-code.patch b/queue-6.6/powerpc-64e-split-out-nohash-book3e-64-bit-code.patch new file mode 100644 index 00000000000..e57ba82b2a0 --- /dev/null +++ b/queue-6.6/powerpc-64e-split-out-nohash-book3e-64-bit-code.patch @@ -0,0 +1,773 @@ +From e914138cb80f239dd64c099a01e6a1fa3d62336c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 Jul 2024 15:51:14 +0200 +Subject: powerpc/64e: split out nohash Book3E 64-bit code + +From: Michael Ellerman + +[ Upstream commit a898530eea3d0ba08c17a60865995a3bb468d1bc ] + +A reasonable chunk of nohash/tlb.c is 64-bit only code, split it out into +a separate file. + +Link: https://lkml.kernel.org/r/cb2b118f9d8a86f82d01bfb9ad309d1d304480a1.1719928057.git.christophe.leroy@csgroup.eu +Signed-off-by: Michael Ellerman +Signed-off-by: Christophe Leroy +Cc: Jason Gunthorpe +Cc: Nicholas Piggin +Cc: Oscar Salvador +Cc: Peter Xu +Signed-off-by: Andrew Morton +Stable-dep-of: d92b5cc29c79 ("powerpc/64e: Define mmu_pte_psize static") +Signed-off-by: Sasha Levin +--- + arch/powerpc/mm/nohash/Makefile | 2 +- + arch/powerpc/mm/nohash/tlb.c | 343 +---------------------------- + arch/powerpc/mm/nohash/tlb_64e.c | 361 +++++++++++++++++++++++++++++++ + 3 files changed, 363 insertions(+), 343 deletions(-) + create mode 100644 arch/powerpc/mm/nohash/tlb_64e.c + +diff --git a/arch/powerpc/mm/nohash/Makefile b/arch/powerpc/mm/nohash/Makefile +index f3894e79d5f7..24b445a5fcac 100644 +--- a/arch/powerpc/mm/nohash/Makefile ++++ b/arch/powerpc/mm/nohash/Makefile +@@ -3,7 +3,7 @@ + ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC) + + obj-y += mmu_context.o tlb.o tlb_low.o kup.o +-obj-$(CONFIG_PPC_BOOK3E_64) += tlb_low_64e.o book3e_pgtable.o ++obj-$(CONFIG_PPC_BOOK3E_64) += tlb_64e.o tlb_low_64e.o book3e_pgtable.o + obj-$(CONFIG_40x) += 40x.o + obj-$(CONFIG_44x) += 44x.o + obj-$(CONFIG_PPC_8xx) += 8xx.o +diff --git a/arch/powerpc/mm/nohash/tlb.c b/arch/powerpc/mm/nohash/tlb.c +index a5bb87ec8578..f57dc721d063 100644 +--- a/arch/powerpc/mm/nohash/tlb.c ++++ b/arch/powerpc/mm/nohash/tlb.c +@@ -110,28 +110,6 @@ struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = { + }; + #endif + +-/* The variables below are currently only used on 64-bit Book3E +- * though this will probably be made common with other nohash +- * implementations at some point +- */ +-#ifdef CONFIG_PPC64 +- +-int mmu_pte_psize; /* Page size used for PTE pages */ +-int mmu_vmemmap_psize; /* Page size used for the virtual mem map */ +-int book3e_htw_mode; /* HW tablewalk? Value is PPC_HTW_* */ +-unsigned long linear_map_top; /* Top of linear mapping */ +- +- +-/* +- * Number of bytes to add to SPRN_SPRG_TLB_EXFRAME on crit/mcheck/debug +- * exceptions. This is used for bolted and e6500 TLB miss handlers which +- * do not modify this SPRG in the TLB miss code; for other TLB miss handlers, +- * this is set to zero. +- */ +-int extlb_level_exc; +- +-#endif /* CONFIG_PPC64 */ +- + #ifdef CONFIG_PPC_E500 + /* next_tlbcam_idx is used to round-robin tlbcam entry assignment */ + DEFINE_PER_CPU(int, next_tlbcam_idx); +@@ -358,326 +336,7 @@ void tlb_flush(struct mmu_gather *tlb) + flush_tlb_mm(tlb->mm); + } + +-/* +- * Below are functions specific to the 64-bit variant of Book3E though that +- * may change in the future +- */ +- +-#ifdef CONFIG_PPC64 +- +-/* +- * Handling of virtual linear page tables or indirect TLB entries +- * flushing when PTE pages are freed +- */ +-void tlb_flush_pgtable(struct mmu_gather *tlb, unsigned long address) +-{ +- int tsize = mmu_psize_defs[mmu_pte_psize].enc; +- +- if (book3e_htw_mode != PPC_HTW_NONE) { +- unsigned long start = address & PMD_MASK; +- unsigned long end = address + PMD_SIZE; +- unsigned long size = 1UL << mmu_psize_defs[mmu_pte_psize].shift; +- +- /* This isn't the most optimal, ideally we would factor out the +- * while preempt & CPU mask mucking around, or even the IPI but +- * it will do for now +- */ +- while (start < end) { +- __flush_tlb_page(tlb->mm, start, tsize, 1); +- start += size; +- } +- } else { +- unsigned long rmask = 0xf000000000000000ul; +- unsigned long rid = (address & rmask) | 0x1000000000000000ul; +- unsigned long vpte = address & ~rmask; +- +- vpte = (vpte >> (PAGE_SHIFT - 3)) & ~0xffful; +- vpte |= rid; +- __flush_tlb_page(tlb->mm, vpte, tsize, 0); +- } +-} +- +-static void __init setup_page_sizes(void) +-{ +- unsigned int tlb0cfg; +- unsigned int eptcfg; +- int psize; +- +-#ifdef CONFIG_PPC_E500 +- unsigned int mmucfg = mfspr(SPRN_MMUCFG); +- int fsl_mmu = mmu_has_feature(MMU_FTR_TYPE_FSL_E); +- +- if (fsl_mmu && (mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V1) { +- unsigned int tlb1cfg = mfspr(SPRN_TLB1CFG); +- unsigned int min_pg, max_pg; +- +- min_pg = (tlb1cfg & TLBnCFG_MINSIZE) >> TLBnCFG_MINSIZE_SHIFT; +- max_pg = (tlb1cfg & TLBnCFG_MAXSIZE) >> TLBnCFG_MAXSIZE_SHIFT; +- +- for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { +- struct mmu_psize_def *def; +- unsigned int shift; +- +- def = &mmu_psize_defs[psize]; +- shift = def->shift; +- +- if (shift == 0 || shift & 1) +- continue; +- +- /* adjust to be in terms of 4^shift Kb */ +- shift = (shift - 10) >> 1; +- +- if ((shift >= min_pg) && (shift <= max_pg)) +- def->flags |= MMU_PAGE_SIZE_DIRECT; +- } +- +- goto out; +- } +- +- if (fsl_mmu && (mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V2) { +- u32 tlb1cfg, tlb1ps; +- +- tlb0cfg = mfspr(SPRN_TLB0CFG); +- tlb1cfg = mfspr(SPRN_TLB1CFG); +- tlb1ps = mfspr(SPRN_TLB1PS); +- eptcfg = mfspr(SPRN_EPTCFG); +- +- if ((tlb1cfg & TLBnCFG_IND) && (tlb0cfg & TLBnCFG_PT)) +- book3e_htw_mode = PPC_HTW_E6500; +- +- /* +- * We expect 4K subpage size and unrestricted indirect size. +- * The lack of a restriction on indirect size is a Freescale +- * extension, indicated by PSn = 0 but SPSn != 0. +- */ +- if (eptcfg != 2) +- book3e_htw_mode = PPC_HTW_NONE; +- +- for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { +- struct mmu_psize_def *def = &mmu_psize_defs[psize]; +- +- if (!def->shift) +- continue; +- +- if (tlb1ps & (1U << (def->shift - 10))) { +- def->flags |= MMU_PAGE_SIZE_DIRECT; +- +- if (book3e_htw_mode && psize == MMU_PAGE_2M) +- def->flags |= MMU_PAGE_SIZE_INDIRECT; +- } +- } +- +- goto out; +- } +-#endif +-out: +- /* Cleanup array and print summary */ +- pr_info("MMU: Supported page sizes\n"); +- for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { +- struct mmu_psize_def *def = &mmu_psize_defs[psize]; +- const char *__page_type_names[] = { +- "unsupported", +- "direct", +- "indirect", +- "direct & indirect" +- }; +- if (def->flags == 0) { +- def->shift = 0; +- continue; +- } +- pr_info(" %8ld KB as %s\n", 1ul << (def->shift - 10), +- __page_type_names[def->flags & 0x3]); +- } +-} +- +-static void __init setup_mmu_htw(void) +-{ +- /* +- * If we want to use HW tablewalk, enable it by patching the TLB miss +- * handlers to branch to the one dedicated to it. +- */ +- +- switch (book3e_htw_mode) { +-#ifdef CONFIG_PPC_E500 +- case PPC_HTW_E6500: +- extlb_level_exc = EX_TLB_SIZE; +- patch_exception(0x1c0, exc_data_tlb_miss_e6500_book3e); +- patch_exception(0x1e0, exc_instruction_tlb_miss_e6500_book3e); +- break; +-#endif +- } +- pr_info("MMU: Book3E HW tablewalk %s\n", +- book3e_htw_mode != PPC_HTW_NONE ? "enabled" : "not supported"); +-} +- +-/* +- * Early initialization of the MMU TLB code +- */ +-static void early_init_this_mmu(void) +-{ +- unsigned int mas4; +- +- /* Set MAS4 based on page table setting */ +- +- mas4 = 0x4 << MAS4_WIMGED_SHIFT; +- switch (book3e_htw_mode) { +- case PPC_HTW_E6500: +- mas4 |= MAS4_INDD; +- mas4 |= BOOK3E_PAGESZ_2M << MAS4_TSIZED_SHIFT; +- mas4 |= MAS4_TLBSELD(1); +- mmu_pte_psize = MMU_PAGE_2M; +- break; +- +- case PPC_HTW_NONE: +- mas4 |= BOOK3E_PAGESZ_4K << MAS4_TSIZED_SHIFT; +- mmu_pte_psize = mmu_virtual_psize; +- break; +- } +- mtspr(SPRN_MAS4, mas4); +- +-#ifdef CONFIG_PPC_E500 +- if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) { +- unsigned int num_cams; +- bool map = true; +- +- /* use a quarter of the TLBCAM for bolted linear map */ +- num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4; +- +- /* +- * Only do the mapping once per core, or else the +- * transient mapping would cause problems. +- */ +-#ifdef CONFIG_SMP +- if (hweight32(get_tensr()) > 1) +- map = false; +-#endif +- +- if (map) +- linear_map_top = map_mem_in_cams(linear_map_top, +- num_cams, false, true); +- } +-#endif +- +- /* A sync won't hurt us after mucking around with +- * the MMU configuration +- */ +- mb(); +-} +- +-static void __init early_init_mmu_global(void) +-{ +- /* XXX This should be decided at runtime based on supported +- * page sizes in the TLB, but for now let's assume 16M is +- * always there and a good fit (which it probably is) +- * +- * Freescale booke only supports 4K pages in TLB0, so use that. +- */ +- if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) +- mmu_vmemmap_psize = MMU_PAGE_4K; +- else +- mmu_vmemmap_psize = MMU_PAGE_16M; +- +- /* XXX This code only checks for TLB 0 capabilities and doesn't +- * check what page size combos are supported by the HW. It +- * also doesn't handle the case where a separate array holds +- * the IND entries from the array loaded by the PT. +- */ +- /* Look for supported page sizes */ +- setup_page_sizes(); +- +- /* Look for HW tablewalk support */ +- setup_mmu_htw(); +- +-#ifdef CONFIG_PPC_E500 +- if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) { +- if (book3e_htw_mode == PPC_HTW_NONE) { +- extlb_level_exc = EX_TLB_SIZE; +- patch_exception(0x1c0, exc_data_tlb_miss_bolted_book3e); +- patch_exception(0x1e0, +- exc_instruction_tlb_miss_bolted_book3e); +- } +- } +-#endif +- +- /* Set the global containing the top of the linear mapping +- * for use by the TLB miss code +- */ +- linear_map_top = memblock_end_of_DRAM(); +- +- ioremap_bot = IOREMAP_BASE; +-} +- +-static void __init early_mmu_set_memory_limit(void) +-{ +-#ifdef CONFIG_PPC_E500 +- if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) { +- /* +- * Limit memory so we dont have linear faults. +- * Unlike memblock_set_current_limit, which limits +- * memory available during early boot, this permanently +- * reduces the memory available to Linux. We need to +- * do this because highmem is not supported on 64-bit. +- */ +- memblock_enforce_memory_limit(linear_map_top); +- } +-#endif +- +- memblock_set_current_limit(linear_map_top); +-} +- +-/* boot cpu only */ +-void __init early_init_mmu(void) +-{ +- early_init_mmu_global(); +- early_init_this_mmu(); +- early_mmu_set_memory_limit(); +-} +- +-void early_init_mmu_secondary(void) +-{ +- early_init_this_mmu(); +-} +- +-void setup_initial_memory_limit(phys_addr_t first_memblock_base, +- phys_addr_t first_memblock_size) +-{ +- /* On non-FSL Embedded 64-bit, we adjust the RMA size to match +- * the bolted TLB entry. We know for now that only 1G +- * entries are supported though that may eventually +- * change. +- * +- * on FSL Embedded 64-bit, usually all RAM is bolted, but with +- * unusual memory sizes it's possible for some RAM to not be mapped +- * (such RAM is not used at all by Linux, since we don't support +- * highmem on 64-bit). We limit ppc64_rma_size to what would be +- * mappable if this memblock is the only one. Additional memblocks +- * can only increase, not decrease, the amount that ends up getting +- * mapped. We still limit max to 1G even if we'll eventually map +- * more. This is due to what the early init code is set up to do. +- * +- * We crop it to the size of the first MEMBLOCK to +- * avoid going over total available memory just in case... +- */ +-#ifdef CONFIG_PPC_E500 +- if (early_mmu_has_feature(MMU_FTR_TYPE_FSL_E)) { +- unsigned long linear_sz; +- unsigned int num_cams; +- +- /* use a quarter of the TLBCAM for bolted linear map */ +- num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4; +- +- linear_sz = map_mem_in_cams(first_memblock_size, num_cams, +- true, true); +- +- ppc64_rma_size = min_t(u64, linear_sz, 0x40000000); +- } else +-#endif +- ppc64_rma_size = min_t(u64, first_memblock_size, 0x40000000); +- +- /* Finally limit subsequent allocations */ +- memblock_set_current_limit(first_memblock_base + ppc64_rma_size); +-} +-#else /* ! CONFIG_PPC64 */ ++#ifndef CONFIG_PPC64 + void __init early_init_mmu(void) + { + unsigned long root = of_get_flat_dt_root(); +diff --git a/arch/powerpc/mm/nohash/tlb_64e.c b/arch/powerpc/mm/nohash/tlb_64e.c +new file mode 100644 +index 000000000000..1dcda261554c +--- /dev/null ++++ b/arch/powerpc/mm/nohash/tlb_64e.c +@@ -0,0 +1,361 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * Copyright 2008,2009 Ben Herrenschmidt ++ * IBM Corp. ++ * ++ * Derived from arch/ppc/mm/init.c: ++ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) ++ * ++ * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) ++ * and Cort Dougan (PReP) (cort@cs.nmt.edu) ++ * Copyright (C) 1996 Paul Mackerras ++ * ++ * Derived from "arch/i386/mm/init.c" ++ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++/* The variables below are currently only used on 64-bit Book3E ++ * though this will probably be made common with other nohash ++ * implementations at some point ++ */ ++int mmu_pte_psize; /* Page size used for PTE pages */ ++int mmu_vmemmap_psize; /* Page size used for the virtual mem map */ ++int book3e_htw_mode; /* HW tablewalk? Value is PPC_HTW_* */ ++unsigned long linear_map_top; /* Top of linear mapping */ ++ ++ ++/* ++ * Number of bytes to add to SPRN_SPRG_TLB_EXFRAME on crit/mcheck/debug ++ * exceptions. This is used for bolted and e6500 TLB miss handlers which ++ * do not modify this SPRG in the TLB miss code; for other TLB miss handlers, ++ * this is set to zero. ++ */ ++int extlb_level_exc; ++ ++/* ++ * Handling of virtual linear page tables or indirect TLB entries ++ * flushing when PTE pages are freed ++ */ ++void tlb_flush_pgtable(struct mmu_gather *tlb, unsigned long address) ++{ ++ int tsize = mmu_psize_defs[mmu_pte_psize].enc; ++ ++ if (book3e_htw_mode != PPC_HTW_NONE) { ++ unsigned long start = address & PMD_MASK; ++ unsigned long end = address + PMD_SIZE; ++ unsigned long size = 1UL << mmu_psize_defs[mmu_pte_psize].shift; ++ ++ /* This isn't the most optimal, ideally we would factor out the ++ * while preempt & CPU mask mucking around, or even the IPI but ++ * it will do for now ++ */ ++ while (start < end) { ++ __flush_tlb_page(tlb->mm, start, tsize, 1); ++ start += size; ++ } ++ } else { ++ unsigned long rmask = 0xf000000000000000ul; ++ unsigned long rid = (address & rmask) | 0x1000000000000000ul; ++ unsigned long vpte = address & ~rmask; ++ ++ vpte = (vpte >> (PAGE_SHIFT - 3)) & ~0xffful; ++ vpte |= rid; ++ __flush_tlb_page(tlb->mm, vpte, tsize, 0); ++ } ++} ++ ++static void __init setup_page_sizes(void) ++{ ++ unsigned int tlb0cfg; ++ unsigned int eptcfg; ++ int psize; ++ ++#ifdef CONFIG_PPC_E500 ++ unsigned int mmucfg = mfspr(SPRN_MMUCFG); ++ int fsl_mmu = mmu_has_feature(MMU_FTR_TYPE_FSL_E); ++ ++ if (fsl_mmu && (mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V1) { ++ unsigned int tlb1cfg = mfspr(SPRN_TLB1CFG); ++ unsigned int min_pg, max_pg; ++ ++ min_pg = (tlb1cfg & TLBnCFG_MINSIZE) >> TLBnCFG_MINSIZE_SHIFT; ++ max_pg = (tlb1cfg & TLBnCFG_MAXSIZE) >> TLBnCFG_MAXSIZE_SHIFT; ++ ++ for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { ++ struct mmu_psize_def *def; ++ unsigned int shift; ++ ++ def = &mmu_psize_defs[psize]; ++ shift = def->shift; ++ ++ if (shift == 0 || shift & 1) ++ continue; ++ ++ /* adjust to be in terms of 4^shift Kb */ ++ shift = (shift - 10) >> 1; ++ ++ if ((shift >= min_pg) && (shift <= max_pg)) ++ def->flags |= MMU_PAGE_SIZE_DIRECT; ++ } ++ ++ goto out; ++ } ++ ++ if (fsl_mmu && (mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V2) { ++ u32 tlb1cfg, tlb1ps; ++ ++ tlb0cfg = mfspr(SPRN_TLB0CFG); ++ tlb1cfg = mfspr(SPRN_TLB1CFG); ++ tlb1ps = mfspr(SPRN_TLB1PS); ++ eptcfg = mfspr(SPRN_EPTCFG); ++ ++ if ((tlb1cfg & TLBnCFG_IND) && (tlb0cfg & TLBnCFG_PT)) ++ book3e_htw_mode = PPC_HTW_E6500; ++ ++ /* ++ * We expect 4K subpage size and unrestricted indirect size. ++ * The lack of a restriction on indirect size is a Freescale ++ * extension, indicated by PSn = 0 but SPSn != 0. ++ */ ++ if (eptcfg != 2) ++ book3e_htw_mode = PPC_HTW_NONE; ++ ++ for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { ++ struct mmu_psize_def *def = &mmu_psize_defs[psize]; ++ ++ if (!def->shift) ++ continue; ++ ++ if (tlb1ps & (1U << (def->shift - 10))) { ++ def->flags |= MMU_PAGE_SIZE_DIRECT; ++ ++ if (book3e_htw_mode && psize == MMU_PAGE_2M) ++ def->flags |= MMU_PAGE_SIZE_INDIRECT; ++ } ++ } ++ ++ goto out; ++ } ++#endif ++out: ++ /* Cleanup array and print summary */ ++ pr_info("MMU: Supported page sizes\n"); ++ for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { ++ struct mmu_psize_def *def = &mmu_psize_defs[psize]; ++ const char *__page_type_names[] = { ++ "unsupported", ++ "direct", ++ "indirect", ++ "direct & indirect" ++ }; ++ if (def->flags == 0) { ++ def->shift = 0; ++ continue; ++ } ++ pr_info(" %8ld KB as %s\n", 1ul << (def->shift - 10), ++ __page_type_names[def->flags & 0x3]); ++ } ++} ++ ++static void __init setup_mmu_htw(void) ++{ ++ /* ++ * If we want to use HW tablewalk, enable it by patching the TLB miss ++ * handlers to branch to the one dedicated to it. ++ */ ++ ++ switch (book3e_htw_mode) { ++#ifdef CONFIG_PPC_E500 ++ case PPC_HTW_E6500: ++ extlb_level_exc = EX_TLB_SIZE; ++ patch_exception(0x1c0, exc_data_tlb_miss_e6500_book3e); ++ patch_exception(0x1e0, exc_instruction_tlb_miss_e6500_book3e); ++ break; ++#endif ++ } ++ pr_info("MMU: Book3E HW tablewalk %s\n", ++ book3e_htw_mode != PPC_HTW_NONE ? "enabled" : "not supported"); ++} ++ ++/* ++ * Early initialization of the MMU TLB code ++ */ ++static void early_init_this_mmu(void) ++{ ++ unsigned int mas4; ++ ++ /* Set MAS4 based on page table setting */ ++ ++ mas4 = 0x4 << MAS4_WIMGED_SHIFT; ++ switch (book3e_htw_mode) { ++ case PPC_HTW_E6500: ++ mas4 |= MAS4_INDD; ++ mas4 |= BOOK3E_PAGESZ_2M << MAS4_TSIZED_SHIFT; ++ mas4 |= MAS4_TLBSELD(1); ++ mmu_pte_psize = MMU_PAGE_2M; ++ break; ++ ++ case PPC_HTW_NONE: ++ mas4 |= BOOK3E_PAGESZ_4K << MAS4_TSIZED_SHIFT; ++ mmu_pte_psize = mmu_virtual_psize; ++ break; ++ } ++ mtspr(SPRN_MAS4, mas4); ++ ++#ifdef CONFIG_PPC_E500 ++ if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) { ++ unsigned int num_cams; ++ bool map = true; ++ ++ /* use a quarter of the TLBCAM for bolted linear map */ ++ num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4; ++ ++ /* ++ * Only do the mapping once per core, or else the ++ * transient mapping would cause problems. ++ */ ++#ifdef CONFIG_SMP ++ if (hweight32(get_tensr()) > 1) ++ map = false; ++#endif ++ ++ if (map) ++ linear_map_top = map_mem_in_cams(linear_map_top, ++ num_cams, false, true); ++ } ++#endif ++ ++ /* A sync won't hurt us after mucking around with ++ * the MMU configuration ++ */ ++ mb(); ++} ++ ++static void __init early_init_mmu_global(void) ++{ ++ /* XXX This should be decided at runtime based on supported ++ * page sizes in the TLB, but for now let's assume 16M is ++ * always there and a good fit (which it probably is) ++ * ++ * Freescale booke only supports 4K pages in TLB0, so use that. ++ */ ++ if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) ++ mmu_vmemmap_psize = MMU_PAGE_4K; ++ else ++ mmu_vmemmap_psize = MMU_PAGE_16M; ++ ++ /* XXX This code only checks for TLB 0 capabilities and doesn't ++ * check what page size combos are supported by the HW. It ++ * also doesn't handle the case where a separate array holds ++ * the IND entries from the array loaded by the PT. ++ */ ++ /* Look for supported page sizes */ ++ setup_page_sizes(); ++ ++ /* Look for HW tablewalk support */ ++ setup_mmu_htw(); ++ ++#ifdef CONFIG_PPC_E500 ++ if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) { ++ if (book3e_htw_mode == PPC_HTW_NONE) { ++ extlb_level_exc = EX_TLB_SIZE; ++ patch_exception(0x1c0, exc_data_tlb_miss_bolted_book3e); ++ patch_exception(0x1e0, ++ exc_instruction_tlb_miss_bolted_book3e); ++ } ++ } ++#endif ++ ++ /* Set the global containing the top of the linear mapping ++ * for use by the TLB miss code ++ */ ++ linear_map_top = memblock_end_of_DRAM(); ++ ++ ioremap_bot = IOREMAP_BASE; ++} ++ ++static void __init early_mmu_set_memory_limit(void) ++{ ++#ifdef CONFIG_PPC_E500 ++ if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) { ++ /* ++ * Limit memory so we dont have linear faults. ++ * Unlike memblock_set_current_limit, which limits ++ * memory available during early boot, this permanently ++ * reduces the memory available to Linux. We need to ++ * do this because highmem is not supported on 64-bit. ++ */ ++ memblock_enforce_memory_limit(linear_map_top); ++ } ++#endif ++ ++ memblock_set_current_limit(linear_map_top); ++} ++ ++/* boot cpu only */ ++void __init early_init_mmu(void) ++{ ++ early_init_mmu_global(); ++ early_init_this_mmu(); ++ early_mmu_set_memory_limit(); ++} ++ ++void early_init_mmu_secondary(void) ++{ ++ early_init_this_mmu(); ++} ++ ++void setup_initial_memory_limit(phys_addr_t first_memblock_base, ++ phys_addr_t first_memblock_size) ++{ ++ /* On non-FSL Embedded 64-bit, we adjust the RMA size to match ++ * the bolted TLB entry. We know for now that only 1G ++ * entries are supported though that may eventually ++ * change. ++ * ++ * on FSL Embedded 64-bit, usually all RAM is bolted, but with ++ * unusual memory sizes it's possible for some RAM to not be mapped ++ * (such RAM is not used at all by Linux, since we don't support ++ * highmem on 64-bit). We limit ppc64_rma_size to what would be ++ * mappable if this memblock is the only one. Additional memblocks ++ * can only increase, not decrease, the amount that ends up getting ++ * mapped. We still limit max to 1G even if we'll eventually map ++ * more. This is due to what the early init code is set up to do. ++ * ++ * We crop it to the size of the first MEMBLOCK to ++ * avoid going over total available memory just in case... ++ */ ++#ifdef CONFIG_PPC_E500 ++ if (early_mmu_has_feature(MMU_FTR_TYPE_FSL_E)) { ++ unsigned long linear_sz; ++ unsigned int num_cams; ++ ++ /* use a quarter of the TLBCAM for bolted linear map */ ++ num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4; ++ ++ linear_sz = map_mem_in_cams(first_memblock_size, num_cams, ++ true, true); ++ ++ ppc64_rma_size = min_t(u64, linear_sz, 0x40000000); ++ } else ++#endif ++ ppc64_rma_size = min_t(u64, first_memblock_size, 0x40000000); ++ ++ /* Finally limit subsequent allocations */ ++ memblock_set_current_limit(first_memblock_base + ppc64_rma_size); ++} +-- +2.43.0 + diff --git a/queue-6.6/powerpc-vdso-don-t-discard-rela-sections.patch b/queue-6.6/powerpc-vdso-don-t-discard-rela-sections.patch new file mode 100644 index 00000000000..6126bd50ca6 --- /dev/null +++ b/queue-6.6/powerpc-vdso-don-t-discard-rela-sections.patch @@ -0,0 +1,73 @@ +From 1ebf3fbd3b35addfa7757a95b7b55d61d93861f5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 20 Aug 2024 13:28:07 +0200 +Subject: powerpc/vdso: Don't discard rela sections + +From: Christophe Leroy + +[ Upstream commit 6114139c3bdde992f4a19264e4f9bfc100d8d776 ] + +After building the VDSO, there is a verification that it contains +no dynamic relocation, see commit aff69273af61 ("vdso: Improve +cmd_vdso_check to check all dynamic relocations"). + +This verification uses readelf -r and doesn't work if rela sections +are discarded. + +Fixes: 8ad57add77d3 ("powerpc/build: vdso linker warning for orphan sections") +Signed-off-by: Christophe Leroy +Signed-off-by: Michael Ellerman +Link: https://msgid.link/45c3e6fc76cad05ad2cac0f5b5dfb4fae86dc9d6.1724153239.git.christophe.leroy@csgroup.eu +Signed-off-by: Sasha Levin +--- + arch/powerpc/kernel/vdso/vdso32.lds.S | 4 +++- + arch/powerpc/kernel/vdso/vdso64.lds.S | 4 ++-- + 2 files changed, 5 insertions(+), 3 deletions(-) + +diff --git a/arch/powerpc/kernel/vdso/vdso32.lds.S b/arch/powerpc/kernel/vdso/vdso32.lds.S +index 426e1ccc6971..8f57107000a2 100644 +--- a/arch/powerpc/kernel/vdso/vdso32.lds.S ++++ b/arch/powerpc/kernel/vdso/vdso32.lds.S +@@ -74,6 +74,8 @@ SECTIONS + .got : { *(.got) } :text + .plt : { *(.plt) } + ++ .rela.dyn : { *(.rela .rela*) } ++ + _end = .; + __end = .; + PROVIDE(end = .); +@@ -87,7 +89,7 @@ SECTIONS + *(.branch_lt) + *(.data .data.* .gnu.linkonce.d.* .sdata*) + *(.bss .sbss .dynbss .dynsbss) +- *(.got1 .glink .iplt .rela*) ++ *(.got1 .glink .iplt) + } + } + +diff --git a/arch/powerpc/kernel/vdso/vdso64.lds.S b/arch/powerpc/kernel/vdso/vdso64.lds.S +index bda6c8cdd459..400819258c06 100644 +--- a/arch/powerpc/kernel/vdso/vdso64.lds.S ++++ b/arch/powerpc/kernel/vdso/vdso64.lds.S +@@ -69,7 +69,7 @@ SECTIONS + .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr + .eh_frame : { KEEP (*(.eh_frame)) } :text + .gcc_except_table : { *(.gcc_except_table) } +- .rela.dyn ALIGN(8) : { *(.rela.dyn) } ++ .rela.dyn ALIGN(8) : { *(.rela .rela*) } + + .got ALIGN(8) : { *(.got .toc) } + +@@ -86,7 +86,7 @@ SECTIONS + *(.data .data.* .gnu.linkonce.d.* .sdata*) + *(.bss .sbss .dynbss .dynsbss) + *(.opd) +- *(.glink .iplt .plt .rela*) ++ *(.glink .iplt .plt) + } + } + +-- +2.43.0 + diff --git a/queue-6.6/riscv-do-not-restrict-memory-size-because-of-linear-.patch b/queue-6.6/riscv-do-not-restrict-memory-size-because-of-linear-.patch new file mode 100644 index 00000000000..a30b206ba0e --- /dev/null +++ b/queue-6.6/riscv-do-not-restrict-memory-size-because-of-linear-.patch @@ -0,0 +1,41 @@ +From fcd7693588f55b07bbf63aef27102535ca245611 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Aug 2024 08:52:30 +0200 +Subject: riscv: Do not restrict memory size because of linear mapping on nommu + +From: Alexandre Ghiti + +[ Upstream commit 5f771088a2b5edd6f2c5c9f34484ca18dc389f3e ] + +It makes no sense to restrict physical memory size because of linear +mapping size constraints when there is no linear mapping, so only do +that when mmu is enabled. + +Reported-by: Geert Uytterhoeven +Closes: https://lore.kernel.org/linux-riscv/CAMuHMdW0bnJt5GMRtOZGkTiM7GK4UaLJCDMF_Ouq++fnDKi3_A@mail.gmail.com/ +Fixes: 3b6564427aea ("riscv: Fix linear mapping checks for non-contiguous memory regions") +Signed-off-by: Alexandre Ghiti +Tested-by: Geert Uytterhoeven +Link: https://lore.kernel.org/r/20240827065230.145021-1-alexghiti@rivosinc.com +Signed-off-by: Palmer Dabbelt +Signed-off-by: Sasha Levin +--- + arch/riscv/mm/init.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c +index abe7a7a7686c..3245bb525212 100644 +--- a/arch/riscv/mm/init.c ++++ b/arch/riscv/mm/init.c +@@ -235,7 +235,7 @@ static void __init setup_bootmem(void) + * The size of the linear page mapping may restrict the amount of + * usable RAM. + */ +- if (IS_ENABLED(CONFIG_64BIT)) { ++ if (IS_ENABLED(CONFIG_64BIT) && IS_ENABLED(CONFIG_MMU)) { + max_mapped_addr = __pa(PAGE_OFFSET) + KERN_VIRT_SIZE; + memblock_cap_memory_range(phys_ram_base, + max_mapped_addr - phys_ram_base); +-- +2.43.0 + diff --git a/queue-6.6/riscv-fix-toolchain-vector-detection.patch b/queue-6.6/riscv-fix-toolchain-vector-detection.patch new file mode 100644 index 00000000000..47a194c278e --- /dev/null +++ b/queue-6.6/riscv-fix-toolchain-vector-detection.patch @@ -0,0 +1,44 @@ +From c33dc3fb77fb63f1ee00cb422132365e1b0f0654 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Aug 2024 00:11:31 +0000 +Subject: riscv: Fix toolchain vector detection + +From: Anton Blanchard + +[ Upstream commit 5ba7a75a53dffbf727e842b5847859bb482ac4aa ] + +A recent change to gcc flags rv64iv as no longer valid: + + cc1: sorry, unimplemented: Currently the 'V' implementation + requires the 'M' extension + +and as a result vector support is disabled. Fix this by adding m +to our toolchain vector detection code. + +Signed-off-by: Anton Blanchard +Fixes: fa8e7cce55da ("riscv: Enable Vector code to be built") +Link: https://lore.kernel.org/r/20240819001131.1738806-1-antonb@tenstorrent.com +Signed-off-by: Palmer Dabbelt +Signed-off-by: Sasha Levin +--- + arch/riscv/Kconfig | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig +index c785a0200573..d5d70dc5656e 100644 +--- a/arch/riscv/Kconfig ++++ b/arch/riscv/Kconfig +@@ -489,8 +489,8 @@ config RISCV_ISA_SVPBMT + config TOOLCHAIN_HAS_V + bool + default y +- depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64iv) +- depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32iv) ++ depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64imv) ++ depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32imv) + depends on LLD_VERSION >= 140000 || LD_VERSION >= 23800 + depends on AS_HAS_OPTION_ARCH + +-- +2.43.0 + diff --git a/queue-6.6/series b/queue-6.6/series index 49072c8f739..f01fd0e9715 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -224,3 +224,39 @@ uprobes-use-kzalloc-to-allocate-xol-area.patch perf-aux-fix-aux-buffer-serialization.patch mm-vmscan-use-folio_migratetype-instead-of-get_pageb.patch revert-mm-skip-cma-pages-when-they-are-not-available.patch +workqueue-wq_watchdog_touch-is-always-called-with-va.patch +workqueue-improve-scalability-of-workqueue-watchdog-.patch +acpi-processor-return-an-error-if-acpi_processor_get.patch +acpi-processor-fix-memory-leaks-in-error-paths-of-pr.patch +arm64-acpi-move-get_cpu_for_acpi_id-to-a-header.patch +arm64-acpi-harden-get_cpu_for_acpi_id-against-missin.patch +can-mcp251xfd-mcp251xfd_handle_rxif_ring_uinc-factor.patch +can-mcp251xfd-rx-prepare-to-workaround-broken-rx-fif.patch +can-mcp251xfd-clarify-the-meaning-of-timestamp.patch +can-mcp251xfd-rx-add-workaround-for-erratum-ds800007.patch +drm-amd-add-gfx12-swizzle-mode-defs.patch +drm-amdgpu-handle-gfx12-in-amdgpu_display_verify_siz.patch +ata-libata-scsi-remove-redundant-sense_buffer-memset.patch +ata-libata-scsi-check-ata_qcflag_rtf_filled-before-u.patch +crypto-starfive-align-rsa-input-data-to-32-bit.patch +crypto-starfive-fix-nent-assignment-in-rsa-dec.patch +clk-qcom-ipq9574-update-the-alpha-pll-type-for-gplls.patch +powerpc-64e-remove-unused-ibm-htw-code.patch +powerpc-64e-split-out-nohash-book3e-64-bit-code.patch +powerpc-64e-define-mmu_pte_psize-static.patch +powerpc-vdso-don-t-discard-rela-sections.patch +asoc-tegra-fix-cbb-error-during-probe.patch +nvmet-tcp-fix-kernel-crash-if-commands-allocation-fa.patch +nvme-pci-allocate-tagset-on-reset-if-necessary.patch +asoc-sof-topology-clear-sof-link-platform-name-upon-.patch +asoc-sunxi-sun4i-i2s-fix-lrclk-polarity-in-i2s-mode.patch +clk-qcom-gcc-sm8550-don-t-use-parking-clk_ops-for-qu.patch +clk-qcom-gcc-sm8550-don-t-park-the-usb-rcg-at-regist.patch +drm-i915-fence-mark-debug_fence_init_onstack-with-__.patch +drm-i915-fence-mark-debug_fence_free-with-__maybe_un.patch +gpio-rockchip-fix-of-node-leak-in-probe.patch +gpio-modepin-enable-module-autoloading.patch +smb-client-fix-double-put-of-cfile-in-smb2_rename_pa.patch +riscv-fix-toolchain-vector-detection.patch +riscv-do-not-restrict-memory-size-because-of-linear-.patch +ublk_drv-fix-null-pointer-dereference-in-ublk_ctrl_s.patch diff --git a/queue-6.6/smb-client-fix-double-put-of-cfile-in-smb2_rename_pa.patch b/queue-6.6/smb-client-fix-double-put-of-cfile-in-smb2_rename_pa.patch new file mode 100644 index 00000000000..7353fb0b320 --- /dev/null +++ b/queue-6.6/smb-client-fix-double-put-of-cfile-in-smb2_rename_pa.patch @@ -0,0 +1,39 @@ +From fb34dd92610955be3490c50f64fdf446df4a0130 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Sep 2024 10:53:23 -0300 +Subject: smb: client: fix double put of @cfile in smb2_rename_path() + +From: Paulo Alcantara + +[ Upstream commit 3523a3df03c6f04f7ea9c2e7050102657e331a4f ] + +If smb2_set_path_attr() is called with a valid @cfile and returned +-EINVAL, we need to call cifs_get_writable_path() again as the +reference of @cfile was already dropped by previous smb2_compound_op() +call. + +Fixes: 71f15c90e785 ("smb: client: retry compound request without reusing lease") +Signed-off-by: Paulo Alcantara (Red Hat) +Cc: David Howells +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/client/smb2inode.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c +index fc82d5ebf923..dd8acd207752 100644 +--- a/fs/smb/client/smb2inode.c ++++ b/fs/smb/client/smb2inode.c +@@ -1106,6 +1106,8 @@ int smb2_rename_path(const unsigned int xid, + co, DELETE, SMB2_OP_RENAME, cfile, source_dentry); + if (rc == -EINVAL) { + cifs_dbg(FYI, "invalid lease key, resending request without lease"); ++ cifs_get_writable_path(tcon, from_name, ++ FIND_WR_WITH_DELETE, &cfile); + rc = smb2_set_path_attr(xid, tcon, from_name, to_name, cifs_sb, + co, DELETE, SMB2_OP_RENAME, cfile, NULL); + } +-- +2.43.0 + diff --git a/queue-6.6/ublk_drv-fix-null-pointer-dereference-in-ublk_ctrl_s.patch b/queue-6.6/ublk_drv-fix-null-pointer-dereference-in-ublk_ctrl_s.patch new file mode 100644 index 00000000000..f786ad2338e --- /dev/null +++ b/queue-6.6/ublk_drv-fix-null-pointer-dereference-in-ublk_ctrl_s.patch @@ -0,0 +1,69 @@ +From be71ecd2d4eef6adad8b09abefe0dcb03542d774 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Sep 2024 11:13:48 +0800 +Subject: ublk_drv: fix NULL pointer dereference in ublk_ctrl_start_recovery() + +From: Li Nan + +[ Upstream commit e58f5142f88320a5b1449f96a146f2f24615c5c7 ] + +When two UBLK_CMD_START_USER_RECOVERY commands are submitted, the +first one sets 'ubq->ubq_daemon' to NULL, and the second one triggers +WARN in ublk_queue_reinit() and subsequently a NULL pointer dereference +issue. + +Fix it by adding the check in ublk_ctrl_start_recovery() and return +immediately in case of zero 'ub->nr_queues_ready'. + + BUG: kernel NULL pointer dereference, address: 0000000000000028 + RIP: 0010:ublk_ctrl_start_recovery.constprop.0+0x82/0x180 + Call Trace: + + ? __die+0x20/0x70 + ? page_fault_oops+0x75/0x170 + ? exc_page_fault+0x64/0x140 + ? asm_exc_page_fault+0x22/0x30 + ? ublk_ctrl_start_recovery.constprop.0+0x82/0x180 + ublk_ctrl_uring_cmd+0x4f7/0x6c0 + ? pick_next_task_idle+0x26/0x40 + io_uring_cmd+0x9a/0x1b0 + io_issue_sqe+0x193/0x3f0 + io_wq_submit_work+0x9b/0x390 + io_worker_handle_work+0x165/0x360 + io_wq_worker+0xcb/0x2f0 + ? finish_task_switch.isra.0+0x203/0x290 + ? finish_task_switch.isra.0+0x203/0x290 + ? __pfx_io_wq_worker+0x10/0x10 + ret_from_fork+0x2d/0x50 + ? __pfx_io_wq_worker+0x10/0x10 + ret_from_fork_asm+0x1a/0x30 + + +Fixes: c732a852b419 ("ublk_drv: add START_USER_RECOVERY and END_USER_RECOVERY support") +Reported-and-tested-by: Changhui Zhong +Closes: https://lore.kernel.org/all/CAGVVp+UvLiS+bhNXV-h2icwX1dyybbYHeQUuH7RYqUvMQf6N3w@mail.gmail.com +Reviewed-by: Ming Lei +Signed-off-by: Li Nan +Link: https://lore.kernel.org/r/20240904031348.4139545-1-ming.lei@redhat.com +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/ublk_drv.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c +index f4e0573c4711..bf7f68e90953 100644 +--- a/drivers/block/ublk_drv.c ++++ b/drivers/block/ublk_drv.c +@@ -2603,6 +2603,8 @@ static int ublk_ctrl_start_recovery(struct ublk_device *ub, + mutex_lock(&ub->mutex); + if (!ublk_can_use_recovery(ub)) + goto out_unlock; ++ if (!ub->nr_queues_ready) ++ goto out_unlock; + /* + * START_RECOVERY is only allowd after: + * +-- +2.43.0 + diff --git a/queue-6.6/workqueue-improve-scalability-of-workqueue-watchdog-.patch b/queue-6.6/workqueue-improve-scalability-of-workqueue-watchdog-.patch new file mode 100644 index 00000000000..da1b07e4bbf --- /dev/null +++ b/queue-6.6/workqueue-improve-scalability-of-workqueue-watchdog-.patch @@ -0,0 +1,77 @@ +From d1f93f72f0cd3e8694b3b9b6f5a2c44cefefc893 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Jun 2024 21:42:45 +1000 +Subject: workqueue: Improve scalability of workqueue watchdog touch + +From: Nicholas Piggin + +[ Upstream commit 98f887f820c993e05a12e8aa816c80b8661d4c87 ] + +On a ~2000 CPU powerpc system, hard lockups have been observed in the +workqueue code when stop_machine runs (in this case due to CPU hotplug). +This is due to lots of CPUs spinning in multi_cpu_stop, calling +touch_nmi_watchdog() which ends up calling wq_watchdog_touch(). +wq_watchdog_touch() writes to the global variable wq_watchdog_touched, +and that can find itself in the same cacheline as other important +workqueue data, which slows down operations to the point of lockups. + +In the case of the following abridged trace, worker_pool_idr was in +the hot line, causing the lockups to always appear at idr_find. + + watchdog: CPU 1125 self-detected hard LOCKUP @ idr_find + Call Trace: + get_work_pool + __queue_work + call_timer_fn + run_timer_softirq + __do_softirq + do_softirq_own_stack + irq_exit + timer_interrupt + decrementer_common_virt + * interrupt: 900 (timer) at multi_cpu_stop + multi_cpu_stop + cpu_stopper_thread + smpboot_thread_fn + kthread + +Fix this by having wq_watchdog_touch() only write to the line if the +last time a touch was recorded exceeds 1/4 of the watchdog threshold. + +Reported-by: Srikar Dronamraju +Signed-off-by: Nicholas Piggin +Reviewed-by: Paul E. McKenney +Signed-off-by: Tejun Heo +Signed-off-by: Sasha Levin +--- + kernel/workqueue.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/kernel/workqueue.c b/kernel/workqueue.c +index a1665c2e04b4..7fa1c7c9151a 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -6456,12 +6456,18 @@ static void wq_watchdog_timer_fn(struct timer_list *unused) + + notrace void wq_watchdog_touch(int cpu) + { ++ unsigned long thresh = READ_ONCE(wq_watchdog_thresh) * HZ; ++ unsigned long touch_ts = READ_ONCE(wq_watchdog_touched); ++ unsigned long now = jiffies; ++ + if (cpu >= 0) +- per_cpu(wq_watchdog_touched_cpu, cpu) = jiffies; ++ per_cpu(wq_watchdog_touched_cpu, cpu) = now; + else + WARN_ONCE(1, "%s should be called with valid CPU", __func__); + +- wq_watchdog_touched = jiffies; ++ /* Don't unnecessarily store to global cacheline */ ++ if (time_after(now, touch_ts + thresh / 4)) ++ WRITE_ONCE(wq_watchdog_touched, jiffies); + } + + static void wq_watchdog_set_thresh(unsigned long thresh) +-- +2.43.0 + diff --git a/queue-6.6/workqueue-wq_watchdog_touch-is-always-called-with-va.patch b/queue-6.6/workqueue-wq_watchdog_touch-is-always-called-with-va.patch new file mode 100644 index 00000000000..d1634b403a5 --- /dev/null +++ b/queue-6.6/workqueue-wq_watchdog_touch-is-always-called-with-va.patch @@ -0,0 +1,36 @@ +From 2c2744a833641a616f33ca086b64971a690a880d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Jun 2024 21:42:44 +1000 +Subject: workqueue: wq_watchdog_touch is always called with valid CPU + +From: Nicholas Piggin + +[ Upstream commit 18e24deb1cc92f2068ce7434a94233741fbd7771 ] + +Warn in the case it is called with cpu == -1. This does not appear +to happen anywhere. + +Signed-off-by: Nicholas Piggin +Reviewed-by: Paul E. McKenney +Signed-off-by: Tejun Heo +Signed-off-by: Sasha Levin +--- + kernel/workqueue.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/kernel/workqueue.c b/kernel/workqueue.c +index 8c7bafbee1b1..a1665c2e04b4 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -6458,6 +6458,8 @@ notrace void wq_watchdog_touch(int cpu) + { + if (cpu >= 0) + per_cpu(wq_watchdog_touched_cpu, cpu) = jiffies; ++ else ++ WARN_ONCE(1, "%s should be called with valid CPU", __func__); + + wq_watchdog_touched = jiffies; + } +-- +2.43.0 + -- 2.47.3