diff options
| author | Christian Loehle <christian.loehle@arm.com> | 2026-09-16 17:27:54 +0100 |
|---|---|---|
| committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2026-09-18 17:29:08 +0200 |
| commit | 09d911c9966333c45409440ec2d777cf80a3305f (patch) | |
| tree | 5cfa52c8b75fe38c3ab1b65e138402346c8f02af /include | |
| parent | 2221dc547b38eeef4893abb0f55352ebd920ddcb (diff) | |
ACPI: CPPC: Reject direct reads of write-only controls
Between _CPC revision 3 and revision 4, Desired Performance changed from
Read/Write to Write. Revision 4 also added the write-only OSPM Nominal
Performance control. ACPI 6.6 section 4.6.3 says reads of write-only bit
positions produce undefined results.
The public Desired Performance helper already rejects revision-4 readback,
but the common register accessor still permits either write-only control to
be read. Move the check into the common accessor and reject both controls
there, so callers cannot consume undefined values.
A partial SystemMemory field still makes cpc_write() read its complete
access unit to preserve bits outside the field. MASK_VAL_WRITE() replaces
every bit of the field being written, so that field's undefined readback is
not propagated. However, another writer sharing the access unit would
preserve and replay the write-only field when performing its own RMW.
Reject such pairs; a partial write-only field may share its access unit
only with disjoint read-only fields.
Also reject readable fields whose logical bits overlap a write-only field,
even if the write-only descriptor is retained as an inaccessible range.
Reading the containing access unit is safe when the undefined bits are
masked out, but an overlapping read field would expose them to callers.
Apply this check before the no-writer shortcut, and reserve the complete
known access range when a write-only field has no usable Bit Width.
Keep an invalid but locatable write-only SystemMemory descriptor
represented during overlap validation, but mark it unreadable and
unwritable. Otherwise a neighbouring RMW field could evade validation and
replay undefined readback into the hidden control. Conservatively claim the
larger of the declared access unit and logical field span. Check if the
writer access unit covers the write-only field so harmless asymmetric
geometries are not rejected. Preserve a decoded access-unit claim even when
the malformed Bit Width is zero, and use that claimed range when testing
whether another writer's access overlaps the hidden field.
Count only accessible descriptors as writers in the generic conflict
rules. The logical-field overlap check protects a retained field from a
full-width write, and the dedicated write-only-field check also protects it
from another writer's RMW.
Mark an inaccessible OSPM Nominal Performance control unsupported because
it is optional. Do the same for inaccessible Desired Performance while
parsing, then let the post-parse control check accept it only for immutable
autonomous selection. This preserves the autonomous-only exception without
accepting an unusable Desired control in non-autonomous mode.
Do not advertise fast switching or zero transition latency unless Desired
Performance remains writable. An inaccessible descriptor retained only for
overlap validation still carries its original address-space identity, but
cannot service a performance request.
Fixes: 71e1815113f7 ("ACPI: CPPC: Add support for CPPC v4")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Link: https://sashiko.dev/#/patchset/20260807111303.1062391-1-christian.loehle%40arm.com
Link: https://sashiko.dev/#/patchset/20260808082644.1251332-1-christian.loehle%40arm.com
Signed-off-by: Christian Loehle <christian.loehle@arm.com>
Tested-by: Sumit Gupta <sumitg@nvidia.com>
Link: https://patch.msgid.link/20260916162805.1039247-10-christian.loehle@arm.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'include')
| -rw-r--r-- | include/acpi/cppc_acpi.h | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h index 737219761c52..53186da6a654 100644 --- a/include/acpi/cppc_acpi.h +++ b/include/acpi/cppc_acpi.h @@ -72,6 +72,8 @@ struct cpc_register_resource { struct { struct cpc_reg reg; bool use_rmw_lock; + bool read_unsupported; + bool write_unsupported; }; u64 int_value; } cpc_entry; |
