summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorZhao Yakui <yakui.zhao@intel.com>2009-01-04 12:04:21 +0800
committerGreg Kroah-Hartman <gregkh@suse.de>2009-02-06 14:00:41 -0800
commit3b9720cedb49b94ca1f9523da9f7c76647878b5a (patch)
treec8098f9ee71f710e3a34bcedc034fe5d71ec3de8 /arch
parent3157bb44c4d5d1c0b8808c13a4b4264f78f0cb8d (diff)
ACPI: Avoid array address overflow when _CST MWAIT hint bits are set
commit 13b40a1a065824d2d4e55c8b48ea9f3f9d162929 upstream. The Cx Register address obtained from the _CST object is used as the MWAIT hints if the register type is FFixedHW. And it is used to check whether the Cx type is supported or not. On some boxes the following Cx state package is obtained from _CST object: >{ ResourceTemplate () { Register (FFixedHW, 0x01, // Bit Width 0x02, // Bit Offset 0x0000000000889759, // Address 0x03, // Access Size ) }, 0x03, 0xF5, 0x015E } In such case we should use the bit[7:4] of Cx address to check whether the Cx type is supported or not. mask the MWAIT hint to avoid array address overflow Signed-off-by: Zhao Yakui <yakui.zhao@intel.com> Acked-by:Venki Pallipadi <venkatesh.pallipadi@intel.com> Signed-off-by: Len Brown <len.brown@intel.com> Cc: Thomas Renninger <trenn@suse.de>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/acpi/cstate.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c
index c2502eb9aa83..a4805b3b4095 100644
--- a/arch/x86/kernel/acpi/cstate.c
+++ b/arch/x86/kernel/acpi/cstate.c
@@ -56,6 +56,7 @@ static struct cstate_entry *cpu_cstate_entry; /* per CPU ptr */
static short mwait_supported[ACPI_PROCESSOR_MAX_POWER];
#define MWAIT_SUBSTATE_MASK (0xf)
+#define MWAIT_CSTATE_MASK (0xf)
#define MWAIT_SUBSTATE_SIZE (4)
#define CPUID_MWAIT_LEAF (5)
@@ -98,7 +99,8 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu,
cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &edx);
/* Check whether this particular cx_type (in CST) is supported or not */
- cstate_type = (cx->address >> MWAIT_SUBSTATE_SIZE) + 1;
+ cstate_type = ((cx->address >> MWAIT_SUBSTATE_SIZE) &
+ MWAIT_CSTATE_MASK) + 1;
edx_part = edx >> (cstate_type * MWAIT_SUBSTATE_SIZE);
num_cstate_subtype = edx_part & MWAIT_SUBSTATE_MASK;