linux/drivers/cpufreq
Konrad Rzeszutek Wilk 46a310b80b [CPUFREQ] Don't set stat->last_index to -1 if the pol->cur has incorrect value.
If the driver submitted an non-existing pol>cur value (say it
used the default initialized value of zero), when the cpufreq
stats tries to setup its initial values it incorrectly sets
stat->last_index to -1 (or 0xfffff...). And cpufreq_stats_update
tries to update at that index location and fails.

This can be caused by:

stat->last_index = freq_table_get_index(stat, policy->cur);

not finding the appropiate frequency in the table (b/c the policy->cur
is wrong) and we end up crashing. The fix however is
concentrated in the 'cpufreq_stats_update' as the last_index
(and old_index) are updated there. Which means it can reset
the last_index to -1 again and on the next iteration cause a crash.

Without this patch, the following crash is observed:

powernow-k8: Found 1 AMD Athlon(tm) 64 Processor 3700+ (1 cpu cores) (version 2.20.00)
powernow-k8: fid 0x2 (1000 MHz), vid 0x12
powernow-k8: fid 0xa (1800 MHz), vid 0xa
powernow-k8: fid 0xc (2000 MHz), vid 0x8
powernow-k8: fid 0xe (2200 MHz), vid 0x8
Marking TSC unstable due to cpufreq changes
powernow-k8: fid trans failed, fid 0x2, curr 0x0
BUG: unable to handle kernel paging request at ffff880807e07b78
IP: [<ffffffff81479163>] cpufreq_stats_update+0x46/0x5b
.. snip..
Pid: 1, comm: swapper Not tainted 3.0.0-rc2 #45 MICRO-STAR INTERNATIONAL CO., LTD MS-7094/MS-7094
..snip..
Call Trace:
 [<ffffffff81479248>] cpufreq_stat_notifier_trans+0x48/0x7c
 [<ffffffff81095d68>] notifier_call_chain+0x32/0x5e
 [<ffffffff81095e6b>] __srcu_notifier_call_chain+0x47/0x63
 [<ffffffff81095e96>] srcu_notifier_call_chain+0xf/0x11
 [<ffffffff81477e7a>] cpufreq_notify_transition+0x111/0x134
 [<ffffffff8147b0d4>] powernowk8_target+0x53b/0x617
 [<ffffffff8147723a>] __cpufreq_driver_target+0x2e/0x30
 [<ffffffff8147a127>] cpufreq_governor_dbs+0x339/0x356
 [<ffffffff81477394>] __cpufreq_governor+0xa8/0xe9
 [<ffffffff81477525>] __cpufreq_set_policy+0x132/0x13e
 [<ffffffff8147848d>] cpufreq_add_dev_interface+0x272/0x28c

Reported-by: Tobias Diedrich <ranma+xen@tdiedrich.de>
Tested-by: Tobias Diedrich <ranma+xen@tdiedrich.de>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: Dave Jones <davej@redhat.com>
2011-06-16 16:31:12 -04:00
..
acpi-cpufreq.c [CPUFREQ] Move x86 drivers to drivers/cpufreq/ 2011-05-19 18:51:07 -04:00
cpufreq_conservative.c [CPUFREQ] Remove unneeded locks 2011-03-16 17:54:32 -04:00
cpufreq_ondemand.c [CPUFREQ] Remove unneeded locks 2011-03-16 17:54:32 -04:00
cpufreq_performance.c [CPUFREQ] use dynamic debug instead of custom infrastructure 2011-05-04 11:50:57 -04:00
cpufreq_powersave.c [CPUFREQ] use dynamic debug instead of custom infrastructure 2011-05-04 11:50:57 -04:00
cpufreq_stats.c [CPUFREQ] Don't set stat->last_index to -1 if the pol->cur has incorrect value. 2011-06-16 16:31:12 -04:00
cpufreq_userspace.c [CPUFREQ] use dynamic debug instead of custom infrastructure 2011-05-04 11:50:57 -04:00
cpufreq-nforce2.c [CPUFREQ] Move x86 drivers to drivers/cpufreq/ 2011-05-19 18:51:07 -04:00
cpufreq.c [CPUFREQ] remove redundant sprintf from request_module call. 2011-05-04 11:50:58 -04:00
db8500-cpufreq.c cpufreq: update DB8500 cpufreq driver 2011-05-24 22:20:05 +02:00
e_powersaver.c [CPUFREQ] Move x86 drivers to drivers/cpufreq/ 2011-05-19 18:51:07 -04:00
elanfreq.c [CPUFREQ] Move x86 drivers to drivers/cpufreq/ 2011-05-19 18:51:07 -04:00
freq_table.c [CPUFREQ] use dynamic debug instead of custom infrastructure 2011-05-04 11:50:57 -04:00
gx-suspmod.c [CPUFREQ] Move x86 drivers to drivers/cpufreq/ 2011-05-19 18:51:07 -04:00
Kconfig [CPUFREQ] Move x86 drivers to drivers/cpufreq/ 2011-05-19 18:51:07 -04:00
Kconfig.x86 Merge branch 'x86-cpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip 2011-05-19 17:55:12 -07:00
longhaul.c [CPUFREQ] Move x86 drivers to drivers/cpufreq/ 2011-05-19 18:51:07 -04:00
longhaul.h [CPUFREQ] Move x86 drivers to drivers/cpufreq/ 2011-05-19 18:51:07 -04:00
longrun.c [CPUFREQ] Move x86 drivers to drivers/cpufreq/ 2011-05-19 18:51:07 -04:00
Makefile cpufreq: make DB8500 cpufreq driver compile 2011-05-24 22:20:14 +02:00
mperf.c [CPUFREQ] Move x86 drivers to drivers/cpufreq/ 2011-05-19 18:51:07 -04:00
mperf.h [CPUFREQ] Move x86 drivers to drivers/cpufreq/ 2011-05-19 18:51:07 -04:00
p4-clockmod.c [CPUFREQ] Move x86 drivers to drivers/cpufreq/ 2011-05-19 18:51:07 -04:00
pcc-cpufreq.c [CPUFREQ] Move x86 drivers to drivers/cpufreq/ 2011-05-19 18:51:07 -04:00
powernow-k6.c [CPUFREQ] Move x86 drivers to drivers/cpufreq/ 2011-05-19 18:51:07 -04:00
powernow-k7.c [CPUFREQ] Move x86 drivers to drivers/cpufreq/ 2011-05-19 18:51:07 -04:00
powernow-k7.h [CPUFREQ] Move x86 drivers to drivers/cpufreq/ 2011-05-19 18:51:07 -04:00
powernow-k8.c [CPUFREQ] Move x86 drivers to drivers/cpufreq/ 2011-05-19 18:51:07 -04:00
powernow-k8.h [CPUFREQ] Move x86 drivers to drivers/cpufreq/ 2011-05-19 18:51:07 -04:00
sc520_freq.c [CPUFREQ] Move x86 drivers to drivers/cpufreq/ 2011-05-19 18:51:07 -04:00
speedstep-centrino.c [CPUFREQ] Move x86 drivers to drivers/cpufreq/ 2011-05-19 18:51:07 -04:00
speedstep-ich.c [CPUFREQ] Move x86 drivers to drivers/cpufreq/ 2011-05-19 18:51:07 -04:00
speedstep-lib.c [CPUFREQ] Move x86 drivers to drivers/cpufreq/ 2011-05-19 18:51:07 -04:00
speedstep-lib.h [CPUFREQ] Move x86 drivers to drivers/cpufreq/ 2011-05-19 18:51:07 -04:00
speedstep-smi.c [CPUFREQ] Move x86 drivers to drivers/cpufreq/ 2011-05-19 18:51:07 -04:00