| From 13b40a1a065824d2d4e55c8b48ea9f3f9d162929 Mon Sep 17 00:00:00 2001 |
| From: Zhao Yakui <yakui.zhao@intel.com> |
| Date: Sun, 4 Jan 2009 12:04:21 +0800 |
| Subject: ACPI: Avoid array address overflow when _CST MWAIT hint bits are set |
| |
| From: Zhao Yakui <yakui.zhao@intel.com> |
| |
| 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> |
| |
| --- |
| arch/x86/kernel/acpi/cstate.c | 4 +++- |
| 1 file changed, 3 insertions(+), 1 deletion(-) |
| |
| --- a/arch/x86/kernel/acpi/cstate.c |
| +++ b/arch/x86/kernel/acpi/cstate.c |
| @@ -56,6 +56,7 @@ static struct cstate_entry *cpu_cstate_e |
| 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(unsi |
| 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; |
| |