summaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/cpufreq
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-01-15 15:46:08 +0100
committerIngo Molnar <mingo@elte.hu>2009-01-20 00:17:01 +0100
commitbfa318ad52a23f1e303d176b44366cdd2bb71ad2 (patch)
treebf58fe12825bfebdc02f1acce0cd79f246491e7b /arch/x86/kernel/cpu/cpufreq
parentcpufreq: use work_on_cpu in acpi-cpufreq.c for drv_read and drv_write (diff)
downloadlinux-bfa318ad52a23f1e303d176b44366cdd2bb71ad2.tar.xz
linux-bfa318ad52a23f1e303d176b44366cdd2bb71ad2.zip
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/cpu/cpufreq')
-rw-r--r--arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c11
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 {
struct drv_cmd {
unsigned int type;
- cpumask_var_t mask;
+ const struct cpumask *mask;
drv_addr_union addr;
u32 val;
};
@@ -231,6 +231,7 @@ static u32 get_cur_val(const struct cpumask *mask)
return 0;
}
+ cmd.mask = mask;
drv_read(&cmd);
dprintk("get_cur_val = %u\n", cmd.val);
@@ -397,9 +398,6 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy,
return -ENODEV;
}
- if (unlikely(!alloc_cpumask_var(&cmd.mask, GFP_KERNEL)))
- return -ENOMEM;
-
perf = data->acpi_data;
result = cpufreq_frequency_table_target(policy,
data->freq_table,
@@ -444,9 +442,9 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy,
/* cpufreq holds the hotplug lock, so we are safe from here on */
if (policy->shared_type != CPUFREQ_SHARED_TYPE_ANY)
- cpumask_and(cmd.mask, cpu_online_mask, policy->cpus);
+ cmd.mask = policy->cpus;
else
- cpumask_copy(cmd.mask, cpumask_of(policy->cpu));
+ cmd.mask = cpumask_of(policy->cpu);
freqs.old = perf->states[perf->state].core_frequency * 1000;
freqs.new = data->freq_table[next_state].frequency;
@@ -473,7 +471,6 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy,
perf->state = next_perf_state;
out:
- free_cpumask_var(cmd.mask);
return result;
}