Skip to content

Commit 6b8e288

Browse files
He Rongguangrafaeljw
authored andcommitted
cpuidle: ACPI/intel: fix MWAIT hint target C-state computation
According to x86 spec ([1] and [2]), MWAIT hint_address[7:4] plus 1 is the corresponding C-state, and 0xF means C0. ACPI C-state table usually only contains C1+, but nothing prevents ACPI firmware from presenting a C-state (maybe C1+) but using MWAIT address C0 (i.e., 0xF in ACPI FFH MWAIT hint address). And if this is the case, Linux erroneously treat this cstate as C16, while actually this should be valid C0 instead of C16, as per the specifications. Since ACPI firmware is out of Linux kernel scope, fix the kernel handling of 0xF ->(to) C0 in this situation. This is found when a tweaked ACPI C-state table is presented by Qemu to VM. Also modify the intel_idle case for code consistency. [1]. Intel SDM Vol 2, Table 4-11. MWAIT Hints Register (EAX): "Value of 0 means C1; 1 means C2 and so on Value of 01111B means C0". [2]. AMD manual Vol 3, MWAIT: "The processor C-state is EAX[7:4]+1, so to request C0 is to place the value F in EAX[7:4] and to request C1 is to place the value 0 in EAX[7:4].". Signed-off-by: He Rongguang <herongguang@linux.alibaba.com> [ rjw: Subject and changelog edits, whitespace fixups ] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent 88390dd commit 6b8e288

File tree

2 files changed

+4
-3
lines changed

2 files changed

+4
-3
lines changed

arch/x86/kernel/acpi/cstate.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,8 @@ static long acpi_processor_ffh_cstate_probe_cpu(void *_cx)
131131
cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &edx);
132132

133133
/* Check whether this particular cx_type (in CST) is supported or not */
134-
cstate_type = ((cx->address >> MWAIT_SUBSTATE_SIZE) &
135-
MWAIT_CSTATE_MASK) + 1;
134+
cstate_type = (((cx->address >> MWAIT_SUBSTATE_SIZE) &
135+
MWAIT_CSTATE_MASK) + 1) & MWAIT_CSTATE_MASK;
136136
edx_part = edx >> (cstate_type * MWAIT_SUBSTATE_SIZE);
137137
num_cstate_subtype = edx_part & MWAIT_SUBSTATE_MASK;
138138

drivers/idle/intel_idle.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1934,7 +1934,8 @@ static void __init spr_idle_state_table_update(void)
19341934

19351935
static bool __init intel_idle_verify_cstate(unsigned int mwait_hint)
19361936
{
1937-
unsigned int mwait_cstate = MWAIT_HINT2CSTATE(mwait_hint) + 1;
1937+
unsigned int mwait_cstate = (MWAIT_HINT2CSTATE(mwait_hint) + 1) &
1938+
MWAIT_CSTATE_MASK;
19381939
unsigned int num_substates = (mwait_substates >> mwait_cstate * 4) &
19391940
MWAIT_SUBSTATE_MASK;
19401941

0 commit comments

Comments
 (0)