From: Sasha Levin Date: Tue, 10 Sep 2024 00:36:18 +0000 (-0400) Subject: Fixes for 6.10 X-Git-Tag: v4.19.322~40 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f521b08152fe2734a3c7c6d70809c977b4eae686;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.10 Signed-off-by: Sasha Levin --- diff --git a/queue-6.10/acpi-processor-fix-memory-leaks-in-error-paths-of-pr.patch b/queue-6.10/acpi-processor-fix-memory-leaks-in-error-paths-of-pr.patch new file mode 100644 index 00000000000..eb962e47f16 --- /dev/null +++ b/queue-6.10/acpi-processor-fix-memory-leaks-in-error-paths-of-pr.patch @@ -0,0 +1,83 @@ +From 9dc855e8cd3a290617b591fcaff389f4d838b357 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 c052cdeca9fd..5f5a01ccfc3a 100644 +--- a/drivers/acpi/acpi_processor.c ++++ b/drivers/acpi/acpi_processor.c +@@ -400,7 +400,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); + +@@ -415,7 +415,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 +@@ -427,12 +427,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; + +@@ -443,10 +443,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.10/acpi-processor-return-an-error-if-acpi_processor_get.patch b/queue-6.10/acpi-processor-return-an-error-if-acpi_processor_get.patch new file mode 100644 index 00000000000..44b5da42162 --- /dev/null +++ b/queue-6.10/acpi-processor-return-an-error-if-acpi_processor_get.patch @@ -0,0 +1,45 @@ +From 53ad826d75cecb93b117a46f50408a82ae72cf23 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 +Stable-dep-of: 47ec9b417ed9 ("ACPI: processor: Fix memory leaks in error paths of processor_add()") +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 7a0dd35d62c9..c052cdeca9fd 100644 +--- a/drivers/acpi/acpi_processor.c ++++ b/drivers/acpi/acpi_processor.c +@@ -400,7 +400,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.10/arm64-acpi-harden-get_cpu_for_acpi_id-against-missin.patch b/queue-6.10/arm64-acpi-harden-get_cpu_for_acpi_id-against-missin.patch new file mode 100644 index 00000000000..57981c74204 --- /dev/null +++ b/queue-6.10/arm64-acpi-harden-get_cpu_for_acpi_id-against-missin.patch @@ -0,0 +1,46 @@ +From 46aeb239d565bac9c67e589f930abb21aaf451c7 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.10/arm64-acpi-move-get_cpu_for_acpi_id-to-a-header.patch b/queue-6.10/arm64-acpi-move-get_cpu_for_acpi_id-to-a-header.patch new file mode 100644 index 00000000000..fa6e5eabf96 --- /dev/null +++ b/queue-6.10/arm64-acpi-move-get_cpu_for_acpi_id-to-a-header.patch @@ -0,0 +1,83 @@ +From b26b83498b9c0e0fc327d426b61f09360e7ce9db 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 +Stable-dep-of: 2488444274c7 ("arm64: acpi: Harden get_cpu_for_acpi_id() against missing CPU entry") +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.10/asoc-sof-topology-clear-sof-link-platform-name-upon-.patch b/queue-6.10/asoc-sof-topology-clear-sof-link-platform-name-upon-.patch new file mode 100644 index 00000000000..fbd0f470104 --- /dev/null +++ b/queue-6.10/asoc-sof-topology-clear-sof-link-platform-name-upon-.patch @@ -0,0 +1,47 @@ +From cb5577c87c389274db0b2618fbb14af080b8a075 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 da182314aa87..ebbd99e34143 100644 +--- a/sound/soc/sof/topology.c ++++ b/sound/soc/sof/topology.c +@@ -2050,6 +2050,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.10/asoc-sunxi-sun4i-i2s-fix-lrclk-polarity-in-i2s-mode.patch b/queue-6.10/asoc-sunxi-sun4i-i2s-fix-lrclk-polarity-in-i2s-mode.patch new file mode 100644 index 00000000000..05e5d8dc553 --- /dev/null +++ b/queue-6.10/asoc-sunxi-sun4i-i2s-fix-lrclk-polarity-in-i2s-mode.patch @@ -0,0 +1,272 @@ +From f2db18a6c8bb6a6a06241c60660a7e61360f62d1 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 5f8d979585b6..3af0b2aab291 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) +@@ -729,65 +729,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; +@@ -805,6 +777,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: +@@ -836,65 +837,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; +@@ -912,6 +885,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.10/asoc-tegra-fix-cbb-error-during-probe.patch b/queue-6.10/asoc-tegra-fix-cbb-error-during-probe.patch new file mode 100644 index 00000000000..9f1522923ea --- /dev/null +++ b/queue-6.10/asoc-tegra-fix-cbb-error-during-probe.patch @@ -0,0 +1,92 @@ +From 2ce1b8663288df69a0c4aa8e9a840cc3add37490 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.10/ata-libata-scsi-check-ata_qcflag_rtf_filled-before-u.patch b/queue-6.10/ata-libata-scsi-check-ata_qcflag_rtf_filled-before-u.patch new file mode 100644 index 00000000000..94c4120999c --- /dev/null +++ b/queue-6.10/ata-libata-scsi-check-ata_qcflag_rtf_filled-before-u.patch @@ -0,0 +1,81 @@ +From c562823a97362bfe4f428369ac7ecb3d830589cf 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 4deee71006ef..4116ae088719 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.10/ata-libata-scsi-remove-redundant-sense_buffer-memset.patch b/queue-6.10/ata-libata-scsi-remove-redundant-sense_buffer-memset.patch new file mode 100644 index 00000000000..c67ef84feb4 --- /dev/null +++ b/queue-6.10/ata-libata-scsi-remove-redundant-sense_buffer-memset.patch @@ -0,0 +1,52 @@ +From 332ce3eccca47b786686bafd5331fae4365389bc 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 +Stable-dep-of: 816be86c7993 ("ata: libata-scsi: Check ATA_QCFLAG_RTF_FILLED before using result_tf") +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 4e0847601103..4deee71006ef 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.10/can-mcp251xfd-clarify-the-meaning-of-timestamp.patch b/queue-6.10/can-mcp251xfd-clarify-the-meaning-of-timestamp.patch new file mode 100644 index 00000000000..1f95b3c2d86 --- /dev/null +++ b/queue-6.10/can-mcp251xfd-clarify-the-meaning-of-timestamp.patch @@ -0,0 +1,297 @@ +From f95872f64c6016d1657bf8a72419f0f237c068fd 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 +Stable-dep-of: 24436be590c6 ("can: mcp251xfd: rx: add workaround for erratum DS80000789E 6 of mcp2518fd") +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 bf1589aef1fc..f1e6007b74ce 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.10/can-mcp251xfd-mcp251xfd_handle_rxif_ring_uinc-factor.patch b/queue-6.10/can-mcp251xfd-mcp251xfd_handle_rxif_ring_uinc-factor.patch new file mode 100644 index 00000000000..ef555ca5cd9 --- /dev/null +++ b/queue-6.10/can-mcp251xfd-mcp251xfd_handle_rxif_ring_uinc-factor.patch @@ -0,0 +1,109 @@ +From c367fd3496e003281327c370eeb09005c2125d49 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 +Stable-dep-of: 85505e585637 ("can: mcp251xfd: rx: prepare to workaround broken RX FIFO head index erratum") +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.10/can-mcp251xfd-rx-add-workaround-for-erratum-ds800007.patch b/queue-6.10/can-mcp251xfd-rx-add-workaround-for-erratum-ds800007.patch new file mode 100644 index 00000000000..f1b11d191cc --- /dev/null +++ b/queue-6.10/can-mcp251xfd-rx-add-workaround-for-erratum-ds800007.patch @@ -0,0 +1,146 @@ +From 5c92cb990d98d0ec07e22d2accfd3043776d4b26 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.10/can-mcp251xfd-rx-prepare-to-workaround-broken-rx-fif.patch b/queue-6.10/can-mcp251xfd-rx-prepare-to-workaround-broken-rx-fif.patch new file mode 100644 index 00000000000..ee29e6ba752 --- /dev/null +++ b/queue-6.10/can-mcp251xfd-rx-prepare-to-workaround-broken-rx-fif.patch @@ -0,0 +1,255 @@ +From 4f116c0ce4d2bcee8aa599ce125e5f4bb5293320 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.10/cifs-fix-smb1-readv-writev-callback-in-the-same-way-.patch b/queue-6.10/cifs-fix-smb1-readv-writev-callback-in-the-same-way-.patch new file mode 100644 index 00000000000..3c7826879b6 --- /dev/null +++ b/queue-6.10/cifs-fix-smb1-readv-writev-callback-in-the-same-way-.patch @@ -0,0 +1,145 @@ +From 4220f3657e211283ec06ef33c406f534c5c1fd3a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Sep 2024 11:15:41 +0100 +Subject: cifs: Fix SMB1 readv/writev callback in the same way as SMB2/3 + +From: David Howells + +[ Upstream commit a68c74865f517e26728735aba0ae05055eaff76c ] + +Port a number of SMB2/3 async readv/writev fixes to the SMB1 transport: + + commit a88d60903696c01de577558080ec4fc738a70475 + cifs: Don't advance the I/O iterator before terminating subrequest + + commit ce5291e56081730ec7d87bc9aa41f3de73ff3256 + cifs: Defer read completion + + commit 1da29f2c39b67b846b74205c81bf0ccd96d34727 + netfs, cifs: Fix handling of short DIO read + +Fixes: 3ee1a1fc3981 ("cifs: Cut over to using netfslib") +Signed-off-by: David Howells +Reported-by: Steve French +Reviewed-by: Paulo Alcantara +cc: Jeff Layton +cc: linux-cifs@vger.kernel.org +cc: netfs@lists.linux.dev +cc: linux-fsdevel@vger.kernel.org +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/client/cifssmb.c | 54 +++++++++++++++++++++++++++++++++++------ + 1 file changed, 46 insertions(+), 8 deletions(-) + +diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c +index 6dce70f17208..cfae2e918209 100644 +--- a/fs/smb/client/cifssmb.c ++++ b/fs/smb/client/cifssmb.c +@@ -1261,16 +1261,32 @@ CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock, + return rc; + } + ++static void cifs_readv_worker(struct work_struct *work) ++{ ++ struct cifs_io_subrequest *rdata = ++ container_of(work, struct cifs_io_subrequest, subreq.work); ++ ++ netfs_subreq_terminated(&rdata->subreq, ++ (rdata->result == 0 || rdata->result == -EAGAIN) ? ++ rdata->got_bytes : rdata->result, true); ++} ++ + static void + cifs_readv_callback(struct mid_q_entry *mid) + { + struct cifs_io_subrequest *rdata = mid->callback_data; ++ struct netfs_inode *ictx = netfs_inode(rdata->rreq->inode); + struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink); + struct TCP_Server_Info *server = tcon->ses->server; + struct smb_rqst rqst = { .rq_iov = rdata->iov, + .rq_nvec = 2, + .rq_iter = rdata->subreq.io_iter }; +- struct cifs_credits credits = { .value = 1, .instance = 0 }; ++ struct cifs_credits credits = { ++ .value = 1, ++ .instance = 0, ++ .rreq_debug_id = rdata->rreq->debug_id, ++ .rreq_debug_index = rdata->subreq.debug_index, ++ }; + + cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%zu\n", + __func__, mid->mid, mid->mid_state, rdata->result, +@@ -1282,6 +1298,7 @@ cifs_readv_callback(struct mid_q_entry *mid) + if (server->sign) { + int rc = 0; + ++ iov_iter_truncate(&rqst.rq_iter, rdata->got_bytes); + rc = cifs_verify_signature(&rqst, server, + mid->sequence_number); + if (rc) +@@ -1306,13 +1323,21 @@ cifs_readv_callback(struct mid_q_entry *mid) + rdata->result = -EIO; + } + +- if (rdata->result == 0 || rdata->result == -EAGAIN) +- iov_iter_advance(&rdata->subreq.io_iter, rdata->got_bytes); ++ if (rdata->result == -ENODATA) { ++ __set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags); ++ rdata->result = 0; ++ } else { ++ if (rdata->got_bytes < rdata->actual_len && ++ rdata->subreq.start + rdata->subreq.transferred + rdata->got_bytes == ++ ictx->remote_i_size) { ++ __set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags); ++ rdata->result = 0; ++ } ++ } ++ + rdata->credits.value = 0; +- netfs_subreq_terminated(&rdata->subreq, +- (rdata->result == 0 || rdata->result == -EAGAIN) ? +- rdata->got_bytes : rdata->result, +- false); ++ INIT_WORK(&rdata->subreq.work, cifs_readv_worker); ++ queue_work(cifsiod_wq, &rdata->subreq.work); + release_mid(mid); + add_credits(server, &credits, 0); + } +@@ -1619,9 +1644,15 @@ static void + cifs_writev_callback(struct mid_q_entry *mid) + { + struct cifs_io_subrequest *wdata = mid->callback_data; ++ struct TCP_Server_Info *server = wdata->server; + struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink); + WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf; +- struct cifs_credits credits = { .value = 1, .instance = 0 }; ++ struct cifs_credits credits = { ++ .value = 1, ++ .instance = 0, ++ .rreq_debug_id = wdata->rreq->debug_id, ++ .rreq_debug_index = wdata->subreq.debug_index, ++ }; + ssize_t result; + size_t written; + +@@ -1657,9 +1688,16 @@ cifs_writev_callback(struct mid_q_entry *mid) + break; + } + ++ trace_smb3_rw_credits(credits.rreq_debug_id, credits.rreq_debug_index, ++ wdata->credits.value, ++ server->credits, server->in_flight, ++ 0, cifs_trace_rw_credits_write_response_clear); + wdata->credits.value = 0; + cifs_write_subrequest_terminated(wdata, result, true); + release_mid(mid); ++ trace_smb3_rw_credits(credits.rreq_debug_id, credits.rreq_debug_index, 0, ++ server->credits, server->in_flight, ++ credits.value, cifs_trace_rw_credits_write_response_add); + add_credits(tcon->ses->server, &credits, 0); + } + +-- +2.43.0 + diff --git a/queue-6.10/cifs-fix-zero_point-init-on-inode-initialisation.patch b/queue-6.10/cifs-fix-zero_point-init-on-inode-initialisation.patch new file mode 100644 index 00000000000..26b98ba340f --- /dev/null +++ b/queue-6.10/cifs-fix-zero_point-init-on-inode-initialisation.patch @@ -0,0 +1,42 @@ +From a7d76caa451b6abd313109e5b1a663eec3f31079 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 3 Sep 2024 15:11:18 +0100 +Subject: cifs: Fix zero_point init on inode initialisation + +From: David Howells + +[ Upstream commit 517b58c1f9242a6b4ac9443d95569dee58bf6b8b ] + +Fix cifs_fattr_to_inode() such that the ->zero_point tracking variable +is initialised when the inode is initialised. + +Fixes: 3ee1a1fc3981 ("cifs: Cut over to using netfslib") +Signed-off-by: David Howells +Reviewed-by: Paulo Alcantara (Red Hat) +cc: Jeff Layton +cc: linux-cifs@vger.kernel.org +cc: netfs@lists.linux.dev +cc: linux-fsdevel@vger.kernel.org +cc: linux-mm@kvack.org +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/client/inode.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c +index dd0afa23734c..73e2e6c230b7 100644 +--- a/fs/smb/client/inode.c ++++ b/fs/smb/client/inode.c +@@ -172,6 +172,8 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr, + CIFS_I(inode)->time = 0; /* force reval */ + return -ESTALE; + } ++ if (inode->i_state & I_NEW) ++ CIFS_I(inode)->netfs.zero_point = fattr->cf_eof; + + cifs_revalidate_cache(inode, fattr); + +-- +2.43.0 + diff --git a/queue-6.10/clk-qcom-gcc-sm8550-don-t-park-the-usb-rcg-at-regist.patch b/queue-6.10/clk-qcom-gcc-sm8550-don-t-park-the-usb-rcg-at-regist.patch new file mode 100644 index 00000000000..f16cd74ab7a --- /dev/null +++ b/queue-6.10/clk-qcom-gcc-sm8550-don-t-park-the-usb-rcg-at-regist.patch @@ -0,0 +1,106 @@ +From 1be66621a505f9dd1aa2940cc31595b09bead705 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 d7414361e432..8e0f3372dc7a 100644 +--- a/drivers/clk/qcom/clk-rcg.h ++++ b/drivers/clk/qcom/clk-rcg.h +@@ -198,6 +198,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 30b19bd39d08..bf26c5448f00 100644 +--- a/drivers/clk/qcom/clk-rcg2.c ++++ b/drivers/clk/qcom/clk-rcg2.c +@@ -1348,6 +1348,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 482ed17733ea..eae42f756c13 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.10/clk-qcom-gcc-sm8550-don-t-use-parking-clk_ops-for-qu.patch b/queue-6.10/clk-qcom-gcc-sm8550-don-t-use-parking-clk_ops-for-qu.patch new file mode 100644 index 00000000000..6e3f65b294a --- /dev/null +++ b/queue-6.10/clk-qcom-gcc-sm8550-don-t-use-parking-clk_ops-for-qu.patch @@ -0,0 +1,285 @@ +From bcab262afd564463742e6b88456de5564ff82c1c 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 26d7349e7642..482ed17733ea 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.10/clk-qcom-gcc-x1e80100-don-t-use-parking-clk_ops-for-.patch b/queue-6.10/clk-qcom-gcc-x1e80100-don-t-use-parking-clk_ops-for-.patch new file mode 100644 index 00000000000..8769bed8094 --- /dev/null +++ b/queue-6.10/clk-qcom-gcc-x1e80100-don-t-use-parking-clk_ops-for-.patch @@ -0,0 +1,255 @@ +From f03bb152bb6dea2645f94c05fcd21a149aa9e336 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 Aug 2024 13:58:56 +0100 +Subject: clk: qcom: gcc-x1e80100: Don't use parking clk_ops for QUPs + +From: Bryan O'Donoghue + +[ Upstream commit ca082333b4356688be715ed9cc762fc5d3d5f4c5 ] + +Per Stephen Boyd's explanation in the link below, QUP RCG clocks do not +need to be parked when switching frequency. A side-effect in parking to a +lower frequency can be a momentary invalid clock driven on an in-use serial +peripheral. + +This can cause "junk" to spewed out of a UART as a low-impact example. On +the x1e80100-crd this serial port junk can be observed on linux-next. + +Apply a similar fix to the x1e80100 Global Clock controller to remediate. + +Link: https://lore.kernel.org/all/20240819233628.2074654-3-swboyd@chromium.org/ +Fixes: 161b7c401f4b ("clk: qcom: Add Global Clock controller (GCC) driver for X1E80100") +Fixes: 929c75d57566 ("clk: qcom: gcc-sm8550: Mark RCGs shared where applicable") +Suggested-by: Neil Armstrong +Signed-off-by: Bryan O'Donoghue +Link: https://lore.kernel.org/r/20240823-x1e80100-clk-fix-v1-1-0b1b4f5a96e8@linaro.org +Reviewed-by: Konrad Dybcio +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/gcc-x1e80100.c | 48 ++++++++++++++++----------------- + 1 file changed, 24 insertions(+), 24 deletions(-) + +diff --git a/drivers/clk/qcom/gcc-x1e80100.c b/drivers/clk/qcom/gcc-x1e80100.c +index 24f84c6705e5..52ea2a0888f3 100644 +--- a/drivers/clk/qcom/gcc-x1e80100.c ++++ b/drivers/clk/qcom/gcc-x1e80100.c +@@ -670,7 +670,7 @@ static struct clk_init_data gcc_qupv3_wrap0_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_wrap0_s0_clk_src = { +@@ -687,7 +687,7 @@ static struct clk_init_data gcc_qupv3_wrap0_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_wrap0_s1_clk_src = { +@@ -719,7 +719,7 @@ static struct clk_init_data gcc_qupv3_wrap0_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_wrap0_s2_clk_src = { +@@ -736,7 +736,7 @@ static struct clk_init_data gcc_qupv3_wrap0_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_wrap0_s3_clk_src = { +@@ -768,7 +768,7 @@ static struct clk_init_data gcc_qupv3_wrap0_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_wrap0_s4_clk_src = { +@@ -785,7 +785,7 @@ static struct clk_init_data gcc_qupv3_wrap0_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_wrap0_s5_clk_src = { +@@ -802,7 +802,7 @@ static struct clk_init_data gcc_qupv3_wrap0_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_wrap0_s6_clk_src = { +@@ -819,7 +819,7 @@ static struct clk_init_data gcc_qupv3_wrap0_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_wrap0_s7_clk_src = { +@@ -836,7 +836,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 = { +@@ -853,7 +853,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 = { +@@ -870,7 +870,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 = { +@@ -887,7 +887,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 = { +@@ -904,7 +904,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 = { +@@ -921,7 +921,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 = { +@@ -938,7 +938,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 = { +@@ -955,7 +955,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 = { +@@ -972,7 +972,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 = { +@@ -989,7 +989,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 = { +@@ -1006,7 +1006,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 = { +@@ -1023,7 +1023,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 = { +@@ -1040,7 +1040,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 = { +@@ -1057,7 +1057,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 = { +@@ -1074,7 +1074,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 = { +@@ -1091,7 +1091,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.10/clk-qcom-gcc-x1e80100-fix-usb-0-and-1-phy-gdsc-pwrst.patch b/queue-6.10/clk-qcom-gcc-x1e80100-fix-usb-0-and-1-phy-gdsc-pwrst.patch new file mode 100644 index 00000000000..27a0e1a52cc --- /dev/null +++ b/queue-6.10/clk-qcom-gcc-x1e80100-fix-usb-0-and-1-phy-gdsc-pwrst.patch @@ -0,0 +1,49 @@ +From 6ac7e8fc4d16fb896a89172d6ea273976a9479d6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 1 Aug 2024 13:21:07 +0300 +Subject: clk: qcom: gcc-x1e80100: Fix USB 0 and 1 PHY GDSC pwrsts flags + +From: Abel Vesa + +[ Upstream commit f4c16a7cdbd2edecdb854f2ce0ef07c6263c5379 ] + +Allowing these GDSCs to collapse makes the QMP combo PHYs lose their +configuration on machine suspend. Currently, the QMP combo PHY driver +doesn't reinitialise the HW on resume. Under such conditions, the USB +SuperSpeed support is broken. To avoid this, mark the pwrsts flags with +RET_ON. This is in line with USB 2 PHY GDSC config. + +Fixes: 161b7c401f4b ("clk: qcom: Add Global Clock controller (GCC) driver for X1E80100") +Signed-off-by: Abel Vesa +Link: https://lore.kernel.org/r/20240801-x1e80100-clk-gcc-fix-usb-phy-gdscs-pwrsts-v1-1-8df016768a0f@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/gcc-x1e80100.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/qcom/gcc-x1e80100.c b/drivers/clk/qcom/gcc-x1e80100.c +index a263f0c412f5..24f84c6705e5 100644 +--- a/drivers/clk/qcom/gcc-x1e80100.c ++++ b/drivers/clk/qcom/gcc-x1e80100.c +@@ -6203,7 +6203,7 @@ static struct gdsc gcc_usb_0_phy_gdsc = { + .pd = { + .name = "gcc_usb_0_phy_gdsc", + }, +- .pwrsts = PWRSTS_OFF_ON, ++ .pwrsts = PWRSTS_RET_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +@@ -6215,7 +6215,7 @@ static struct gdsc gcc_usb_1_phy_gdsc = { + .pd = { + .name = "gcc_usb_1_phy_gdsc", + }, +- .pwrsts = PWRSTS_OFF_ON, ++ .pwrsts = PWRSTS_RET_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +-- +2.43.0 + diff --git a/queue-6.10/clk-qcom-ipq9574-update-the-alpha-pll-type-for-gplls.patch b/queue-6.10/clk-qcom-ipq9574-update-the-alpha-pll-type-for-gplls.patch new file mode 100644 index 00000000000..59df1b35ac9 --- /dev/null +++ b/queue-6.10/clk-qcom-ipq9574-update-the-alpha-pll-type-for-gplls.patch @@ -0,0 +1,101 @@ +From 56d1f45fd1da2a146a7bd1003f6e57001d33c3e7 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.10/crypto-starfive-align-rsa-input-data-to-32-bit.patch b/queue-6.10/crypto-starfive-align-rsa-input-data-to-32-bit.patch new file mode 100644 index 00000000000..b0eb3bcf662 --- /dev/null +++ b/queue-6.10/crypto-starfive-align-rsa-input-data-to-32-bit.patch @@ -0,0 +1,87 @@ +From 4f23b503419ae4192fce0785ccfbc6fb011e1432 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 +Stable-dep-of: 8323c036789b ("crypto: starfive - Fix nent assignment in rsa dec") +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 494a74f52706..85c65c6c0327 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; +@@ -222,7 +223,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 33093ba4b13a..59f5979e9360 100644 +--- a/drivers/crypto/starfive/jh7110-rsa.c ++++ b/drivers/crypto/starfive/jh7110-rsa.c +@@ -31,7 +31,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) +@@ -74,7 +73,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; +@@ -251,12 +250,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.10/crypto-starfive-fix-nent-assignment-in-rsa-dec.patch b/queue-6.10/crypto-starfive-fix-nent-assignment-in-rsa-dec.patch new file mode 100644 index 00000000000..400ae27c1cd --- /dev/null +++ b/queue-6.10/crypto-starfive-fix-nent-assignment-in-rsa-dec.patch @@ -0,0 +1,57 @@ +From bd443064bee5305415d367bc80d0faf3676c0916 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 85c65c6c0327..5ed4ba5da7f9 100644 +--- a/drivers/crypto/starfive/jh7110-cryp.h ++++ b/drivers/crypto/starfive/jh7110-cryp.h +@@ -218,7 +218,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 59f5979e9360..a778c4846025 100644 +--- a/drivers/crypto/starfive/jh7110-rsa.c ++++ b/drivers/crypto/starfive/jh7110-rsa.c +@@ -259,7 +259,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) { +@@ -309,7 +309,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.10/drm-amd-add-gfx12-swizzle-mode-defs.patch b/queue-6.10/drm-amd-add-gfx12-swizzle-mode-defs.patch new file mode 100644 index 00000000000..5507fe6c632 --- /dev/null +++ b/queue-6.10/drm-amd-add-gfx12-swizzle-mode-defs.patch @@ -0,0 +1,64 @@ +From 4df23d758555cb29a4408ddb603b42b82f7070e6 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 +Stable-dep-of: 8dd1426e2c80 ("drm/amdgpu: handle gfx12 in amdgpu_display_verify_sizes") +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 84d502e42961..4168445fbb8b 100644 +--- a/include/uapi/drm/drm_fourcc.h ++++ b/include/uapi/drm/drm_fourcc.h +@@ -1476,6 +1476,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 +@@ -1486,6 +1487,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 +@@ -1493,6 +1496,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.10/drm-amdgpu-handle-gfx12-in-amdgpu_display_verify_siz.patch b/queue-6.10/drm-amdgpu-handle-gfx12-in-amdgpu_display_verify_siz.patch new file mode 100644 index 00000000000..7028b923d74 --- /dev/null +++ b/queue-6.10/drm-amdgpu-handle-gfx12-in-amdgpu_display_verify_siz.patch @@ -0,0 +1,84 @@ +From 9659df59bd36813de0da098ddb29030b0d5e83ab 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 4fcc227db00b..30755ce4002d 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +@@ -1041,6 +1041,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); + +@@ -1076,7 +1100,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 4168445fbb8b..2d84a8052b15 100644 +--- a/include/uapi/drm/drm_fourcc.h ++++ b/include/uapi/drm/drm_fourcc.h +@@ -1506,6 +1506,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.10/drm-i915-fence-mark-debug_fence_free-with-__maybe_un.patch b/queue-6.10/drm-i915-fence-mark-debug_fence_free-with-__maybe_un.patch new file mode 100644 index 00000000000..f9cf4715b74 --- /dev/null +++ b/queue-6.10/drm-i915-fence-mark-debug_fence_free-with-__maybe_un.patch @@ -0,0 +1,59 @@ +From 2bd891c8b6e93c5ef168f007d140bee43352cbd2 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.10/drm-i915-fence-mark-debug_fence_init_onstack-with-__.patch b/queue-6.10/drm-i915-fence-mark-debug_fence_init_onstack-with-__.patch new file mode 100644 index 00000000000..15a13ca4808 --- /dev/null +++ b/queue-6.10/drm-i915-fence-mark-debug_fence_init_onstack-with-__.patch @@ -0,0 +1,58 @@ +From 94357f39e115b6bd3dfe00aa73e1aa034d9ed086 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.10/drm-xe-xe2-add-workaround-14021402888.patch b/queue-6.10/drm-xe-xe2-add-workaround-14021402888.patch new file mode 100644 index 00000000000..1abdd625c5f --- /dev/null +++ b/queue-6.10/drm-xe-xe2-add-workaround-14021402888.patch @@ -0,0 +1,55 @@ +From 126d317b320fd72b7a28d8946f07f45c0e85ea31 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Apr 2024 16:45:34 +0530 +Subject: drm/xe/xe2: Add workaround 14021402888 + +From: Bommu Krishnaiah + +[ Upstream commit 598dc939edf8d7bb1d69e84513c31451812128fc ] + +This workaround applies to Graphics 20.01 as RCS engine workaround + +Signed-off-by: Bommu Krishnaiah +Cc: Tejas Upadhyay +Cc: Matt Roper +Cc: Himal Prasad Ghimiray +Reviewed-by: Himal Prasad Ghimiray +Link: https://patchwork.freedesktop.org/patch/msgid/20240418111534.481568-1-krishnaiah.bommu@intel.com +Signed-off-by: Lucas De Marchi +Stable-dep-of: b196e6fcc711 ("drm/xe/xe2lpg: Extend workaround 14021402888") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/regs/xe_gt_regs.h | 1 + + drivers/gpu/drm/xe/xe_wa.c | 4 ++++ + 2 files changed, 5 insertions(+) + +diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h +index 94445810ccc9..23c302af4cd5 100644 +--- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h ++++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h +@@ -350,6 +350,7 @@ + + #define HALF_SLICE_CHICKEN7 XE_REG_MCR(0xe194, XE_REG_OPTION_MASKED) + #define DG2_DISABLE_ROUND_ENABLE_ALLOW_FOR_SSLA REG_BIT(15) ++#define CLEAR_OPTIMIZATION_DISABLE REG_BIT(6) + + #define CACHE_MODE_SS XE_REG_MCR(0xe420, XE_REG_OPTION_MASKED) + #define DISABLE_ECC REG_BIT(5) +diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c +index dd214d95e4b6..303f18ce91e6 100644 +--- a/drivers/gpu/drm/xe/xe_wa.c ++++ b/drivers/gpu/drm/xe/xe_wa.c +@@ -533,6 +533,10 @@ static const struct xe_rtp_entry_sr engine_was[] = { + FUNC(xe_rtp_match_first_render_or_compute)), + XE_RTP_ACTIONS(SET(LSC_CHICKEN_BIT_0, WR_REQ_CHAINING_DIS)) + }, ++ { XE_RTP_NAME("14021402888"), ++ XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)), ++ XE_RTP_ACTIONS(SET(HALF_SLICE_CHICKEN7, CLEAR_OPTIMIZATION_DISABLE)) ++ }, + + /* Xe2_HPM */ + +-- +2.43.0 + diff --git a/queue-6.10/drm-xe-xe2lpg-extend-workaround-14021402888.patch b/queue-6.10/drm-xe-xe2lpg-extend-workaround-14021402888.patch new file mode 100644 index 00000000000..806337fca40 --- /dev/null +++ b/queue-6.10/drm-xe-xe2lpg-extend-workaround-14021402888.patch @@ -0,0 +1,44 @@ +From cca52114c1b9bac45bc3f381b06c047151cad1c2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Jul 2024 14:37:54 +0530 +Subject: drm/xe/xe2lpg: Extend workaround 14021402888 + +From: Bommu Krishnaiah + +[ Upstream commit b196e6fcc71186134b4cfe756067d87ae41b1ed9 ] + +workaround 14021402888 also applies to Xe2_LPG. +Replicate the existing entry to one specific for Xe2_LPG. + +Signed-off-by: Bommu Krishnaiah +Cc: Tejas Upadhyay +Cc: Matt Roper +Cc: Himal Prasad Ghimiray +Reviewed-by: Matt Roper +Link: https://patchwork.freedesktop.org/patch/msgid/20240703090754.1323647-1-krishnaiah.bommu@intel.com +Signed-off-by: Lucas De Marchi +(cherry picked from commit 56ab6986992ba143aee0bda33e15a764343e271d) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_wa.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c +index 303f18ce91e6..66dafe980b9c 100644 +--- a/drivers/gpu/drm/xe/xe_wa.c ++++ b/drivers/gpu/drm/xe/xe_wa.c +@@ -485,6 +485,10 @@ static const struct xe_rtp_entry_sr engine_was[] = { + XE_RTP_RULES(GRAPHICS_VERSION(2004), FUNC(xe_rtp_match_first_render_or_compute)), + XE_RTP_ACTIONS(SET(TDL_TSL_CHICKEN, SLM_WMTP_RESTORE)) + }, ++ { XE_RTP_NAME("14021402888"), ++ XE_RTP_RULES(GRAPHICS_VERSION(2004), ENGINE_CLASS(RENDER)), ++ XE_RTP_ACTIONS(SET(HALF_SLICE_CHICKEN7, CLEAR_OPTIMIZATION_DISABLE)) ++ }, + + /* Xe2_HPG */ + +-- +2.43.0 + diff --git a/queue-6.10/fs-relax-permissions-for-listmount.patch b/queue-6.10/fs-relax-permissions-for-listmount.patch new file mode 100644 index 00000000000..a078ca8cd19 --- /dev/null +++ b/queue-6.10/fs-relax-permissions-for-listmount.patch @@ -0,0 +1,36 @@ +From f4b84ac592845e08733c2fc29425f54f4be88b7c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Jun 2024 11:49:44 -0400 +Subject: fs: relax permissions for listmount() + +From: Christian Brauner + +[ Upstream commit dd7cb142f467c4660698bcaa4a48c688b443ab81 ] + +It is sufficient to have capabilities in the owning user namespace of +the mount namespace to list all mounts regardless of whether they are +reachable or not. + +Link: https://lore.kernel.org/r/8adc0d3f4f7495faacc6a7c63095961f7f1637c7.1719243756.git.josef@toxicpanda.com +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/namespace.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/namespace.c b/fs/namespace.c +index ef7b202f8e85..e1ced589d835 100644 +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -5074,7 +5074,7 @@ static ssize_t do_listmount(u64 mnt_parent_id, u64 last_mnt_id, u64 *mnt_ids, + * mounts to show users. + */ + if (!is_path_reachable(real_mount(orig.mnt), orig.dentry, &root) && +- !ns_capable_noaudit(&init_user_ns, CAP_SYS_ADMIN)) ++ !ns_capable_noaudit(ns->user_ns, CAP_SYS_ADMIN)) + return -EPERM; + + ret = security_sb_statfs(orig.dentry); +-- +2.43.0 + diff --git a/queue-6.10/fs-simplify-error-handling.patch b/queue-6.10/fs-simplify-error-handling.patch new file mode 100644 index 00000000000..89b9db331dc --- /dev/null +++ b/queue-6.10/fs-simplify-error-handling.patch @@ -0,0 +1,76 @@ +From e128adbbd83de1c4373c5174c7dcbed000a4db36 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Jun 2024 16:55:36 +0200 +Subject: fs: simplify error handling + +From: Christian Brauner + +[ Upstream commit 17e70161281bb66316e94e63a15d1a8498bf6f01 ] + +Rely on cleanup helper and simplify error handling + +Link: https://lore.kernel.org/r/20240607-vfs-listmount-reverse-v1-3-7877a2bfa5e5@kernel.org +Reviewed-by: Josef Bacik +Signed-off-by: Christian Brauner +Stable-dep-of: dd7cb142f467 ("fs: relax permissions for listmount()") +Signed-off-by: Sasha Levin +--- + fs/namespace.c | 18 ++++++------------ + 1 file changed, 6 insertions(+), 12 deletions(-) + +diff --git a/fs/namespace.c b/fs/namespace.c +index 1390e9e521d6..ef7b202f8e85 100644 +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -5051,7 +5051,7 @@ static struct mount *listmnt_next(struct mount *curr) + static ssize_t do_listmount(u64 mnt_parent_id, u64 last_mnt_id, u64 *mnt_ids, + size_t nr_mnt_ids) + { +- struct path root; ++ struct path root __free(path_put) = {}; + struct mnt_namespace *ns = current->nsproxy->mnt_ns; + struct path orig; + struct mount *r, *first; +@@ -5064,10 +5064,8 @@ static ssize_t do_listmount(u64 mnt_parent_id, u64 last_mnt_id, u64 *mnt_ids, + orig = root; + } else { + orig.mnt = lookup_mnt_in_ns(mnt_parent_id, ns); +- if (!orig.mnt) { +- ret = -ENOENT; +- goto err; +- } ++ if (!orig.mnt) ++ return -ENOENT; + orig.dentry = orig.mnt->mnt_root; + } + +@@ -5076,14 +5074,12 @@ static ssize_t do_listmount(u64 mnt_parent_id, u64 last_mnt_id, u64 *mnt_ids, + * mounts to show users. + */ + if (!is_path_reachable(real_mount(orig.mnt), orig.dentry, &root) && +- !ns_capable_noaudit(&init_user_ns, CAP_SYS_ADMIN)) { +- ret = -EPERM; +- goto err; +- } ++ !ns_capable_noaudit(&init_user_ns, CAP_SYS_ADMIN)) ++ return -EPERM; + + ret = security_sb_statfs(orig.dentry); + if (ret) +- goto err; ++ return ret; + + if (!last_mnt_id) + first = node_to_mount(rb_first(&ns->mounts)); +@@ -5100,8 +5096,6 @@ static ssize_t do_listmount(u64 mnt_parent_id, u64 last_mnt_id, u64 *mnt_ids, + nr_mnt_ids--; + ret++; + } +-err: +- path_put(&root); + return ret; + } + +-- +2.43.0 + diff --git a/queue-6.10/gpio-modepin-enable-module-autoloading.patch b/queue-6.10/gpio-modepin-enable-module-autoloading.patch new file mode 100644 index 00000000000..99cd8d0eb19 --- /dev/null +++ b/queue-6.10/gpio-modepin-enable-module-autoloading.patch @@ -0,0 +1,37 @@ +From 6e4f15bfc8a986ebe8dc13340037b485abedb45f 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.10/gpio-rockchip-fix-of-node-leak-in-probe.patch b/queue-6.10/gpio-rockchip-fix-of-node-leak-in-probe.patch new file mode 100644 index 00000000000..c996d62ab98 --- /dev/null +++ b/queue-6.10/gpio-rockchip-fix-of-node-leak-in-probe.patch @@ -0,0 +1,38 @@ +From 0410f4823107330ac211c68e77ea7d15f21a3915 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 0bd339813110..365ab947983c 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.10/hid-bpf-add-bpf_jit-dependency.patch b/queue-6.10/hid-bpf-add-bpf_jit-dependency.patch new file mode 100644 index 00000000000..a67304cbb66 --- /dev/null +++ b/queue-6.10/hid-bpf-add-bpf_jit-dependency.patch @@ -0,0 +1,50 @@ +From e2ab8bf5691a8c4a1f46743f26be97acec2dab87 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 19 Jul 2024 11:51:07 +0200 +Subject: hid: bpf: add BPF_JIT dependency + +From: Arnd Bergmann + +[ Upstream commit bacc15e010fc5a235fb2020b06a29a9961b5db82 ] + +The module does not do anything when the JIT is disabled, but instead +causes a warning: + +In file included from include/linux/bpf_verifier.h:7, + from drivers/hid/bpf/hid_bpf_struct_ops.c:10: +drivers/hid/bpf/hid_bpf_struct_ops.c: In function 'hid_bpf_struct_ops_init': +include/linux/bpf.h:1853:50: error: statement with no effect [-Werror=unused-value] + 1853 | #define register_bpf_struct_ops(st_ops, type) ({ (void *)(st_ops); 0; }) + | ^~~~~~~~~~~~~~~~ +drivers/hid/bpf/hid_bpf_struct_ops.c:305:16: note: in expansion of macro 'register_bpf_struct_ops' + 305 | return register_bpf_struct_ops(&bpf_hid_bpf_ops, hid_bpf_ops); + | ^~~~~~~~~~~~~~~~~~~~~~~ + +Add a Kconfig dependency to only allow building the HID-BPF support +when a JIT is enabled. + +Fixes: ebc0d8093e8c ("HID: bpf: implement HID-BPF through bpf_struct_ops") +Signed-off-by: Arnd Bergmann +Link: https://patch.msgid.link/96a00b6f-eb81-4c67-8c4b-6b1f3f045034@app.fastmail.com +Signed-off-by: Benjamin Tissoires +Signed-off-by: Sasha Levin +--- + drivers/hid/bpf/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/hid/bpf/Kconfig b/drivers/hid/bpf/Kconfig +index 83214bae6768..d65482e02a6c 100644 +--- a/drivers/hid/bpf/Kconfig ++++ b/drivers/hid/bpf/Kconfig +@@ -3,7 +3,7 @@ menu "HID-BPF support" + + config HID_BPF + bool "HID-BPF support" +- depends on BPF ++ depends on BPF_JIT + depends on BPF_SYSCALL + depends on DYNAMIC_FTRACE_WITH_DIRECT_CALLS + help +-- +2.43.0 + diff --git a/queue-6.10/net-mlx5e-shampo-fix-page-leak.patch b/queue-6.10/net-mlx5e-shampo-fix-page-leak.patch new file mode 100644 index 00000000000..1e8f28ed1cd --- /dev/null +++ b/queue-6.10/net-mlx5e-shampo-fix-page-leak.patch @@ -0,0 +1,72 @@ +From e41fb96ab9ac6aa543b138cf3f682d1932b331fa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 Aug 2024 10:16:08 +0300 +Subject: net/mlx5e: SHAMPO, Fix page leak + +From: Dragos Tatulea + +[ Upstream commit f232de7cdb4b99adb2c7f2bc5e0b7e4e1292873b ] + +When SHAMPO is used, a receive queue currently almost always leaks one +page on shutdown. + +A page has MLX5E_SHAMPO_WQ_HEADER_PER_PAGE (8) headers. These headers +are tracked in the SHAMPO bitmap. Each page is released when the last +header index in the group is processed. During header allocation, there +can be leftovers from a page that will be used in a subsequent +allocation. This is normally fine, except for the following scenario +(simplified a bit): + +1) Allocate N new page fragments, showing only the relevant last 4 + fragments: + + 0: new page + 1: new page + 2: new page + 3: new page + 4: page from previous allocation + 5: page from previous allocation + 6: page from previous allocation + 7: page from previous allocation + +2) NAPI processes header indices 4-7 because they are the oldest + allocated. Bit 7 will be set to 0. + +3) Receive queue shutdown occurs. All the remaining bits are being + iterated on to release the pages. But the page assigned to header + indices 0-3 will not be freed due to what happened in step 2. + +This patch fixes the issue by making sure that on allocation, header +fragments are always allocated in groups of +MLX5E_SHAMPO_WQ_HEADER_PER_PAGE so that there is never a partial page +left over between allocations. + +A more appropriate fix would be a refactoring of +mlx5e_alloc_rx_hd_mpwqe() and mlx5e_build_shampo_hd_umr(). But this +refactoring is too big for net. It will be targeted for net-next. + +Fixes: e839ac9a89cb ("net/mlx5e: SHAMPO, Simplify header page release in teardown") +Signed-off-by: Dragos Tatulea +Signed-off-by: Tariq Toukan +Link: https://patch.msgid.link/20240815071611.2211873-2-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +index 2df96648e3f4..cbc45dc34a60 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +@@ -727,6 +727,7 @@ static int mlx5e_alloc_rx_hd_mpwqe(struct mlx5e_rq *rq) + ksm_entries = bitmap_find_window(shampo->bitmap, + shampo->hd_per_wqe, + shampo->hd_per_wq, shampo->pi); ++ ksm_entries = ALIGN_DOWN(ksm_entries, MLX5E_SHAMPO_WQ_HEADER_PER_PAGE); + if (!ksm_entries) + return 0; + +-- +2.43.0 + diff --git a/queue-6.10/net-mlx5e-shampo-use-ksms-instead-of-klms.patch b/queue-6.10/net-mlx5e-shampo-use-ksms-instead-of-klms.patch new file mode 100644 index 00000000000..d04bca848d5 --- /dev/null +++ b/queue-6.10/net-mlx5e-shampo-use-ksms-instead-of-klms.patch @@ -0,0 +1,333 @@ +From ab26650068d8fa3568eee0fc7a083b8343f20730 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Jun 2024 00:22:17 +0300 +Subject: net/mlx5e: SHAMPO, Use KSMs instead of KLMs + +From: Yoray Zack + +[ Upstream commit 758191c9ea7bcc45dd99398a538ae4ab27c4029e ] + +KSM Mkey is KLM Mkey with a fixed buffer size. Due to this fact, +it is a faster mechanism than KLM. + +SHAMPO feature used KLMs Mkeys for memory mappings of its headers buffer. +As it used KLMs with the same buffer size for each entry, +we can use KSMs instead. + +This commit changes the Mkeys that map the SHAMPO headers buffer +from KLMs to KSMs. + +Signed-off-by: Yoray Zack +Signed-off-by: Tariq Toukan +Link: https://lore.kernel.org/r/20240603212219.1037656-13-tariqt@nvidia.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: f232de7cdb4b ("net/mlx5e: SHAMPO, Fix page leak") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en.h | 20 +----- + .../ethernet/mellanox/mlx5/core/en/params.c | 12 ++-- + .../net/ethernet/mellanox/mlx5/core/en/txrx.h | 19 ++++++ + .../net/ethernet/mellanox/mlx5/core/en_main.c | 21 +++--- + .../net/ethernet/mellanox/mlx5/core/en_rx.c | 65 +++++++++---------- + include/linux/mlx5/device.h | 1 + + 6 files changed, 71 insertions(+), 67 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h +index e85fb71bf0b4..3cebc3a435db 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h +@@ -80,6 +80,7 @@ struct page_pool; + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) + + #define MLX5E_RX_MAX_HEAD (256) ++#define MLX5E_SHAMPO_LOG_HEADER_ENTRY_SIZE (8) + #define MLX5E_SHAMPO_LOG_MAX_HEADER_ENTRY_SIZE (9) + #define MLX5E_SHAMPO_WQ_HEADER_PER_PAGE (PAGE_SIZE >> MLX5E_SHAMPO_LOG_MAX_HEADER_ENTRY_SIZE) + #define MLX5E_SHAMPO_WQ_BASE_HEAD_ENTRY_SIZE (64) +@@ -146,25 +147,6 @@ struct page_pool; + #define MLX5E_TX_XSK_POLL_BUDGET 64 + #define MLX5E_SQ_RECOVER_MIN_INTERVAL 500 /* msecs */ + +-#define MLX5E_KLM_UMR_WQE_SZ(sgl_len)\ +- (sizeof(struct mlx5e_umr_wqe) +\ +- (sizeof(struct mlx5_klm) * (sgl_len))) +- +-#define MLX5E_KLM_UMR_WQEBBS(klm_entries) \ +- (DIV_ROUND_UP(MLX5E_KLM_UMR_WQE_SZ(klm_entries), MLX5_SEND_WQE_BB)) +- +-#define MLX5E_KLM_UMR_DS_CNT(klm_entries)\ +- (DIV_ROUND_UP(MLX5E_KLM_UMR_WQE_SZ(klm_entries), MLX5_SEND_WQE_DS)) +- +-#define MLX5E_KLM_MAX_ENTRIES_PER_WQE(wqe_size)\ +- (((wqe_size) - sizeof(struct mlx5e_umr_wqe)) / sizeof(struct mlx5_klm)) +- +-#define MLX5E_KLM_ENTRIES_PER_WQE(wqe_size)\ +- ALIGN_DOWN(MLX5E_KLM_MAX_ENTRIES_PER_WQE(wqe_size), MLX5_UMR_KLM_NUM_ENTRIES_ALIGNMENT) +- +-#define MLX5E_MAX_KLM_PER_WQE(mdev) \ +- MLX5E_KLM_ENTRIES_PER_WQE(MLX5_SEND_WQE_BB * mlx5e_get_max_sq_aligned_wqebbs(mdev)) +- + #define mlx5e_state_dereference(priv, p) \ + rcu_dereference_protected((p), lockdep_is_held(&(priv)->state_lock)) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/params.c b/drivers/net/ethernet/mellanox/mlx5/core/en/params.c +index ec819dfc98be..6c9ccccca81e 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/params.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/params.c +@@ -1071,18 +1071,18 @@ static u32 mlx5e_shampo_icosq_sz(struct mlx5_core_dev *mdev, + struct mlx5e_params *params, + struct mlx5e_rq_param *rq_param) + { +- int max_num_of_umr_per_wqe, max_hd_per_wqe, max_klm_per_umr, rest; ++ int max_num_of_umr_per_wqe, max_hd_per_wqe, max_ksm_per_umr, rest; + void *wqc = MLX5_ADDR_OF(rqc, rq_param->rqc, wq); + int wq_size = BIT(MLX5_GET(wq, wqc, log_wq_sz)); + u32 wqebbs; + +- max_klm_per_umr = MLX5E_MAX_KLM_PER_WQE(mdev); ++ max_ksm_per_umr = MLX5E_MAX_KSM_PER_WQE(mdev); + max_hd_per_wqe = mlx5e_shampo_hd_per_wqe(mdev, params, rq_param); +- max_num_of_umr_per_wqe = max_hd_per_wqe / max_klm_per_umr; +- rest = max_hd_per_wqe % max_klm_per_umr; +- wqebbs = MLX5E_KLM_UMR_WQEBBS(max_klm_per_umr) * max_num_of_umr_per_wqe; ++ max_num_of_umr_per_wqe = max_hd_per_wqe / max_ksm_per_umr; ++ rest = max_hd_per_wqe % max_ksm_per_umr; ++ wqebbs = MLX5E_KSM_UMR_WQEBBS(max_ksm_per_umr) * max_num_of_umr_per_wqe; + if (rest) +- wqebbs += MLX5E_KLM_UMR_WQEBBS(rest); ++ wqebbs += MLX5E_KSM_UMR_WQEBBS(rest); + wqebbs *= wq_size; + return wqebbs; + } +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h b/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h +index 879d698b6119..d1f0f868d494 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h +@@ -34,6 +34,25 @@ + + #define MLX5E_RX_ERR_CQE(cqe) (get_cqe_opcode(cqe) != MLX5_CQE_RESP_SEND) + ++#define MLX5E_KSM_UMR_WQE_SZ(sgl_len)\ ++ (sizeof(struct mlx5e_umr_wqe) +\ ++ (sizeof(struct mlx5_ksm) * (sgl_len))) ++ ++#define MLX5E_KSM_UMR_WQEBBS(ksm_entries) \ ++ (DIV_ROUND_UP(MLX5E_KSM_UMR_WQE_SZ(ksm_entries), MLX5_SEND_WQE_BB)) ++ ++#define MLX5E_KSM_UMR_DS_CNT(ksm_entries)\ ++ (DIV_ROUND_UP(MLX5E_KSM_UMR_WQE_SZ(ksm_entries), MLX5_SEND_WQE_DS)) ++ ++#define MLX5E_KSM_MAX_ENTRIES_PER_WQE(wqe_size)\ ++ (((wqe_size) - sizeof(struct mlx5e_umr_wqe)) / sizeof(struct mlx5_ksm)) ++ ++#define MLX5E_KSM_ENTRIES_PER_WQE(wqe_size)\ ++ ALIGN_DOWN(MLX5E_KSM_MAX_ENTRIES_PER_WQE(wqe_size), MLX5_UMR_KSM_NUM_ENTRIES_ALIGNMENT) ++ ++#define MLX5E_MAX_KSM_PER_WQE(mdev) \ ++ MLX5E_KSM_ENTRIES_PER_WQE(MLX5_SEND_WQE_BB * mlx5e_get_max_sq_aligned_wqebbs(mdev)) ++ + static inline + ktime_t mlx5e_cqe_ts_to_ns(cqe_ts_to_ns func, struct mlx5_clock *clock, u64 cqe_ts) + { +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +index 409f525f1703..632129de24ba 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +@@ -504,8 +504,8 @@ static int mlx5e_create_umr_mkey(struct mlx5_core_dev *mdev, + return err; + } + +-static int mlx5e_create_umr_klm_mkey(struct mlx5_core_dev *mdev, +- u64 nentries, ++static int mlx5e_create_umr_ksm_mkey(struct mlx5_core_dev *mdev, ++ u64 nentries, u8 log_entry_size, + u32 *umr_mkey) + { + int inlen; +@@ -525,12 +525,13 @@ static int mlx5e_create_umr_klm_mkey(struct mlx5_core_dev *mdev, + MLX5_SET(mkc, mkc, umr_en, 1); + MLX5_SET(mkc, mkc, lw, 1); + MLX5_SET(mkc, mkc, lr, 1); +- MLX5_SET(mkc, mkc, access_mode_1_0, MLX5_MKC_ACCESS_MODE_KLMS); ++ MLX5_SET(mkc, mkc, access_mode_1_0, MLX5_MKC_ACCESS_MODE_KSM); + mlx5e_mkey_set_relaxed_ordering(mdev, mkc); + MLX5_SET(mkc, mkc, qpn, 0xffffff); + MLX5_SET(mkc, mkc, pd, mdev->mlx5e_res.hw_objs.pdn); + MLX5_SET(mkc, mkc, translations_octword_size, nentries); +- MLX5_SET(mkc, mkc, length64, 1); ++ MLX5_SET(mkc, mkc, log_page_size, log_entry_size); ++ MLX5_SET64(mkc, mkc, len, nentries << log_entry_size); + err = mlx5_core_create_mkey(mdev, umr_mkey, in, inlen); + + kvfree(in); +@@ -565,14 +566,16 @@ static int mlx5e_create_rq_umr_mkey(struct mlx5_core_dev *mdev, struct mlx5e_rq + static int mlx5e_create_rq_hd_umr_mkey(struct mlx5_core_dev *mdev, + struct mlx5e_rq *rq) + { +- u32 max_klm_size = BIT(MLX5_CAP_GEN(mdev, log_max_klm_list_size)); ++ u32 max_ksm_size = BIT(MLX5_CAP_GEN(mdev, log_max_klm_list_size)); + +- if (max_klm_size < rq->mpwqe.shampo->hd_per_wq) { +- mlx5_core_err(mdev, "max klm list size 0x%x is smaller than shampo header buffer list size 0x%x\n", +- max_klm_size, rq->mpwqe.shampo->hd_per_wq); ++ if (max_ksm_size < rq->mpwqe.shampo->hd_per_wq) { ++ mlx5_core_err(mdev, "max ksm list size 0x%x is smaller than shampo header buffer list size 0x%x\n", ++ max_ksm_size, rq->mpwqe.shampo->hd_per_wq); + return -EINVAL; + } +- return mlx5e_create_umr_klm_mkey(mdev, rq->mpwqe.shampo->hd_per_wq, ++ ++ return mlx5e_create_umr_ksm_mkey(mdev, rq->mpwqe.shampo->hd_per_wq, ++ MLX5E_SHAMPO_LOG_HEADER_ENTRY_SIZE, + &rq->mpwqe.shampo->mkey); + } + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +index 0138f77eaeed..2df96648e3f4 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +@@ -619,25 +619,25 @@ static int bitmap_find_window(unsigned long *bitmap, int len, + return min(len, count); + } + +-static void build_klm_umr(struct mlx5e_icosq *sq, struct mlx5e_umr_wqe *umr_wqe, +- __be32 key, u16 offset, u16 klm_len, u16 wqe_bbs) ++static void build_ksm_umr(struct mlx5e_icosq *sq, struct mlx5e_umr_wqe *umr_wqe, ++ __be32 key, u16 offset, u16 ksm_len) + { +- memset(umr_wqe, 0, offsetof(struct mlx5e_umr_wqe, inline_klms)); ++ memset(umr_wqe, 0, offsetof(struct mlx5e_umr_wqe, inline_ksms)); + umr_wqe->ctrl.opmod_idx_opcode = + cpu_to_be32((sq->pc << MLX5_WQE_CTRL_WQE_INDEX_SHIFT) | + MLX5_OPCODE_UMR); + umr_wqe->ctrl.umr_mkey = key; + umr_wqe->ctrl.qpn_ds = cpu_to_be32((sq->sqn << MLX5_WQE_CTRL_QPN_SHIFT) +- | MLX5E_KLM_UMR_DS_CNT(klm_len)); ++ | MLX5E_KSM_UMR_DS_CNT(ksm_len)); + umr_wqe->uctrl.flags = MLX5_UMR_TRANSLATION_OFFSET_EN | MLX5_UMR_INLINE; + umr_wqe->uctrl.xlt_offset = cpu_to_be16(offset); +- umr_wqe->uctrl.xlt_octowords = cpu_to_be16(klm_len); ++ umr_wqe->uctrl.xlt_octowords = cpu_to_be16(ksm_len); + umr_wqe->uctrl.mkey_mask = cpu_to_be64(MLX5_MKEY_MASK_FREE); + } + + static int mlx5e_build_shampo_hd_umr(struct mlx5e_rq *rq, + struct mlx5e_icosq *sq, +- u16 klm_entries, u16 index) ++ u16 ksm_entries, u16 index) + { + struct mlx5e_shampo_hd *shampo = rq->mpwqe.shampo; + u16 entries, pi, header_offset, err, wqe_bbs, new_entries; +@@ -650,20 +650,20 @@ static int mlx5e_build_shampo_hd_umr(struct mlx5e_rq *rq, + int headroom, i; + + headroom = rq->buff.headroom; +- new_entries = klm_entries - (shampo->pi & (MLX5_UMR_KLM_NUM_ENTRIES_ALIGNMENT - 1)); +- entries = ALIGN(klm_entries, MLX5_UMR_KLM_NUM_ENTRIES_ALIGNMENT); +- wqe_bbs = MLX5E_KLM_UMR_WQEBBS(entries); ++ new_entries = ksm_entries - (shampo->pi & (MLX5_UMR_KSM_NUM_ENTRIES_ALIGNMENT - 1)); ++ entries = ALIGN(ksm_entries, MLX5_UMR_KSM_NUM_ENTRIES_ALIGNMENT); ++ wqe_bbs = MLX5E_KSM_UMR_WQEBBS(entries); + pi = mlx5e_icosq_get_next_pi(sq, wqe_bbs); + umr_wqe = mlx5_wq_cyc_get_wqe(&sq->wq, pi); +- build_klm_umr(sq, umr_wqe, shampo->key, index, entries, wqe_bbs); ++ build_ksm_umr(sq, umr_wqe, shampo->key, index, entries); + + frag_page = &shampo->pages[page_index]; + + for (i = 0; i < entries; i++, index++) { + dma_info = &shampo->info[index]; +- if (i >= klm_entries || (index < shampo->pi && shampo->pi - index < +- MLX5_UMR_KLM_NUM_ENTRIES_ALIGNMENT)) +- goto update_klm; ++ if (i >= ksm_entries || (index < shampo->pi && shampo->pi - index < ++ MLX5_UMR_KSM_NUM_ENTRIES_ALIGNMENT)) ++ goto update_ksm; + header_offset = (index & (MLX5E_SHAMPO_WQ_HEADER_PER_PAGE - 1)) << + MLX5E_SHAMPO_LOG_MAX_HEADER_ENTRY_SIZE; + if (!(header_offset & (PAGE_SIZE - 1))) { +@@ -683,12 +683,11 @@ static int mlx5e_build_shampo_hd_umr(struct mlx5e_rq *rq, + dma_info->frag_page = frag_page; + } + +-update_klm: +- umr_wqe->inline_klms[i].bcount = +- cpu_to_be32(MLX5E_RX_MAX_HEAD); +- umr_wqe->inline_klms[i].key = cpu_to_be32(lkey); +- umr_wqe->inline_klms[i].va = +- cpu_to_be64(dma_info->addr + headroom); ++update_ksm: ++ umr_wqe->inline_ksms[i] = (struct mlx5_ksm) { ++ .key = cpu_to_be32(lkey), ++ .va = cpu_to_be64(dma_info->addr + headroom), ++ }; + } + + sq->db.wqe_info[pi] = (struct mlx5e_icosq_wqe_info) { +@@ -720,37 +719,37 @@ static int mlx5e_build_shampo_hd_umr(struct mlx5e_rq *rq, + static int mlx5e_alloc_rx_hd_mpwqe(struct mlx5e_rq *rq) + { + struct mlx5e_shampo_hd *shampo = rq->mpwqe.shampo; +- u16 klm_entries, num_wqe, index, entries_before; ++ u16 ksm_entries, num_wqe, index, entries_before; + struct mlx5e_icosq *sq = rq->icosq; +- int i, err, max_klm_entries, len; ++ int i, err, max_ksm_entries, len; + +- max_klm_entries = MLX5E_MAX_KLM_PER_WQE(rq->mdev); +- klm_entries = bitmap_find_window(shampo->bitmap, ++ max_ksm_entries = MLX5E_MAX_KSM_PER_WQE(rq->mdev); ++ ksm_entries = bitmap_find_window(shampo->bitmap, + shampo->hd_per_wqe, + shampo->hd_per_wq, shampo->pi); +- if (!klm_entries) ++ if (!ksm_entries) + return 0; + +- klm_entries += (shampo->pi & (MLX5_UMR_KLM_NUM_ENTRIES_ALIGNMENT - 1)); +- index = ALIGN_DOWN(shampo->pi, MLX5_UMR_KLM_NUM_ENTRIES_ALIGNMENT); ++ ksm_entries += (shampo->pi & (MLX5_UMR_KSM_NUM_ENTRIES_ALIGNMENT - 1)); ++ index = ALIGN_DOWN(shampo->pi, MLX5_UMR_KSM_NUM_ENTRIES_ALIGNMENT); + entries_before = shampo->hd_per_wq - index; + +- if (unlikely(entries_before < klm_entries)) +- num_wqe = DIV_ROUND_UP(entries_before, max_klm_entries) + +- DIV_ROUND_UP(klm_entries - entries_before, max_klm_entries); ++ if (unlikely(entries_before < ksm_entries)) ++ num_wqe = DIV_ROUND_UP(entries_before, max_ksm_entries) + ++ DIV_ROUND_UP(ksm_entries - entries_before, max_ksm_entries); + else +- num_wqe = DIV_ROUND_UP(klm_entries, max_klm_entries); ++ num_wqe = DIV_ROUND_UP(ksm_entries, max_ksm_entries); + + for (i = 0; i < num_wqe; i++) { +- len = (klm_entries > max_klm_entries) ? max_klm_entries : +- klm_entries; ++ len = (ksm_entries > max_ksm_entries) ? max_ksm_entries : ++ ksm_entries; + if (unlikely(index + len > shampo->hd_per_wq)) + len = shampo->hd_per_wq - index; + err = mlx5e_build_shampo_hd_umr(rq, sq, len, index); + if (unlikely(err)) + return err; + index = (index + len) & (rq->mpwqe.shampo->hd_per_wq - 1); +- klm_entries -= len; ++ ksm_entries -= len; + } + + return 0; +diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h +index d7bb31d9a446..da09bfaa7b81 100644 +--- a/include/linux/mlx5/device.h ++++ b/include/linux/mlx5/device.h +@@ -294,6 +294,7 @@ enum { + #define MLX5_UMR_FLEX_ALIGNMENT 0x40 + #define MLX5_UMR_MTT_NUM_ENTRIES_ALIGNMENT (MLX5_UMR_FLEX_ALIGNMENT / sizeof(struct mlx5_mtt)) + #define MLX5_UMR_KLM_NUM_ENTRIES_ALIGNMENT (MLX5_UMR_FLEX_ALIGNMENT / sizeof(struct mlx5_klm)) ++#define MLX5_UMR_KSM_NUM_ENTRIES_ALIGNMENT (MLX5_UMR_FLEX_ALIGNMENT / sizeof(struct mlx5_ksm)) + + #define MLX5_USER_INDEX_LEN (MLX5_FLD_SZ_BYTES(qpc, user_index) * 8) + +-- +2.43.0 + diff --git a/queue-6.10/nouveau-fix-the-fwsec-sb-verification-register.patch b/queue-6.10/nouveau-fix-the-fwsec-sb-verification-register.patch new file mode 100644 index 00000000000..eb0856b3ed5 --- /dev/null +++ b/queue-6.10/nouveau-fix-the-fwsec-sb-verification-register.patch @@ -0,0 +1,37 @@ +From 884c3955ef8a63c23e3a39123546d0dddd29151b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 28 Aug 2024 12:37:19 +1000 +Subject: nouveau: fix the fwsec sb verification register. + +From: Dave Airlie + +[ Upstream commit f33b9ab0495b7e3bb01bf6d76045f078e20ada65 ] + +This aligns with what open gpu does, the 0x15 hex is just to trick you. + +Fixes: 176fdcbddfd2 ("drm/nouveau/gsp/r535: add support for booting GSP-RM") +Reviewed-by: Ben Skeggs +Signed-off-by: Dave Airlie +Signed-off-by: Danilo Krummrich +Link: https://patchwork.freedesktop.org/patch/msgid/20240828023720.1596602-1-airlied@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/nouveau/nvkm/subdev/gsp/fwsec.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/fwsec.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/fwsec.c +index 330d72b1a4af..52412965fac1 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/fwsec.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/fwsec.c +@@ -324,7 +324,7 @@ nvkm_gsp_fwsec_sb(struct nvkm_gsp *gsp) + return ret; + + /* Verify. */ +- err = nvkm_rd32(device, 0x001400 + (0xf * 4)) & 0x0000ffff; ++ err = nvkm_rd32(device, 0x001400 + (0x15 * 4)) & 0x0000ffff; + if (err) { + nvkm_error(subdev, "fwsec-sb: 0x%04x\n", err); + return -EIO; +-- +2.43.0 + diff --git a/queue-6.10/nvme-fix-status-magic-numbers.patch b/queue-6.10/nvme-fix-status-magic-numbers.patch new file mode 100644 index 00000000000..d23242417b0 --- /dev/null +++ b/queue-6.10/nvme-fix-status-magic-numbers.patch @@ -0,0 +1,211 @@ +From 88df106648c6cbe44885d3d46c5d8cdb3dd265c6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Jun 2024 20:57:00 +0800 +Subject: nvme: fix status magic numbers + +From: Weiwen Hu + +[ Upstream commit d89a5c6705998ddc42b104f8eabd3c4b9e8fde08 ] + +Replaced some magic numbers about SC and SCT with enum and macro. + +Signed-off-by: Weiwen Hu +Reviewed-by: Sagi Grimberg +Reviewed-by: Chaitanya Kulkarni +Reviewed-by: Christoph Hellwig +Signed-off-by: Keith Busch +Stable-dep-of: 899d2e5a4e3d ("nvmet: Identify-Active Namespace ID List command should reject invalid nsid") +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/constants.c | 2 +- + drivers/nvme/host/core.c | 18 +++++++++--------- + drivers/nvme/host/multipath.c | 2 +- + drivers/nvme/host/nvme.h | 4 ++-- + drivers/nvme/host/pr.c | 2 +- + include/linux/nvme.h | 14 ++++++++++++-- + 6 files changed, 26 insertions(+), 16 deletions(-) + +diff --git a/drivers/nvme/host/constants.c b/drivers/nvme/host/constants.c +index 6f2ebb5fcdb0..2b9e6cfaf2a8 100644 +--- a/drivers/nvme/host/constants.c ++++ b/drivers/nvme/host/constants.c +@@ -173,7 +173,7 @@ static const char * const nvme_statuses[] = { + + const char *nvme_get_error_status_str(u16 status) + { +- status &= 0x7ff; ++ status &= NVME_SCT_SC_MASK; + if (status < ARRAY_SIZE(nvme_statuses) && nvme_statuses[status]) + return nvme_statuses[status]; + return "Unknown"; +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index d973d063bbf5..431f98f45388 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -261,7 +261,7 @@ void nvme_delete_ctrl_sync(struct nvme_ctrl *ctrl) + + static blk_status_t nvme_error_status(u16 status) + { +- switch (status & 0x7ff) { ++ switch (status & NVME_SCT_SC_MASK) { + case NVME_SC_SUCCESS: + return BLK_STS_OK; + case NVME_SC_CAP_EXCEEDED: +@@ -329,8 +329,8 @@ static void nvme_log_error(struct request *req) + nvme_sect_to_lba(ns->head, blk_rq_pos(req)), + blk_rq_bytes(req) >> ns->head->lba_shift, + nvme_get_error_status_str(nr->status), +- nr->status >> 8 & 7, /* Status Code Type */ +- nr->status & 0xff, /* Status Code */ ++ NVME_SCT(nr->status), /* Status Code Type */ ++ nr->status & NVME_SC_MASK, /* Status Code */ + nr->status & NVME_SC_MORE ? "MORE " : "", + nr->status & NVME_SC_DNR ? "DNR " : ""); + return; +@@ -341,8 +341,8 @@ static void nvme_log_error(struct request *req) + nvme_get_admin_opcode_str(nr->cmd->common.opcode), + nr->cmd->common.opcode, + nvme_get_error_status_str(nr->status), +- nr->status >> 8 & 7, /* Status Code Type */ +- nr->status & 0xff, /* Status Code */ ++ NVME_SCT(nr->status), /* Status Code Type */ ++ nr->status & NVME_SC_MASK, /* Status Code */ + nr->status & NVME_SC_MORE ? "MORE " : "", + nr->status & NVME_SC_DNR ? "DNR " : ""); + } +@@ -359,8 +359,8 @@ static void nvme_log_err_passthru(struct request *req) + nvme_get_admin_opcode_str(nr->cmd->common.opcode), + nr->cmd->common.opcode, + nvme_get_error_status_str(nr->status), +- nr->status >> 8 & 7, /* Status Code Type */ +- nr->status & 0xff, /* Status Code */ ++ NVME_SCT(nr->status), /* Status Code Type */ ++ nr->status & NVME_SC_MASK, /* Status Code */ + nr->status & NVME_SC_MORE ? "MORE " : "", + nr->status & NVME_SC_DNR ? "DNR " : "", + nr->cmd->common.cdw10, +@@ -388,7 +388,7 @@ static inline enum nvme_disposition nvme_decide_disposition(struct request *req) + nvme_req(req)->retries >= nvme_max_retries) + return COMPLETE; + +- if ((nvme_req(req)->status & 0x7ff) == NVME_SC_AUTH_REQUIRED) ++ if ((nvme_req(req)->status & NVME_SCT_SC_MASK) == NVME_SC_AUTH_REQUIRED) + return AUTHENTICATE; + + if (req->cmd_flags & REQ_NVME_MPATH) { +@@ -1224,7 +1224,7 @@ EXPORT_SYMBOL_NS_GPL(nvme_passthru_end, NVME_TARGET_PASSTHRU); + + /* + * Recommended frequency for KATO commands per NVMe 1.4 section 7.12.1: +- * ++ * + * The host should send Keep Alive commands at half of the Keep Alive Timeout + * accounting for transport roundtrip times [..]. + */ +diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c +index d8b6b4648eaf..03a6868f4dbc 100644 +--- a/drivers/nvme/host/multipath.c ++++ b/drivers/nvme/host/multipath.c +@@ -83,7 +83,7 @@ void nvme_mpath_start_freeze(struct nvme_subsystem *subsys) + void nvme_failover_req(struct request *req) + { + struct nvme_ns *ns = req->q->queuedata; +- u16 status = nvme_req(req)->status & 0x7ff; ++ u16 status = nvme_req(req)->status & NVME_SCT_SC_MASK; + unsigned long flags; + struct bio *bio; + +diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h +index 68b400f9c42d..2b35304e520d 100644 +--- a/drivers/nvme/host/nvme.h ++++ b/drivers/nvme/host/nvme.h +@@ -689,7 +689,7 @@ static inline u32 nvme_bytes_to_numd(size_t len) + + static inline bool nvme_is_ana_error(u16 status) + { +- switch (status & 0x7ff) { ++ switch (status & NVME_SCT_SC_MASK) { + case NVME_SC_ANA_TRANSITION: + case NVME_SC_ANA_INACCESSIBLE: + case NVME_SC_ANA_PERSISTENT_LOSS: +@@ -702,7 +702,7 @@ static inline bool nvme_is_ana_error(u16 status) + static inline bool nvme_is_path_error(u16 status) + { + /* check for a status code type of 'path related status' */ +- return (status & 0x700) == 0x300; ++ return (status & NVME_SCT_MASK) == NVME_SCT_PATH; + } + + /* +diff --git a/drivers/nvme/host/pr.c b/drivers/nvme/host/pr.c +index a6db5edfab03..7347ddf85f00 100644 +--- a/drivers/nvme/host/pr.c ++++ b/drivers/nvme/host/pr.c +@@ -77,7 +77,7 @@ static int nvme_status_to_pr_err(int status) + if (nvme_is_path_error(status)) + return PR_STS_PATH_FAILED; + +- switch (status & 0x7ff) { ++ switch (status & NVME_SCT_SC_MASK) { + case NVME_SC_SUCCESS: + return PR_STS_SUCCESS; + case NVME_SC_RESERVATION_CONFLICT: +diff --git a/include/linux/nvme.h b/include/linux/nvme.h +index c693ac344ec0..ed0d668e77c5 100644 +--- a/include/linux/nvme.h ++++ b/include/linux/nvme.h +@@ -1848,6 +1848,7 @@ enum { + /* + * Generic Command Status: + */ ++ NVME_SCT_GENERIC = 0x0, + NVME_SC_SUCCESS = 0x0, + NVME_SC_INVALID_OPCODE = 0x1, + NVME_SC_INVALID_FIELD = 0x2, +@@ -1895,6 +1896,7 @@ enum { + /* + * Command Specific Status: + */ ++ NVME_SCT_COMMAND_SPECIFIC = 0x100, + NVME_SC_CQ_INVALID = 0x100, + NVME_SC_QID_INVALID = 0x101, + NVME_SC_QUEUE_SIZE = 0x102, +@@ -1968,6 +1970,7 @@ enum { + /* + * Media and Data Integrity Errors: + */ ++ NVME_SCT_MEDIA_ERROR = 0x200, + NVME_SC_WRITE_FAULT = 0x280, + NVME_SC_READ_ERROR = 0x281, + NVME_SC_GUARD_CHECK = 0x282, +@@ -1980,6 +1983,7 @@ enum { + /* + * Path-related Errors: + */ ++ NVME_SCT_PATH = 0x300, + NVME_SC_INTERNAL_PATH_ERROR = 0x300, + NVME_SC_ANA_PERSISTENT_LOSS = 0x301, + NVME_SC_ANA_INACCESSIBLE = 0x302, +@@ -1988,11 +1992,17 @@ enum { + NVME_SC_HOST_PATH_ERROR = 0x370, + NVME_SC_HOST_ABORTED_CMD = 0x371, + +- NVME_SC_CRD = 0x1800, ++ NVME_SC_MASK = 0x00ff, /* Status Code */ ++ NVME_SCT_MASK = 0x0700, /* Status Code Type */ ++ NVME_SCT_SC_MASK = NVME_SCT_MASK | NVME_SC_MASK, ++ ++ NVME_SC_CRD = 0x1800, /* Command Retry Delayed */ + NVME_SC_MORE = 0x2000, +- NVME_SC_DNR = 0x4000, ++ NVME_SC_DNR = 0x4000, /* Do Not Retry */ + }; + ++#define NVME_SCT(status) ((status) >> 8 & 7) ++ + struct nvme_completion { + /* + * Used by Admin and Fabrics commands to return data: +-- +2.43.0 + diff --git a/queue-6.10/nvme-pci-allocate-tagset-on-reset-if-necessary.patch b/queue-6.10/nvme-pci-allocate-tagset-on-reset-if-necessary.patch new file mode 100644 index 00000000000..a25ced6f78d --- /dev/null +++ b/queue-6.10/nvme-pci-allocate-tagset-on-reset-if-necessary.patch @@ -0,0 +1,43 @@ +From 9ae0ad3d3ef6dc3615ca24f6c7f8301157cb7c13 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 146d33c4839f..18d85575cdb4 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -2473,6 +2473,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.10/nvme-rename-cdr-more-dnr-to-nvme_status_.patch b/queue-6.10/nvme-rename-cdr-more-dnr-to-nvme_status_.patch new file mode 100644 index 00000000000..b027bde88c8 --- /dev/null +++ b/queue-6.10/nvme-rename-cdr-more-dnr-to-nvme_status_.patch @@ -0,0 +1,1129 @@ +From b369563b31f1cacee9da2df692f9b5e9ca6f77f4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Jun 2024 20:57:01 +0800 +Subject: nvme: rename CDR/MORE/DNR to NVME_STATUS_* + +From: Weiwen Hu + +[ Upstream commit dd0b0a4a2c5d7209457dc172997d1243ad269cfa ] + +CDR/MORE/DNR fields are not belonging to SC in the NVMe spec, rename +them to NVME_STATUS_* to avoid confusion. + +Signed-off-by: Weiwen Hu +Reviewed-by: Sagi Grimberg +Reviewed-by: Chaitanya Kulkarni +Reviewed-by: Christoph Hellwig +Signed-off-by: Keith Busch +Stable-dep-of: 899d2e5a4e3d ("nvmet: Identify-Active Namespace ID List command should reject invalid nsid") +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/core.c | 22 ++++++------ + drivers/nvme/host/fabrics.c | 10 +++--- + drivers/nvme/host/fault_inject.c | 2 +- + drivers/nvme/host/fc.c | 6 ++-- + drivers/nvme/host/nvme.h | 2 +- + drivers/nvme/target/admin-cmd.c | 24 +++++++------- + drivers/nvme/target/core.c | 46 +++++++++++++------------- + drivers/nvme/target/discovery.c | 14 ++++---- + drivers/nvme/target/fabrics-cmd-auth.c | 16 ++++----- + drivers/nvme/target/fabrics-cmd.c | 36 ++++++++++---------- + drivers/nvme/target/io-cmd-bdev.c | 12 +++---- + drivers/nvme/target/passthru.c | 10 +++--- + drivers/nvme/target/rdma.c | 10 +++--- + drivers/nvme/target/tcp.c | 4 +-- + drivers/nvme/target/zns.c | 30 ++++++++--------- + include/linux/nvme.h | 6 ++-- + 16 files changed, 125 insertions(+), 125 deletions(-) + +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index 431f98f45388..5569cf4183b2 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -307,7 +307,7 @@ static void nvme_retry_req(struct request *req) + u16 crd; + + /* The mask and shift result must be <= 3 */ +- crd = (nvme_req(req)->status & NVME_SC_CRD) >> 11; ++ crd = (nvme_req(req)->status & NVME_STATUS_CRD) >> 11; + if (crd) + delay = nvme_req(req)->ctrl->crdt[crd - 1] * 100; + +@@ -331,8 +331,8 @@ static void nvme_log_error(struct request *req) + nvme_get_error_status_str(nr->status), + NVME_SCT(nr->status), /* Status Code Type */ + nr->status & NVME_SC_MASK, /* Status Code */ +- nr->status & NVME_SC_MORE ? "MORE " : "", +- nr->status & NVME_SC_DNR ? "DNR " : ""); ++ nr->status & NVME_STATUS_MORE ? "MORE " : "", ++ nr->status & NVME_STATUS_DNR ? "DNR " : ""); + return; + } + +@@ -343,8 +343,8 @@ static void nvme_log_error(struct request *req) + nvme_get_error_status_str(nr->status), + NVME_SCT(nr->status), /* Status Code Type */ + nr->status & NVME_SC_MASK, /* Status Code */ +- nr->status & NVME_SC_MORE ? "MORE " : "", +- nr->status & NVME_SC_DNR ? "DNR " : ""); ++ nr->status & NVME_STATUS_MORE ? "MORE " : "", ++ nr->status & NVME_STATUS_DNR ? "DNR " : ""); + } + + static void nvme_log_err_passthru(struct request *req) +@@ -361,8 +361,8 @@ static void nvme_log_err_passthru(struct request *req) + nvme_get_error_status_str(nr->status), + NVME_SCT(nr->status), /* Status Code Type */ + nr->status & NVME_SC_MASK, /* Status Code */ +- nr->status & NVME_SC_MORE ? "MORE " : "", +- nr->status & NVME_SC_DNR ? "DNR " : "", ++ nr->status & NVME_STATUS_MORE ? "MORE " : "", ++ nr->status & NVME_STATUS_DNR ? "DNR " : "", + nr->cmd->common.cdw10, + nr->cmd->common.cdw11, + nr->cmd->common.cdw12, +@@ -384,7 +384,7 @@ static inline enum nvme_disposition nvme_decide_disposition(struct request *req) + return COMPLETE; + + if (blk_noretry_request(req) || +- (nvme_req(req)->status & NVME_SC_DNR) || ++ (nvme_req(req)->status & NVME_STATUS_DNR) || + nvme_req(req)->retries >= nvme_max_retries) + return COMPLETE; + +@@ -3887,7 +3887,7 @@ static void nvme_ns_remove_by_nsid(struct nvme_ctrl *ctrl, u32 nsid) + + static void nvme_validate_ns(struct nvme_ns *ns, struct nvme_ns_info *info) + { +- int ret = NVME_SC_INVALID_NS | NVME_SC_DNR; ++ int ret = NVME_SC_INVALID_NS | NVME_STATUS_DNR; + + if (!nvme_ns_ids_equal(&ns->head->ids, &info->ids)) { + dev_err(ns->ctrl->device, +@@ -3903,7 +3903,7 @@ static void nvme_validate_ns(struct nvme_ns *ns, struct nvme_ns_info *info) + * + * TODO: we should probably schedule a delayed retry here. + */ +- if (ret > 0 && (ret & NVME_SC_DNR)) ++ if (ret > 0 && (ret & NVME_STATUS_DNR)) + nvme_ns_remove(ns); + } + +@@ -4095,7 +4095,7 @@ static void nvme_scan_work(struct work_struct *work) + * they report) but don't actually support it. + */ + ret = nvme_scan_ns_list(ctrl); +- if (ret > 0 && ret & NVME_SC_DNR) ++ if (ret > 0 && ret & NVME_STATUS_DNR) + nvme_scan_ns_sequential(ctrl); + } + mutex_unlock(&ctrl->scan_lock); +diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c +index ceb9c0ed3120..b5a4b5fd573e 100644 +--- a/drivers/nvme/host/fabrics.c ++++ b/drivers/nvme/host/fabrics.c +@@ -187,7 +187,7 @@ int nvmf_reg_read32(struct nvme_ctrl *ctrl, u32 off, u32 *val) + if (unlikely(ret != 0)) + dev_err(ctrl->device, + "Property Get error: %d, offset %#x\n", +- ret > 0 ? ret & ~NVME_SC_DNR : ret, off); ++ ret > 0 ? ret & ~NVME_STATUS_DNR : ret, off); + + return ret; + } +@@ -233,7 +233,7 @@ int nvmf_reg_read64(struct nvme_ctrl *ctrl, u32 off, u64 *val) + if (unlikely(ret != 0)) + dev_err(ctrl->device, + "Property Get error: %d, offset %#x\n", +- ret > 0 ? ret & ~NVME_SC_DNR : ret, off); ++ ret > 0 ? ret & ~NVME_STATUS_DNR : ret, off); + return ret; + } + EXPORT_SYMBOL_GPL(nvmf_reg_read64); +@@ -275,7 +275,7 @@ int nvmf_reg_write32(struct nvme_ctrl *ctrl, u32 off, u32 val) + if (unlikely(ret)) + dev_err(ctrl->device, + "Property Set error: %d, offset %#x\n", +- ret > 0 ? ret & ~NVME_SC_DNR : ret, off); ++ ret > 0 ? ret & ~NVME_STATUS_DNR : ret, off); + return ret; + } + EXPORT_SYMBOL_GPL(nvmf_reg_write32); +@@ -295,7 +295,7 @@ static void nvmf_log_connect_error(struct nvme_ctrl *ctrl, + int errval, int offset, struct nvme_command *cmd, + struct nvmf_connect_data *data) + { +- int err_sctype = errval & ~NVME_SC_DNR; ++ int err_sctype = errval & ~NVME_STATUS_DNR; + + if (errval < 0) { + dev_err(ctrl->device, +@@ -573,7 +573,7 @@ EXPORT_SYMBOL_GPL(nvmf_connect_io_queue); + */ + bool nvmf_should_reconnect(struct nvme_ctrl *ctrl, int status) + { +- if (status > 0 && (status & NVME_SC_DNR)) ++ if (status > 0 && (status & NVME_STATUS_DNR)) + return false; + + if (status == -EKEYREJECTED) +diff --git a/drivers/nvme/host/fault_inject.c b/drivers/nvme/host/fault_inject.c +index 1ba10a5c656d..1d1b6441a339 100644 +--- a/drivers/nvme/host/fault_inject.c ++++ b/drivers/nvme/host/fault_inject.c +@@ -75,7 +75,7 @@ void nvme_should_fail(struct request *req) + /* inject status code and DNR bit */ + status = fault_inject->status; + if (fault_inject->dont_retry) +- status |= NVME_SC_DNR; ++ status |= NVME_STATUS_DNR; + nvme_req(req)->status = status; + } + } +diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c +index f0b081332749..beaad6576a67 100644 +--- a/drivers/nvme/host/fc.c ++++ b/drivers/nvme/host/fc.c +@@ -3132,7 +3132,7 @@ nvme_fc_create_association(struct nvme_fc_ctrl *ctrl) + if (ctrl->ctrl.icdoff) { + dev_err(ctrl->ctrl.device, "icdoff %d is not supported!\n", + ctrl->ctrl.icdoff); +- ret = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ ret = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + goto out_stop_keep_alive; + } + +@@ -3140,7 +3140,7 @@ nvme_fc_create_association(struct nvme_fc_ctrl *ctrl) + if (!nvme_ctrl_sgl_supported(&ctrl->ctrl)) { + dev_err(ctrl->ctrl.device, + "Mandatory sgls are not supported!\n"); +- ret = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ ret = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + goto out_stop_keep_alive; + } + +@@ -3325,7 +3325,7 @@ nvme_fc_reconnect_or_delete(struct nvme_fc_ctrl *ctrl, int status) + queue_delayed_work(nvme_wq, &ctrl->connect_work, recon_delay); + } else { + if (portptr->port_state == FC_OBJSTATE_ONLINE) { +- if (status > 0 && (status & NVME_SC_DNR)) ++ if (status > 0 && (status & NVME_STATUS_DNR)) + dev_warn(ctrl->ctrl.device, + "NVME-FC{%d}: reconnect failure\n", + ctrl->cnum); +diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h +index 2b35304e520d..5e66bcb34d53 100644 +--- a/drivers/nvme/host/nvme.h ++++ b/drivers/nvme/host/nvme.h +@@ -877,7 +877,7 @@ enum { + NVME_SUBMIT_NOWAIT = (__force nvme_submit_flags_t)(1 << 1), + /* Set BLK_MQ_REQ_RESERVED when allocating request */ + NVME_SUBMIT_RESERVED = (__force nvme_submit_flags_t)(1 << 2), +- /* Retry command when NVME_SC_DNR is not set in the result */ ++ /* Retry command when NVME_STATUS_DNR is not set in the result */ + NVME_SUBMIT_RETRY = (__force nvme_submit_flags_t)(1 << 3), + }; + +diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c +index f5b7054a4a05..f7e1156ac7ec 100644 +--- a/drivers/nvme/target/admin-cmd.c ++++ b/drivers/nvme/target/admin-cmd.c +@@ -344,7 +344,7 @@ static void nvmet_execute_get_log_page(struct nvmet_req *req) + pr_debug("unhandled lid %d on qid %d\n", + req->cmd->get_log_page.lid, req->sq->qid); + req->error_loc = offsetof(struct nvme_get_log_page_command, lid); +- nvmet_req_complete(req, NVME_SC_INVALID_FIELD | NVME_SC_DNR); ++ nvmet_req_complete(req, NVME_SC_INVALID_FIELD | NVME_STATUS_DNR); + } + + static void nvmet_execute_identify_ctrl(struct nvmet_req *req) +@@ -496,7 +496,7 @@ static void nvmet_execute_identify_ns(struct nvmet_req *req) + + if (le32_to_cpu(req->cmd->identify.nsid) == NVME_NSID_ALL) { + req->error_loc = offsetof(struct nvme_identify, nsid); +- status = NVME_SC_INVALID_NS | NVME_SC_DNR; ++ status = NVME_SC_INVALID_NS | NVME_STATUS_DNR; + goto out; + } + +@@ -662,7 +662,7 @@ static void nvmet_execute_identify_desclist(struct nvmet_req *req) + + if (sg_zero_buffer(req->sg, req->sg_cnt, NVME_IDENTIFY_DATA_SIZE - off, + off) != NVME_IDENTIFY_DATA_SIZE - off) +- status = NVME_SC_INTERNAL | NVME_SC_DNR; ++ status = NVME_SC_INTERNAL | NVME_STATUS_DNR; + + out: + nvmet_req_complete(req, status); +@@ -724,7 +724,7 @@ static void nvmet_execute_identify(struct nvmet_req *req) + pr_debug("unhandled identify cns %d on qid %d\n", + req->cmd->identify.cns, req->sq->qid); + req->error_loc = offsetof(struct nvme_identify, cns); +- nvmet_req_complete(req, NVME_SC_INVALID_FIELD | NVME_SC_DNR); ++ nvmet_req_complete(req, NVME_SC_INVALID_FIELD | NVME_STATUS_DNR); + } + + /* +@@ -807,7 +807,7 @@ u16 nvmet_set_feat_async_event(struct nvmet_req *req, u32 mask) + + if (val32 & ~mask) { + req->error_loc = offsetof(struct nvme_common_command, cdw11); +- return NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ return NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + } + + WRITE_ONCE(req->sq->ctrl->aen_enabled, val32); +@@ -833,7 +833,7 @@ void nvmet_execute_set_features(struct nvmet_req *req) + ncqr = (cdw11 >> 16) & 0xffff; + nsqr = cdw11 & 0xffff; + if (ncqr == 0xffff || nsqr == 0xffff) { +- status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + break; + } + nvmet_set_result(req, +@@ -846,14 +846,14 @@ void nvmet_execute_set_features(struct nvmet_req *req) + status = nvmet_set_feat_async_event(req, NVMET_AEN_CFG_ALL); + break; + case NVME_FEAT_HOST_ID: +- status = NVME_SC_CMD_SEQ_ERROR | NVME_SC_DNR; ++ status = NVME_SC_CMD_SEQ_ERROR | NVME_STATUS_DNR; + break; + case NVME_FEAT_WRITE_PROTECT: + status = nvmet_set_feat_write_protect(req); + break; + default: + req->error_loc = offsetof(struct nvme_common_command, cdw10); +- status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + break; + } + +@@ -939,7 +939,7 @@ void nvmet_execute_get_features(struct nvmet_req *req) + if (!(req->cmd->common.cdw11 & cpu_to_le32(1 << 0))) { + req->error_loc = + offsetof(struct nvme_common_command, cdw11); +- status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + break; + } + +@@ -952,7 +952,7 @@ void nvmet_execute_get_features(struct nvmet_req *req) + default: + req->error_loc = + offsetof(struct nvme_common_command, cdw10); +- status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + break; + } + +@@ -969,7 +969,7 @@ void nvmet_execute_async_event(struct nvmet_req *req) + mutex_lock(&ctrl->lock); + if (ctrl->nr_async_event_cmds >= NVMET_ASYNC_EVENTS) { + mutex_unlock(&ctrl->lock); +- nvmet_req_complete(req, NVME_SC_ASYNC_LIMIT | NVME_SC_DNR); ++ nvmet_req_complete(req, NVME_SC_ASYNC_LIMIT | NVME_STATUS_DNR); + return; + } + ctrl->async_event_cmds[ctrl->nr_async_event_cmds++] = req; +@@ -1006,7 +1006,7 @@ u16 nvmet_parse_admin_cmd(struct nvmet_req *req) + if (nvme_is_fabrics(cmd)) + return nvmet_parse_fabrics_admin_cmd(req); + if (unlikely(!nvmet_check_auth_status(req))) +- return NVME_SC_AUTH_REQUIRED | NVME_SC_DNR; ++ return NVME_SC_AUTH_REQUIRED | NVME_STATUS_DNR; + if (nvmet_is_disc_subsys(nvmet_req_subsys(req))) + return nvmet_parse_discovery_cmd(req); + +diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c +index 4ff460ba2826..c0973810e6af 100644 +--- a/drivers/nvme/target/core.c ++++ b/drivers/nvme/target/core.c +@@ -55,18 +55,18 @@ inline u16 errno_to_nvme_status(struct nvmet_req *req, int errno) + return NVME_SC_SUCCESS; + case -ENOSPC: + req->error_loc = offsetof(struct nvme_rw_command, length); +- return NVME_SC_CAP_EXCEEDED | NVME_SC_DNR; ++ return NVME_SC_CAP_EXCEEDED | NVME_STATUS_DNR; + case -EREMOTEIO: + req->error_loc = offsetof(struct nvme_rw_command, slba); +- return NVME_SC_LBA_RANGE | NVME_SC_DNR; ++ return NVME_SC_LBA_RANGE | NVME_STATUS_DNR; + case -EOPNOTSUPP: + req->error_loc = offsetof(struct nvme_common_command, opcode); + switch (req->cmd->common.opcode) { + case nvme_cmd_dsm: + case nvme_cmd_write_zeroes: +- return NVME_SC_ONCS_NOT_SUPPORTED | NVME_SC_DNR; ++ return NVME_SC_ONCS_NOT_SUPPORTED | NVME_STATUS_DNR; + default: +- return NVME_SC_INVALID_OPCODE | NVME_SC_DNR; ++ return NVME_SC_INVALID_OPCODE | NVME_STATUS_DNR; + } + break; + case -ENODATA: +@@ -76,7 +76,7 @@ inline u16 errno_to_nvme_status(struct nvmet_req *req, int errno) + fallthrough; + default: + req->error_loc = offsetof(struct nvme_common_command, opcode); +- return NVME_SC_INTERNAL | NVME_SC_DNR; ++ return NVME_SC_INTERNAL | NVME_STATUS_DNR; + } + } + +@@ -86,7 +86,7 @@ u16 nvmet_report_invalid_opcode(struct nvmet_req *req) + req->sq->qid); + + req->error_loc = offsetof(struct nvme_common_command, opcode); +- return NVME_SC_INVALID_OPCODE | NVME_SC_DNR; ++ return NVME_SC_INVALID_OPCODE | NVME_STATUS_DNR; + } + + static struct nvmet_subsys *nvmet_find_get_subsys(struct nvmet_port *port, +@@ -97,7 +97,7 @@ u16 nvmet_copy_to_sgl(struct nvmet_req *req, off_t off, const void *buf, + { + if (sg_pcopy_from_buffer(req->sg, req->sg_cnt, buf, len, off) != len) { + req->error_loc = offsetof(struct nvme_common_command, dptr); +- return NVME_SC_SGL_INVALID_DATA | NVME_SC_DNR; ++ return NVME_SC_SGL_INVALID_DATA | NVME_STATUS_DNR; + } + return 0; + } +@@ -106,7 +106,7 @@ u16 nvmet_copy_from_sgl(struct nvmet_req *req, off_t off, void *buf, size_t len) + { + if (sg_pcopy_to_buffer(req->sg, req->sg_cnt, buf, len, off) != len) { + req->error_loc = offsetof(struct nvme_common_command, dptr); +- return NVME_SC_SGL_INVALID_DATA | NVME_SC_DNR; ++ return NVME_SC_SGL_INVALID_DATA | NVME_STATUS_DNR; + } + return 0; + } +@@ -115,7 +115,7 @@ u16 nvmet_zero_sgl(struct nvmet_req *req, off_t off, size_t len) + { + if (sg_zero_buffer(req->sg, req->sg_cnt, len, off) != len) { + req->error_loc = offsetof(struct nvme_common_command, dptr); +- return NVME_SC_SGL_INVALID_DATA | NVME_SC_DNR; ++ return NVME_SC_SGL_INVALID_DATA | NVME_STATUS_DNR; + } + return 0; + } +@@ -145,7 +145,7 @@ static void nvmet_async_events_failall(struct nvmet_ctrl *ctrl) + while (ctrl->nr_async_event_cmds) { + req = ctrl->async_event_cmds[--ctrl->nr_async_event_cmds]; + mutex_unlock(&ctrl->lock); +- nvmet_req_complete(req, NVME_SC_INTERNAL | NVME_SC_DNR); ++ nvmet_req_complete(req, NVME_SC_INTERNAL | NVME_STATUS_DNR); + mutex_lock(&ctrl->lock); + } + mutex_unlock(&ctrl->lock); +@@ -444,7 +444,7 @@ u16 nvmet_req_find_ns(struct nvmet_req *req) + req->error_loc = offsetof(struct nvme_common_command, nsid); + if (nvmet_subsys_nsid_exists(subsys, nsid)) + return NVME_SC_INTERNAL_PATH_ERROR; +- return NVME_SC_INVALID_NS | NVME_SC_DNR; ++ return NVME_SC_INVALID_NS | NVME_STATUS_DNR; + } + + percpu_ref_get(&req->ns->ref); +@@ -904,7 +904,7 @@ static u16 nvmet_parse_io_cmd(struct nvmet_req *req) + return nvmet_parse_fabrics_io_cmd(req); + + if (unlikely(!nvmet_check_auth_status(req))) +- return NVME_SC_AUTH_REQUIRED | NVME_SC_DNR; ++ return NVME_SC_AUTH_REQUIRED | NVME_STATUS_DNR; + + ret = nvmet_check_ctrl_status(req); + if (unlikely(ret)) +@@ -967,7 +967,7 @@ bool nvmet_req_init(struct nvmet_req *req, struct nvmet_cq *cq, + /* no support for fused commands yet */ + if (unlikely(flags & (NVME_CMD_FUSE_FIRST | NVME_CMD_FUSE_SECOND))) { + req->error_loc = offsetof(struct nvme_common_command, flags); +- status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + goto fail; + } + +@@ -978,7 +978,7 @@ bool nvmet_req_init(struct nvmet_req *req, struct nvmet_cq *cq, + */ + if (unlikely((flags & NVME_CMD_SGL_ALL) != NVME_CMD_SGL_METABUF)) { + req->error_loc = offsetof(struct nvme_common_command, flags); +- status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + goto fail; + } + +@@ -996,7 +996,7 @@ bool nvmet_req_init(struct nvmet_req *req, struct nvmet_cq *cq, + trace_nvmet_req_init(req, req->cmd); + + if (unlikely(!percpu_ref_tryget_live(&sq->ref))) { +- status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + goto fail; + } + +@@ -1023,7 +1023,7 @@ bool nvmet_check_transfer_len(struct nvmet_req *req, size_t len) + { + if (unlikely(len != req->transfer_len)) { + req->error_loc = offsetof(struct nvme_common_command, dptr); +- nvmet_req_complete(req, NVME_SC_SGL_INVALID_DATA | NVME_SC_DNR); ++ nvmet_req_complete(req, NVME_SC_SGL_INVALID_DATA | NVME_STATUS_DNR); + return false; + } + +@@ -1035,7 +1035,7 @@ bool nvmet_check_data_len_lte(struct nvmet_req *req, size_t data_len) + { + if (unlikely(data_len > req->transfer_len)) { + req->error_loc = offsetof(struct nvme_common_command, dptr); +- nvmet_req_complete(req, NVME_SC_SGL_INVALID_DATA | NVME_SC_DNR); ++ nvmet_req_complete(req, NVME_SC_SGL_INVALID_DATA | NVME_STATUS_DNR); + return false; + } + +@@ -1304,18 +1304,18 @@ u16 nvmet_check_ctrl_status(struct nvmet_req *req) + if (unlikely(!(req->sq->ctrl->cc & NVME_CC_ENABLE))) { + pr_err("got cmd %d while CC.EN == 0 on qid = %d\n", + req->cmd->common.opcode, req->sq->qid); +- return NVME_SC_CMD_SEQ_ERROR | NVME_SC_DNR; ++ return NVME_SC_CMD_SEQ_ERROR | NVME_STATUS_DNR; + } + + if (unlikely(!(req->sq->ctrl->csts & NVME_CSTS_RDY))) { + pr_err("got cmd %d while CSTS.RDY == 0 on qid = %d\n", + req->cmd->common.opcode, req->sq->qid); +- return NVME_SC_CMD_SEQ_ERROR | NVME_SC_DNR; ++ return NVME_SC_CMD_SEQ_ERROR | NVME_STATUS_DNR; + } + + if (unlikely(!nvmet_check_auth_status(req))) { + pr_warn("qid %d not authenticated\n", req->sq->qid); +- return NVME_SC_AUTH_REQUIRED | NVME_SC_DNR; ++ return NVME_SC_AUTH_REQUIRED | NVME_STATUS_DNR; + } + return 0; + } +@@ -1389,7 +1389,7 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn, + int ret; + u16 status; + +- status = NVME_SC_CONNECT_INVALID_PARAM | NVME_SC_DNR; ++ status = NVME_SC_CONNECT_INVALID_PARAM | NVME_STATUS_DNR; + subsys = nvmet_find_get_subsys(req->port, subsysnqn); + if (!subsys) { + pr_warn("connect request for invalid subsystem %s!\n", +@@ -1405,7 +1405,7 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn, + hostnqn, subsysnqn); + req->cqe->result.u32 = IPO_IATTR_CONNECT_DATA(hostnqn); + up_read(&nvmet_config_sem); +- status = NVME_SC_CONNECT_INVALID_HOST | NVME_SC_DNR; ++ status = NVME_SC_CONNECT_INVALID_HOST | NVME_STATUS_DNR; + req->error_loc = offsetof(struct nvme_common_command, dptr); + goto out_put_subsystem; + } +@@ -1456,7 +1456,7 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn, + subsys->cntlid_min, subsys->cntlid_max, + GFP_KERNEL); + if (ret < 0) { +- status = NVME_SC_CONNECT_CTRL_BUSY | NVME_SC_DNR; ++ status = NVME_SC_CONNECT_CTRL_BUSY | NVME_STATUS_DNR; + goto out_free_sqs; + } + ctrl->cntlid = ret; +diff --git a/drivers/nvme/target/discovery.c b/drivers/nvme/target/discovery.c +index ce54da8c6b36..28843df5fa7c 100644 +--- a/drivers/nvme/target/discovery.c ++++ b/drivers/nvme/target/discovery.c +@@ -179,7 +179,7 @@ static void nvmet_execute_disc_get_log_page(struct nvmet_req *req) + if (req->cmd->get_log_page.lid != NVME_LOG_DISC) { + req->error_loc = + offsetof(struct nvme_get_log_page_command, lid); +- status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + goto out; + } + +@@ -187,7 +187,7 @@ static void nvmet_execute_disc_get_log_page(struct nvmet_req *req) + if (offset & 0x3) { + req->error_loc = + offsetof(struct nvme_get_log_page_command, lpo); +- status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + goto out; + } + +@@ -256,7 +256,7 @@ static void nvmet_execute_disc_identify(struct nvmet_req *req) + + if (req->cmd->identify.cns != NVME_ID_CNS_CTRL) { + req->error_loc = offsetof(struct nvme_identify, cns); +- status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + goto out; + } + +@@ -320,7 +320,7 @@ static void nvmet_execute_disc_set_features(struct nvmet_req *req) + default: + req->error_loc = + offsetof(struct nvme_common_command, cdw10); +- stat = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ stat = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + break; + } + +@@ -345,7 +345,7 @@ static void nvmet_execute_disc_get_features(struct nvmet_req *req) + default: + req->error_loc = + offsetof(struct nvme_common_command, cdw10); +- stat = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ stat = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + break; + } + +@@ -361,7 +361,7 @@ u16 nvmet_parse_discovery_cmd(struct nvmet_req *req) + cmd->common.opcode); + req->error_loc = + offsetof(struct nvme_common_command, opcode); +- return NVME_SC_INVALID_OPCODE | NVME_SC_DNR; ++ return NVME_SC_INVALID_OPCODE | NVME_STATUS_DNR; + } + + switch (cmd->common.opcode) { +@@ -386,7 +386,7 @@ u16 nvmet_parse_discovery_cmd(struct nvmet_req *req) + default: + pr_debug("unhandled cmd %d\n", cmd->common.opcode); + req->error_loc = offsetof(struct nvme_common_command, opcode); +- return NVME_SC_INVALID_OPCODE | NVME_SC_DNR; ++ return NVME_SC_INVALID_OPCODE | NVME_STATUS_DNR; + } + + } +diff --git a/drivers/nvme/target/fabrics-cmd-auth.c b/drivers/nvme/target/fabrics-cmd-auth.c +index cb34d644ed08..3f2857c17d95 100644 +--- a/drivers/nvme/target/fabrics-cmd-auth.c ++++ b/drivers/nvme/target/fabrics-cmd-auth.c +@@ -189,26 +189,26 @@ void nvmet_execute_auth_send(struct nvmet_req *req) + u8 dhchap_status; + + if (req->cmd->auth_send.secp != NVME_AUTH_DHCHAP_PROTOCOL_IDENTIFIER) { +- status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + req->error_loc = + offsetof(struct nvmf_auth_send_command, secp); + goto done; + } + if (req->cmd->auth_send.spsp0 != 0x01) { +- status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + req->error_loc = + offsetof(struct nvmf_auth_send_command, spsp0); + goto done; + } + if (req->cmd->auth_send.spsp1 != 0x01) { +- status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + req->error_loc = + offsetof(struct nvmf_auth_send_command, spsp1); + goto done; + } + tl = le32_to_cpu(req->cmd->auth_send.tl); + if (!tl) { +- status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + req->error_loc = + offsetof(struct nvmf_auth_send_command, tl); + goto done; +@@ -437,26 +437,26 @@ void nvmet_execute_auth_receive(struct nvmet_req *req) + u16 status = 0; + + if (req->cmd->auth_receive.secp != NVME_AUTH_DHCHAP_PROTOCOL_IDENTIFIER) { +- status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + req->error_loc = + offsetof(struct nvmf_auth_receive_command, secp); + goto done; + } + if (req->cmd->auth_receive.spsp0 != 0x01) { +- status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + req->error_loc = + offsetof(struct nvmf_auth_receive_command, spsp0); + goto done; + } + if (req->cmd->auth_receive.spsp1 != 0x01) { +- status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + req->error_loc = + offsetof(struct nvmf_auth_receive_command, spsp1); + goto done; + } + al = le32_to_cpu(req->cmd->auth_receive.al); + if (!al) { +- status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + req->error_loc = + offsetof(struct nvmf_auth_receive_command, al); + goto done; +diff --git a/drivers/nvme/target/fabrics-cmd.c b/drivers/nvme/target/fabrics-cmd.c +index 69d77d34bec1..c4b2eddd5666 100644 +--- a/drivers/nvme/target/fabrics-cmd.c ++++ b/drivers/nvme/target/fabrics-cmd.c +@@ -18,7 +18,7 @@ static void nvmet_execute_prop_set(struct nvmet_req *req) + if (req->cmd->prop_set.attrib & 1) { + req->error_loc = + offsetof(struct nvmf_property_set_command, attrib); +- status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + goto out; + } + +@@ -29,7 +29,7 @@ static void nvmet_execute_prop_set(struct nvmet_req *req) + default: + req->error_loc = + offsetof(struct nvmf_property_set_command, offset); +- status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + } + out: + nvmet_req_complete(req, status); +@@ -50,7 +50,7 @@ static void nvmet_execute_prop_get(struct nvmet_req *req) + val = ctrl->cap; + break; + default: +- status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + break; + } + } else { +@@ -65,7 +65,7 @@ static void nvmet_execute_prop_get(struct nvmet_req *req) + val = ctrl->csts; + break; + default: +- status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + break; + } + } +@@ -105,7 +105,7 @@ u16 nvmet_parse_fabrics_admin_cmd(struct nvmet_req *req) + pr_debug("received unknown capsule type 0x%x\n", + cmd->fabrics.fctype); + req->error_loc = offsetof(struct nvmf_common_command, fctype); +- return NVME_SC_INVALID_OPCODE | NVME_SC_DNR; ++ return NVME_SC_INVALID_OPCODE | NVME_STATUS_DNR; + } + + return 0; +@@ -128,7 +128,7 @@ u16 nvmet_parse_fabrics_io_cmd(struct nvmet_req *req) + pr_debug("received unknown capsule type 0x%x\n", + cmd->fabrics.fctype); + req->error_loc = offsetof(struct nvmf_common_command, fctype); +- return NVME_SC_INVALID_OPCODE | NVME_SC_DNR; ++ return NVME_SC_INVALID_OPCODE | NVME_STATUS_DNR; + } + + return 0; +@@ -147,14 +147,14 @@ static u16 nvmet_install_queue(struct nvmet_ctrl *ctrl, struct nvmet_req *req) + pr_warn("queue size zero!\n"); + req->error_loc = offsetof(struct nvmf_connect_command, sqsize); + req->cqe->result.u32 = IPO_IATTR_CONNECT_SQE(sqsize); +- ret = NVME_SC_CONNECT_INVALID_PARAM | NVME_SC_DNR; ++ ret = NVME_SC_CONNECT_INVALID_PARAM | NVME_STATUS_DNR; + goto err; + } + + if (ctrl->sqs[qid] != NULL) { + pr_warn("qid %u has already been created\n", qid); + req->error_loc = offsetof(struct nvmf_connect_command, qid); +- return NVME_SC_CMD_SEQ_ERROR | NVME_SC_DNR; ++ return NVME_SC_CMD_SEQ_ERROR | NVME_STATUS_DNR; + } + + /* for fabrics, this value applies to only the I/O Submission Queues */ +@@ -163,14 +163,14 @@ static u16 nvmet_install_queue(struct nvmet_ctrl *ctrl, struct nvmet_req *req) + sqsize, mqes, ctrl->cntlid); + req->error_loc = offsetof(struct nvmf_connect_command, sqsize); + req->cqe->result.u32 = IPO_IATTR_CONNECT_SQE(sqsize); +- return NVME_SC_CONNECT_INVALID_PARAM | NVME_SC_DNR; ++ return NVME_SC_CONNECT_INVALID_PARAM | NVME_STATUS_DNR; + } + + old = cmpxchg(&req->sq->ctrl, NULL, ctrl); + if (old) { + pr_warn("queue already connected!\n"); + req->error_loc = offsetof(struct nvmf_connect_command, opcode); +- return NVME_SC_CONNECT_CTRL_BUSY | NVME_SC_DNR; ++ return NVME_SC_CONNECT_CTRL_BUSY | NVME_STATUS_DNR; + } + + /* note: convert queue size from 0's-based value to 1's-based value */ +@@ -230,14 +230,14 @@ static void nvmet_execute_admin_connect(struct nvmet_req *req) + pr_warn("invalid connect version (%d).\n", + le16_to_cpu(c->recfmt)); + req->error_loc = offsetof(struct nvmf_connect_command, recfmt); +- status = NVME_SC_CONNECT_FORMAT | NVME_SC_DNR; ++ status = NVME_SC_CONNECT_FORMAT | NVME_STATUS_DNR; + goto out; + } + + if (unlikely(d->cntlid != cpu_to_le16(0xffff))) { + pr_warn("connect attempt for invalid controller ID %#x\n", + d->cntlid); +- status = NVME_SC_CONNECT_INVALID_PARAM | NVME_SC_DNR; ++ status = NVME_SC_CONNECT_INVALID_PARAM | NVME_STATUS_DNR; + req->cqe->result.u32 = IPO_IATTR_CONNECT_DATA(cntlid); + goto out; + } +@@ -257,7 +257,7 @@ static void nvmet_execute_admin_connect(struct nvmet_req *req) + dhchap_status); + nvmet_ctrl_put(ctrl); + if (dhchap_status == NVME_AUTH_DHCHAP_FAILURE_FAILED) +- status = (NVME_SC_CONNECT_INVALID_HOST | NVME_SC_DNR); ++ status = (NVME_SC_CONNECT_INVALID_HOST | NVME_STATUS_DNR); + else + status = NVME_SC_INTERNAL; + goto out; +@@ -305,7 +305,7 @@ static void nvmet_execute_io_connect(struct nvmet_req *req) + if (c->recfmt != 0) { + pr_warn("invalid connect version (%d).\n", + le16_to_cpu(c->recfmt)); +- status = NVME_SC_CONNECT_FORMAT | NVME_SC_DNR; ++ status = NVME_SC_CONNECT_FORMAT | NVME_STATUS_DNR; + goto out; + } + +@@ -314,13 +314,13 @@ static void nvmet_execute_io_connect(struct nvmet_req *req) + ctrl = nvmet_ctrl_find_get(d->subsysnqn, d->hostnqn, + le16_to_cpu(d->cntlid), req); + if (!ctrl) { +- status = NVME_SC_CONNECT_INVALID_PARAM | NVME_SC_DNR; ++ status = NVME_SC_CONNECT_INVALID_PARAM | NVME_STATUS_DNR; + goto out; + } + + if (unlikely(qid > ctrl->subsys->max_qid)) { + pr_warn("invalid queue id (%d)\n", qid); +- status = NVME_SC_CONNECT_INVALID_PARAM | NVME_SC_DNR; ++ status = NVME_SC_CONNECT_INVALID_PARAM | NVME_STATUS_DNR; + req->cqe->result.u32 = IPO_IATTR_CONNECT_SQE(qid); + goto out_ctrl_put; + } +@@ -350,13 +350,13 @@ u16 nvmet_parse_connect_cmd(struct nvmet_req *req) + pr_debug("invalid command 0x%x on unconnected queue.\n", + cmd->fabrics.opcode); + req->error_loc = offsetof(struct nvme_common_command, opcode); +- return NVME_SC_INVALID_OPCODE | NVME_SC_DNR; ++ return NVME_SC_INVALID_OPCODE | NVME_STATUS_DNR; + } + if (cmd->fabrics.fctype != nvme_fabrics_type_connect) { + pr_debug("invalid capsule type 0x%x on unconnected queue.\n", + cmd->fabrics.fctype); + req->error_loc = offsetof(struct nvmf_common_command, fctype); +- return NVME_SC_INVALID_OPCODE | NVME_SC_DNR; ++ return NVME_SC_INVALID_OPCODE | NVME_STATUS_DNR; + } + + if (cmd->connect.qid == 0) +diff --git a/drivers/nvme/target/io-cmd-bdev.c b/drivers/nvme/target/io-cmd-bdev.c +index 6426aac2634a..e511b055ece7 100644 +--- a/drivers/nvme/target/io-cmd-bdev.c ++++ b/drivers/nvme/target/io-cmd-bdev.c +@@ -135,11 +135,11 @@ u16 blk_to_nvme_status(struct nvmet_req *req, blk_status_t blk_sts) + */ + switch (blk_sts) { + case BLK_STS_NOSPC: +- status = NVME_SC_CAP_EXCEEDED | NVME_SC_DNR; ++ status = NVME_SC_CAP_EXCEEDED | NVME_STATUS_DNR; + req->error_loc = offsetof(struct nvme_rw_command, length); + break; + case BLK_STS_TARGET: +- status = NVME_SC_LBA_RANGE | NVME_SC_DNR; ++ status = NVME_SC_LBA_RANGE | NVME_STATUS_DNR; + req->error_loc = offsetof(struct nvme_rw_command, slba); + break; + case BLK_STS_NOTSUPP: +@@ -147,10 +147,10 @@ u16 blk_to_nvme_status(struct nvmet_req *req, blk_status_t blk_sts) + switch (req->cmd->common.opcode) { + case nvme_cmd_dsm: + case nvme_cmd_write_zeroes: +- status = NVME_SC_ONCS_NOT_SUPPORTED | NVME_SC_DNR; ++ status = NVME_SC_ONCS_NOT_SUPPORTED | NVME_STATUS_DNR; + break; + default: +- status = NVME_SC_INVALID_OPCODE | NVME_SC_DNR; ++ status = NVME_SC_INVALID_OPCODE | NVME_STATUS_DNR; + } + break; + case BLK_STS_MEDIUM: +@@ -159,7 +159,7 @@ u16 blk_to_nvme_status(struct nvmet_req *req, blk_status_t blk_sts) + break; + case BLK_STS_IOERR: + default: +- status = NVME_SC_INTERNAL | NVME_SC_DNR; ++ status = NVME_SC_INTERNAL | NVME_STATUS_DNR; + req->error_loc = offsetof(struct nvme_common_command, opcode); + } + +@@ -356,7 +356,7 @@ u16 nvmet_bdev_flush(struct nvmet_req *req) + return 0; + + if (blkdev_issue_flush(req->ns->bdev)) +- return NVME_SC_INTERNAL | NVME_SC_DNR; ++ return NVME_SC_INTERNAL | NVME_STATUS_DNR; + return 0; + } + +diff --git a/drivers/nvme/target/passthru.c b/drivers/nvme/target/passthru.c +index f003782d4ecf..24d0e2418d2e 100644 +--- a/drivers/nvme/target/passthru.c ++++ b/drivers/nvme/target/passthru.c +@@ -306,7 +306,7 @@ static void nvmet_passthru_execute_cmd(struct nvmet_req *req) + ns = nvme_find_get_ns(ctrl, nsid); + if (unlikely(!ns)) { + pr_err("failed to get passthru ns nsid:%u\n", nsid); +- status = NVME_SC_INVALID_NS | NVME_SC_DNR; ++ status = NVME_SC_INVALID_NS | NVME_STATUS_DNR; + goto out; + } + +@@ -426,7 +426,7 @@ u16 nvmet_parse_passthru_io_cmd(struct nvmet_req *req) + * emulated in the future if regular targets grow support for + * this feature. + */ +- return NVME_SC_INVALID_OPCODE | NVME_SC_DNR; ++ return NVME_SC_INVALID_OPCODE | NVME_STATUS_DNR; + } + + return nvmet_setup_passthru_command(req); +@@ -478,7 +478,7 @@ static u16 nvmet_passthru_get_set_features(struct nvmet_req *req) + case NVME_FEAT_RESV_PERSIST: + /* No reservations, see nvmet_parse_passthru_io_cmd() */ + default: +- return NVME_SC_INVALID_OPCODE | NVME_SC_DNR; ++ return NVME_SC_INVALID_OPCODE | NVME_STATUS_DNR; + } + } + +@@ -546,7 +546,7 @@ u16 nvmet_parse_passthru_admin_cmd(struct nvmet_req *req) + req->p.use_workqueue = true; + return NVME_SC_SUCCESS; + } +- return NVME_SC_INVALID_OPCODE | NVME_SC_DNR; ++ return NVME_SC_INVALID_OPCODE | NVME_STATUS_DNR; + case NVME_ID_CNS_NS: + req->execute = nvmet_passthru_execute_cmd; + req->p.use_workqueue = true; +@@ -558,7 +558,7 @@ u16 nvmet_parse_passthru_admin_cmd(struct nvmet_req *req) + req->p.use_workqueue = true; + return NVME_SC_SUCCESS; + } +- return NVME_SC_INVALID_OPCODE | NVME_SC_DNR; ++ return NVME_SC_INVALID_OPCODE | NVME_STATUS_DNR; + default: + return nvmet_setup_passthru_command(req); + } +diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c +index 689bb5d3cfdc..498b3ca59651 100644 +--- a/drivers/nvme/target/rdma.c ++++ b/drivers/nvme/target/rdma.c +@@ -852,12 +852,12 @@ static u16 nvmet_rdma_map_sgl_inline(struct nvmet_rdma_rsp *rsp) + if (!nvme_is_write(rsp->req.cmd)) { + rsp->req.error_loc = + offsetof(struct nvme_common_command, opcode); +- return NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ return NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + } + + if (off + len > rsp->queue->dev->inline_data_size) { + pr_err("invalid inline data offset!\n"); +- return NVME_SC_SGL_INVALID_OFFSET | NVME_SC_DNR; ++ return NVME_SC_SGL_INVALID_OFFSET | NVME_STATUS_DNR; + } + + /* no data command? */ +@@ -919,7 +919,7 @@ static u16 nvmet_rdma_map_sgl(struct nvmet_rdma_rsp *rsp) + pr_err("invalid SGL subtype: %#x\n", sgl->type); + rsp->req.error_loc = + offsetof(struct nvme_common_command, dptr); +- return NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ return NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + } + case NVME_KEY_SGL_FMT_DATA_DESC: + switch (sgl->type & 0xf) { +@@ -931,12 +931,12 @@ static u16 nvmet_rdma_map_sgl(struct nvmet_rdma_rsp *rsp) + pr_err("invalid SGL subtype: %#x\n", sgl->type); + rsp->req.error_loc = + offsetof(struct nvme_common_command, dptr); +- return NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ return NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + } + default: + pr_err("invalid SGL type: %#x\n", sgl->type); + rsp->req.error_loc = offsetof(struct nvme_common_command, dptr); +- return NVME_SC_SGL_INVALID_TYPE | NVME_SC_DNR; ++ return NVME_SC_SGL_INVALID_TYPE | NVME_STATUS_DNR; + } + } + +diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c +index ebf25819a7da..45b46c55681f 100644 +--- a/drivers/nvme/target/tcp.c ++++ b/drivers/nvme/target/tcp.c +@@ -416,10 +416,10 @@ static int nvmet_tcp_map_data(struct nvmet_tcp_cmd *cmd) + if (sgl->type == ((NVME_SGL_FMT_DATA_DESC << 4) | + NVME_SGL_FMT_OFFSET)) { + if (!nvme_is_write(cmd->req.cmd)) +- return NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ return NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + + if (len > cmd->req.port->inline_data_size) +- return NVME_SC_SGL_INVALID_OFFSET | NVME_SC_DNR; ++ return NVME_SC_SGL_INVALID_OFFSET | NVME_STATUS_DNR; + cmd->pdu_len = len; + } + cmd->req.transfer_len += len; +diff --git a/drivers/nvme/target/zns.c b/drivers/nvme/target/zns.c +index 0021d06041c1..af9e13be7678 100644 +--- a/drivers/nvme/target/zns.c ++++ b/drivers/nvme/target/zns.c +@@ -100,7 +100,7 @@ void nvmet_execute_identify_ns_zns(struct nvmet_req *req) + + if (le32_to_cpu(req->cmd->identify.nsid) == NVME_NSID_ALL) { + req->error_loc = offsetof(struct nvme_identify, nsid); +- status = NVME_SC_INVALID_NS | NVME_SC_DNR; ++ status = NVME_SC_INVALID_NS | NVME_STATUS_DNR; + goto out; + } + +@@ -121,7 +121,7 @@ void nvmet_execute_identify_ns_zns(struct nvmet_req *req) + } + + if (!bdev_is_zoned(req->ns->bdev)) { +- status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + req->error_loc = offsetof(struct nvme_identify, nsid); + goto out; + } +@@ -158,17 +158,17 @@ static u16 nvmet_bdev_validate_zone_mgmt_recv(struct nvmet_req *req) + + if (sect >= get_capacity(req->ns->bdev->bd_disk)) { + req->error_loc = offsetof(struct nvme_zone_mgmt_recv_cmd, slba); +- return NVME_SC_LBA_RANGE | NVME_SC_DNR; ++ return NVME_SC_LBA_RANGE | NVME_STATUS_DNR; + } + + if (out_bufsize < sizeof(struct nvme_zone_report)) { + req->error_loc = offsetof(struct nvme_zone_mgmt_recv_cmd, numd); +- return NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ return NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + } + + if (req->cmd->zmr.zra != NVME_ZRA_ZONE_REPORT) { + req->error_loc = offsetof(struct nvme_zone_mgmt_recv_cmd, zra); +- return NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ return NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + } + + switch (req->cmd->zmr.pr) { +@@ -177,7 +177,7 @@ static u16 nvmet_bdev_validate_zone_mgmt_recv(struct nvmet_req *req) + break; + default: + req->error_loc = offsetof(struct nvme_zone_mgmt_recv_cmd, pr); +- return NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ return NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + } + + switch (req->cmd->zmr.zrasf) { +@@ -193,7 +193,7 @@ static u16 nvmet_bdev_validate_zone_mgmt_recv(struct nvmet_req *req) + default: + req->error_loc = + offsetof(struct nvme_zone_mgmt_recv_cmd, zrasf); +- return NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ return NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + } + + return NVME_SC_SUCCESS; +@@ -341,7 +341,7 @@ static u16 blkdev_zone_mgmt_errno_to_nvme_status(int ret) + return NVME_SC_SUCCESS; + case -EINVAL: + case -EIO: +- return NVME_SC_ZONE_INVALID_TRANSITION | NVME_SC_DNR; ++ return NVME_SC_ZONE_INVALID_TRANSITION | NVME_STATUS_DNR; + default: + return NVME_SC_INTERNAL; + } +@@ -463,7 +463,7 @@ static u16 nvmet_bdev_execute_zmgmt_send_all(struct nvmet_req *req) + default: + /* this is needed to quiet compiler warning */ + req->error_loc = offsetof(struct nvme_zone_mgmt_send_cmd, zsa); +- return NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ return NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + } + + return NVME_SC_SUCCESS; +@@ -481,7 +481,7 @@ static void nvmet_bdev_zmgmt_send_work(struct work_struct *w) + + if (op == REQ_OP_LAST) { + req->error_loc = offsetof(struct nvme_zone_mgmt_send_cmd, zsa); +- status = NVME_SC_ZONE_INVALID_TRANSITION | NVME_SC_DNR; ++ status = NVME_SC_ZONE_INVALID_TRANSITION | NVME_STATUS_DNR; + goto out; + } + +@@ -493,13 +493,13 @@ static void nvmet_bdev_zmgmt_send_work(struct work_struct *w) + + if (sect >= get_capacity(bdev->bd_disk)) { + req->error_loc = offsetof(struct nvme_zone_mgmt_send_cmd, slba); +- status = NVME_SC_LBA_RANGE | NVME_SC_DNR; ++ status = NVME_SC_LBA_RANGE | NVME_STATUS_DNR; + goto out; + } + + if (sect & (zone_sectors - 1)) { + req->error_loc = offsetof(struct nvme_zone_mgmt_send_cmd, slba); +- status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + goto out; + } + +@@ -551,13 +551,13 @@ void nvmet_bdev_execute_zone_append(struct nvmet_req *req) + + if (sect >= get_capacity(req->ns->bdev->bd_disk)) { + req->error_loc = offsetof(struct nvme_rw_command, slba); +- status = NVME_SC_LBA_RANGE | NVME_SC_DNR; ++ status = NVME_SC_LBA_RANGE | NVME_STATUS_DNR; + goto out; + } + + if (sect & (bdev_zone_sectors(req->ns->bdev) - 1)) { + req->error_loc = offsetof(struct nvme_rw_command, slba); +- status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; ++ status = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + goto out; + } + +@@ -590,7 +590,7 @@ void nvmet_bdev_execute_zone_append(struct nvmet_req *req) + } + + if (total_len != nvmet_rw_data_len(req)) { +- status = NVME_SC_INTERNAL | NVME_SC_DNR; ++ status = NVME_SC_INTERNAL | NVME_STATUS_DNR; + goto out_put_bio; + } + +diff --git a/include/linux/nvme.h b/include/linux/nvme.h +index ed0d668e77c5..efda407622c1 100644 +--- a/include/linux/nvme.h ++++ b/include/linux/nvme.h +@@ -1996,9 +1996,9 @@ enum { + NVME_SCT_MASK = 0x0700, /* Status Code Type */ + NVME_SCT_SC_MASK = NVME_SCT_MASK | NVME_SC_MASK, + +- NVME_SC_CRD = 0x1800, /* Command Retry Delayed */ +- NVME_SC_MORE = 0x2000, +- NVME_SC_DNR = 0x4000, /* Do Not Retry */ ++ NVME_STATUS_CRD = 0x1800, /* Command Retry Delayed */ ++ NVME_STATUS_MORE = 0x2000, ++ NVME_STATUS_DNR = 0x4000, /* Do Not Retry */ + }; + + #define NVME_SCT(status) ((status) >> 8 & 7) +-- +2.43.0 + diff --git a/queue-6.10/nvme-rename-nvme_sc_to_pr_err-to-nvme_status_to_pr_e.patch b/queue-6.10/nvme-rename-nvme_sc_to_pr_err-to-nvme_status_to_pr_e.patch new file mode 100644 index 00000000000..b8114eeb069 --- /dev/null +++ b/queue-6.10/nvme-rename-nvme_sc_to_pr_err-to-nvme_status_to_pr_e.patch @@ -0,0 +1,65 @@ +From 69090bebf3fef104559f8ac95006c531e3bccb26 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Jun 2024 20:56:59 +0800 +Subject: nvme: rename nvme_sc_to_pr_err to nvme_status_to_pr_err + +From: Weiwen Hu + +[ Upstream commit 22f19a584d7045e0509f103dbc5c0acfd6415163 ] + +This should better match its semantic. "sc" is used in the NVMe spec to +specifically refer to the last 8 bits in the status field. We should not +reuse "sc" here. + +Signed-off-by: Weiwen Hu +Reviewed-by: Sagi Grimberg +Reviewed-by: Chaitanya Kulkarni +Reviewed-by: Christoph Hellwig +Signed-off-by: Keith Busch +Stable-dep-of: 899d2e5a4e3d ("nvmet: Identify-Active Namespace ID List command should reject invalid nsid") +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/pr.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/drivers/nvme/host/pr.c b/drivers/nvme/host/pr.c +index 8fa1ffcdaed4..a6db5edfab03 100644 +--- a/drivers/nvme/host/pr.c ++++ b/drivers/nvme/host/pr.c +@@ -72,12 +72,12 @@ static int nvme_send_ns_pr_command(struct nvme_ns *ns, struct nvme_command *c, + return nvme_submit_sync_cmd(ns->queue, c, data, data_len); + } + +-static int nvme_sc_to_pr_err(int nvme_sc) ++static int nvme_status_to_pr_err(int status) + { +- if (nvme_is_path_error(nvme_sc)) ++ if (nvme_is_path_error(status)) + return PR_STS_PATH_FAILED; + +- switch (nvme_sc & 0x7ff) { ++ switch (status & 0x7ff) { + case NVME_SC_SUCCESS: + return PR_STS_SUCCESS; + case NVME_SC_RESERVATION_CONFLICT: +@@ -121,7 +121,7 @@ static int nvme_pr_command(struct block_device *bdev, u32 cdw10, + if (ret < 0) + return ret; + +- return nvme_sc_to_pr_err(ret); ++ return nvme_status_to_pr_err(ret); + } + + static int nvme_pr_register(struct block_device *bdev, u64 old, +@@ -196,7 +196,7 @@ static int nvme_pr_resv_report(struct block_device *bdev, void *data, + if (ret < 0) + return ret; + +- return nvme_sc_to_pr_err(ret); ++ return nvme_status_to_pr_err(ret); + } + + static int nvme_pr_read_keys(struct block_device *bdev, +-- +2.43.0 + diff --git a/queue-6.10/nvmet-identify-active-namespace-id-list-command-shou.patch b/queue-6.10/nvmet-identify-active-namespace-id-list-command-shou.patch new file mode 100644 index 00000000000..338e6cd5ac6 --- /dev/null +++ b/queue-6.10/nvmet-identify-active-namespace-id-list-command-shou.patch @@ -0,0 +1,47 @@ +From 3aaa4d0bd1aaf97fa2433b011fd88a131b21b928 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Aug 2024 11:52:14 +0200 +Subject: nvmet: Identify-Active Namespace ID List command should reject + invalid nsid + +From: Maurizio Lombardi + +[ Upstream commit 899d2e5a4e3d36689e8938e152f4b69a4bcc6b4d ] + +nsid values of 0xFFFFFFFE and 0XFFFFFFFF should be rejected with +a status code of "Invalid Namespace or Format". +See NVMe Base Specification, Active Namespace ID list (CNS 02h). + +Fixes: a07b4970f464 ("nvmet: add a generic NVMe target") +Signed-off-by: Maurizio Lombardi +Reviewed-by: Sagi Grimberg +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/target/admin-cmd.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c +index f7e1156ac7ec..85006b2df8ae 100644 +--- a/drivers/nvme/target/admin-cmd.c ++++ b/drivers/nvme/target/admin-cmd.c +@@ -587,6 +587,16 @@ static void nvmet_execute_identify_nslist(struct nvmet_req *req) + u16 status = 0; + int i = 0; + ++ /* ++ * NSID values 0xFFFFFFFE and NVME_NSID_ALL are invalid ++ * See NVMe Base Specification, Active Namespace ID list (CNS 02h). ++ */ ++ if (min_nsid == 0xFFFFFFFE || min_nsid == NVME_NSID_ALL) { ++ req->error_loc = offsetof(struct nvme_identify, nsid); ++ status = NVME_SC_INVALID_NS | NVME_STATUS_DNR; ++ goto out; ++ } ++ + list = kzalloc(buf_size, GFP_KERNEL); + if (!list) { + status = NVME_SC_INTERNAL; +-- +2.43.0 + diff --git a/queue-6.10/nvmet-tcp-fix-kernel-crash-if-commands-allocation-fa.patch b/queue-6.10/nvmet-tcp-fix-kernel-crash-if-commands-allocation-fa.patch new file mode 100644 index 00000000000..031afd3a6f4 --- /dev/null +++ b/queue-6.10/nvmet-tcp-fix-kernel-crash-if-commands-allocation-fa.patch @@ -0,0 +1,48 @@ +From 312d026a5242b69ed108886f5e319839d0a09015 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 380f22ee3ebb..ebf25819a7da 100644 +--- a/drivers/nvme/target/tcp.c ++++ b/drivers/nvme/target/tcp.c +@@ -2146,8 +2146,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.10/path-add-cleanup-helper.patch b/queue-6.10/path-add-cleanup-helper.patch new file mode 100644 index 00000000000..779ec101020 --- /dev/null +++ b/queue-6.10/path-add-cleanup-helper.patch @@ -0,0 +1,44 @@ +From 3d5fb0ef05bb33638a64ba588f8e8e287d2e5162 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Jun 2024 16:55:35 +0200 +Subject: path: add cleanup helper + +From: Christian Brauner + +[ Upstream commit ff2c570ef7eaa9ded58e7a02dd7a68874a897508 ] + +Add a simple cleanup helper so we can cleanup struct path easily. +No need for any extra machinery. Avoid DEFINE_FREE() as it causes a +local copy of struct path to be used. Just rely on path_put() directly +called from a cleanup helper. + +Link: https://lore.kernel.org/r/20240607-vfs-listmount-reverse-v1-2-7877a2bfa5e5@kernel.org +Reviewed-by: Josef Bacik +Signed-off-by: Christian Brauner +Stable-dep-of: dd7cb142f467 ("fs: relax permissions for listmount()") +Signed-off-by: Sasha Levin +--- + include/linux/path.h | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/include/linux/path.h b/include/linux/path.h +index 475225a03d0d..ca073e70decd 100644 +--- a/include/linux/path.h ++++ b/include/linux/path.h +@@ -24,4 +24,13 @@ static inline void path_put_init(struct path *path) + *path = (struct path) { }; + } + ++/* ++ * Cleanup macro for use with __free(path_put). Avoids dereference and ++ * copying @path unlike DEFINE_FREE(). path_put() will handle the empty ++ * path correctly just ensure @path is initialized: ++ * ++ * struct path path __free(path_put) = {}; ++ */ ++#define __free_path_put path_put ++ + #endif /* _LINUX_PATH_H */ +-- +2.43.0 + diff --git a/queue-6.10/powerpc-64e-define-mmu_pte_psize-static.patch b/queue-6.10/powerpc-64e-define-mmu_pte_psize-static.patch new file mode 100644 index 00000000000..f75a4b83f4a --- /dev/null +++ b/queue-6.10/powerpc-64e-define-mmu_pte_psize-static.patch @@ -0,0 +1,38 @@ +From 596424e8d4390fe94fadad13d373bb6e6eaab708 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.10/powerpc-64e-remove-unused-ibm-htw-code.patch b/queue-6.10/powerpc-64e-remove-unused-ibm-htw-code.patch new file mode 100644 index 00000000000..1e41f22887a --- /dev/null +++ b/queue-6.10/powerpc-64e-remove-unused-ibm-htw-code.patch @@ -0,0 +1,380 @@ +From f8218f326713b683370e42afe0548325fc30166a 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.10/powerpc-64e-split-out-nohash-book3e-64-bit-code.patch b/queue-6.10/powerpc-64e-split-out-nohash-book3e-64-bit-code.patch new file mode 100644 index 00000000000..bf02aaf4316 --- /dev/null +++ b/queue-6.10/powerpc-64e-split-out-nohash-book3e-64-bit-code.patch @@ -0,0 +1,773 @@ +From 9e4eab46d23751a6637942268f1b00cff3c4d36b 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 b3f0498dd42f..90e846f0c46c 100644 +--- a/arch/powerpc/mm/nohash/Makefile ++++ b/arch/powerpc/mm/nohash/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + + 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.10/powerpc-vdso-don-t-discard-rela-sections.patch b/queue-6.10/powerpc-vdso-don-t-discard-rela-sections.patch new file mode 100644 index 00000000000..068eefa8b43 --- /dev/null +++ b/queue-6.10/powerpc-vdso-don-t-discard-rela-sections.patch @@ -0,0 +1,73 @@ +From 14b6fb881bee97d6838bdaf55aa9f6b9d9727382 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.10/riscv-add-tracepoints-for-sbi-calls-and-returns.patch b/queue-6.10/riscv-add-tracepoints-for-sbi-calls-and-returns.patch new file mode 100644 index 00000000000..ad0d099beb3 --- /dev/null +++ b/queue-6.10/riscv-add-tracepoints-for-sbi-calls-and-returns.patch @@ -0,0 +1,120 @@ +From ac9399cdf90e8e8f81e08b798c8d49612709c238 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Mar 2024 16:01:25 -0700 +Subject: riscv: Add tracepoints for SBI calls and returns + +From: Samuel Holland + +[ Upstream commit 56c1c1a09ab93c7b7c957860f01f8600d6c03143 ] + +These are useful for measuring the latency of SBI calls. The SBI HSM +extension is excluded because those functions are called from contexts +such as cpuidle where instrumentation is not allowed. + +Reviewed-by: Andrew Jones +Signed-off-by: Samuel Holland +Link: https://lore.kernel.org/r/20240321230131.1838105-1-samuel.holland@sifive.com +Signed-off-by: Palmer Dabbelt +Stable-dep-of: 1ff95eb2bebd ("riscv: Fix RISCV_ALTERNATIVE_EARLY") +Signed-off-by: Sasha Levin +--- + arch/riscv/include/asm/trace.h | 54 ++++++++++++++++++++++++++++++++++ + arch/riscv/kernel/sbi.c | 7 +++++ + 2 files changed, 61 insertions(+) + create mode 100644 arch/riscv/include/asm/trace.h + +diff --git a/arch/riscv/include/asm/trace.h b/arch/riscv/include/asm/trace.h +new file mode 100644 +index 000000000000..6151cee5450c +--- /dev/null ++++ b/arch/riscv/include/asm/trace.h +@@ -0,0 +1,54 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++#undef TRACE_SYSTEM ++#define TRACE_SYSTEM riscv ++ ++#if !defined(_TRACE_RISCV_H) || defined(TRACE_HEADER_MULTI_READ) ++#define _TRACE_RISCV_H ++ ++#include ++ ++TRACE_EVENT_CONDITION(sbi_call, ++ TP_PROTO(int ext, int fid), ++ TP_ARGS(ext, fid), ++ TP_CONDITION(ext != SBI_EXT_HSM), ++ ++ TP_STRUCT__entry( ++ __field(int, ext) ++ __field(int, fid) ++ ), ++ ++ TP_fast_assign( ++ __entry->ext = ext; ++ __entry->fid = fid; ++ ), ++ ++ TP_printk("ext=0x%x fid=%d", __entry->ext, __entry->fid) ++); ++ ++TRACE_EVENT_CONDITION(sbi_return, ++ TP_PROTO(int ext, long error, long value), ++ TP_ARGS(ext, error, value), ++ TP_CONDITION(ext != SBI_EXT_HSM), ++ ++ TP_STRUCT__entry( ++ __field(long, error) ++ __field(long, value) ++ ), ++ ++ TP_fast_assign( ++ __entry->error = error; ++ __entry->value = value; ++ ), ++ ++ TP_printk("error=%ld value=0x%lx", __entry->error, __entry->value) ++); ++ ++#endif /* _TRACE_RISCV_H */ ++ ++#undef TRACE_INCLUDE_PATH ++#undef TRACE_INCLUDE_FILE ++ ++#define TRACE_INCLUDE_PATH asm ++#define TRACE_INCLUDE_FILE trace ++ ++#include +diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c +index e66e0999a800..a1d21d8f5293 100644 +--- a/arch/riscv/kernel/sbi.c ++++ b/arch/riscv/kernel/sbi.c +@@ -14,6 +14,9 @@ + #include + #include + ++#define CREATE_TRACE_POINTS ++#include ++ + /* default SBI version is 0.1 */ + unsigned long sbi_spec_version __ro_after_init = SBI_SPEC_VERSION_DEFAULT; + EXPORT_SYMBOL(sbi_spec_version); +@@ -31,6 +34,8 @@ struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0, + { + struct sbiret ret; + ++ trace_sbi_call(ext, fid); ++ + register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0); + register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1); + register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2); +@@ -46,6 +51,8 @@ struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0, + ret.error = a0; + ret.value = a1; + ++ trace_sbi_return(ext, ret.error, ret.value); ++ + return ret; + } + EXPORT_SYMBOL(sbi_ecall); +-- +2.43.0 + diff --git a/queue-6.10/riscv-do-not-restrict-memory-size-because-of-linear-.patch b/queue-6.10/riscv-do-not-restrict-memory-size-because-of-linear-.patch new file mode 100644 index 00000000000..c99822dab55 --- /dev/null +++ b/queue-6.10/riscv-do-not-restrict-memory-size-because-of-linear-.patch @@ -0,0 +1,41 @@ +From f8e844bf02c6867a38bca378127c7560b382253b 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 c5c66f53971a..91346c9da8ef 100644 +--- a/arch/riscv/mm/init.c ++++ b/arch/riscv/mm/init.c +@@ -251,7 +251,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.10/riscv-fix-riscv_alternative_early.patch b/queue-6.10/riscv-fix-riscv_alternative_early.patch new file mode 100644 index 00000000000..c34b4019cca --- /dev/null +++ b/queue-6.10/riscv-fix-riscv_alternative_early.patch @@ -0,0 +1,262 @@ +From ade871aec9c59b6f5cc299f266135c1160b5514e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 29 Aug 2024 18:50:48 +0200 +Subject: riscv: Fix RISCV_ALTERNATIVE_EARLY + +From: Alexandre Ghiti + +[ Upstream commit 1ff95eb2bebda50c4c5406caaf201e0fcb24cc8f ] + +RISCV_ALTERNATIVE_EARLY will issue sbi_ecall() very early in the boot +process, before the first memory mapping is setup so we can't have any +instrumentation happening here. + +In addition, when the kernel is relocatable, we must also not issue any +relocation this early since they would have been patched virtually only. + +So, instead of disabling instrumentation for the whole kernel/sbi.c file +and compiling it with -fno-pie, simply move __sbi_ecall() and +__sbi_base_ecall() into their own file where this is fixed. + +Reported-by: Conor Dooley +Closes: https://lore.kernel.org/linux-riscv/20240813-pony-truck-3e7a83e9759e@spud/ +Reported-by: syzbot+cfbcb82adf6d7279fd35@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/linux-riscv/00000000000065062c061fcec37b@google.com/ +Fixes: 1745cfafebdf ("riscv: don't use global static vars to store alternative data") +Signed-off-by: Alexandre Ghiti +Link: https://lore.kernel.org/r/20240829165048.49756-1-alexghiti@rivosinc.com +Signed-off-by: Palmer Dabbelt +Signed-off-by: Sasha Levin +--- + arch/riscv/include/asm/sbi.h | 20 ++++++++++- + arch/riscv/kernel/Makefile | 6 +++- + arch/riscv/kernel/sbi.c | 63 ----------------------------------- + arch/riscv/kernel/sbi_ecall.c | 48 ++++++++++++++++++++++++++ + 4 files changed, 72 insertions(+), 65 deletions(-) + create mode 100644 arch/riscv/kernel/sbi_ecall.c + +diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h +index 7cffd4ffecd0..7bd3746028c9 100644 +--- a/arch/riscv/include/asm/sbi.h ++++ b/arch/riscv/include/asm/sbi.h +@@ -9,6 +9,7 @@ + + #include + #include ++#include + + #ifdef CONFIG_RISCV_SBI + enum sbi_ext_id { +@@ -304,6 +305,7 @@ struct sbiret { + }; + + void sbi_init(void); ++long __sbi_base_ecall(int fid); + struct sbiret __sbi_ecall(unsigned long arg0, unsigned long arg1, + unsigned long arg2, unsigned long arg3, + unsigned long arg4, unsigned long arg5, +@@ -373,7 +375,23 @@ static inline unsigned long sbi_mk_version(unsigned long major, + | (minor & SBI_SPEC_VERSION_MINOR_MASK); + } + +-int sbi_err_map_linux_errno(int err); ++static inline int sbi_err_map_linux_errno(int err) ++{ ++ switch (err) { ++ case SBI_SUCCESS: ++ return 0; ++ case SBI_ERR_DENIED: ++ return -EPERM; ++ case SBI_ERR_INVALID_PARAM: ++ return -EINVAL; ++ case SBI_ERR_INVALID_ADDRESS: ++ return -EFAULT; ++ case SBI_ERR_NOT_SUPPORTED: ++ case SBI_ERR_FAILURE: ++ default: ++ return -ENOTSUPP; ++ }; ++} + + extern bool sbi_debug_console_available; + int sbi_debug_console_write(const char *bytes, unsigned int num_bytes); +diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile +index 5b243d46f4b1..1d71002e4f7b 100644 +--- a/arch/riscv/kernel/Makefile ++++ b/arch/riscv/kernel/Makefile +@@ -20,17 +20,21 @@ endif + ifdef CONFIG_RISCV_ALTERNATIVE_EARLY + CFLAGS_alternative.o := -mcmodel=medany + CFLAGS_cpufeature.o := -mcmodel=medany ++CFLAGS_sbi_ecall.o := -mcmodel=medany + ifdef CONFIG_FTRACE + CFLAGS_REMOVE_alternative.o = $(CC_FLAGS_FTRACE) + CFLAGS_REMOVE_cpufeature.o = $(CC_FLAGS_FTRACE) ++CFLAGS_REMOVE_sbi_ecall.o = $(CC_FLAGS_FTRACE) + endif + ifdef CONFIG_RELOCATABLE + CFLAGS_alternative.o += -fno-pie + CFLAGS_cpufeature.o += -fno-pie ++CFLAGS_sbi_ecall.o += -fno-pie + endif + ifdef CONFIG_KASAN + KASAN_SANITIZE_alternative.o := n + KASAN_SANITIZE_cpufeature.o := n ++KASAN_SANITIZE_sbi_ecall.o := n + endif + endif + +@@ -86,7 +90,7 @@ obj-$(CONFIG_DYNAMIC_FTRACE) += mcount-dyn.o + + obj-$(CONFIG_PERF_EVENTS) += perf_callchain.o + obj-$(CONFIG_HAVE_PERF_REGS) += perf_regs.o +-obj-$(CONFIG_RISCV_SBI) += sbi.o ++obj-$(CONFIG_RISCV_SBI) += sbi.o sbi_ecall.o + ifeq ($(CONFIG_RISCV_SBI), y) + obj-$(CONFIG_SMP) += sbi-ipi.o + obj-$(CONFIG_SMP) += cpu_ops_sbi.o +diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c +index 837bdab2601b..1989b8cade1b 100644 +--- a/arch/riscv/kernel/sbi.c ++++ b/arch/riscv/kernel/sbi.c +@@ -14,9 +14,6 @@ + #include + #include + +-#define CREATE_TRACE_POINTS +-#include +- + /* default SBI version is 0.1 */ + unsigned long sbi_spec_version __ro_after_init = SBI_SPEC_VERSION_DEFAULT; + EXPORT_SYMBOL(sbi_spec_version); +@@ -27,55 +24,6 @@ static int (*__sbi_rfence)(int fid, const struct cpumask *cpu_mask, + unsigned long start, unsigned long size, + unsigned long arg4, unsigned long arg5) __ro_after_init; + +-struct sbiret __sbi_ecall(unsigned long arg0, unsigned long arg1, +- unsigned long arg2, unsigned long arg3, +- unsigned long arg4, unsigned long arg5, +- int fid, int ext) +-{ +- struct sbiret ret; +- +- trace_sbi_call(ext, fid); +- +- register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0); +- register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1); +- register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2); +- register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3); +- register uintptr_t a4 asm ("a4") = (uintptr_t)(arg4); +- register uintptr_t a5 asm ("a5") = (uintptr_t)(arg5); +- register uintptr_t a6 asm ("a6") = (uintptr_t)(fid); +- register uintptr_t a7 asm ("a7") = (uintptr_t)(ext); +- asm volatile ("ecall" +- : "+r" (a0), "+r" (a1) +- : "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7) +- : "memory"); +- ret.error = a0; +- ret.value = a1; +- +- trace_sbi_return(ext, ret.error, ret.value); +- +- return ret; +-} +-EXPORT_SYMBOL(__sbi_ecall); +- +-int sbi_err_map_linux_errno(int err) +-{ +- switch (err) { +- case SBI_SUCCESS: +- return 0; +- case SBI_ERR_DENIED: +- return -EPERM; +- case SBI_ERR_INVALID_PARAM: +- return -EINVAL; +- case SBI_ERR_INVALID_ADDRESS: +- return -EFAULT; +- case SBI_ERR_NOT_SUPPORTED: +- case SBI_ERR_FAILURE: +- default: +- return -ENOTSUPP; +- }; +-} +-EXPORT_SYMBOL(sbi_err_map_linux_errno); +- + #ifdef CONFIG_RISCV_SBI_V01 + static unsigned long __sbi_v01_cpumask_to_hartmask(const struct cpumask *cpu_mask) + { +@@ -535,17 +483,6 @@ long sbi_probe_extension(int extid) + } + EXPORT_SYMBOL(sbi_probe_extension); + +-static long __sbi_base_ecall(int fid) +-{ +- struct sbiret ret; +- +- ret = sbi_ecall(SBI_EXT_BASE, fid, 0, 0, 0, 0, 0, 0); +- if (!ret.error) +- return ret.value; +- else +- return sbi_err_map_linux_errno(ret.error); +-} +- + static inline long sbi_get_spec_version(void) + { + return __sbi_base_ecall(SBI_EXT_BASE_GET_SPEC_VERSION); +diff --git a/arch/riscv/kernel/sbi_ecall.c b/arch/riscv/kernel/sbi_ecall.c +new file mode 100644 +index 000000000000..24aabb4fbde3 +--- /dev/null ++++ b/arch/riscv/kernel/sbi_ecall.c +@@ -0,0 +1,48 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* Copyright (c) 2024 Rivos Inc. */ ++ ++#include ++#define CREATE_TRACE_POINTS ++#include ++ ++long __sbi_base_ecall(int fid) ++{ ++ struct sbiret ret; ++ ++ ret = sbi_ecall(SBI_EXT_BASE, fid, 0, 0, 0, 0, 0, 0); ++ if (!ret.error) ++ return ret.value; ++ else ++ return sbi_err_map_linux_errno(ret.error); ++} ++EXPORT_SYMBOL(__sbi_base_ecall); ++ ++struct sbiret __sbi_ecall(unsigned long arg0, unsigned long arg1, ++ unsigned long arg2, unsigned long arg3, ++ unsigned long arg4, unsigned long arg5, ++ int fid, int ext) ++{ ++ struct sbiret ret; ++ ++ trace_sbi_call(ext, fid); ++ ++ register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0); ++ register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1); ++ register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2); ++ register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3); ++ register uintptr_t a4 asm ("a4") = (uintptr_t)(arg4); ++ register uintptr_t a5 asm ("a5") = (uintptr_t)(arg5); ++ register uintptr_t a6 asm ("a6") = (uintptr_t)(fid); ++ register uintptr_t a7 asm ("a7") = (uintptr_t)(ext); ++ asm volatile ("ecall" ++ : "+r" (a0), "+r" (a1) ++ : "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7) ++ : "memory"); ++ ret.error = a0; ++ ret.value = a1; ++ ++ trace_sbi_return(ext, ret.error, ret.value); ++ ++ return ret; ++} ++EXPORT_SYMBOL(__sbi_ecall); +-- +2.43.0 + diff --git a/queue-6.10/riscv-fix-toolchain-vector-detection.patch b/queue-6.10/riscv-fix-toolchain-vector-detection.patch new file mode 100644 index 00000000000..b2c7f015637 --- /dev/null +++ b/queue-6.10/riscv-fix-toolchain-vector-detection.patch @@ -0,0 +1,44 @@ +From f1e75cfc38ba241c35d980931e25f10d992ec334 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 0525ee2d63c7..006232b67b46 100644 +--- a/arch/riscv/Kconfig ++++ b/arch/riscv/Kconfig +@@ -545,8 +545,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.10/riscv-improve-sbi_ecall-code-generation-by-reorderin.patch b/queue-6.10/riscv-improve-sbi_ecall-code-generation-by-reorderin.patch new file mode 100644 index 00000000000..5e5512602fe --- /dev/null +++ b/queue-6.10/riscv-improve-sbi_ecall-code-generation-by-reorderin.patch @@ -0,0 +1,113 @@ +From a1c7379d00a5c886599f723f49ffe25bd3398770 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Mar 2024 12:26:29 +0100 +Subject: riscv: Improve sbi_ecall() code generation by reordering arguments + +From: Alexandre Ghiti + +[ Upstream commit 16badacd8af48980c546839626d0329bab32b4c3 ] + +The sbi_ecall() function arguments are not in the same order as the +ecall arguments, so we end up re-ordering the registers before the +ecall which is useless and costly. + +So simply reorder the arguments in the same way as expected by ecall. +Instead of reordering directly the arguments of sbi_ecall(), use a proxy +macro since the current ordering is more natural. + +Before: + +Dump of assembler code for function sbi_ecall: + 0xffffffff800085e0 <+0>: add sp,sp,-32 + 0xffffffff800085e2 <+2>: sd s0,24(sp) + 0xffffffff800085e4 <+4>: mv t1,a0 + 0xffffffff800085e6 <+6>: add s0,sp,32 + 0xffffffff800085e8 <+8>: mv t3,a1 + 0xffffffff800085ea <+10>: mv a0,a2 + 0xffffffff800085ec <+12>: mv a1,a3 + 0xffffffff800085ee <+14>: mv a2,a4 + 0xffffffff800085f0 <+16>: mv a3,a5 + 0xffffffff800085f2 <+18>: mv a4,a6 + 0xffffffff800085f4 <+20>: mv a5,a7 + 0xffffffff800085f6 <+22>: mv a6,t3 + 0xffffffff800085f8 <+24>: mv a7,t1 + 0xffffffff800085fa <+26>: ecall + 0xffffffff800085fe <+30>: ld s0,24(sp) + 0xffffffff80008600 <+32>: add sp,sp,32 + 0xffffffff80008602 <+34>: ret + +After: + +Dump of assembler code for function __sbi_ecall: + 0xffffffff8000b6b2 <+0>: add sp,sp,-32 + 0xffffffff8000b6b4 <+2>: sd s0,24(sp) + 0xffffffff8000b6b6 <+4>: add s0,sp,32 + 0xffffffff8000b6b8 <+6>: ecall + 0xffffffff8000b6bc <+10>: ld s0,24(sp) + 0xffffffff8000b6be <+12>: add sp,sp,32 + 0xffffffff8000b6c0 <+14>: ret + +Signed-off-by: Alexandre Ghiti +Reviewed-by: Atish Patra +Reviewed-by: Yunhui Cui +Link: https://lore.kernel.org/r/20240322112629.68170-1-alexghiti@rivosinc.com +Signed-off-by: Palmer Dabbelt +Stable-dep-of: 1ff95eb2bebd ("riscv: Fix RISCV_ALTERNATIVE_EARLY") +Signed-off-by: Sasha Levin +--- + arch/riscv/include/asm/sbi.h | 10 ++++++---- + arch/riscv/kernel/sbi.c | 10 +++++----- + 2 files changed, 11 insertions(+), 9 deletions(-) + +diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h +index 1079e214fe85..7cffd4ffecd0 100644 +--- a/arch/riscv/include/asm/sbi.h ++++ b/arch/riscv/include/asm/sbi.h +@@ -304,10 +304,12 @@ struct sbiret { + }; + + void sbi_init(void); +-struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0, +- unsigned long arg1, unsigned long arg2, +- unsigned long arg3, unsigned long arg4, +- unsigned long arg5); ++struct sbiret __sbi_ecall(unsigned long arg0, unsigned long arg1, ++ unsigned long arg2, unsigned long arg3, ++ unsigned long arg4, unsigned long arg5, ++ int fid, int ext); ++#define sbi_ecall(e, f, a0, a1, a2, a3, a4, a5) \ ++ __sbi_ecall(a0, a1, a2, a3, a4, a5, f, e) + + #ifdef CONFIG_RISCV_SBI_V01 + void sbi_console_putchar(int ch); +diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c +index a1d21d8f5293..837bdab2601b 100644 +--- a/arch/riscv/kernel/sbi.c ++++ b/arch/riscv/kernel/sbi.c +@@ -27,10 +27,10 @@ static int (*__sbi_rfence)(int fid, const struct cpumask *cpu_mask, + unsigned long start, unsigned long size, + unsigned long arg4, unsigned long arg5) __ro_after_init; + +-struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0, +- unsigned long arg1, unsigned long arg2, +- unsigned long arg3, unsigned long arg4, +- unsigned long arg5) ++struct sbiret __sbi_ecall(unsigned long arg0, unsigned long arg1, ++ unsigned long arg2, unsigned long arg3, ++ unsigned long arg4, unsigned long arg5, ++ int fid, int ext) + { + struct sbiret ret; + +@@ -55,7 +55,7 @@ struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0, + + return ret; + } +-EXPORT_SYMBOL(sbi_ecall); ++EXPORT_SYMBOL(__sbi_ecall); + + int sbi_err_map_linux_errno(int err) + { +-- +2.43.0 + diff --git a/queue-6.10/riscv-mm-do-not-restrict-mmap-address-based-on-hint.patch b/queue-6.10/riscv-mm-do-not-restrict-mmap-address-based-on-hint.patch new file mode 100644 index 00000000000..c31f503d8aa --- /dev/null +++ b/queue-6.10/riscv-mm-do-not-restrict-mmap-address-based-on-hint.patch @@ -0,0 +1,70 @@ +From 80336ce81b7b4acd1398cb41747e9494905a5d7b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 26 Aug 2024 09:36:47 -0700 +Subject: riscv: mm: Do not restrict mmap address based on hint + +From: Charlie Jenkins + +[ Upstream commit 2116988d5372aec51f8c4fb85bf8e305ecda47a0 ] + +The hint address should not forcefully restrict the addresses returned +by mmap as this causes mmap to report ENOMEM when there is memory still +available. + +Signed-off-by: Charlie Jenkins +Fixes: b5b4287accd7 ("riscv: mm: Use hint address in mmap if available") +Fixes: add2cc6b6515 ("RISC-V: mm: Restrict address space for sv39,sv48,sv57") +Closes: https://lore.kernel.org/linux-kernel/ZbxTNjQPFKBatMq+@ghost/T/#mccb1890466bf5a488c9ce7441e57e42271895765 +Link: https://lore.kernel.org/r/20240826-riscv_mmap-v1-3-cd8962afe47f@rivosinc.com +Signed-off-by: Palmer Dabbelt +Signed-off-by: Sasha Levin +--- + arch/riscv/include/asm/processor.h | 26 ++------------------------ + 1 file changed, 2 insertions(+), 24 deletions(-) + +diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h +index 68c3432dc6ea..6c129144ef19 100644 +--- a/arch/riscv/include/asm/processor.h ++++ b/arch/riscv/include/asm/processor.h +@@ -14,36 +14,14 @@ + + #include + +-/* +- * addr is a hint to the maximum userspace address that mmap should provide, so +- * this macro needs to return the largest address space available so that +- * mmap_end < addr, being mmap_end the top of that address space. +- * See Documentation/arch/riscv/vm-layout.rst for more details. +- */ + #define arch_get_mmap_end(addr, len, flags) \ + ({ \ +- unsigned long mmap_end; \ +- typeof(addr) _addr = (addr); \ +- if ((_addr) == 0 || is_compat_task() || \ +- ((_addr + len) > BIT(VA_BITS - 1))) \ +- mmap_end = STACK_TOP_MAX; \ +- else \ +- mmap_end = (_addr + len); \ +- mmap_end; \ ++ STACK_TOP_MAX; \ + }) + + #define arch_get_mmap_base(addr, base) \ + ({ \ +- unsigned long mmap_base; \ +- typeof(addr) _addr = (addr); \ +- typeof(base) _base = (base); \ +- unsigned long rnd_gap = DEFAULT_MAP_WINDOW - (_base); \ +- if ((_addr) == 0 || is_compat_task() || \ +- ((_addr + len) > BIT(VA_BITS - 1))) \ +- mmap_base = (_base); \ +- else \ +- mmap_base = (_addr + len) - rnd_gap; \ +- mmap_base; \ ++ base; \ + }) + + #ifdef CONFIG_64BIT +-- +2.43.0 + diff --git a/queue-6.10/riscv-selftests-remove-mmap-hint-address-checks.patch b/queue-6.10/riscv-selftests-remove-mmap-hint-address-checks.patch new file mode 100644 index 00000000000..e5683648779 --- /dev/null +++ b/queue-6.10/riscv-selftests-remove-mmap-hint-address-checks.patch @@ -0,0 +1,134 @@ +From d2863914d6e650c45af5a37f259bc260581f39cd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 26 Aug 2024 09:36:46 -0700 +Subject: riscv: selftests: Remove mmap hint address checks + +From: Charlie Jenkins + +[ Upstream commit 83dae72ac0382693540a055ec6210dd3691a8df6 ] + +The mmap behavior that restricts the addresses returned by mmap caused +unexpected behavior, so get rid of the test cases that check that +behavior. + +Signed-off-by: Charlie Jenkins +Fixes: 73d05262a2ca ("selftests: riscv: Generalize mm selftests") +Link: https://lore.kernel.org/r/20240826-riscv_mmap-v1-2-cd8962afe47f@rivosinc.com +Signed-off-by: Palmer Dabbelt +Signed-off-by: Sasha Levin +--- + .../selftests/riscv/mm/mmap_bottomup.c | 2 - + .../testing/selftests/riscv/mm/mmap_default.c | 2 - + tools/testing/selftests/riscv/mm/mmap_test.h | 67 ------------------- + 3 files changed, 71 deletions(-) + +diff --git a/tools/testing/selftests/riscv/mm/mmap_bottomup.c b/tools/testing/selftests/riscv/mm/mmap_bottomup.c +index 7f7d3eb8b9c9..f9ccae50349b 100644 +--- a/tools/testing/selftests/riscv/mm/mmap_bottomup.c ++++ b/tools/testing/selftests/riscv/mm/mmap_bottomup.c +@@ -7,8 +7,6 @@ + TEST(infinite_rlimit) + { + EXPECT_EQ(BOTTOM_UP, memory_layout()); +- +- TEST_MMAPS; + } + + TEST_HARNESS_MAIN +diff --git a/tools/testing/selftests/riscv/mm/mmap_default.c b/tools/testing/selftests/riscv/mm/mmap_default.c +index 2ba3ec990006..3f53b6ecc326 100644 +--- a/tools/testing/selftests/riscv/mm/mmap_default.c ++++ b/tools/testing/selftests/riscv/mm/mmap_default.c +@@ -7,8 +7,6 @@ + TEST(default_rlimit) + { + EXPECT_EQ(TOP_DOWN, memory_layout()); +- +- TEST_MMAPS; + } + + TEST_HARNESS_MAIN +diff --git a/tools/testing/selftests/riscv/mm/mmap_test.h b/tools/testing/selftests/riscv/mm/mmap_test.h +index 3b29ca3bb3d4..75918d15919f 100644 +--- a/tools/testing/selftests/riscv/mm/mmap_test.h ++++ b/tools/testing/selftests/riscv/mm/mmap_test.h +@@ -10,76 +10,9 @@ + #define TOP_DOWN 0 + #define BOTTOM_UP 1 + +-#if __riscv_xlen == 64 +-uint64_t random_addresses[] = { +- 0x19764f0d73b3a9f0, 0x016049584cecef59, 0x3580bdd3562f4acd, +- 0x1164219f20b17da0, 0x07d97fcb40ff2373, 0x76ec528921272ee7, +- 0x4dd48c38a3de3f70, 0x2e11415055f6997d, 0x14b43334ac476c02, +- 0x375a60795aff19f6, 0x47f3051725b8ee1a, 0x4e697cf240494a9f, +- 0x456b59b5c2f9e9d1, 0x101724379d63cb96, 0x7fe9ad31619528c1, +- 0x2f417247c495c2ea, 0x329a5a5b82943a5e, 0x06d7a9d6adcd3827, +- 0x327b0b9ee37f62d5, 0x17c7b1851dfd9b76, 0x006ebb6456ec2cd9, +- 0x00836cd14146a134, 0x00e5c4dcde7126db, 0x004c29feadf75753, +- 0x00d8b20149ed930c, 0x00d71574c269387a, 0x0006ebe4a82acb7a, +- 0x0016135df51f471b, 0x00758bdb55455160, 0x00d0bdd949b13b32, +- 0x00ecea01e7c5f54b, 0x00e37b071b9948b1, 0x0011fdd00ff57ab3, +- 0x00e407294b52f5ea, 0x00567748c200ed20, 0x000d073084651046, +- 0x00ac896f4365463c, 0x00eb0d49a0b26216, 0x0066a2564a982a31, +- 0x002e0d20237784ae, 0x0000554ff8a77a76, 0x00006ce07a54c012, +- 0x000009570516d799, 0x00000954ca15b84d, 0x0000684f0d453379, +- 0x00002ae5816302b5, 0x0000042403fb54bf, 0x00004bad7392bf30, +- 0x00003e73bfa4b5e3, 0x00005442c29978e0, 0x00002803f11286b6, +- 0x000073875d745fc6, 0x00007cede9cb8240, 0x000027df84cc6a4f, +- 0x00006d7e0e74242a, 0x00004afd0b836e02, 0x000047d0e837cd82, +- 0x00003b42405efeda, 0x00001531bafa4c95, 0x00007172cae34ac4, +-}; +-#else +-uint32_t random_addresses[] = { +- 0x8dc302e0, 0x929ab1e0, 0xb47683ba, 0xea519c73, 0xa19f1c90, 0xc49ba213, +- 0x8f57c625, 0xadfe5137, 0x874d4d95, 0xaa20f09d, 0xcf21ebfc, 0xda7737f1, +- 0xcedf392a, 0x83026c14, 0xccedca52, 0xc6ccf826, 0xe0cd9415, 0x997472ca, +- 0xa21a44c1, 0xe82196f5, 0xa23fd66b, 0xc28d5590, 0xd009cdce, 0xcf0be646, +- 0x8fc8c7ff, 0xe2a85984, 0xa3d3236b, 0x89a0619d, 0xc03db924, 0xb5d4cc1b, +- 0xb96ee04c, 0xd191da48, 0xb432a000, 0xaa2bebbc, 0xa2fcb289, 0xb0cca89b, +- 0xb0c18d6a, 0x88f58deb, 0xa4d42d1c, 0xe4d74e86, 0x99902b09, 0x8f786d31, +- 0xbec5e381, 0x9a727e65, 0xa9a65040, 0xa880d789, 0x8f1b335e, 0xfc821c1e, +- 0x97e34be4, 0xbbef84ed, 0xf447d197, 0xfd7ceee2, 0xe632348d, 0xee4590f4, +- 0x958992a5, 0xd57e05d6, 0xfd240970, 0xc5b0dcff, 0xd96da2c2, 0xa7ae041d, +-}; +-#endif +- +-// Only works on 64 bit +-#if __riscv_xlen == 64 + #define PROT (PROT_READ | PROT_WRITE) + #define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS) + +-/* mmap must return a value that doesn't use more bits than the hint address. */ +-static inline unsigned long get_max_value(unsigned long input) +-{ +- unsigned long max_bit = (1UL << (((sizeof(unsigned long) * 8) - 1 - +- __builtin_clzl(input)))); +- +- return max_bit + (max_bit - 1); +-} +- +-#define TEST_MMAPS \ +- ({ \ +- void *mmap_addr; \ +- for (int i = 0; i < ARRAY_SIZE(random_addresses); i++) { \ +- mmap_addr = mmap((void *)random_addresses[i], \ +- 5 * sizeof(int), PROT, FLAGS, 0, 0); \ +- EXPECT_NE(MAP_FAILED, mmap_addr); \ +- EXPECT_GE((void *)get_max_value(random_addresses[i]), \ +- mmap_addr); \ +- mmap_addr = mmap((void *)random_addresses[i], \ +- 5 * sizeof(int), PROT, FLAGS, 0, 0); \ +- EXPECT_NE(MAP_FAILED, mmap_addr); \ +- EXPECT_GE((void *)get_max_value(random_addresses[i]), \ +- mmap_addr); \ +- } \ +- }) +-#endif /* __riscv_xlen == 64 */ +- + static inline int memory_layout(void) + { + void *value1 = mmap(NULL, sizeof(int), PROT, FLAGS, 0, 0); +-- +2.43.0 + diff --git a/queue-6.10/series b/queue-6.10/series index 5f66fa9bdf7..aab0056cbe4 100644 --- a/queue-6.10/series +++ b/queue-6.10/series @@ -309,3 +309,61 @@ uprobes-use-kzalloc-to-allocate-xol-area.patch perf-aux-fix-aux-buffer-serialization.patch mm-zswap-rename-is_zswap_enabled-to-zswap_is_enabled.patch mm-memcontrol-respect-zswap.writeback-setting-from-p.patch +workqueue-wq_watchdog_touch-is-always-called-with-va.patch +workqueue-improve-scalability-of-workqueue-watchdog-.patch +path-add-cleanup-helper.patch +fs-simplify-error-handling.patch +fs-relax-permissions-for-listmount.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 +hid-bpf-add-bpf_jit-dependency.patch +net-mlx5e-shampo-use-ksms-instead-of-klms.patch +net-mlx5e-shampo-fix-page-leak.patch +drm-xe-xe2-add-workaround-14021402888.patch +drm-xe-xe2lpg-extend-workaround-14021402888.patch +clk-qcom-gcc-x1e80100-fix-usb-0-and-1-phy-gdsc-pwrst.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 +clk-qcom-gcc-x1e80100-don-t-use-parking-clk_ops-for-.patch +asoc-sof-topology-clear-sof-link-platform-name-upon-.patch +riscv-selftests-remove-mmap-hint-address-checks.patch +riscv-mm-do-not-restrict-mmap-address-based-on-hint.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 +nouveau-fix-the-fwsec-sb-verification-register.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 +riscv-add-tracepoints-for-sbi-calls-and-returns.patch +riscv-improve-sbi_ecall-code-generation-by-reorderin.patch +riscv-fix-riscv_alternative_early.patch +cifs-fix-zero_point-init-on-inode-initialisation.patch +cifs-fix-smb1-readv-writev-callback-in-the-same-way-.patch +nvme-rename-nvme_sc_to_pr_err-to-nvme_status_to_pr_e.patch +nvme-fix-status-magic-numbers.patch +nvme-rename-cdr-more-dnr-to-nvme_status_.patch +nvmet-identify-active-namespace-id-list-command-shou.patch +ublk_drv-fix-null-pointer-dereference-in-ublk_ctrl_s.patch diff --git a/queue-6.10/smb-client-fix-double-put-of-cfile-in-smb2_rename_pa.patch b/queue-6.10/smb-client-fix-double-put-of-cfile-in-smb2_rename_pa.patch new file mode 100644 index 00000000000..762721066c1 --- /dev/null +++ b/queue-6.10/smb-client-fix-double-put-of-cfile-in-smb2_rename_pa.patch @@ -0,0 +1,39 @@ +From ac18f2db5391f6773896297c520b38e04622ea44 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 2a2847601f26..11a1c53c64e0 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.10/ublk_drv-fix-null-pointer-dereference-in-ublk_ctrl_s.patch b/queue-6.10/ublk_drv-fix-null-pointer-dereference-in-ublk_ctrl_s.patch new file mode 100644 index 00000000000..bd4468466c4 --- /dev/null +++ b/queue-6.10/ublk_drv-fix-null-pointer-dereference-in-ublk_ctrl_s.patch @@ -0,0 +1,69 @@ +From 057cc6356166f2b39b8b61b8887b8ef10fbb25ca 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 3b5883932133..fc001e9f95f6 100644 +--- a/drivers/block/ublk_drv.c ++++ b/drivers/block/ublk_drv.c +@@ -2664,6 +2664,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.10/workqueue-improve-scalability-of-workqueue-watchdog-.patch b/queue-6.10/workqueue-improve-scalability-of-workqueue-watchdog-.patch new file mode 100644 index 00000000000..778d3296e68 --- /dev/null +++ b/queue-6.10/workqueue-improve-scalability-of-workqueue-watchdog-.patch @@ -0,0 +1,77 @@ +From 18167a95f056c8669022c8f395fbd857778604db 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 f26b0511b023..ffbf99fb53bf 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -7586,12 +7586,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.10/workqueue-wq_watchdog_touch-is-always-called-with-va.patch b/queue-6.10/workqueue-wq_watchdog_touch-is-always-called-with-va.patch new file mode 100644 index 00000000000..ba98f8e7396 --- /dev/null +++ b/queue-6.10/workqueue-wq_watchdog_touch-is-always-called-with-va.patch @@ -0,0 +1,37 @@ +From d83c51d651dfd5dc3238c092db0a07f654317005 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 +Stable-dep-of: 98f887f820c9 ("workqueue: Improve scalability of workqueue watchdog touch") +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 c970eec25c5a..f26b0511b023 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -7588,6 +7588,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 +