* [PATCH] cpufreq: acpi-cpufreq: add NULL check for acpi_perf_data before freeing
@ 2026-08-10 6:10 lirongqing
2026-08-10 6:10 ` [PATCH] cpufreq: acpi-cpufreq: Initialize cmd.val in drv_read() lirongqing
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: lirongqing @ 2026-08-10 6:10 UTC (permalink / raw)
To: Rafael J . Wysocki, Viresh Kumar, linux-pm; +Cc: Li RongQing
From: Li RongQing <lirongqing@baidu.com>
If alloc_percpu() fails in acpi_cpufreq_early_init(), acpi_perf_data is
NULL. Calling free_acpi_perf_data() will execute per_cpu_ptr(NULL, i),
which does not return NULL but an offset pointer.
Dereferencing ->shared_cpu_map on this invalid pointer leads to a kernel
crash.
Fix these issues by adding a NULL check at the start of
free_acpi_perf_data() and setting acpi_perf_data to NULL after freeing.
Signed-off-by: Li RongQing <lirongqing@baidu.com>
---
drivers/cpufreq/acpi-cpufreq.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
index 87e4923..cd2ca87 100644
--- a/drivers/cpufreq/acpi-cpufreq.c
+++ b/drivers/cpufreq/acpi-cpufreq.c
@@ -517,11 +517,14 @@ static void free_acpi_perf_data(void)
{
unsigned int i;
- /* Freeing a NULL pointer is OK, and alloc_percpu zeroes. */
+ if (!acpi_perf_data)
+ return;
+
for_each_possible_cpu(i)
free_cpumask_var(per_cpu_ptr(acpi_perf_data, i)
->shared_cpu_map);
free_percpu(acpi_perf_data);
+ acpi_perf_data = NULL;
}
static int cpufreq_boost_down_prep(unsigned int cpu)
--
2.9.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH] cpufreq: acpi-cpufreq: Initialize cmd.val in drv_read()
2026-08-10 6:10 [PATCH] cpufreq: acpi-cpufreq: add NULL check for acpi_perf_data before freeing lirongqing
@ 2026-08-10 6:10 ` lirongqing
2026-08-10 12:15 ` Zhongqiu Han
2026-08-10 6:10 ` [PATCH] cpufreq: acpi-cpufreq: Using cpufreq_for_each_entry() to iterate in extract_io() lirongqing
2026-08-10 11:21 ` [PATCH] cpufreq: acpi-cpufreq: add NULL check for acpi_perf_data before freeing Zhongqiu Han
2 siblings, 1 reply; 6+ messages in thread
From: lirongqing @ 2026-08-10 6:10 UTC (permalink / raw)
To: Rafael J . Wysocki, Viresh Kumar, linux-pm; +Cc: Li RongQing
From: Li RongQing <lirongqing@baidu.com>
In drv_read(), struct drv_cmd cmd is allocated on the stack with .val left
uninitialized. If smp_call_function_any() fails, do_drv_read() will not
run to populate cmd.val. As a result, drv_read() would return uninitialized
stack data.
Fix this by explicitly initializing .val to 0 when declaring cmd.
Signed-off-by: Li RongQing <lirongqing@baidu.com>
---
drivers/cpufreq/acpi-cpufreq.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
index cd2ca87..6c7ece9 100644
--- a/drivers/cpufreq/acpi-cpufreq.c
+++ b/drivers/cpufreq/acpi-cpufreq.c
@@ -308,6 +308,7 @@ static u32 drv_read(struct acpi_cpufreq_data *data, const struct cpumask *mask)
struct acpi_processor_performance *perf = to_perf_data(data);
struct drv_cmd cmd = {
.reg = &perf->control_register,
+ .val = 0,
.func.read = data->cpu_freq_read,
};
int err;
--
2.9.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH] cpufreq: acpi-cpufreq: Using cpufreq_for_each_entry() to iterate in extract_io()
2026-08-10 6:10 [PATCH] cpufreq: acpi-cpufreq: add NULL check for acpi_perf_data before freeing lirongqing
2026-08-10 6:10 ` [PATCH] cpufreq: acpi-cpufreq: Initialize cmd.val in drv_read() lirongqing
@ 2026-08-10 6:10 ` lirongqing
2026-08-10 11:21 ` [PATCH] cpufreq: acpi-cpufreq: add NULL check for acpi_perf_data before freeing Zhongqiu Han
2 siblings, 0 replies; 6+ messages in thread
From: lirongqing @ 2026-08-10 6:10 UTC (permalink / raw)
To: Rafael J . Wysocki, Viresh Kumar, linux-pm; +Cc: Li RongQing
From: Li RongQing <lirongqing@baidu.com>
In extract_io(), the loop iterates up to perf->state_count. However,
when building policy->freq_table in acpi_cpufreq_cpu_init(), duplicate
frequency entries are skipped, making freq_table smaller than
perf->state_count.
Iterating perf->state_count times directly over policy->freq_table[i] can
result in out-of-bounds array reads. Furthermore, policy->freq_table[i]
does not necessarily correspond to perf->states[i], as the original P-state
index is stored in freq_table[entry].driver_data.
Fix this by using cpufreq_for_each_entry() to iterate over
policy->freq_table, similar to extract_msr().
Signed-off-by: Li RongQing <lirongqing@baidu.com>
---
drivers/cpufreq/acpi-cpufreq.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
index 21639d9..87e4923 100644
--- a/drivers/cpufreq/acpi-cpufreq.c
+++ b/drivers/cpufreq/acpi-cpufreq.c
@@ -196,15 +196,14 @@ static int check_amd_hwpstate_cpu(unsigned int cpuid)
static unsigned extract_io(struct cpufreq_policy *policy, u32 value)
{
struct acpi_cpufreq_data *data = policy->driver_data;
+ struct cpufreq_frequency_table *pos;
struct acpi_processor_performance *perf;
- int i;
perf = to_perf_data(data);
- for (i = 0; i < perf->state_count; i++) {
- if (value == perf->states[i].status)
- return policy->freq_table[i].frequency;
- }
+ cpufreq_for_each_entry(pos, policy->freq_table)
+ if (value == perf->states[pos->driver_data].status)
+ return pos->frequency;
return 0;
}
--
2.9.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] cpufreq: acpi-cpufreq: add NULL check for acpi_perf_data before freeing
2026-08-10 6:10 [PATCH] cpufreq: acpi-cpufreq: add NULL check for acpi_perf_data before freeing lirongqing
2026-08-10 6:10 ` [PATCH] cpufreq: acpi-cpufreq: Initialize cmd.val in drv_read() lirongqing
2026-08-10 6:10 ` [PATCH] cpufreq: acpi-cpufreq: Using cpufreq_for_each_entry() to iterate in extract_io() lirongqing
@ 2026-08-10 11:21 ` Zhongqiu Han
2026-08-10 11:52 ` Zhongqiu Han
2 siblings, 1 reply; 6+ messages in thread
From: Zhongqiu Han @ 2026-08-10 11:21 UTC (permalink / raw)
To: lirongqing, Rafael J . Wysocki, Viresh Kumar, linux-pm; +Cc: zhongqiu.han
On 8/10/2026 2:10 PM, lirongqing wrote:
> From: Li RongQing <lirongqing@baidu.com>
>
> If alloc_percpu() fails in acpi_cpufreq_early_init(), acpi_perf_data is
> NULL. Calling free_acpi_perf_data() will execute per_cpu_ptr(NULL, i),
> which does not return NULL but an offset pointer.
Hi RongQing,
Could you please confirm if acpi_perf_data() can ever be executed when
alloc_percpu() fails?
> Dereferencing ->shared_cpu_map on this invalid pointer leads to a kernel
> crash.
>
> Fix these issues by adding a NULL check at the start of
> free_acpi_perf_data() and setting acpi_perf_data to NULL after freeing.
>
> Signed-off-by: Li RongQing <lirongqing@baidu.com>
> ---
> drivers/cpufreq/acpi-cpufreq.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
> index 87e4923..cd2ca87 100644
> --- a/drivers/cpufreq/acpi-cpufreq.c
> +++ b/drivers/cpufreq/acpi-cpufreq.c
> @@ -517,11 +517,14 @@ static void free_acpi_perf_data(void)
> {
> unsigned int i;
>
> - /* Freeing a NULL pointer is OK, and alloc_percpu zeroes. */
> + if (!acpi_perf_data)
> + return;
> +
> for_each_possible_cpu(i)
> free_cpumask_var(per_cpu_ptr(acpi_perf_data, i)
> ->shared_cpu_map);
> free_percpu(acpi_perf_data);
> + acpi_perf_data = NULL;
> }
>
> static int cpufreq_boost_down_prep(unsigned int cpu)
--
Thx and BRs,
Zhongqiu Han
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] cpufreq: acpi-cpufreq: add NULL check for acpi_perf_data before freeing
2026-08-10 11:21 ` [PATCH] cpufreq: acpi-cpufreq: add NULL check for acpi_perf_data before freeing Zhongqiu Han
@ 2026-08-10 11:52 ` Zhongqiu Han
0 siblings, 0 replies; 6+ messages in thread
From: Zhongqiu Han @ 2026-08-10 11:52 UTC (permalink / raw)
To: lirongqing, Rafael J . Wysocki, Viresh Kumar, linux-pm; +Cc: zhongqiu.han
On 8/10/2026 7:21 PM, Zhongqiu Han wrote:
> On 8/10/2026 2:10 PM, lirongqing wrote:
>> From: Li RongQing <lirongqing@baidu.com>
>>
>> If alloc_percpu() fails in acpi_cpufreq_early_init(), acpi_perf_data is
>> NULL. Calling free_acpi_perf_data() will execute per_cpu_ptr(NULL, i),
>> which does not return NULL but an offset pointer.
>
> Hi RongQing,
>
> Could you please confirm if acpi_perf_data() can ever be executed when
> alloc_percpu() fails?
Sorry, typo: acpi_perf_data() --> free_acpi_perf_data()
>
>
>> Dereferencing ->shared_cpu_map on this invalid pointer leads to a kernel
>> crash.
>>
>> Fix these issues by adding a NULL check at the start of
>> free_acpi_perf_data() and setting acpi_perf_data to NULL after freeing.
>>
>> Signed-off-by: Li RongQing <lirongqing@baidu.com>
>> ---
>> drivers/cpufreq/acpi-cpufreq.c | 5 ++++-
>> 1 file changed, 4 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-
>> cpufreq.c
>> index 87e4923..cd2ca87 100644
>> --- a/drivers/cpufreq/acpi-cpufreq.c
>> +++ b/drivers/cpufreq/acpi-cpufreq.c
>> @@ -517,11 +517,14 @@ static void free_acpi_perf_data(void)
>> {
>> unsigned int i;
>> - /* Freeing a NULL pointer is OK, and alloc_percpu zeroes. */
>> + if (!acpi_perf_data)
>> + return;
>> +
>> for_each_possible_cpu(i)
>> free_cpumask_var(per_cpu_ptr(acpi_perf_data, i)
>> ->shared_cpu_map);
>> free_percpu(acpi_perf_data);
>> + acpi_perf_data = NULL;
>> }
>> static int cpufreq_boost_down_prep(unsigned int cpu)
>
>
--
Thx and BRs,
Zhongqiu Han
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] cpufreq: acpi-cpufreq: Initialize cmd.val in drv_read()
2026-08-10 6:10 ` [PATCH] cpufreq: acpi-cpufreq: Initialize cmd.val in drv_read() lirongqing
@ 2026-08-10 12:15 ` Zhongqiu Han
0 siblings, 0 replies; 6+ messages in thread
From: Zhongqiu Han @ 2026-08-10 12:15 UTC (permalink / raw)
To: lirongqing, Rafael J . Wysocki, Viresh Kumar, linux-pm; +Cc: zhongqiu.han
On 8/10/2026 2:10 PM, lirongqing wrote:
> From: Li RongQing <lirongqing@baidu.com>
>
> In drv_read(), struct drv_cmd cmd is allocated on the stack with .val left
> uninitialized. If smp_call_function_any() fails, do_drv_read() will not
> run to populate cmd.val. As a result, drv_read() would return uninitialized
> stack data.
>
> Fix this by explicitly initializing .val to 0 when declaring cmd.
>
> Signed-off-by: Li RongQing <lirongqing@baidu.com>
> ---
> drivers/cpufreq/acpi-cpufreq.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
> index cd2ca87..6c7ece9 100644
> --- a/drivers/cpufreq/acpi-cpufreq.c
> +++ b/drivers/cpufreq/acpi-cpufreq.c
> @@ -308,6 +308,7 @@ static u32 drv_read(struct acpi_cpufreq_data *data, const struct cpumask *mask)
> struct acpi_processor_performance *perf = to_perf_data(data);
> struct drv_cmd cmd = {
> .reg = &perf->control_register,
> + .val = 0,
Will the compiler handle this automatically?
https://en.cppreference.com/c/language/initialization
> .func.read = data->cpu_freq_read,
> };
> int err;
--
Thx and BRs,
Zhongqiu Han
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-08-10 12:15 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-10 6:10 [PATCH] cpufreq: acpi-cpufreq: add NULL check for acpi_perf_data before freeing lirongqing
2026-08-10 6:10 ` [PATCH] cpufreq: acpi-cpufreq: Initialize cmd.val in drv_read() lirongqing
2026-08-10 12:15 ` Zhongqiu Han
2026-08-10 6:10 ` [PATCH] cpufreq: acpi-cpufreq: Using cpufreq_for_each_entry() to iterate in extract_io() lirongqing
2026-08-10 11:21 ` [PATCH] cpufreq: acpi-cpufreq: add NULL check for acpi_perf_data before freeing Zhongqiu Han
2026-08-10 11:52 ` Zhongqiu Han
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox