aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/processor_perflib.c
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2009-05-26 15:11:06 -0400
committerLen Brown <len.brown@intel.com>2009-05-29 20:45:58 -0400
commit34d531e640cb805973cf656b15c716b961565cea (patch)
tree6f62bdd6a5eef1ec6b49ab8b5e6808abba528b6d /drivers/acpi/processor_perflib.c
parentb18f1e21993f73f072b1e0859f942fb11afddcb1 (diff)
ACPI: sanity check _PSS frequency to prevent cpufreq crash
When BIOS SETUP is changed to disable EIST, some BIOS hand the OS an un-initialized _PSS: Name (_PSS, Package (0x06) { Package (0x06) { 0x80000000, // frequency [MHz] 0x80000000, // power [mW] 0x80000000, // latency [us] 0x80000000, // BM latency [us] 0x80000000, // control 0x80000000 // status }, ... These are outrageous values for frequency, power and latency, raising the question where to draw the line between legal and illegal. We tend to survive garbage in the power and latency fields, but we can BUG_ON when garbage is in the frequency field. Cpufreq multiplies the frequency by 1000 and stores it in a u32 KHz. So disregard a _PSS with a frequency so large that it can't be represented by cpufreq. https://bugzilla.redhat.com/show_bug.cgi?id=500311 Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/processor_perflib.c')
-rw-r--r--drivers/acpi/processor_perflib.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index cafb41000f6b..60e543d3234e 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -309,9 +309,15 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr)
309 (u32) px->bus_master_latency, 309 (u32) px->bus_master_latency,
310 (u32) px->control, (u32) px->status)); 310 (u32) px->control, (u32) px->status));
311 311
312 if (!px->core_frequency) { 312 /*
313 printk(KERN_ERR PREFIX 313 * Check that ACPI's u64 MHz will be valid as u32 KHz in cpufreq
314 "Invalid _PSS data: freq is zero\n"); 314 */
315 if (!px->core_frequency ||
316 ((u32)(px->core_frequency * 1000) !=
317 (px->core_frequency * 1000))) {
318 printk(KERN_ERR FW_BUG PREFIX
319 "Invalid BIOS _PSS frequency: 0x%llx MHz\n",
320 px->core_frequency);
315 result = -EFAULT; 321 result = -EFAULT;
316 kfree(pr->performance->states); 322 kfree(pr->performance->states);
317 goto end; 323 goto end;