diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-01-15 09:46:08 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-01-15 09:46:12 -0500 |
commit | 5cd7376200be7b8bab085557ff5876b04bd84191 (patch) | |
tree | 7796adba26ea92b8b640d7db7c5f5096b07a50fb | |
parent | 49a93bc978b4b3d564f6b330179b4cc2724a031d (diff) |
fix: crash: IP: __bitmap_intersects+0x48/0x73
-tip testing found this crash:
> [ 35.258515] calling acpi_cpufreq_init+0x0/0x127 @ 1
> [ 35.264127] BUG: unable to handle kernel NULL pointer dereference at (null)
> [ 35.267554] IP: [<ffffffff80478092>] __bitmap_intersects+0x48/0x73
> [ 35.267554] PGD 0
> [ 35.267554] Oops: 0000 [#1] SMP DEBUG_PAGEALLOC
arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c is still broken: there's no
allocation of the variable mask, so we pass in an uninitialized cmd.mask
field to drv_read(), which then passes it to the scheduler which then
crashes ...
Switch it over to the much simpler constant-cpumask-pointers approach.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 13 |
1 files changed, 4 insertions, 9 deletions
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index 6f11e029e8c5..019276717a7f 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | |||
@@ -145,7 +145,7 @@ typedef union { | |||
145 | 145 | ||
146 | struct drv_cmd { | 146 | struct drv_cmd { |
147 | unsigned int type; | 147 | unsigned int type; |
148 | cpumask_var_t mask; | 148 | const struct cpumask *mask; |
149 | drv_addr_union addr; | 149 | drv_addr_union addr; |
150 | u32 val; | 150 | u32 val; |
151 | }; | 151 | }; |
@@ -235,8 +235,7 @@ static u32 get_cur_val(const struct cpumask *mask) | |||
235 | return 0; | 235 | return 0; |
236 | } | 236 | } |
237 | 237 | ||
238 | cpumask_copy(cmd.mask, mask); | 238 | cmd.mask = mask; |
239 | |||
240 | drv_read(&cmd); | 239 | drv_read(&cmd); |
241 | 240 | ||
242 | dprintk("get_cur_val = %u\n", cmd.val); | 241 | dprintk("get_cur_val = %u\n", cmd.val); |
@@ -403,9 +402,6 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, | |||
403 | return -ENODEV; | 402 | return -ENODEV; |
404 | } | 403 | } |
405 | 404 | ||
406 | if (unlikely(!alloc_cpumask_var(&cmd.mask, GFP_KERNEL))) | ||
407 | return -ENOMEM; | ||
408 | |||
409 | perf = data->acpi_data; | 405 | perf = data->acpi_data; |
410 | result = cpufreq_frequency_table_target(policy, | 406 | result = cpufreq_frequency_table_target(policy, |
411 | data->freq_table, | 407 | data->freq_table, |
@@ -450,9 +446,9 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, | |||
450 | 446 | ||
451 | /* cpufreq holds the hotplug lock, so we are safe from here on */ | 447 | /* cpufreq holds the hotplug lock, so we are safe from here on */ |
452 | if (policy->shared_type != CPUFREQ_SHARED_TYPE_ANY) | 448 | if (policy->shared_type != CPUFREQ_SHARED_TYPE_ANY) |
453 | cpumask_and(cmd.mask, cpu_online_mask, policy->cpus); | 449 | cmd.mask = policy->cpus; |
454 | else | 450 | else |
455 | cpumask_copy(cmd.mask, cpumask_of(policy->cpu)); | 451 | cmd.mask = cpumask_of(policy->cpu); |
456 | 452 | ||
457 | freqs.old = perf->states[perf->state].core_frequency * 1000; | 453 | freqs.old = perf->states[perf->state].core_frequency * 1000; |
458 | freqs.new = data->freq_table[next_state].frequency; | 454 | freqs.new = data->freq_table[next_state].frequency; |
@@ -479,7 +475,6 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, | |||
479 | perf->state = next_perf_state; | 475 | perf->state = next_perf_state; |
480 | 476 | ||
481 | out: | 477 | out: |
482 | free_cpumask_var(cmd.mask); | ||
483 | return result; | 478 | return result; |
484 | } | 479 | } |
485 | 480 | ||