]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.15
authorSasha Levin <sashal@kernel.org>
Wed, 7 May 2025 15:36:16 +0000 (11:36 -0400)
committerSasha Levin <sashal@kernel.org>
Wed, 7 May 2025 15:36:16 +0000 (11:36 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
20 files changed:
queue-5.15/arm-dts-opos6ul-add-ksz8081-phy-properties.patch [new file with mode: 0644]
queue-5.15/cpufreq-intel_pstate-do-not-update-global.turbo_disa.patch [new file with mode: 0644]
queue-5.15/cpufreq-intel_pstate-fold-intel_pstate_max_within_li.patch [new file with mode: 0644]
queue-5.15/cpufreq-intel_pstate-process-hwp-guaranteed-change-n.patch [new file with mode: 0644]
queue-5.15/cpufreq-intel_pstate-revise-global-turbo-disable-che.patch [new file with mode: 0644]
queue-5.15/cpufreq-intel_pstate-unchecked-msr-aceess-in-legacy-.patch [new file with mode: 0644]
queue-5.15/cpufreq-intel_pstate-update-cpuinfo.max_freq-on-hwp_.patch [new file with mode: 0644]
queue-5.15/firmware-arm_scmi-balance-device-refcount-when-destr.patch [new file with mode: 0644]
queue-5.15/iommu-arm-smmu-v3-fix-iommu_device_probe-bug-due-to-.patch [new file with mode: 0644]
queue-5.15/iommu-arm-smmu-v3-use-the-new-rb-tree-helpers.patch [new file with mode: 0644]
queue-5.15/irqchip-gic-v2m-add-const-to-of_device_id.patch [new file with mode: 0644]
queue-5.15/irqchip-gic-v2m-mark-a-few-functions-__init.patch [new file with mode: 0644]
queue-5.15/irqchip-gic-v2m-prevent-use-after-free-of-gicv2m_get.patch [new file with mode: 0644]
queue-5.15/net-phy-microchip-force-irq-polling-mode-for-lan88xx.patch [new file with mode: 0644]
queue-5.15/revert-drm-meson-vclk-fix-calculation-of-59.94-fract.patch [new file with mode: 0644]
queue-5.15/riscv-uprobes-add-missing-fence.i-after-building-the.patch [new file with mode: 0644]
queue-5.15/serial-msm-configure-correct-working-mode-before-sta.patch [new file with mode: 0644]
queue-5.15/series
queue-5.15/spi-tegra114-don-t-fail-set_cs_timing-when-delays-ar.patch [new file with mode: 0644]
queue-5.15/spi-tegra114-remove-unnecessary-null-pointer-checks.patch [new file with mode: 0644]

diff --git a/queue-5.15/arm-dts-opos6ul-add-ksz8081-phy-properties.patch b/queue-5.15/arm-dts-opos6ul-add-ksz8081-phy-properties.patch
new file mode 100644 (file)
index 0000000..bdddc1b
--- /dev/null
@@ -0,0 +1,44 @@
+From ecd209e97dcf5523048b9b06998629601b012d6d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Mar 2025 17:20:38 +0100
+Subject: ARM: dts: opos6ul: add ksz8081 phy properties
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Sébastien Szymanski <sebastien.szymanski@armadeus.com>
+
+[ Upstream commit 6e1a7bc8382b0d4208258f7d2a4474fae788dd90 ]
+
+Commit c7e73b5051d6 ("ARM: imx: mach-imx6ul: remove 14x14 EVK specific
+PHY fixup") removed a PHY fixup that setted the clock mode and the LED
+mode.
+Make the Ethernet interface work again by doing as advised in the
+commit's log, set clock mode and the LED mode in the device tree.
+
+Fixes: c7e73b5051d6 ("ARM: imx: mach-imx6ul: remove 14x14 EVK specific PHY fixup")
+Signed-off-by: Sébastien Szymanski <sebastien.szymanski@armadeus.com>
+Reviewed-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/imx6ul-imx6ull-opos6ul.dtsi | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/arm/boot/dts/imx6ul-imx6ull-opos6ul.dtsi b/arch/arm/boot/dts/imx6ul-imx6ull-opos6ul.dtsi
+index f2386dcb9ff2c..dda4fa91b2f2c 100644
+--- a/arch/arm/boot/dts/imx6ul-imx6ull-opos6ul.dtsi
++++ b/arch/arm/boot/dts/imx6ul-imx6ull-opos6ul.dtsi
+@@ -40,6 +40,9 @@
+                       reg = <1>;
+                       interrupt-parent = <&gpio4>;
+                       interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
++                      micrel,led-mode = <1>;
++                      clocks = <&clks IMX6UL_CLK_ENET_REF>;
++                      clock-names = "rmii-ref";
+                       status = "okay";
+               };
+       };
+-- 
+2.39.5
+
diff --git a/queue-5.15/cpufreq-intel_pstate-do-not-update-global.turbo_disa.patch b/queue-5.15/cpufreq-intel_pstate-do-not-update-global.turbo_disa.patch
new file mode 100644 (file)
index 0000000..f92f25f
--- /dev/null
@@ -0,0 +1,196 @@
+From f8932eb7f77838e33fa7d95510c125f26c98a4dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Mar 2024 18:02:42 +0100
+Subject: cpufreq: intel_pstate: Do not update global.turbo_disabled after
+ initialization
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 0940f1a8011fd69be5082015068e0dc31c800c20 ]
+
+The global.turbo_disabled is updated quite often, especially in the
+passive mode in which case it is updated every time the scheduler calls
+into the driver.  However, this is generally not necessary and it adds
+MSR read overhead to scheduler code paths (and that particular MSR is
+slow to read).
+
+For this reason, make the driver read MSR_IA32_MISC_ENABLE_TURBO_DISABLE
+just once at the cpufreq driver registration time and remove all of the
+in-flight updates of global.turbo_disabled.
+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Stable-dep-of: ac4e04d9e378 ("cpufreq: intel_pstate: Unchecked MSR aceess in legacy mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/intel_pstate.c | 51 ++++++----------------------------
+ 1 file changed, 8 insertions(+), 43 deletions(-)
+
+diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
+index bcfde997f445d..a26d28c437699 100644
+--- a/drivers/cpufreq/intel_pstate.c
++++ b/drivers/cpufreq/intel_pstate.c
+@@ -172,7 +172,6 @@ struct vid_data {
+  *                    based on the MSR_IA32_MISC_ENABLE value and whether or
+  *                    not the maximum reported turbo P-state is different from
+  *                    the maximum reported non-turbo one.
+- * @turbo_disabled_mf:        The @turbo_disabled value reflected by cpuinfo.max_freq.
+  * @min_perf_pct:     Minimum capacity limit in percent of the maximum turbo
+  *                    P-state capacity.
+  * @max_perf_pct:     Maximum capacity limit in percent of the maximum turbo
+@@ -181,7 +180,6 @@ struct vid_data {
+ struct global_params {
+       bool no_turbo;
+       bool turbo_disabled;
+-      bool turbo_disabled_mf;
+       int max_perf_pct;
+       int min_perf_pct;
+ };
+@@ -560,12 +558,13 @@ static void intel_pstate_hybrid_hwp_adjust(struct cpudata *cpu)
+       cpu->pstate.min_pstate = intel_pstate_freq_to_hwp(cpu, freq);
+ }
+-static inline void update_turbo_state(void)
++static bool turbo_is_disabled(void)
+ {
+       u64 misc_en;
+       rdmsrl(MSR_IA32_MISC_ENABLE, misc_en);
+-      global.turbo_disabled = misc_en & MSR_IA32_MISC_ENABLE_TURBO_DISABLE;
++
++      return !!(misc_en & MSR_IA32_MISC_ENABLE_TURBO_DISABLE);
+ }
+ static int min_perf_pct_min(void)
+@@ -1110,40 +1109,16 @@ static void intel_pstate_update_policies(void)
+ static void __intel_pstate_update_max_freq(struct cpudata *cpudata,
+                                          struct cpufreq_policy *policy)
+ {
+-      policy->cpuinfo.max_freq = global.turbo_disabled_mf ?
++      policy->cpuinfo.max_freq = global.turbo_disabled ?
+                       cpudata->pstate.max_freq : cpudata->pstate.turbo_freq;
+       refresh_frequency_limits(policy);
+ }
+-static void intel_pstate_update_max_freq(unsigned int cpu)
+-{
+-      struct cpufreq_policy *policy = cpufreq_cpu_acquire(cpu);
+-
+-      if (!policy)
+-              return;
+-
+-      __intel_pstate_update_max_freq(all_cpu_data[cpu], policy);
+-
+-      cpufreq_cpu_release(policy);
+-}
+-
+ static void intel_pstate_update_limits(unsigned int cpu)
+ {
+       mutex_lock(&intel_pstate_driver_lock);
+-      update_turbo_state();
+-      /*
+-       * If turbo has been turned on or off globally, policy limits for
+-       * all CPUs need to be updated to reflect that.
+-       */
+-      if (global.turbo_disabled_mf != global.turbo_disabled) {
+-              global.turbo_disabled_mf = global.turbo_disabled;
+-              arch_set_max_freq_ratio(global.turbo_disabled);
+-              for_each_possible_cpu(cpu)
+-                      intel_pstate_update_max_freq(cpu);
+-      } else {
+-              cpufreq_update_policy(cpu);
+-      }
++      cpufreq_update_policy(cpu);
+       mutex_unlock(&intel_pstate_driver_lock);
+ }
+@@ -1243,7 +1218,6 @@ static ssize_t show_no_turbo(struct kobject *kobj,
+               return -EAGAIN;
+       }
+-      update_turbo_state();
+       if (global.turbo_disabled)
+               ret = sprintf(buf, "%u\n", global.turbo_disabled);
+       else
+@@ -1273,7 +1247,6 @@ static ssize_t store_no_turbo(struct kobject *a, struct kobj_attribute *b,
+       mutex_lock(&intel_pstate_limits_lock);
+-      update_turbo_state();
+       if (global.turbo_disabled) {
+               pr_notice_once("Turbo disabled by BIOS or unavailable on processor\n");
+               mutex_unlock(&intel_pstate_limits_lock);
+@@ -2205,8 +2178,6 @@ static void intel_pstate_adjust_pstate(struct cpudata *cpu)
+       struct sample *sample;
+       int target_pstate;
+-      update_turbo_state();
+-
+       target_pstate = get_target_pstate(cpu);
+       target_pstate = intel_pstate_prepare_request(cpu, target_pstate);
+       trace_cpu_frequency(target_pstate * cpu->pstate.scaling, cpu->cpu);
+@@ -2523,7 +2494,6 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
+                * be invoked on them.
+                */
+               intel_pstate_clear_update_util_hook(policy->cpu);
+-              update_turbo_state();
+               intel_pstate_set_pstate(cpu, pstate);
+       } else {
+               intel_pstate_set_update_util_hook(policy->cpu);
+@@ -2562,7 +2532,6 @@ static void intel_pstate_verify_cpu_policy(struct cpudata *cpu,
+ {
+       int max_freq;
+-      update_turbo_state();
+       if (hwp_active) {
+               intel_pstate_get_hwp_cap(cpu);
+               max_freq = global.no_turbo || global.turbo_disabled ?
+@@ -2659,8 +2628,6 @@ static int __intel_pstate_cpu_init(struct cpufreq_policy *policy)
+       /* cpuinfo and default policy values */
+       policy->cpuinfo.min_freq = cpu->pstate.min_freq;
+-      update_turbo_state();
+-      global.turbo_disabled_mf = global.turbo_disabled;
+       policy->cpuinfo.max_freq = global.turbo_disabled ?
+                       cpu->pstate.max_freq : cpu->pstate.turbo_freq;
+@@ -2826,8 +2793,6 @@ static int intel_cpufreq_target(struct cpufreq_policy *policy,
+       struct cpufreq_freqs freqs;
+       int target_pstate;
+-      update_turbo_state();
+-
+       freqs.old = policy->cur;
+       freqs.new = target_freq;
+@@ -2849,8 +2814,6 @@ static unsigned int intel_cpufreq_fast_switch(struct cpufreq_policy *policy,
+       struct cpudata *cpu = all_cpu_data[policy->cpu];
+       int target_pstate;
+-      update_turbo_state();
+-
+       target_pstate = intel_pstate_freq_to_hwp(cpu, target_freq);
+       target_pstate = intel_cpufreq_update_pstate(policy, target_pstate, true);
+@@ -2868,7 +2831,6 @@ static void intel_cpufreq_adjust_perf(unsigned int cpunum,
+       int old_pstate = cpu->pstate.current_pstate;
+       int cap_pstate, min_pstate, max_pstate, target_pstate;
+-      update_turbo_state();
+       cap_pstate = global.turbo_disabled ? HWP_GUARANTEED_PERF(hwp_cap) :
+                                            HWP_HIGHEST_PERF(hwp_cap);
+@@ -3058,6 +3020,9 @@ static int intel_pstate_register_driver(struct cpufreq_driver *driver)
+       memset(&global, 0, sizeof(global));
+       global.max_perf_pct = 100;
++      global.turbo_disabled = turbo_is_disabled();
++
++      arch_set_max_freq_ratio(global.turbo_disabled);
+       intel_pstate_driver = driver;
+       ret = cpufreq_register_driver(intel_pstate_driver);
+-- 
+2.39.5
+
diff --git a/queue-5.15/cpufreq-intel_pstate-fold-intel_pstate_max_within_li.patch b/queue-5.15/cpufreq-intel_pstate-fold-intel_pstate_max_within_li.patch
new file mode 100644 (file)
index 0000000..83f4980
--- /dev/null
@@ -0,0 +1,61 @@
+From 84097c4bb28e934fd60bcf17878f9d97822c7a17 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Mar 2024 18:01:58 +0100
+Subject: cpufreq: intel_pstate: Fold intel_pstate_max_within_limits() into
+ caller
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 032c5565eb80edb6f2faeb31939540c897987119 ]
+
+Fold intel_pstate_max_within_limits() into its only caller.
+
+No functional impact.
+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Stable-dep-of: ac4e04d9e378 ("cpufreq: intel_pstate: Unchecked MSR aceess in legacy mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/intel_pstate.c | 13 ++++---------
+ 1 file changed, 4 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
+index 6f69e396ce8c8..bcfde997f445d 100644
+--- a/drivers/cpufreq/intel_pstate.c
++++ b/drivers/cpufreq/intel_pstate.c
+@@ -1936,14 +1936,6 @@ static void intel_pstate_set_min_pstate(struct cpudata *cpu)
+       intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate);
+ }
+-static void intel_pstate_max_within_limits(struct cpudata *cpu)
+-{
+-      int pstate = max(cpu->pstate.min_pstate, cpu->max_perf_ratio);
+-
+-      update_turbo_state();
+-      intel_pstate_set_pstate(cpu, pstate);
+-}
+-
+ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
+ {
+       int perf_ctl_max_phys = pstate_funcs.get_max_physical(cpu->cpu);
+@@ -2524,12 +2516,15 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
+       intel_pstate_update_perf_limits(cpu, policy->min, policy->max);
+       if (cpu->policy == CPUFREQ_POLICY_PERFORMANCE) {
++              int pstate = max(cpu->pstate.min_pstate, cpu->max_perf_ratio);
++
+               /*
+                * NOHZ_FULL CPUs need this as the governor callback may not
+                * be invoked on them.
+                */
+               intel_pstate_clear_update_util_hook(policy->cpu);
+-              intel_pstate_max_within_limits(cpu);
++              update_turbo_state();
++              intel_pstate_set_pstate(cpu, pstate);
+       } else {
+               intel_pstate_set_update_util_hook(policy->cpu);
+       }
+-- 
+2.39.5
+
diff --git a/queue-5.15/cpufreq-intel_pstate-process-hwp-guaranteed-change-n.patch b/queue-5.15/cpufreq-intel_pstate-process-hwp-guaranteed-change-n.patch
new file mode 100644 (file)
index 0000000..a7e3cb1
--- /dev/null
@@ -0,0 +1,261 @@
+From aa88dc777754b1557313c1cbf447c1720dcfbc7e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Sep 2021 09:42:17 -0700
+Subject: cpufreq: intel_pstate: Process HWP Guaranteed change notification
+
+From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+
+[ Upstream commit 57577c996d731ce1e5a4a488e64e6e201b360847 ]
+
+It is possible that HWP guaranteed ratio is changed in response to
+change in power and thermal limits. For example when Intel Speed Select
+performance profile is changed or there is change in TDP, hardware can
+send notifications. It is possible that the guaranteed ratio is
+increased. This creates an issue when turbo is disabled, as the old
+limits set in MSR_HWP_REQUEST are still lower and hardware will clip
+to older limits.
+
+This change enables HWP interrupt and process HWP interrupts. When
+guaranteed is changed, calls cpufreq_update_policy() so that driver
+callbacks are called to update to new HWP limits. This callback
+is called from a delayed workqueue of 10ms to avoid frequent updates.
+
+Although the scope of IA32_HWP_INTERRUPT is per logical cpu, on some
+plaforms interrupt is generated on all CPUs. This is particularly a
+problem during initialization, when the driver didn't allocated
+data for other CPUs. So this change uses a cpumask of enabled CPUs and
+process interrupts on those CPUs only.
+
+When the cpufreq offline() or suspend() callback is called, HWP interrupt
+is disabled on those CPUs and also cancels any pending work item.
+
+Spin lock is used to protect data and processing shared with interrupt
+handler. Here READ_ONCE(), WRITE_ONCE() macros are used to designate
+shared data, even though spin lock act as an optimization barrier here.
+
+Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Tested-by: pablomh@gmail.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Stable-dep-of: ac4e04d9e378 ("cpufreq: intel_pstate: Unchecked MSR aceess in legacy mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/intel_pstate.c | 117 +++++++++++++++++++++++++++++++--
+ 1 file changed, 111 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
+index 4de71e772f514..2a1d21438a468 100644
+--- a/drivers/cpufreq/intel_pstate.c
++++ b/drivers/cpufreq/intel_pstate.c
+@@ -33,6 +33,7 @@
+ #include <asm/cpu_device_id.h>
+ #include <asm/cpufeature.h>
+ #include <asm/intel-family.h>
++#include "../drivers/thermal/intel/thermal_interrupt.h"
+ #define INTEL_PSTATE_SAMPLING_INTERVAL        (10 * NSEC_PER_MSEC)
+@@ -220,6 +221,7 @@ struct global_params {
+  * @sched_flags:      Store scheduler flags for possible cross CPU update
+  * @hwp_boost_min:    Last HWP boosted min performance
+  * @suspended:                Whether or not the driver has been suspended.
++ * @hwp_notify_work:  workqueue for HWP notifications.
+  *
+  * This structure stores per CPU instance data for all CPUs.
+  */
+@@ -258,6 +260,7 @@ struct cpudata {
+       unsigned int sched_flags;
+       u32 hwp_boost_min;
+       bool suspended;
++      struct delayed_work hwp_notify_work;
+ };
+ static struct cpudata **all_cpu_data;
+@@ -983,11 +986,15 @@ static void intel_pstate_hwp_set(unsigned int cpu)
+       wrmsrl_on_cpu(cpu, MSR_HWP_REQUEST, value);
+ }
++static void intel_pstate_disable_hwp_interrupt(struct cpudata *cpudata);
++
+ static void intel_pstate_hwp_offline(struct cpudata *cpu)
+ {
+       u64 value = READ_ONCE(cpu->hwp_req_cached);
+       int min_perf;
++      intel_pstate_disable_hwp_interrupt(cpu);
++
+       if (boot_cpu_has(X86_FEATURE_HWP_EPP)) {
+               /*
+                * In case the EPP has been set to "performance" by the
+@@ -1064,6 +1071,9 @@ static int intel_pstate_suspend(struct cpufreq_policy *policy)
+       cpu->suspended = true;
++      /* disable HWP interrupt and cancel any pending work */
++      intel_pstate_disable_hwp_interrupt(cpu);
++
+       return 0;
+ }
+@@ -1557,15 +1567,105 @@ static void intel_pstate_sysfs_hide_hwp_dynamic_boost(void)
+ /************************** sysfs end ************************/
++static void intel_pstate_notify_work(struct work_struct *work)
++{
++      struct cpudata *cpudata =
++              container_of(to_delayed_work(work), struct cpudata, hwp_notify_work);
++
++      cpufreq_update_policy(cpudata->cpu);
++      wrmsrl_on_cpu(cpudata->cpu, MSR_HWP_STATUS, 0);
++}
++
++static DEFINE_SPINLOCK(hwp_notify_lock);
++static cpumask_t hwp_intr_enable_mask;
++
++void notify_hwp_interrupt(void)
++{
++      unsigned int this_cpu = smp_processor_id();
++      struct cpudata *cpudata;
++      unsigned long flags;
++      u64 value;
++
++      if (!READ_ONCE(hwp_active) || !boot_cpu_has(X86_FEATURE_HWP_NOTIFY))
++              return;
++
++      rdmsrl_safe(MSR_HWP_STATUS, &value);
++      if (!(value & 0x01))
++              return;
++
++      spin_lock_irqsave(&hwp_notify_lock, flags);
++
++      if (!cpumask_test_cpu(this_cpu, &hwp_intr_enable_mask))
++              goto ack_intr;
++
++      /*
++       * Currently we never free all_cpu_data. And we can't reach here
++       * without this allocated. But for safety for future changes, added
++       * check.
++       */
++      if (unlikely(!READ_ONCE(all_cpu_data)))
++              goto ack_intr;
++
++      /*
++       * The free is done during cleanup, when cpufreq registry is failed.
++       * We wouldn't be here if it fails on init or switch status. But for
++       * future changes, added check.
++       */
++      cpudata = READ_ONCE(all_cpu_data[this_cpu]);
++      if (unlikely(!cpudata))
++              goto ack_intr;
++
++      schedule_delayed_work(&cpudata->hwp_notify_work, msecs_to_jiffies(10));
++
++      spin_unlock_irqrestore(&hwp_notify_lock, flags);
++
++      return;
++
++ack_intr:
++      wrmsrl_safe(MSR_HWP_STATUS, 0);
++      spin_unlock_irqrestore(&hwp_notify_lock, flags);
++}
++
++static void intel_pstate_disable_hwp_interrupt(struct cpudata *cpudata)
++{
++      unsigned long flags;
++
++      /* wrmsrl_on_cpu has to be outside spinlock as this can result in IPC */
++      wrmsrl_on_cpu(cpudata->cpu, MSR_HWP_INTERRUPT, 0x00);
++
++      spin_lock_irqsave(&hwp_notify_lock, flags);
++      if (cpumask_test_and_clear_cpu(cpudata->cpu, &hwp_intr_enable_mask))
++              cancel_delayed_work(&cpudata->hwp_notify_work);
++      spin_unlock_irqrestore(&hwp_notify_lock, flags);
++}
++
++static void intel_pstate_enable_hwp_interrupt(struct cpudata *cpudata)
++{
++      /* Enable HWP notification interrupt for guaranteed performance change */
++      if (boot_cpu_has(X86_FEATURE_HWP_NOTIFY)) {
++              unsigned long flags;
++
++              spin_lock_irqsave(&hwp_notify_lock, flags);
++              INIT_DELAYED_WORK(&cpudata->hwp_notify_work, intel_pstate_notify_work);
++              cpumask_set_cpu(cpudata->cpu, &hwp_intr_enable_mask);
++              spin_unlock_irqrestore(&hwp_notify_lock, flags);
++
++              /* wrmsrl_on_cpu has to be outside spinlock as this can result in IPC */
++              wrmsrl_on_cpu(cpudata->cpu, MSR_HWP_INTERRUPT, 0x01);
++      }
++}
++
+ static void intel_pstate_hwp_enable(struct cpudata *cpudata)
+ {
+-      /* First disable HWP notification interrupt as we don't process them */
++      /* First disable HWP notification interrupt till we activate again */
+       if (boot_cpu_has(X86_FEATURE_HWP_NOTIFY))
+               wrmsrl_on_cpu(cpudata->cpu, MSR_HWP_INTERRUPT, 0x00);
+       wrmsrl_on_cpu(cpudata->cpu, MSR_PM_ENABLE, 0x1);
+       if (cpudata->epp_default == -EINVAL)
+               cpudata->epp_default = intel_pstate_get_epp(cpudata, 0);
++
++      intel_pstate_enable_hwp_interrupt(cpudata);
+ }
+ static int atom_get_min_pstate(int not_used)
+@@ -2266,7 +2366,7 @@ static int intel_pstate_init_cpu(unsigned int cpunum)
+               if (!cpu)
+                       return -ENOMEM;
+-              all_cpu_data[cpunum] = cpu;
++              WRITE_ONCE(all_cpu_data[cpunum], cpu);
+               cpu->cpu = cpunum;
+@@ -2937,8 +3037,10 @@ static void intel_pstate_driver_cleanup(void)
+                       if (intel_pstate_driver == &intel_pstate)
+                               intel_pstate_clear_update_util_hook(cpu);
++                      spin_lock(&hwp_notify_lock);
+                       kfree(all_cpu_data[cpu]);
+-                      all_cpu_data[cpu] = NULL;
++                      WRITE_ONCE(all_cpu_data[cpu], NULL);
++                      spin_unlock(&hwp_notify_lock);
+               }
+       }
+       cpus_read_unlock();
+@@ -3207,6 +3309,7 @@ static bool intel_pstate_hwp_is_enabled(void)
+ static int __init intel_pstate_init(void)
+ {
++      static struct cpudata **_all_cpu_data;
+       const struct x86_cpu_id *id;
+       int rc;
+@@ -3232,7 +3335,7 @@ static int __init intel_pstate_init(void)
+                * deal with it.
+                */
+               if ((!no_hwp && boot_cpu_has(X86_FEATURE_HWP_EPP)) || hwp_forced) {
+-                      hwp_active++;
++                      WRITE_ONCE(hwp_active, 1);
+                       hwp_mode_bdw = id->driver_data;
+                       intel_pstate.attr = hwp_cpufreq_attrs;
+                       intel_cpufreq.attr = hwp_cpufreq_attrs;
+@@ -3283,10 +3386,12 @@ static int __init intel_pstate_init(void)
+       pr_info("Intel P-state driver initializing\n");
+-      all_cpu_data = vzalloc(array_size(sizeof(void *), num_possible_cpus()));
+-      if (!all_cpu_data)
++      _all_cpu_data = vzalloc(array_size(sizeof(void *), num_possible_cpus()));
++      if (!_all_cpu_data)
+               return -ENOMEM;
++      WRITE_ONCE(all_cpu_data, _all_cpu_data);
++
+       intel_pstate_request_control_from_smm();
+       intel_pstate_sysfs_expose_params();
+-- 
+2.39.5
+
diff --git a/queue-5.15/cpufreq-intel_pstate-revise-global-turbo-disable-che.patch b/queue-5.15/cpufreq-intel_pstate-revise-global-turbo-disable-che.patch
new file mode 100644 (file)
index 0000000..d7d12d5
--- /dev/null
@@ -0,0 +1,69 @@
+From c954aeeeadc7694c41fb563942cbabf72fe2e1e3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Sep 2023 11:02:07 -0700
+Subject: cpufreq: intel_pstate: Revise global turbo disable check
+
+From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+
+[ Upstream commit 37b6ddba967c601479bea418a7ac6ff16b6232b7 ]
+
+Setting global turbo flag based on CPU 0 P-state limits is problematic
+as it limits max P-state request on every CPU on the system just based
+on its P-state limits.
+
+There are two cases in which global.turbo_disabled flag is set:
+- When the MSR_IA32_MISC_ENABLE_TURBO_DISABLE bit is set to 1
+in the MSR MSR_IA32_MISC_ENABLE. This bit can be only changed by
+the system BIOS before power up.
+- When the max non turbo P-state is same as max turbo P-state for CPU 0.
+
+The second check is not a valid to decide global turbo state based on
+the CPU 0. CPU 0 max turbo P-state can be same as max non turbo P-state,
+but for other CPUs this may not be true.
+
+There is no guarantee that max P-state limits are same for every CPU. This
+is possible that during fusing max P-state for a CPU is constrained. Also
+with the Intel Speed Select performance profile, CPU 0 may not be present
+in all profiles. In this case the max non turbo and turbo P-state can be
+set to the lowest possible P-state by the hardware when switched to
+such profile. Since max non turbo and turbo P-state is same,
+global.turbo_disabled flag will be set.
+
+Once global.turbo_disabled is set, any scaling max and min frequency
+update for any CPU will result in its max P-state constrained to the max
+non turbo P-state.
+
+Hence remove the check of max non turbo P-state equal to max turbo P-state
+of CPU 0 to set global turbo disabled flag.
+
+Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+[ rjw: Subject edit ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Stable-dep-of: ac4e04d9e378 ("cpufreq: intel_pstate: Unchecked MSR aceess in legacy mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/intel_pstate.c | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
+index cb6fb9cdba0b8..6f69e396ce8c8 100644
+--- a/drivers/cpufreq/intel_pstate.c
++++ b/drivers/cpufreq/intel_pstate.c
+@@ -563,13 +563,9 @@ static void intel_pstate_hybrid_hwp_adjust(struct cpudata *cpu)
+ static inline void update_turbo_state(void)
+ {
+       u64 misc_en;
+-      struct cpudata *cpu;
+-      cpu = all_cpu_data[0];
+       rdmsrl(MSR_IA32_MISC_ENABLE, misc_en);
+-      global.turbo_disabled =
+-              (misc_en & MSR_IA32_MISC_ENABLE_TURBO_DISABLE ||
+-               cpu->pstate.max_pstate == cpu->pstate.turbo_pstate);
++      global.turbo_disabled = misc_en & MSR_IA32_MISC_ENABLE_TURBO_DISABLE;
+ }
+ static int min_perf_pct_min(void)
+-- 
+2.39.5
+
diff --git a/queue-5.15/cpufreq-intel_pstate-unchecked-msr-aceess-in-legacy-.patch b/queue-5.15/cpufreq-intel_pstate-unchecked-msr-aceess-in-legacy-.patch
new file mode 100644 (file)
index 0000000..9fe71ac
--- /dev/null
@@ -0,0 +1,65 @@
+From 440d08e6e32a6192de35b667bd2b69f71d972009 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Apr 2025 14:07:11 -0700
+Subject: cpufreq: intel_pstate: Unchecked MSR aceess in legacy mode
+
+From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+
+[ Upstream commit ac4e04d9e378f5aa826c2406ad7871ae1b6a6fb9 ]
+
+When turbo mode is unavailable on a Skylake-X system, executing the
+command:
+
+ # echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo
+
+results in an unchecked MSR access error:
+
+ WRMSR to 0x199 (attempted to write 0x0000000100001300).
+
+This issue was reproduced on an OEM (Original Equipment Manufacturer)
+system and is not a common problem across all Skylake-X systems.
+
+This error occurs because the MSR 0x199 Turbo Engage Bit (bit 32) is set
+when turbo mode is disabled. The issue arises when intel_pstate fails to
+detect that turbo mode is disabled. Here intel_pstate relies on
+MSR_IA32_MISC_ENABLE bit 38 to determine the status of turbo mode.
+However, on this system, bit 38 is not set even when turbo mode is
+disabled.
+
+According to the Intel Software Developer's Manual (SDM), the BIOS sets
+this bit during platform initialization to enable or disable
+opportunistic processor performance operations. Logically, this bit
+should be set in such cases. However, the SDM also specifies that "OS
+and applications must use CPUID leaf 06H to detect processors with
+opportunistic processor performance operations enabled."
+
+Therefore, in addition to checking MSR_IA32_MISC_ENABLE bit 38, verify
+that CPUID.06H:EAX[1] is 0 to accurately determine if turbo mode is
+disabled.
+
+Fixes: 4521e1a0ce17 ("cpufreq: intel_pstate: Reflect current no_turbo state correctly")
+Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Cc: All applicable <stable@vger.kernel.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/intel_pstate.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
+index a26d28c437699..875c8cdaddda1 100644
+--- a/drivers/cpufreq/intel_pstate.c
++++ b/drivers/cpufreq/intel_pstate.c
+@@ -562,6 +562,9 @@ static bool turbo_is_disabled(void)
+ {
+       u64 misc_en;
++      if (!cpu_feature_enabled(X86_FEATURE_IDA))
++              return true;
++
+       rdmsrl(MSR_IA32_MISC_ENABLE, misc_en);
+       return !!(misc_en & MSR_IA32_MISC_ENABLE_TURBO_DISABLE);
+-- 
+2.39.5
+
diff --git a/queue-5.15/cpufreq-intel_pstate-update-cpuinfo.max_freq-on-hwp_.patch b/queue-5.15/cpufreq-intel_pstate-update-cpuinfo.max_freq-on-hwp_.patch
new file mode 100644 (file)
index 0000000..ca30ec4
--- /dev/null
@@ -0,0 +1,89 @@
+From f9f9bd456c7f1a49b58ecb484e5d2509c0e340b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Dec 2021 20:06:08 +0100
+Subject: cpufreq: intel_pstate: Update cpuinfo.max_freq on HWP_CAP changes
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit dfeeedc1bf5772226bddf51ed3f853e5a6707bf1 ]
+
+With HWP enabled, when the turbo range of performance levels is
+disabled by the platform firmware, the CPU capacity is given by
+the "guaranteed performance" field in MSR_HWP_CAPABILITIES which
+is generally dynamic.  When it changes, the kernel receives an HWP
+notification interrupt handled by notify_hwp_interrupt().
+
+When the "guaranteed performance" value changes in the above
+configuration, the CPU performance scaling needs to be adjusted so
+as to use the new CPU capacity in computations, which means that
+the cpuinfo.max_freq value needs to be updated for that CPU.
+
+Accordingly, modify intel_pstate_notify_work() to read
+MSR_HWP_CAPABILITIES and update cpuinfo.max_freq to reflect the
+new configuration (this update can be carried out even if the
+configuration doesn't actually change, because it simply doesn't
+matter then and it takes less time to update it than to do extra
+checks to decide whether or not a change has really occurred).
+
+Reported-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Tested-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Stable-dep-of: ac4e04d9e378 ("cpufreq: intel_pstate: Unchecked MSR aceess in legacy mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpufreq/intel_pstate.c | 24 +++++++++++++++++-------
+ 1 file changed, 17 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
+index 2a1d21438a468..cb6fb9cdba0b8 100644
+--- a/drivers/cpufreq/intel_pstate.c
++++ b/drivers/cpufreq/intel_pstate.c
+@@ -1111,19 +1111,22 @@ static void intel_pstate_update_policies(void)
+               cpufreq_update_policy(cpu);
+ }
++static void __intel_pstate_update_max_freq(struct cpudata *cpudata,
++                                         struct cpufreq_policy *policy)
++{
++      policy->cpuinfo.max_freq = global.turbo_disabled_mf ?
++                      cpudata->pstate.max_freq : cpudata->pstate.turbo_freq;
++      refresh_frequency_limits(policy);
++}
++
+ static void intel_pstate_update_max_freq(unsigned int cpu)
+ {
+       struct cpufreq_policy *policy = cpufreq_cpu_acquire(cpu);
+-      struct cpudata *cpudata;
+       if (!policy)
+               return;
+-      cpudata = all_cpu_data[cpu];
+-      policy->cpuinfo.max_freq = global.turbo_disabled_mf ?
+-                      cpudata->pstate.max_freq : cpudata->pstate.turbo_freq;
+-
+-      refresh_frequency_limits(policy);
++      __intel_pstate_update_max_freq(all_cpu_data[cpu], policy);
+       cpufreq_cpu_release(policy);
+ }
+@@ -1571,8 +1574,15 @@ static void intel_pstate_notify_work(struct work_struct *work)
+ {
+       struct cpudata *cpudata =
+               container_of(to_delayed_work(work), struct cpudata, hwp_notify_work);
++      struct cpufreq_policy *policy = cpufreq_cpu_acquire(cpudata->cpu);
++
++      if (policy) {
++              intel_pstate_get_hwp_cap(cpudata);
++              __intel_pstate_update_max_freq(cpudata, policy);
++
++              cpufreq_cpu_release(policy);
++      }
+-      cpufreq_update_policy(cpudata->cpu);
+       wrmsrl_on_cpu(cpudata->cpu, MSR_HWP_STATUS, 0);
+ }
+-- 
+2.39.5
+
diff --git a/queue-5.15/firmware-arm_scmi-balance-device-refcount-when-destr.patch b/queue-5.15/firmware-arm_scmi-balance-device-refcount-when-destr.patch
new file mode 100644 (file)
index 0000000..bf8e160
--- /dev/null
@@ -0,0 +1,86 @@
+From 03f6a515d22b7b74dec567c6ce37dfc47d8d3033 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Mar 2025 18:54:47 +0000
+Subject: firmware: arm_scmi: Balance device refcount when destroying devices
+
+From: Cristian Marussi <cristian.marussi@arm.com>
+
+[ Upstream commit 9ca67840c0ddf3f39407339624cef824a4f27599 ]
+
+Using device_find_child() to lookup the proper SCMI device to destroy
+causes an unbalance in device refcount, since device_find_child() calls an
+implicit get_device(): this, in turns, inhibits the call of the provided
+release methods upon devices destruction.
+
+As a consequence, one of the structures that is not freed properly upon
+destruction is the internal struct device_private dev->p populated by the
+drivers subsystem core.
+
+KMemleak detects this situation since loading/unloding some SCMI driver
+causes related devices to be created/destroyed without calling any
+device_release method.
+
+unreferenced object 0xffff00000f583800 (size 512):
+  comm "insmod", pid 227, jiffies 4294912190
+  hex dump (first 32 bytes):
+    00 00 00 00 ad 4e ad de ff ff ff ff 00 00 00 00  .....N..........
+    ff ff ff ff ff ff ff ff 60 36 1d 8a 00 80 ff ff  ........`6......
+  backtrace (crc 114e2eed):
+    kmemleak_alloc+0xbc/0xd8
+    __kmalloc_cache_noprof+0x2dc/0x398
+    device_add+0x954/0x12d0
+    device_register+0x28/0x40
+    __scmi_device_create.part.0+0x1bc/0x380
+    scmi_device_create+0x2d0/0x390
+    scmi_create_protocol_devices+0x74/0xf8
+    scmi_device_request_notifier+0x1f8/0x2a8
+    notifier_call_chain+0x110/0x3b0
+    blocking_notifier_call_chain+0x70/0xb0
+    scmi_driver_register+0x350/0x7f0
+    0xffff80000a3b3038
+    do_one_initcall+0x12c/0x730
+    do_init_module+0x1dc/0x640
+    load_module+0x4b20/0x5b70
+    init_module_from_file+0xec/0x158
+
+$ ./scripts/faddr2line ./vmlinux device_add+0x954/0x12d0
+device_add+0x954/0x12d0:
+kmalloc_noprof at include/linux/slab.h:901
+(inlined by) kzalloc_noprof at include/linux/slab.h:1037
+(inlined by) device_private_init at drivers/base/core.c:3510
+(inlined by) device_add at drivers/base/core.c:3561
+
+Balance device refcount by issuing a put_device() on devices found via
+device_find_child().
+
+Reported-by: Alice Ryhl <aliceryhl@google.com>
+Closes: https://lore.kernel.org/linux-arm-kernel/Z8nK3uFkspy61yjP@arm.com/T/#mc1f73a0ea5e41014fa145147b7b839fc988ada8f
+CC: Sudeep Holla <sudeep.holla@arm.com>
+CC: Catalin Marinas <catalin.marinas@arm.com>
+Fixes: d4f9dddd21f3 ("firmware: arm_scmi: Add dynamic scmi devices creation")
+Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
+Tested-by: Alice Ryhl <aliceryhl@google.com>
+Message-Id: <20250306185447.2039336-1-cristian.marussi@arm.com>
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/arm_scmi/bus.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
+index 7c1c0951e562d..758ced6a8cc4e 100644
+--- a/drivers/firmware/arm_scmi/bus.c
++++ b/drivers/firmware/arm_scmi/bus.c
+@@ -73,6 +73,9 @@ struct scmi_device *scmi_child_dev_find(struct device *parent,
+       if (!dev)
+               return NULL;
++      /* Drop the refcnt bumped implicitly by device_find_child */
++      put_device(dev);
++
+       return to_scmi_dev(dev);
+ }
+-- 
+2.39.5
+
diff --git a/queue-5.15/iommu-arm-smmu-v3-fix-iommu_device_probe-bug-due-to-.patch b/queue-5.15/iommu-arm-smmu-v3-fix-iommu_device_probe-bug-due-to-.patch
new file mode 100644 (file)
index 0000000..521e53b
--- /dev/null
@@ -0,0 +1,123 @@
+From 4466804dfcd58d18f1a062683e4713379f65f30e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Apr 2025 11:56:20 -0700
+Subject: iommu/arm-smmu-v3: Fix iommu_device_probe bug due to duplicated
+ stream ids
+
+From: Nicolin Chen <nicolinc@nvidia.com>
+
+[ Upstream commit b00d24997a11c10d3e420614f0873b83ce358a34 ]
+
+ASPEED VGA card has two built-in devices:
+ 0008:06:00.0 PCI bridge: ASPEED Technology, Inc. AST1150 PCI-to-PCI Bridge (rev 06)
+ 0008:07:00.0 VGA compatible controller: ASPEED Technology, Inc. ASPEED Graphics Family (rev 52)
+
+Its toplogy looks like this:
+ +-[0008:00]---00.0-[01-09]--+-00.0-[02-09]--+-00.0-[03]----00.0  Sandisk Corp Device 5017
+                             |               +-01.0-[04]--
+                             |               +-02.0-[05]----00.0  NVIDIA Corporation Device
+                             |               +-03.0-[06-07]----00.0-[07]----00.0  ASPEED Technology, Inc. ASPEED Graphics Family
+                             |               +-04.0-[08]----00.0  Renesas Technology Corp. uPD720201 USB 3.0 Host Controller
+                             |               \-05.0-[09]----00.0  Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller
+                             \-00.1  PMC-Sierra Inc. Device 4028
+
+The IORT logic populaties two identical IDs into the fwspec->ids array via
+DMA aliasing in iort_pci_iommu_init() called by pci_for_each_dma_alias().
+
+Though the SMMU driver had been able to handle this situation since commit
+563b5cbe334e ("iommu/arm-smmu-v3: Cope with duplicated Stream IDs"), that
+got broken by the later commit cdf315f907d4 ("iommu/arm-smmu-v3: Maintain
+a SID->device structure"), which ended up with allocating separate streams
+with the same stuffing.
+
+On a kernel prior to v6.15-rc1, there has been an overlooked warning:
+  pci 0008:07:00.0: vgaarb: setting as boot VGA device
+  pci 0008:07:00.0: vgaarb: bridge control possible
+  pci 0008:07:00.0: vgaarb: VGA device added: decodes=io+mem,owns=none,locks=none
+  pcieport 0008:06:00.0: Adding to iommu group 14
+  ast 0008:07:00.0: stream 67328 already in tree   <===== WARNING
+  ast 0008:07:00.0: enabling device (0002 -> 0003)
+  ast 0008:07:00.0: Using default configuration
+  ast 0008:07:00.0: AST 2600 detected
+  ast 0008:07:00.0: [drm] Using analog VGA
+  ast 0008:07:00.0: [drm] dram MCLK=396 Mhz type=1 bus_width=16
+  [drm] Initialized ast 0.1.0 for 0008:07:00.0 on minor 0
+  ast 0008:07:00.0: [drm] fb0: astdrmfb frame buffer device
+
+With v6.15-rc, since the commit bcb81ac6ae3c ("iommu: Get DT/ACPI parsing
+into the proper probe path"), the error returned with the warning is moved
+to the SMMU device probe flow:
+  arm_smmu_probe_device+0x15c/0x4c0
+  __iommu_probe_device+0x150/0x4f8
+  probe_iommu_group+0x44/0x80
+  bus_for_each_dev+0x7c/0x100
+  bus_iommu_probe+0x48/0x1a8
+  iommu_device_register+0xb8/0x178
+  arm_smmu_device_probe+0x1350/0x1db0
+which then fails the entire SMMU driver probe:
+  pci 0008:06:00.0: Adding to iommu group 21
+  pci 0008:07:00.0: stream 67328 already in tree
+  arm-smmu-v3 arm-smmu-v3.9.auto: Failed to register iommu
+  arm-smmu-v3 arm-smmu-v3.9.auto: probe with driver arm-smmu-v3 failed with error -22
+
+Since SMMU driver had been already expecting a potential duplicated Stream
+ID in arm_smmu_install_ste_for_dev(), change the arm_smmu_insert_master()
+routine to ignore a duplicated ID from the fwspec->sids array as well.
+
+Note: this has been failing the iommu_device_probe() since 2021, although a
+recent iommu commit in v6.15-rc1 that moves iommu_device_probe() started to
+fail the SMMU driver probe. Since nobody has cared about DMA Alias support,
+leave that as it was but fix the fundamental iommu_device_probe() breakage.
+
+Fixes: cdf315f907d4 ("iommu/arm-smmu-v3: Maintain a SID->device structure")
+Cc: stable@vger.kernel.org
+Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
+Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
+Link: https://lore.kernel.org/r/20250415185620.504299-1-nicolinc@nvidia.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 19 +++++++++++++++----
+ 1 file changed, 15 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+index fc07ecce426ef..bc65e7b4f0045 100644
+--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
++++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+@@ -2582,6 +2582,7 @@ static int arm_smmu_insert_master(struct arm_smmu_device *smmu,
+       mutex_lock(&smmu->streams_mutex);
+       for (i = 0; i < fwspec->num_ids; i++) {
+               struct arm_smmu_stream *new_stream = &master->streams[i];
++              struct rb_node *existing;
+               u32 sid = fwspec->ids[i];
+               new_stream->id = sid;
+@@ -2603,10 +2604,20 @@ static int arm_smmu_insert_master(struct arm_smmu_device *smmu,
+               }
+               /* Insert into SID tree */
+-              if (rb_find_add(&new_stream->node, &smmu->streams,
+-                              arm_smmu_streams_cmp_node)) {
+-                      dev_warn(master->dev, "stream %u already in tree\n",
+-                               sid);
++              existing = rb_find_add(&new_stream->node, &smmu->streams,
++                                     arm_smmu_streams_cmp_node);
++              if (existing) {
++                      struct arm_smmu_master *existing_master =
++                              rb_entry(existing, struct arm_smmu_stream, node)
++                                      ->master;
++
++                      /* Bridged PCI devices may end up with duplicated IDs */
++                      if (existing_master == master)
++                              continue;
++
++                      dev_warn(master->dev,
++                               "stream %u already in tree from dev %s\n", sid,
++                               dev_name(existing_master->dev));
+                       ret = -EINVAL;
+                       break;
+               }
+-- 
+2.39.5
+
diff --git a/queue-5.15/iommu-arm-smmu-v3-use-the-new-rb-tree-helpers.patch b/queue-5.15/iommu-arm-smmu-v3-use-the-new-rb-tree-helpers.patch
new file mode 100644 (file)
index 0000000..5cfad76
--- /dev/null
@@ -0,0 +1,140 @@
+From 088020d89aca9ab4a1dca05b88a8775c88a21286 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Aug 2024 20:31:15 -0300
+Subject: iommu/arm-smmu-v3: Use the new rb tree helpers
+
+From: Jason Gunthorpe <jgg@nvidia.com>
+
+[ Upstream commit a2bb820e862d61f9ca1499e500915f9f505a2655 ]
+
+Since v5.12 the rbtree has gained some simplifying helpers aimed at making
+rb tree users write less convoluted boiler plate code. Instead the caller
+provides a single comparison function and the helpers generate the prior
+open-coded stuff.
+
+Update smmu->streams to use rb_find_add() and rb_find().
+
+Tested-by: Nicolin Chen <nicolinc@nvidia.com>
+Reviewed-by: Mostafa Saleh <smostafa@google.com>
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Link: https://lore.kernel.org/r/1-v3-9fef8cdc2ff6+150d1-smmuv3_tidy_jgg@nvidia.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Stable-dep-of: b00d24997a11 ("iommu/arm-smmu-v3: Fix iommu_device_probe bug due to duplicated stream ids")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 68 ++++++++++-----------
+ 1 file changed, 31 insertions(+), 37 deletions(-)
+
+diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+index ec4c87095c6cd..fc07ecce426ef 100644
+--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
++++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+@@ -1430,26 +1430,37 @@ static int arm_smmu_init_l2_strtab(struct arm_smmu_device *smmu, u32 sid)
+       return 0;
+ }
++static int arm_smmu_streams_cmp_key(const void *lhs, const struct rb_node *rhs)
++{
++      struct arm_smmu_stream *stream_rhs =
++              rb_entry(rhs, struct arm_smmu_stream, node);
++      const u32 *sid_lhs = lhs;
++
++      if (*sid_lhs < stream_rhs->id)
++              return -1;
++      if (*sid_lhs > stream_rhs->id)
++              return 1;
++      return 0;
++}
++
++static int arm_smmu_streams_cmp_node(struct rb_node *lhs,
++                                   const struct rb_node *rhs)
++{
++      return arm_smmu_streams_cmp_key(
++              &rb_entry(lhs, struct arm_smmu_stream, node)->id, rhs);
++}
++
+ static struct arm_smmu_master *
+ arm_smmu_find_master(struct arm_smmu_device *smmu, u32 sid)
+ {
+       struct rb_node *node;
+-      struct arm_smmu_stream *stream;
+       lockdep_assert_held(&smmu->streams_mutex);
+-      node = smmu->streams.rb_node;
+-      while (node) {
+-              stream = rb_entry(node, struct arm_smmu_stream, node);
+-              if (stream->id < sid)
+-                      node = node->rb_right;
+-              else if (stream->id > sid)
+-                      node = node->rb_left;
+-              else
+-                      return stream->master;
+-      }
+-
+-      return NULL;
++      node = rb_find(&sid, &smmu->streams, arm_smmu_streams_cmp_key);
++      if (!node)
++              return NULL;
++      return rb_entry(node, struct arm_smmu_stream, node)->master;
+ }
+ /* IRQ and event handlers */
+@@ -2560,8 +2571,6 @@ static int arm_smmu_insert_master(struct arm_smmu_device *smmu,
+ {
+       int i;
+       int ret = 0;
+-      struct arm_smmu_stream *new_stream, *cur_stream;
+-      struct rb_node **new_node, *parent_node = NULL;
+       struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(master->dev);
+       master->streams = kcalloc(fwspec->num_ids, sizeof(*master->streams),
+@@ -2572,9 +2581,9 @@ static int arm_smmu_insert_master(struct arm_smmu_device *smmu,
+       mutex_lock(&smmu->streams_mutex);
+       for (i = 0; i < fwspec->num_ids; i++) {
++              struct arm_smmu_stream *new_stream = &master->streams[i];
+               u32 sid = fwspec->ids[i];
+-              new_stream = &master->streams[i];
+               new_stream->id = sid;
+               new_stream->master = master;
+@@ -2594,28 +2603,13 @@ static int arm_smmu_insert_master(struct arm_smmu_device *smmu,
+               }
+               /* Insert into SID tree */
+-              new_node = &(smmu->streams.rb_node);
+-              while (*new_node) {
+-                      cur_stream = rb_entry(*new_node, struct arm_smmu_stream,
+-                                            node);
+-                      parent_node = *new_node;
+-                      if (cur_stream->id > new_stream->id) {
+-                              new_node = &((*new_node)->rb_left);
+-                      } else if (cur_stream->id < new_stream->id) {
+-                              new_node = &((*new_node)->rb_right);
+-                      } else {
+-                              dev_warn(master->dev,
+-                                       "stream %u already in tree\n",
+-                                       cur_stream->id);
+-                              ret = -EINVAL;
+-                              break;
+-                      }
+-              }
+-              if (ret)
++              if (rb_find_add(&new_stream->node, &smmu->streams,
++                              arm_smmu_streams_cmp_node)) {
++                      dev_warn(master->dev, "stream %u already in tree\n",
++                               sid);
++                      ret = -EINVAL;
+                       break;
+-
+-              rb_link_node(&new_stream->node, parent_node, new_node);
+-              rb_insert_color(&new_stream->node, &smmu->streams);
++              }
+       }
+       if (ret) {
+-- 
+2.39.5
+
diff --git a/queue-5.15/irqchip-gic-v2m-add-const-to-of_device_id.patch b/queue-5.15/irqchip-gic-v2m-add-const-to-of_device_id.patch
new file mode 100644 (file)
index 0000000..5a3bdd4
--- /dev/null
@@ -0,0 +1,36 @@
+From 008c2b91aea386652fac6390c4bc1c509bfc1f64 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Dec 2021 21:24:53 +0800
+Subject: irqchip/gic-v2m: Add const to of_device_id
+
+From: Xiang wangx <wangxiang@cdjrlc.com>
+
+[ Upstream commit c10f2f8b5d8027c1ea77f777f2d16cb9043a6c09 ]
+
+struct of_device_id should normally be const.
+
+Signed-off-by: Xiang wangx <wangxiang@cdjrlc.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20211209132453.25623-1-wangxiang@cdjrlc.com
+Stable-dep-of: 3318dc299b07 ("irqchip/gic-v2m: Prevent use after free of gicv2m_get_fwnode()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/irq-gic-v2m.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
+index 0e57c60681aab..48e2eed33f8fa 100644
+--- a/drivers/irqchip/irq-gic-v2m.c
++++ b/drivers/irqchip/irq-gic-v2m.c
+@@ -405,7 +405,7 @@ static int __init gicv2m_init_one(struct fwnode_handle *fwnode,
+       return ret;
+ }
+-static struct of_device_id gicv2m_device_id[] = {
++static const struct of_device_id gicv2m_device_id[] = {
+       {       .compatible     = "arm,gic-v2m-frame",  },
+       {},
+ };
+-- 
+2.39.5
+
diff --git a/queue-5.15/irqchip-gic-v2m-mark-a-few-functions-__init.patch b/queue-5.15/irqchip-gic-v2m-mark-a-few-functions-__init.patch
new file mode 100644 (file)
index 0000000..214a9e1
--- /dev/null
@@ -0,0 +1,72 @@
+From 0896b5f7e2d73af58cc009091bb4d13998633322 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Nov 2022 15:39:33 +0100
+Subject: irqchip/gic-v2m: Mark a few functions __init
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+[ Upstream commit d51a15af37ce8cf59e73de51dcdce3c9f4944974 ]
+
+They are all part of the init sequence.
+
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20221121140048.534395323@linutronix.de
+Stable-dep-of: 3318dc299b07 ("irqchip/gic-v2m: Prevent use after free of gicv2m_get_fwnode()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/irq-gic-v2m.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
+index 48e2eed33f8fa..6790a621a9324 100644
+--- a/drivers/irqchip/irq-gic-v2m.c
++++ b/drivers/irqchip/irq-gic-v2m.c
+@@ -263,7 +263,7 @@ static struct msi_domain_info gicv2m_pmsi_domain_info = {
+       .chip   = &gicv2m_pmsi_irq_chip,
+ };
+-static void gicv2m_teardown(void)
++static void __init gicv2m_teardown(void)
+ {
+       struct v2m_data *v2m, *tmp;
+@@ -278,7 +278,7 @@ static void gicv2m_teardown(void)
+       }
+ }
+-static int gicv2m_allocate_domains(struct irq_domain *parent)
++static __init int gicv2m_allocate_domains(struct irq_domain *parent)
+ {
+       struct irq_domain *inner_domain, *pci_domain, *plat_domain;
+       struct v2m_data *v2m;
+@@ -405,7 +405,7 @@ static int __init gicv2m_init_one(struct fwnode_handle *fwnode,
+       return ret;
+ }
+-static const struct of_device_id gicv2m_device_id[] = {
++static __initconst struct of_device_id gicv2m_device_id[] = {
+       {       .compatible     = "arm,gic-v2m-frame",  },
+       {},
+ };
+@@ -455,7 +455,7 @@ static int __init gicv2m_of_init(struct fwnode_handle *parent_handle,
+ #ifdef CONFIG_ACPI
+ static int acpi_num_msi;
+-static struct fwnode_handle *gicv2m_get_fwnode(struct device *dev)
++static __init struct fwnode_handle *gicv2m_get_fwnode(struct device *dev)
+ {
+       struct v2m_data *data;
+@@ -470,7 +470,7 @@ static struct fwnode_handle *gicv2m_get_fwnode(struct device *dev)
+       return data->fwnode;
+ }
+-static bool acpi_check_amazon_graviton_quirks(void)
++static __init bool acpi_check_amazon_graviton_quirks(void)
+ {
+       static struct acpi_table_madt *madt;
+       acpi_status status;
+-- 
+2.39.5
+
diff --git a/queue-5.15/irqchip-gic-v2m-prevent-use-after-free-of-gicv2m_get.patch b/queue-5.15/irqchip-gic-v2m-prevent-use-after-free-of-gicv2m_get.patch
new file mode 100644 (file)
index 0000000..217cf07
--- /dev/null
@@ -0,0 +1,51 @@
+From 85ce65866dc9f70c0e585e324fa0e7eb5524d241 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Apr 2025 17:16:16 +0100
+Subject: irqchip/gic-v2m: Prevent use after free of gicv2m_get_fwnode()
+
+From: Suzuki K Poulose <suzuki.poulose@arm.com>
+
+[ Upstream commit 3318dc299b072a0511d6dfd8367f3304fb6d9827 ]
+
+With ACPI in place, gicv2m_get_fwnode() is registered with the pci
+subsystem as pci_msi_get_fwnode_cb(), which may get invoked at runtime
+during a PCI host bridge probe. But, the call back is wrongly marked as
+__init, causing it to be freed, while being registered with the PCI
+subsystem and could trigger:
+
+ Unable to handle kernel paging request at virtual address ffff8000816c0400
+  gicv2m_get_fwnode+0x0/0x58 (P)
+  pci_set_bus_msi_domain+0x74/0x88
+  pci_register_host_bridge+0x194/0x548
+
+This is easily reproducible on a Juno board with ACPI boot.
+
+Retain the function for later use.
+
+Fixes: 0644b3daca28 ("irqchip/gic-v2m: acpi: Introducing GICv2m ACPI support")
+Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Reviewed-by: Marc Zyngier <maz@kernel.org>
+Cc: stable@vger.kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/irqchip/irq-gic-v2m.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
+index 6790a621a9324..9d99b19cd21b6 100644
+--- a/drivers/irqchip/irq-gic-v2m.c
++++ b/drivers/irqchip/irq-gic-v2m.c
+@@ -455,7 +455,7 @@ static int __init gicv2m_of_init(struct fwnode_handle *parent_handle,
+ #ifdef CONFIG_ACPI
+ static int acpi_num_msi;
+-static __init struct fwnode_handle *gicv2m_get_fwnode(struct device *dev)
++static struct fwnode_handle *gicv2m_get_fwnode(struct device *dev)
+ {
+       struct v2m_data *data;
+-- 
+2.39.5
+
diff --git a/queue-5.15/net-phy-microchip-force-irq-polling-mode-for-lan88xx.patch b/queue-5.15/net-phy-microchip-force-irq-polling-mode-for-lan88xx.patch
new file mode 100644 (file)
index 0000000..da942ba
--- /dev/null
@@ -0,0 +1,111 @@
+From 6c5d5144b5ad7be45a8bb814f928dfa603805af5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Apr 2025 12:24:13 +0200
+Subject: net: phy: microchip: force IRQ polling mode for lan88xx
+
+From: Fiona Klute <fiona.klute@gmx.de>
+
+[ Upstream commit 30a41ed32d3088cd0d682a13d7f30b23baed7e93 ]
+
+With lan88xx based devices the lan78xx driver can get stuck in an
+interrupt loop while bringing the device up, flooding the kernel log
+with messages like the following:
+
+lan78xx 2-3:1.0 enp1s0u3: kevent 4 may have been dropped
+
+Removing interrupt support from the lan88xx PHY driver forces the
+driver to use polling instead, which avoids the problem.
+
+The issue has been observed with Raspberry Pi devices at least since
+4.14 (see [1], bug report for their downstream kernel), as well as
+with Nvidia devices [2] in 2020, where disabling interrupts was the
+vendor-suggested workaround (together with the claim that phylib
+changes in 4.9 made the interrupt handling in lan78xx incompatible).
+
+Iperf reports well over 900Mbits/sec per direction with client in
+--dualtest mode, so there does not seem to be a significant impact on
+throughput (lan88xx device connected via switch to the peer).
+
+[1] https://github.com/raspberrypi/linux/issues/2447
+[2] https://forums.developer.nvidia.com/t/jetson-xavier-and-lan7800-problem/142134/11
+
+Link: https://lore.kernel.org/0901d90d-3f20-4a10-b680-9c978e04ddda@lunn.ch
+Fixes: 792aec47d59d ("add microchip LAN88xx phy driver")
+Signed-off-by: Fiona Klute <fiona.klute@gmx.de>
+Cc: kernel-list@raspberrypi.com
+Cc: stable@vger.kernel.org
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250416102413.30654-1-fiona.klute@gmx.de
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/microchip.c | 46 +++----------------------------------
+ 1 file changed, 3 insertions(+), 43 deletions(-)
+
+diff --git a/drivers/net/phy/microchip.c b/drivers/net/phy/microchip.c
+index 230f2fcf9c46a..7c8bcec0a8fab 100644
+--- a/drivers/net/phy/microchip.c
++++ b/drivers/net/phy/microchip.c
+@@ -31,47 +31,6 @@ static int lan88xx_write_page(struct phy_device *phydev, int page)
+       return __phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS, page);
+ }
+-static int lan88xx_phy_config_intr(struct phy_device *phydev)
+-{
+-      int rc;
+-
+-      if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
+-              /* unmask all source and clear them before enable */
+-              rc = phy_write(phydev, LAN88XX_INT_MASK, 0x7FFF);
+-              rc = phy_read(phydev, LAN88XX_INT_STS);
+-              rc = phy_write(phydev, LAN88XX_INT_MASK,
+-                             LAN88XX_INT_MASK_MDINTPIN_EN_ |
+-                             LAN88XX_INT_MASK_LINK_CHANGE_);
+-      } else {
+-              rc = phy_write(phydev, LAN88XX_INT_MASK, 0);
+-              if (rc)
+-                      return rc;
+-
+-              /* Ack interrupts after they have been disabled */
+-              rc = phy_read(phydev, LAN88XX_INT_STS);
+-      }
+-
+-      return rc < 0 ? rc : 0;
+-}
+-
+-static irqreturn_t lan88xx_handle_interrupt(struct phy_device *phydev)
+-{
+-      int irq_status;
+-
+-      irq_status = phy_read(phydev, LAN88XX_INT_STS);
+-      if (irq_status < 0) {
+-              phy_error(phydev);
+-              return IRQ_NONE;
+-      }
+-
+-      if (!(irq_status & LAN88XX_INT_STS_LINK_CHANGE_))
+-              return IRQ_NONE;
+-
+-      phy_trigger_machine(phydev);
+-
+-      return IRQ_HANDLED;
+-}
+-
+ static int lan88xx_suspend(struct phy_device *phydev)
+ {
+       struct lan88xx_priv *priv = phydev->priv;
+@@ -388,8 +347,9 @@ static struct phy_driver microchip_phy_driver[] = {
+       .config_aneg    = lan88xx_config_aneg,
+       .link_change_notify = lan88xx_link_change_notify,
+-      .config_intr    = lan88xx_phy_config_intr,
+-      .handle_interrupt = lan88xx_handle_interrupt,
++      /* Interrupt handling is broken, do not define related
++       * functions to force polling.
++       */
+       .suspend        = lan88xx_suspend,
+       .resume         = genphy_resume,
+-- 
+2.39.5
+
diff --git a/queue-5.15/revert-drm-meson-vclk-fix-calculation-of-59.94-fract.patch b/queue-5.15/revert-drm-meson-vclk-fix-calculation-of-59.94-fract.patch
new file mode 100644 (file)
index 0000000..b71cdc9
--- /dev/null
@@ -0,0 +1,61 @@
+From fab9fd871d60ae99aae98d129645fdfcd3977a8c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Apr 2025 22:12:59 +0200
+Subject: Revert "drm/meson: vclk: fix calculation of 59.94 fractional rates"
+
+From: Christian Hewitt <christianshewitt@gmail.com>
+
+[ Upstream commit f37bb5486ea536c1d61df89feeaeff3f84f0b560 ]
+
+This reverts commit bfbc68e.
+
+The patch does permit the offending YUV420 @ 59.94 phy_freq and
+vclk_freq mode to match in calculations. It also results in all
+fractional rates being unavailable for use. This was unintended
+and requires the patch to be reverted.
+
+Fixes: bfbc68e4d869 ("drm/meson: vclk: fix calculation of 59.94 fractional rates")
+Cc: stable@vger.kernel.org
+Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
+Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://lore.kernel.org/r/20250421201300.778955-2-martin.blumenstingl@googlemail.com
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://lore.kernel.org/r/20250421201300.778955-2-martin.blumenstingl@googlemail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/meson/meson_vclk.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c
+index 2a942dc6a6dc2..2a82119eb58ed 100644
+--- a/drivers/gpu/drm/meson/meson_vclk.c
++++ b/drivers/gpu/drm/meson/meson_vclk.c
+@@ -790,13 +790,13 @@ meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq,
+                                FREQ_1000_1001(params[i].pixel_freq));
+               DRM_DEBUG_DRIVER("i = %d phy_freq = %d alt = %d\n",
+                                i, params[i].phy_freq,
+-                               FREQ_1000_1001(params[i].phy_freq/1000)*1000);
++                               FREQ_1000_1001(params[i].phy_freq/10)*10);
+               /* Match strict frequency */
+               if (phy_freq == params[i].phy_freq &&
+                   vclk_freq == params[i].vclk_freq)
+                       return MODE_OK;
+               /* Match 1000/1001 variant */
+-              if (phy_freq == (FREQ_1000_1001(params[i].phy_freq/1000)*1000) &&
++              if (phy_freq == (FREQ_1000_1001(params[i].phy_freq/10)*10) &&
+                   vclk_freq == FREQ_1000_1001(params[i].vclk_freq))
+                       return MODE_OK;
+       }
+@@ -1070,7 +1070,7 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
+       for (freq = 0 ; params[freq].pixel_freq ; ++freq) {
+               if ((phy_freq == params[freq].phy_freq ||
+-                   phy_freq == FREQ_1000_1001(params[freq].phy_freq/1000)*1000) &&
++                   phy_freq == FREQ_1000_1001(params[freq].phy_freq/10)*10) &&
+                   (vclk_freq == params[freq].vclk_freq ||
+                    vclk_freq == FREQ_1000_1001(params[freq].vclk_freq))) {
+                       if (vclk_freq != params[freq].vclk_freq)
+-- 
+2.39.5
+
diff --git a/queue-5.15/riscv-uprobes-add-missing-fence.i-after-building-the.patch b/queue-5.15/riscv-uprobes-add-missing-fence.i-after-building-the.patch
new file mode 100644 (file)
index 0000000..f1e4eda
--- /dev/null
@@ -0,0 +1,61 @@
+From de23949570352bbe4c66024ff9ce06e6f9199761 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 19 Apr 2025 13:14:00 +0200
+Subject: riscv: uprobes: Add missing fence.i after building the XOL buffer
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Björn Töpel <bjorn@rivosinc.com>
+
+[ Upstream commit 7d1d19a11cfbfd8bae1d89cc010b2cc397cd0c48 ]
+
+The XOL (execute out-of-line) buffer is used to single-step the
+replaced instruction(s) for uprobes. The RISC-V port was missing a
+proper fence.i (i$ flushing) after constructing the XOL buffer, which
+can result in incorrect execution of stale/broken instructions.
+
+This was found running the BPF selftests "test_progs:
+uprobe_autoattach, attach_probe" on the Spacemit K1/X60, where the
+uprobes tests randomly blew up.
+
+Reviewed-by: Guo Ren <guoren@kernel.org>
+Fixes: 74784081aac8 ("riscv: Add uprobes supported")
+Signed-off-by: Björn Töpel <bjorn@rivosinc.com>
+Link: https://lore.kernel.org/r/20250419111402.1660267-2-bjorn@kernel.org
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/probes/uprobes.c | 10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+diff --git a/arch/riscv/kernel/probes/uprobes.c b/arch/riscv/kernel/probes/uprobes.c
+index 194f166b2cc40..0d18ee53fd649 100644
+--- a/arch/riscv/kernel/probes/uprobes.c
++++ b/arch/riscv/kernel/probes/uprobes.c
+@@ -161,6 +161,7 @@ void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr,
+       /* Initialize the slot */
+       void *kaddr = kmap_atomic(page);
+       void *dst = kaddr + (vaddr & ~PAGE_MASK);
++      unsigned long start = (unsigned long)dst;
+       memcpy(dst, src, len);
+@@ -170,13 +171,6 @@ void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr,
+               *(uprobe_opcode_t *)dst = __BUG_INSN_32;
+       }
++      flush_icache_range(start, start + len);
+       kunmap_atomic(kaddr);
+-
+-      /*
+-       * We probably need flush_icache_user_page() but it needs vma.
+-       * This should work on most of architectures by default. If
+-       * architecture needs to do something different it can define
+-       * its own version of the function.
+-       */
+-      flush_dcache_page(page);
+ }
+-- 
+2.39.5
+
diff --git a/queue-5.15/serial-msm-configure-correct-working-mode-before-sta.patch b/queue-5.15/serial-msm-configure-correct-working-mode-before-sta.patch
new file mode 100644 (file)
index 0000000..f7dfdfe
--- /dev/null
@@ -0,0 +1,60 @@
+From 7ca7c5e6908c8a1e9ce3c1d33577705f99f017bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Apr 2025 19:22:47 +0200
+Subject: serial: msm: Configure correct working mode before starting earlycon
+
+From: Stephan Gerhold <stephan.gerhold@linaro.org>
+
+[ Upstream commit 7094832b5ac861b0bd7ed8866c93cb15ef619996 ]
+
+The MSM UART DM controller supports different working modes, e.g. DMA or
+the "single-character mode", where all reads/writes operate on a single
+character rather than 4 chars (32-bit) at once. When using earlycon,
+__msm_console_write() always writes 4 characters at a time, but we don't
+know which mode the bootloader was using and we don't set the mode either.
+
+This causes garbled output if the bootloader was using the single-character
+mode, because only every 4th character appears in the serial console, e.g.
+
+  "[ 00oni pi  000xf0[ 00i s 5rm9(l)l s 1  1 SPMTA 7:C 5[ 00A ade k d[
+   00ano:ameoi .Q1B[ 00ac _idaM00080oo'"
+
+If the bootloader was using the DMA ("DM") mode, output would likely fail
+entirely. Later, when the full serial driver probes, the port is
+re-initialized and output works as expected.
+
+Fix this also for earlycon by clearing the DMEN register and
+reset+re-enable the transmitter to apply the change. This ensures the
+transmitter is in the expected state before writing any output.
+
+Cc: stable <stable@kernel.org>
+Fixes: 0efe72963409 ("tty: serial: msm: Add earlycon support")
+Signed-off-by: Stephan Gerhold <stephan.gerhold@linaro.org>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Link: https://lore.kernel.org/r/20250408-msm-serial-earlycon-v1-1-429080127530@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/msm_serial.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
+index 03ff63438e772..9740bc301cc27 100644
+--- a/drivers/tty/serial/msm_serial.c
++++ b/drivers/tty/serial/msm_serial.c
+@@ -1732,6 +1732,12 @@ msm_serial_early_console_setup_dm(struct earlycon_device *device,
+       if (!device->port.membase)
+               return -ENODEV;
++      /* Disable DM / single-character modes */
++      msm_write(&device->port, 0, UARTDM_DMEN);
++      msm_write(&device->port, MSM_UART_CR_CMD_RESET_RX, MSM_UART_CR);
++      msm_write(&device->port, MSM_UART_CR_CMD_RESET_TX, MSM_UART_CR);
++      msm_write(&device->port, MSM_UART_CR_TX_ENABLE, MSM_UART_CR);
++
+       device->con->write = msm_serial_early_write_dm;
+       return 0;
+ }
+-- 
+2.39.5
+
index 036ebd52953ea57b2bcf5f5586acb9a1699e0361..537d35b987807beb38980f1c4b33a4890e11cb20 100644 (file)
@@ -42,3 +42,22 @@ net-hns3-defer-calling-ptp_clock_register.patch
 pci-imx6-skip-controller_id-generation-logic-for-i.mx7d.patch
 of-module-add-buffer-overflow-check-in-of_modalias.patch
 net-hns3-fix-deadlock-issue-when-externel_lb-and-reset-are-executed-together.patch
+firmware-arm_scmi-balance-device-refcount-when-destr.patch
+arm-dts-opos6ul-add-ksz8081-phy-properties.patch
+net-phy-microchip-force-irq-polling-mode-for-lan88xx.patch
+revert-drm-meson-vclk-fix-calculation-of-59.94-fract.patch
+irqchip-gic-v2m-add-const-to-of_device_id.patch
+irqchip-gic-v2m-mark-a-few-functions-__init.patch
+irqchip-gic-v2m-prevent-use-after-free-of-gicv2m_get.patch
+serial-msm-configure-correct-working-mode-before-sta.patch
+riscv-uprobes-add-missing-fence.i-after-building-the.patch
+cpufreq-intel_pstate-process-hwp-guaranteed-change-n.patch
+cpufreq-intel_pstate-update-cpuinfo.max_freq-on-hwp_.patch
+cpufreq-intel_pstate-revise-global-turbo-disable-che.patch
+cpufreq-intel_pstate-fold-intel_pstate_max_within_li.patch
+cpufreq-intel_pstate-do-not-update-global.turbo_disa.patch
+cpufreq-intel_pstate-unchecked-msr-aceess-in-legacy-.patch
+spi-tegra114-remove-unnecessary-null-pointer-checks.patch
+spi-tegra114-don-t-fail-set_cs_timing-when-delays-ar.patch
+iommu-arm-smmu-v3-use-the-new-rb-tree-helpers.patch
+iommu-arm-smmu-v3-fix-iommu_device_probe-bug-due-to-.patch
diff --git a/queue-5.15/spi-tegra114-don-t-fail-set_cs_timing-when-delays-ar.patch b/queue-5.15/spi-tegra114-don-t-fail-set_cs_timing-when-delays-ar.patch
new file mode 100644 (file)
index 0000000..e8228c5
--- /dev/null
@@ -0,0 +1,44 @@
+From 781aebf1222acd569312d0568eb700bcfaef90f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Apr 2025 21:03:03 -0500
+Subject: spi: tegra114: Don't fail set_cs_timing when delays are zero
+
+From: Aaron Kling <webgeek1234@gmail.com>
+
+[ Upstream commit 4426e6b4ecf632bb75d973051e1179b8bfac2320 ]
+
+The original code would skip null delay pointers, but when the pointers
+were converted to point within the spi_device struct, the check was not
+updated to skip delays of zero. Hence all spi devices that didn't set
+delays would fail to probe.
+
+Fixes: 04e6bb0d6bb1 ("spi: modify set_cs_timing parameter")
+Cc: stable@vger.kernel.org
+Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
+Link: https://patch.msgid.link/20250423-spi-tegra114-v1-1-2d608bcc12f9@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-tegra114.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c
+index b6f081227cbd4..af9ed52445fe6 100644
+--- a/drivers/spi/spi-tegra114.c
++++ b/drivers/spi/spi-tegra114.c
+@@ -729,9 +729,9 @@ static int tegra_spi_set_hw_cs_timing(struct spi_device *spi)
+       u32 inactive_cycles;
+       u8 cs_state;
+-      if (setup->unit != SPI_DELAY_UNIT_SCK ||
+-          hold->unit != SPI_DELAY_UNIT_SCK ||
+-          inactive->unit != SPI_DELAY_UNIT_SCK) {
++      if ((setup->unit && setup->unit != SPI_DELAY_UNIT_SCK) ||
++          (hold->unit && hold->unit != SPI_DELAY_UNIT_SCK) ||
++          (inactive->unit && inactive->unit != SPI_DELAY_UNIT_SCK)) {
+               dev_err(&spi->dev,
+                       "Invalid delay unit %d, should be SPI_DELAY_UNIT_SCK\n",
+                       SPI_DELAY_UNIT_SCK);
+-- 
+2.39.5
+
diff --git a/queue-5.15/spi-tegra114-remove-unnecessary-null-pointer-checks.patch b/queue-5.15/spi-tegra114-remove-unnecessary-null-pointer-checks.patch
new file mode 100644 (file)
index 0000000..c456c10
--- /dev/null
@@ -0,0 +1,74 @@
+From c47743b1dc5476f8cec47629183a425586b25a69 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Aug 2023 12:20:58 +0300
+Subject: spi: tegra114: Remove unnecessary NULL-pointer checks
+
+From: Alexander Danilenko <al.b.danilenko@gmail.com>
+
+[ Upstream commit 373c36bf7914e3198ac2654dede499f340c52950 ]
+
+cs_setup, cs_hold and cs_inactive points to fields of spi_device struct,
+so there is no sense in checking them for NULL.
+
+Found by Linux Verification Center (linuxtesting.org) with SVACE.
+
+Fixes: 04e6bb0d6bb1 ("spi: modify set_cs_timing parameter")
+Signed-off-by: Alexander Danilenko <al.b.danilenko@gmail.com>
+Link: https://lore.kernel.org/r/20230815092058.4083-1-al.b.danilenko@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 4426e6b4ecf6 ("spi: tegra114: Don't fail set_cs_timing when delays are zero")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-tegra114.c | 18 +++++++-----------
+ 1 file changed, 7 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c
+index 8f345247a8c32..b6f081227cbd4 100644
+--- a/drivers/spi/spi-tegra114.c
++++ b/drivers/spi/spi-tegra114.c
+@@ -723,27 +723,23 @@ static int tegra_spi_set_hw_cs_timing(struct spi_device *spi)
+       struct spi_delay *setup = &spi->cs_setup;
+       struct spi_delay *hold = &spi->cs_hold;
+       struct spi_delay *inactive = &spi->cs_inactive;
+-      u8 setup_dly, hold_dly, inactive_dly;
++      u8 setup_dly, hold_dly;
+       u32 setup_hold;
+       u32 spi_cs_timing;
+       u32 inactive_cycles;
+       u8 cs_state;
+-      if ((setup && setup->unit != SPI_DELAY_UNIT_SCK) ||
+-          (hold && hold->unit != SPI_DELAY_UNIT_SCK) ||
+-          (inactive && inactive->unit != SPI_DELAY_UNIT_SCK)) {
++      if (setup->unit != SPI_DELAY_UNIT_SCK ||
++          hold->unit != SPI_DELAY_UNIT_SCK ||
++          inactive->unit != SPI_DELAY_UNIT_SCK) {
+               dev_err(&spi->dev,
+                       "Invalid delay unit %d, should be SPI_DELAY_UNIT_SCK\n",
+                       SPI_DELAY_UNIT_SCK);
+               return -EINVAL;
+       }
+-      setup_dly = setup ? setup->value : 0;
+-      hold_dly = hold ? hold->value : 0;
+-      inactive_dly = inactive ? inactive->value : 0;
+-
+-      setup_dly = min_t(u8, setup_dly, MAX_SETUP_HOLD_CYCLES);
+-      hold_dly = min_t(u8, hold_dly, MAX_SETUP_HOLD_CYCLES);
++      setup_dly = min_t(u8, setup->value, MAX_SETUP_HOLD_CYCLES);
++      hold_dly = min_t(u8, hold->value, MAX_SETUP_HOLD_CYCLES);
+       if (setup_dly && hold_dly) {
+               setup_hold = SPI_SETUP_HOLD(setup_dly - 1, hold_dly - 1);
+               spi_cs_timing = SPI_CS_SETUP_HOLD(tspi->spi_cs_timing1,
+@@ -755,7 +751,7 @@ static int tegra_spi_set_hw_cs_timing(struct spi_device *spi)
+               }
+       }
+-      inactive_cycles = min_t(u8, inactive_dly, MAX_INACTIVE_CYCLES);
++      inactive_cycles = min_t(u8, inactive->value, MAX_INACTIVE_CYCLES);
+       if (inactive_cycles)
+               inactive_cycles--;
+       cs_state = inactive_cycles ? 0 : 1;
+-- 
+2.39.5
+