cpuidle: ACPI/intel: fix MWAIT hint target C-state computation
authorHe Rongguang <herongguang@linux.alibaba.com>
Mon, 4 Mar 2024 06:14:06 +0000 (14:14 +0800)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 5 Mar 2024 20:25:18 +0000 (21:25 +0100)
commit6b8e288f49570ee2ba15a2a07c2ebf7ad2210422
tree55e9684f9d81955f7ae0bd1550a900b936c2edab
parent88390dd788db485912ee7f9a8d3d56fc5265d52f
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>
arch/x86/kernel/acpi/cstate.c
drivers/idle/intel_idle.c