Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bfa318ad authored by Ingo Molnar's avatar Ingo Molnar
Browse files

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: default avatarIngo Molnar <mingo@elte.hu>
parent 72859081
Loading
Loading
Loading
Loading
+4 −7
Original line number Original line Diff line number Diff line
@@ -145,7 +145,7 @@ typedef union {


struct drv_cmd {
struct drv_cmd {
	unsigned int type;
	unsigned int type;
	cpumask_var_t mask;
	const struct cpumask *mask;
	drv_addr_union addr;
	drv_addr_union addr;
	u32 val;
	u32 val;
};
};
@@ -231,6 +231,7 @@ static u32 get_cur_val(const struct cpumask *mask)
		return 0;
		return 0;
	}
	}


	cmd.mask = mask;
	drv_read(&cmd);
	drv_read(&cmd);


	dprintk("get_cur_val = %u\n", cmd.val);
	dprintk("get_cur_val = %u\n", cmd.val);
@@ -397,9 +398,6 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy,
		return -ENODEV;
		return -ENODEV;
	}
	}


	if (unlikely(!alloc_cpumask_var(&cmd.mask, GFP_KERNEL)))
		return -ENOMEM;

	perf = data->acpi_data;
	perf = data->acpi_data;
	result = cpufreq_frequency_table_target(policy,
	result = cpufreq_frequency_table_target(policy,
						data->freq_table,
						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 */
	/* cpufreq holds the hotplug lock, so we are safe from here on */
	if (policy->shared_type != CPUFREQ_SHARED_TYPE_ANY)
	if (policy->shared_type != CPUFREQ_SHARED_TYPE_ANY)
		cpumask_and(cmd.mask, cpu_online_mask, policy->cpus);
		cmd.mask = policy->cpus;
	else
	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.old = perf->states[perf->state].core_frequency * 1000;
	freqs.new = data->freq_table[next_state].frequency;
	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;
	perf->state = next_perf_state;


out:
out:
	free_cpumask_var(cmd.mask);
	return result;
	return result;
}
}