diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-01-15 09:46:08 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-01-19 18:17:01 -0500 |
commit | bfa318ad52a23f1e303d176b44366cdd2bb71ad2 (patch) | |
tree | bf58fe12825bfebdc02f1acce0cd79f246491e7b /arch/x86/kernel | |
parent | 72859081851af2bda04117ca3d64206ffa199e5e (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>
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 11 |
1 files changed, 4 insertions, 7 deletions
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index 5bf2c834a236..4b1c319d30c3 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 | }; |
@@ -231,6 +231,7 @@ static u32 get_cur_val(const struct cpumask *mask) | |||
231 | return 0; | 231 | return 0; |
232 | } | 232 | } |
233 | 233 | ||
234 | cmd.mask = mask; | ||
234 | drv_read(&cmd); | 235 | drv_read(&cmd); |
235 | 236 | ||
236 | dprintk("get_cur_val = %u\n", cmd.val); | 237 | dprintk("get_cur_val = %u\n", cmd.val); |
@@ -397,9 +398,6 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, | |||
397 | return -ENODEV; | 398 | return -ENODEV; |
398 | } | 399 | } |
399 | 400 | ||
400 | if (unlikely(!alloc_cpumask_var(&cmd.mask, GFP_KERNEL))) | ||
401 | return -ENOMEM; | ||
402 | |||
403 | perf = data->acpi_data; | 401 | perf = data->acpi_data; |
404 | result = cpufreq_frequency_table_target(policy, | 402 | result = cpufreq_frequency_table_target(policy, |
405 | data->freq_table, | 403 | data->freq_table, |
@@ -444,9 +442,9 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, | |||
444 | 442 | ||
445 | /* cpufreq holds the hotplug lock, so we are safe from here on */ | 443 | /* cpufreq holds the hotplug lock, so we are safe from here on */ |
446 | if (policy->shared_type != CPUFREQ_SHARED_TYPE_ANY) | 444 | if (policy->shared_type != CPUFREQ_SHARED_TYPE_ANY) |
447 | cpumask_and(cmd.mask, cpu_online_mask, policy->cpus); | 445 | cmd.mask = policy->cpus; |
448 | else | 446 | else |
449 | cpumask_copy(cmd.mask, cpumask_of(policy->cpu)); | 447 | cmd.mask = cpumask_of(policy->cpu); |
450 | 448 | ||
451 | freqs.old = perf->states[perf->state].core_frequency * 1000; | 449 | freqs.old = perf->states[perf->state].core_frequency * 1000; |
452 | freqs.new = data->freq_table[next_state].frequency; | 450 | freqs.new = data->freq_table[next_state].frequency; |
@@ -473,7 +471,6 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, | |||
473 | perf->state = next_perf_state; | 471 | perf->state = next_perf_state; |
474 | 472 | ||
475 | out: | 473 | out: |
476 | free_cpumask_var(cmd.mask); | ||
477 | return result; | 474 | return result; |
478 | } | 475 | } |
479 | 476 | ||