--- /dev/null
+From 201bf0f129e1715a33568d1563d9a75b840ab4d3 Mon Sep 17 00:00:00 2001
+From: Andreas Herrmann <andreas.herrmann3@amd.com>
+Date: Fri, 6 Jan 2012 15:56:31 +0100
+Subject: [CPUFREQ] powernow-k8: Avoid Pstate MSR accesses on systems supporting CPB
+
+From: Andreas Herrmann <andreas.herrmann3@amd.com>
+
+commit 201bf0f129e1715a33568d1563d9a75b840ab4d3 upstream.
+
+Due to CPB we can't directly map SW Pstates to Pstate MSRs. Get rid of
+the paranoia check. (assuming that the ACPI Pstate information is
+correct.)
+
+Signed-off-by: Andreas Herrmann <andreas.herrmann3@amd.com>
+Signed-off-by: Dave Jones <davej@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/cpufreq/powernow-k8.c | 19 ++++++++++---------
+ 1 file changed, 10 insertions(+), 9 deletions(-)
+
+--- a/drivers/cpufreq/powernow-k8.c
++++ b/drivers/cpufreq/powernow-k8.c
+@@ -926,23 +926,24 @@ static int fill_powernow_table_pstate(st
+ invalidate_entry(powernow_table, i);
+ continue;
+ }
+- rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi);
+- if (!(hi & HW_PSTATE_VALID_MASK)) {
+- pr_debug("invalid pstate %d, ignoring\n", index);
+- invalidate_entry(powernow_table, i);
+- continue;
+- }
+-
+- powernow_table[i].index = index;
+-
+ /* Frequency may be rounded for these */
+ if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10)
+ || boot_cpu_data.x86 == 0x11) {
++
++ rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi);
++ if (!(hi & HW_PSTATE_VALID_MASK)) {
++ pr_debug("invalid pstate %d, ignoring\n", index);
++ invalidate_entry(powernow_table, i);
++ continue;
++ }
++
+ powernow_table[i].frequency =
+ freq_from_fid_did(lo & 0x3f, (lo >> 6) & 7);
+ } else
+ powernow_table[i].frequency =
+ data->acpi_data.states[i].core_frequency * 1000;
++
++ powernow_table[i].index = index;
+ }
+ return 0;
+ }
--- /dev/null
+From a8eb28480e9b637cc78b9aa5e08612ba97e1317a Mon Sep 17 00:00:00 2001
+From: Andreas Herrmann <andreas.herrmann3@amd.com>
+Date: Fri, 6 Jan 2012 15:57:55 +0100
+Subject: [CPUFREQ] powernow-k8: Fix indexing issue
+
+From: Andreas Herrmann <andreas.herrmann3@amd.com>
+
+commit a8eb28480e9b637cc78b9aa5e08612ba97e1317a upstream.
+
+The driver uses the pstate number from the status register as index in
+its table of ACPI pstates (powernow_table). This is wrong as this is
+not a 1-to-1 mapping.
+
+For example we can have _PSS information to just utilize Pstate 0 and
+Pstate 4, ie.
+
+ powernow-k8: Core Performance Boosting: on.
+ powernow-k8: 0 : pstate 0 (2200 MHz)
+ powernow-k8: 1 : pstate 4 (1400 MHz)
+
+In this example the driver's powernow_table has just 2 entries. Using
+the pstate number (4) as index into this table is just plain wrong.
+
+Signed-off-by: Andreas Herrmann <andreas.herrmann3@amd.com>
+Signed-off-by: Dave Jones <davej@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/cpufreq/powernow-k8.c | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+--- a/drivers/cpufreq/powernow-k8.c
++++ b/drivers/cpufreq/powernow-k8.c
+@@ -54,6 +54,9 @@ static DEFINE_PER_CPU(struct powernow_k8
+
+ static int cpu_family = CPU_OPTERON;
+
++/* array to map SW pstate number to acpi state */
++static u32 ps_to_as[8];
++
+ /* core performance boost */
+ static bool cpb_capable, cpb_enabled;
+ static struct msr __percpu *msrs;
+@@ -80,9 +83,9 @@ static u32 find_khz_freq_from_fid(u32 fi
+ }
+
+ static u32 find_khz_freq_from_pstate(struct cpufreq_frequency_table *data,
+- u32 pstate)
++ u32 pstate)
+ {
+- return data[pstate].frequency;
++ return data[ps_to_as[pstate]].frequency;
+ }
+
+ /* Return the vco fid for an input fid
+@@ -926,6 +929,9 @@ static int fill_powernow_table_pstate(st
+ invalidate_entry(powernow_table, i);
+ continue;
+ }
++
++ ps_to_as[index] = i;
++
+ /* Frequency may be rounded for these */
+ if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10)
+ || boot_cpu_data.x86 == 0x11) {
+@@ -1190,7 +1196,8 @@ static int powernowk8_target(struct cpuf
+ powernow_k8_acpi_pst_values(data, newstate);
+
+ if (cpu_family == CPU_HW_PSTATE)
+- ret = transition_frequency_pstate(data, newstate);
++ ret = transition_frequency_pstate(data,
++ data->powernow_table[newstate].index);
+ else
+ ret = transition_frequency_fidvid(data, newstate);
+ if (ret) {
+@@ -1203,7 +1210,7 @@ static int powernowk8_target(struct cpuf
+
+ if (cpu_family == CPU_HW_PSTATE)
+ pol->cur = find_khz_freq_from_pstate(data->powernow_table,
+- newstate);
++ data->powernow_table[newstate].index);
+ else
+ pol->cur = find_khz_freq_from_fid(data->currfid);
+ ret = 0;