* [PATCH 0/2] thermal/drivers/qcom/tsens: Drop __init from the ->init callbacks
@ 2026-11-04 14:57 Christian Schmidbauer
2026-11-04 14:57 ` [PATCH 1/2] thermal/drivers/qcom/tsens: Drop __init from init_common() Christian Schmidbauer
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Christian Schmidbauer @ 2026-11-04 14:57 UTC (permalink / raw)
To: Amit Kucheria, Thara Gopinath, Rafael J. Wysocki, Daniel Lezcano
Cc: Zhang Rui, Lukasz Luba, Dmitry Baryshkov, Konrad Dybcio,
AngeloGioacchino Del Regno, linux-pm, linux-arm-msm,
linux-kernel, Christian Schmidbauer
Every function that tsens_probe() calls through priv->ops->init() is
marked __init, so a probe after free_initmem() jumps into freed memory.
On IPQ8064 with CONFIG_IPQ_LCC_806X disabled, fw_devlink defers the
probe of gcc and its tsens child until the deferred probe timeout,
which expires after init memory is freed. On an Aruba AP-325 the probe
then crashes in init_common(). With CONFIG_QCOM_TSENS=m the driver has
the same problem once the module's init function has returned.
Patch 1 drops __init from init_common() in a one-line change that
applies to every stable tree. Patch 2 drops it from the eight per-SoC
callbacks.
Patch 1 was tested on an Aruba AP-325 on a v7.2-rc7 based tree.
Not tested:
- Patch 2 on hardware. None of msm8226, msm8909, msm8939, msm8952,
msm8956, mdm9607, ipq5018, ipq5332 or ipq5424 was available, so patch
2 is only compile-tested.
- CONFIG_QCOM_TSENS=m on hardware.
Christian Schmidbauer (2):
thermal/drivers/qcom/tsens: Drop __init from init_common()
thermal/drivers/qcom/tsens: Drop __init from the per-SoC ->init
callbacks
drivers/thermal/qcom/tsens-v0_1.c | 9 +++++----
drivers/thermal/qcom/tsens-v1.c | 7 ++++---
drivers/thermal/qcom/tsens-v2.c | 2 +-
drivers/thermal/qcom/tsens.c | 2 +-
4 files changed, 11 insertions(+), 9 deletions(-)
base-commit: 2dc1f296b5754dd2441fc8b6613a362a47f6b98f
--
2.54.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2] thermal/drivers/qcom/tsens: Drop __init from init_common()
2026-11-04 14:57 [PATCH 0/2] thermal/drivers/qcom/tsens: Drop __init from the ->init callbacks Christian Schmidbauer
@ 2026-11-04 14:57 ` Christian Schmidbauer
2026-11-04 14:57 ` [PATCH 2/2] thermal/drivers/qcom/tsens: Drop __init from the per-SoC ->init callbacks Christian Schmidbauer
2026-11-04 15:33 ` [PATCH 0/2] thermal/drivers/qcom/tsens: Drop __init from the " Daniel Lezcano
2 siblings, 0 replies; 4+ messages in thread
From: Christian Schmidbauer @ 2026-11-04 14:57 UTC (permalink / raw)
To: Amit Kucheria, Thara Gopinath, Rafael J. Wysocki, Daniel Lezcano
Cc: Zhang Rui, Lukasz Luba, Dmitry Baryshkov, Konrad Dybcio,
AngeloGioacchino Del Regno, linux-pm, linux-arm-msm,
linux-kernel, Christian Schmidbauer
Several tsens_ops instances store init_common() as their ->init
callback, which tsens_probe() calls through priv->ops->init().
init_common() is marked __init, but tsens_probe() is a normal platform
driver probe and can run after free_initmem().
This happens on IPQ8064 when CONFIG_IPQ_LCC_806X is disabled. In
qcom-ipq8064.dtsi the tsens node is a child of gcc, which uses a clock
from the LCC. Because no driver binds the LCC, fw_devlink defers the
probe of gcc until deferred_probe_timeout_work_func() runs.
deferred_probe_initcall() schedules that work to run
CONFIG_DRIVER_DEFERRED_PROBE_TIMEOUT seconds later, when kernel_init()
has already freed init memory. On an Aruba AP-325 the probe then
crashes:
Unable to handle kernel execution of memory at virtual address c0e1ffe0
Workqueue: events_unbound deferred_probe_work_func
PC is at init_common+0x0/0x540
LR is at tsens_probe+0x138/0x4b4
With CONFIG_QCOM_TSENS=m the driver has the same problem, because the
module loader frees __init code once the module's init function returns
and a later bind then calls into freed memory.
Removing __init from init_common() covers the ops that store it
directly, but the per-SoC init functions that wrap it are also marked
__init and need the same change.
Tested on an Aruba AP-325.
Fixes: 9066073c6c27 ("thermal: qcom: tsens: Add a skeletal TSENS drivers")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5
Signed-off-by: Christian Schmidbauer <opensource@grische.xyz>
---
drivers/thermal/qcom/tsens.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c
index 4d7013fc79d6..710c78aff8bc 100644
--- a/drivers/thermal/qcom/tsens.c
+++ b/drivers/thermal/qcom/tsens.c
@@ -929,7 +929,7 @@ static const struct regmap_config tsens_srot_config = {
.reg_stride = 4,
};
-int __init init_common(struct tsens_priv *priv)
+int init_common(struct tsens_priv *priv)
{
void __iomem *tm_base, *srot_base;
struct device *dev = priv->dev;
--
2.54.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 2/2] thermal/drivers/qcom/tsens: Drop __init from the per-SoC ->init callbacks
2026-11-04 14:57 [PATCH 0/2] thermal/drivers/qcom/tsens: Drop __init from the ->init callbacks Christian Schmidbauer
2026-11-04 14:57 ` [PATCH 1/2] thermal/drivers/qcom/tsens: Drop __init from init_common() Christian Schmidbauer
@ 2026-11-04 14:57 ` Christian Schmidbauer
2026-11-04 15:33 ` [PATCH 0/2] thermal/drivers/qcom/tsens: Drop __init from the " Daniel Lezcano
2 siblings, 0 replies; 4+ messages in thread
From: Christian Schmidbauer @ 2026-11-04 14:57 UTC (permalink / raw)
To: Amit Kucheria, Thara Gopinath, Rafael J. Wysocki, Daniel Lezcano
Cc: Zhang Rui, Lukasz Luba, Dmitry Baryshkov, Konrad Dybcio,
AngeloGioacchino Del Regno, linux-pm, linux-arm-msm,
linux-kernel, Christian Schmidbauer
init_8226(), init_8909(), init_8939(), init_8952(), init_8956(),
init_9607(), init_tsens_v1_no_rpm() and init_tsens_v2_no_rpm() are
marked __init, but tsens_probe() calls them through priv->ops->init()
and can run after free_initmem(). The call then jumps into memory that
is no longer mapped executable, and the kernel oopses.
The probe runs that late when fw_devlink defers it until the deferred
probe timeout.
Fixes: a7d3006be5ca ("thermal/drivers/tsens: Sort out msm8976 vs msm8956 data")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Christian Schmidbauer <opensource@grische.xyz>
---
drivers/thermal/qcom/tsens-v0_1.c | 9 +++++----
drivers/thermal/qcom/tsens-v1.c | 7 ++++---
drivers/thermal/qcom/tsens-v2.c | 2 +-
3 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c
index 32d2d3e33287..a13897632b91 100644
--- a/drivers/thermal/qcom/tsens-v0_1.c
+++ b/drivers/thermal/qcom/tsens-v0_1.c
@@ -207,7 +207,7 @@ static int calibrate_8974(struct tsens_priv *priv)
return 0;
}
-static int __init init_8226(struct tsens_priv *priv)
+static int init_8226(struct tsens_priv *priv)
{
priv->sensor[0].slope = 2901;
priv->sensor[1].slope = 2846;
@@ -219,7 +219,7 @@ static int __init init_8226(struct tsens_priv *priv)
return init_common(priv);
}
-static int __init init_8909(struct tsens_priv *priv)
+static int init_8909(struct tsens_priv *priv)
{
int i;
@@ -240,7 +240,8 @@ static int __init init_8909(struct tsens_priv *priv)
return init_common(priv);
}
-static int __init init_8939(struct tsens_priv *priv) {
+static int init_8939(struct tsens_priv *priv)
+{
priv->sensor[0].slope = 2911;
priv->sensor[1].slope = 2789;
priv->sensor[2].slope = 2906;
@@ -255,7 +256,7 @@ static int __init init_8939(struct tsens_priv *priv) {
return init_common(priv);
}
-static int __init init_9607(struct tsens_priv *priv)
+static int init_9607(struct tsens_priv *priv)
{
int i;
diff --git a/drivers/thermal/qcom/tsens-v1.c b/drivers/thermal/qcom/tsens-v1.c
index 7bda8e6087c4..ed0064f4e1ae 100644
--- a/drivers/thermal/qcom/tsens-v1.c
+++ b/drivers/thermal/qcom/tsens-v1.c
@@ -145,7 +145,7 @@ static const struct reg_field tsens_v1_regfields[MAX_REGFIELDS] = {
[TRDY] = REG_FIELD(TM_TRDY_OFF, 0, 0),
};
-static int __init init_8952(struct tsens_priv *priv)
+static int init_8952(struct tsens_priv *priv)
{
priv->sensor[0].p1_calib_offset = 2;
priv->sensor[0].p2_calib_offset = -1;
@@ -173,7 +173,8 @@ static int __init init_8952(struct tsens_priv *priv)
return init_common(priv);
}
-static int __init init_8956(struct tsens_priv *priv) {
+static int init_8956(struct tsens_priv *priv)
+{
priv->sensor[0].slope = 3313;
priv->sensor[1].slope = 3275;
priv->sensor[2].slope = 3320;
@@ -189,7 +190,7 @@ static int __init init_8956(struct tsens_priv *priv) {
return init_common(priv);
}
-static int __init init_tsens_v1_no_rpm(struct tsens_priv *priv)
+static int init_tsens_v1_no_rpm(struct tsens_priv *priv)
{
int i, ret;
u32 mask = 0;
diff --git a/drivers/thermal/qcom/tsens-v2.c b/drivers/thermal/qcom/tsens-v2.c
index 843dd29fad2e..22284973bb61 100644
--- a/drivers/thermal/qcom/tsens-v2.c
+++ b/drivers/thermal/qcom/tsens-v2.c
@@ -220,7 +220,7 @@ static int tsens_v2_calibration(struct tsens_priv *priv)
return 0;
}
-static int __init init_tsens_v2_no_rpm(struct tsens_priv *priv)
+static int init_tsens_v2_no_rpm(struct tsens_priv *priv)
{
struct device *dev = priv->dev;
int i, ret;
--
2.54.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 0/2] thermal/drivers/qcom/tsens: Drop __init from the ->init callbacks
2026-11-04 14:57 [PATCH 0/2] thermal/drivers/qcom/tsens: Drop __init from the ->init callbacks Christian Schmidbauer
2026-11-04 14:57 ` [PATCH 1/2] thermal/drivers/qcom/tsens: Drop __init from init_common() Christian Schmidbauer
2026-11-04 14:57 ` [PATCH 2/2] thermal/drivers/qcom/tsens: Drop __init from the per-SoC ->init callbacks Christian Schmidbauer
@ 2026-11-04 15:33 ` Daniel Lezcano
2 siblings, 0 replies; 4+ messages in thread
From: Daniel Lezcano @ 2026-11-04 15:33 UTC (permalink / raw)
To: Christian Schmidbauer, Amit Kucheria, Thara Gopinath,
Rafael J. Wysocki, Daniel Lezcano
Cc: Zhang Rui, Lukasz Luba, Dmitry Baryshkov, Konrad Dybcio,
AngeloGioacchino Del Regno, linux-pm, linux-arm-msm,
linux-kernel
Hi Christian,
I don't see the patches along with the cover letter
On 11/4/26 15:57, Christian Schmidbauer wrote:
> Every function that tsens_probe() calls through priv->ops->init() is
> marked __init, so a probe after free_initmem() jumps into freed memory.
> On IPQ8064 with CONFIG_IPQ_LCC_806X disabled, fw_devlink defers the
> probe of gcc and its tsens child until the deferred probe timeout,
> which expires after init memory is freed. On an Aruba AP-325 the probe
> then crashes in init_common(). With CONFIG_QCOM_TSENS=m the driver has
> the same problem once the module's init function has returned.
>
> Patch 1 drops __init from init_common() in a one-line change that
> applies to every stable tree. Patch 2 drops it from the eight per-SoC
> callbacks.
>
> Patch 1 was tested on an Aruba AP-325 on a v7.2-rc7 based tree.
>
> Not tested:
> - Patch 2 on hardware. None of msm8226, msm8909, msm8939, msm8952,
> msm8956, mdm9607, ipq5018, ipq5332 or ipq5424 was available, so patch
> 2 is only compile-tested.
> - CONFIG_QCOM_TSENS=m on hardware.
>
> Christian Schmidbauer (2):
> thermal/drivers/qcom/tsens: Drop __init from init_common()
> thermal/drivers/qcom/tsens: Drop __init from the per-SoC ->init
> callbacks
>
> drivers/thermal/qcom/tsens-v0_1.c | 9 +++++----
> drivers/thermal/qcom/tsens-v1.c | 7 ++++---
> drivers/thermal/qcom/tsens-v2.c | 2 +-
> drivers/thermal/qcom/tsens.c | 2 +-
> 4 files changed, 11 insertions(+), 9 deletions(-)
>
>
> base-commit: 2dc1f296b5754dd2441fc8b6613a362a47f6b98f
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-11-04 15:33 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-04 14:57 [PATCH 0/2] thermal/drivers/qcom/tsens: Drop __init from the ->init callbacks Christian Schmidbauer
2026-11-04 14:57 ` [PATCH 1/2] thermal/drivers/qcom/tsens: Drop __init from init_common() Christian Schmidbauer
2026-11-04 14:57 ` [PATCH 2/2] thermal/drivers/qcom/tsens: Drop __init from the per-SoC ->init callbacks Christian Schmidbauer
2026-11-04 15:33 ` [PATCH 0/2] thermal/drivers/qcom/tsens: Drop __init from the " Daniel Lezcano
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®