aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-01-15 09:46:08 -0500
committerIngo Molnar <mingo@elte.hu>2009-01-15 09:46:12 -0500
commit5cd7376200be7b8bab085557ff5876b04bd84191 (patch)
tree7796adba26ea92b8b640d7db7c5f5096b07a50fb
parent49a93bc978b4b3d564f6b330179b4cc2724a031d (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.c13
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
146struct drv_cmd { 146struct 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
481out: 477out:
482 free_cpumask_var(cmd.mask);
483 return result; 478 return result;
484} 479}
485 480