Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 392

kernel-2.6.18-194.11.1.el5.src.rpm

From: Bhavna Sarathy <bnagendr@redhat.com>
Date: Wed, 20 Jan 2010 16:30:42 -0500
Subject: [cpufreq] powernow-k8: fix crash on AMD family 0x11 procs
Message-id: <20100120163406.8231.85909.sendpatchset@localhost.localdomain>
Patchwork-id: 22679
O-Subject: [RHEL5 PATCH] Fix for Powernow-k8 crash on AMD family 0x11 processors
Bugzilla: 555180
RH-Acked-by: Jarod Wilson <jarod@redhat.com>
RH-Acked-by: Anton Arapov <Anton@redhat.com>

Resolves BZ 555180

A workaround for AMD CPU family 11h erratum 311 might cause that the P-state
status Register shows a "current P-state" which is larger than the "current
P-state limit" in P-state Current Limit Register. For the wrong P-state value
there is no ACPI _PSS object defined and powernow-k8/cpufreq can't determine
the proper CPU frequency for that state.  As a consequence this can cause a
panic during boot.

HP/Compaq 6735b laptop was affected and the issue is now fixed.

Upstream patches:

http://git.kernel.org/?p=linux/kernel/git/davej/cpufreq.git;a=commit;h=a266d9f1253a38ec2d5655ebcd6846298b0554f4

These patches are needed to fix incorrect value reported in
cpuinfo_cur_freq:

[PATCH 0/2] powernow-k8: fix incorrect value reported in
cpuinfo_cur_freq
http://lkml.indiana.edu/hypermail/linux/kernel/0906.1/02241.html

[PATCH 1/2] powernow-k8: read P-state from HW
http://lkml.indiana.edu/hypermail/linux/kernel/0906.1/02242.html

[PATCH 2/2] powernow-k8: get drv data for correct CPU
http://lkml.indiana.edu/hypermail/linux/kernel/0906.1/02246.html

Testing:
Brew build:
https://brewweb.devel.redhat.com/taskinfo?taskID=2203740

Testing:
Successfully tested overnight on HP 6735b laptop, with over 200
reboots with no issues recorded.  Both 64-bit and 32-bit tested.

Please review and ACK

Signed-off-by: Jarod Wilson <jarod@redhat.com>

diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
index 6f55c00..5ed35db 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
@@ -131,6 +131,14 @@ static int query_current_values_with_pending_wait(struct powernow_k8_data *data)
 		rdmsr(MSR_PSTATE_STATUS, lo, hi);
 		i = lo & HW_PSTATE_MASK;
 		data->currpstate = i;
+
+		/*
+		 * a workaround for family 11h erratum 311 might cause
+		 * an "out-of-range Pstate if the core is in Pstate-0
+		 */
+		if ((boot_cpu_data.x86 == 0x11) && (i >= data->numps))
+ 			data->currpstate = HW_PSTATE_0;
+
 		return 0;
 	}
 	do {
@@ -1261,6 +1269,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
 	}
 
 	data->cpu = pol->cpu;
+	data->currpstate = HW_PSTATE_INVALID;
 
 	if (powernow_k8_cpu_init_acpi(data)) {
 		/*
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
index 7528192..cb1a869 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
@@ -5,6 +5,18 @@
  *  http://www.gnu.org/licenses/gpl.html
  */
 
+enum pstate {
+	HW_PSTATE_INVALID = 0xff,
+	HW_PSTATE_0 = 0,
+	HW_PSTATE_1 = 1,
+	HW_PSTATE_2 = 2,
+	HW_PSTATE_3 = 3,
+	HW_PSTATE_4 = 4,
+	HW_PSTATE_5 = 5,
+	HW_PSTATE_6 = 6,
+	HW_PSTATE_7 = 7,
+};
+
 struct powernow_k8_data {
 	unsigned int cpu;
 
@@ -23,7 +35,9 @@ struct powernow_k8_data {
         u32 exttype; /* extended interface = 1 */
 
 	/* keep track of the current fid / vid or pstate */
-	u32 currvid, currfid, currpstate;
+	u32 currvid;
+	u32 currfid;
+	enum pstate currpstate;
 
 	/* the powernow_table includes all frequency and vid/fid pairings:
 	 * fid are the lower 8 bits of the index, vid are the upper 8 bits.