Skip to content

Commit 4aa8a47

Browse files
Suzuki K Poulosewildea01
authored andcommitted
arm64: Documentation - Expose CPU feature registers
Documentation for the infrastructure to expose CPU feature register by emulating MRS. Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Will Deacon <will.deacon@arm.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Dave Martin <dave.martin@arm.com> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
1 parent 77c97b4 commit 4aa8a47

File tree

2 files changed

+244
-0
lines changed

2 files changed

+244
-0
lines changed
Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
ARM64 CPU Feature Registers
2+
===========================
3+
4+
Author: Suzuki K Poulose <suzuki.poulose@arm.com>
5+
6+
7+
This file describes the ABI for exporting the AArch64 CPU ID/feature
8+
registers to userspace. The availability of this ABI is advertised
9+
via the HWCAP_CPUID in HWCAPs.
10+
11+
1. Motivation
12+
---------------
13+
14+
The ARM architecture defines a set of feature registers, which describe
15+
the capabilities of the CPU/system. Access to these system registers is
16+
restricted from EL0 and there is no reliable way for an application to
17+
extract this information to make better decisions at runtime. There is
18+
limited information available to the application via HWCAPs, however
19+
there are some issues with their usage.
20+
21+
a) Any change to the HWCAPs requires an update to userspace (e.g libc)
22+
to detect the new changes, which can take a long time to appear in
23+
distributions. Exposing the registers allows applications to get the
24+
information without requiring updates to the toolchains.
25+
26+
b) Access to HWCAPs is sometimes limited (e.g prior to libc, or
27+
when ld is initialised at startup time).
28+
29+
c) HWCAPs cannot represent non-boolean information effectively. The
30+
architecture defines a canonical format for representing features
31+
in the ID registers; this is well defined and is capable of
32+
representing all valid architecture variations.
33+
34+
35+
2. Requirements
36+
-----------------
37+
38+
a) Safety :
39+
Applications should be able to use the information provided by the
40+
infrastructure to run safely across the system. This has greater
41+
implications on a system with heterogeneous CPUs.
42+
The infrastructure exports a value that is safe across all the
43+
available CPU on the system.
44+
45+
e.g, If at least one CPU doesn't implement CRC32 instructions, while
46+
others do, we should report that the CRC32 is not implemented.
47+
Otherwise an application could crash when scheduled on the CPU
48+
which doesn't support CRC32.
49+
50+
b) Security :
51+
Applications should only be able to receive information that is
52+
relevant to the normal operation in userspace. Hence, some of the
53+
fields are masked out(i.e, made invisible) and their values are set to
54+
indicate the feature is 'not supported'. See Section 4 for the list
55+
of visible features. Also, the kernel may manipulate the fields
56+
based on what it supports. e.g, If FP is not supported by the
57+
kernel, the values could indicate that the FP is not available
58+
(even when the CPU provides it).
59+
60+
c) Implementation Defined Features
61+
The infrastructure doesn't expose any register which is
62+
IMPLEMENTATION DEFINED as per ARMv8-A Architecture.
63+
64+
d) CPU Identification :
65+
MIDR_EL1 is exposed to help identify the processor. On a
66+
heterogeneous system, this could be racy (just like getcpu()). The
67+
process could be migrated to another CPU by the time it uses the
68+
register value, unless the CPU affinity is set. Hence, there is no
69+
guarantee that the value reflects the processor that it is
70+
currently executing on. The REVIDR is not exposed due to this
71+
constraint, as REVIDR makes sense only in conjunction with the
72+
MIDR. Alternately, MIDR_EL1 and REVIDR_EL1 are exposed via sysfs
73+
at:
74+
75+
/sys/devices/system/cpu/cpu$ID/regs/identification/
76+
\- midr
77+
\- revidr
78+
79+
3. Implementation
80+
--------------------
81+
82+
The infrastructure is built on the emulation of the 'MRS' instruction.
83+
Accessing a restricted system register from an application generates an
84+
exception and ends up in SIGILL being delivered to the process.
85+
The infrastructure hooks into the exception handler and emulates the
86+
operation if the source belongs to the supported system register space.
87+
88+
The infrastructure emulates only the following system register space:
89+
Op0=3, Op1=0, CRn=0, CRm=0,4,5,6,7
90+
91+
(See Table C5-6 'System instruction encodings for non-Debug System
92+
register accesses' in ARMv8 ARM DDI 0487A.h, for the list of
93+
registers).
94+
95+
The following rules are applied to the value returned by the
96+
infrastructure:
97+
98+
a) The value of an 'IMPLEMENTATION DEFINED' field is set to 0.
99+
b) The value of a reserved field is populated with the reserved
100+
value as defined by the architecture.
101+
c) The value of a 'visible' field holds the system wide safe value
102+
for the particular feature (except for MIDR_EL1, see section 4).
103+
d) All other fields (i.e, invisible fields) are set to indicate
104+
the feature is missing (as defined by the architecture).
105+
106+
4. List of registers with visible features
107+
-------------------------------------------
108+
109+
1) ID_AA64ISAR0_EL1 - Instruction Set Attribute Register 0
110+
x--------------------------------------------------x
111+
| Name | bits | visible |
112+
|--------------------------------------------------|
113+
| RES0 | [63-32] | n |
114+
|--------------------------------------------------|
115+
| RDM | [31-28] | y |
116+
|--------------------------------------------------|
117+
| ATOMICS | [23-20] | y |
118+
|--------------------------------------------------|
119+
| CRC32 | [19-16] | y |
120+
|--------------------------------------------------|
121+
| SHA2 | [15-12] | y |
122+
|--------------------------------------------------|
123+
| SHA1 | [11-8] | y |
124+
|--------------------------------------------------|
125+
| AES | [7-4] | y |
126+
|--------------------------------------------------|
127+
| RES0 | [3-0] | n |
128+
x--------------------------------------------------x
129+
130+
131+
2) ID_AA64PFR0_EL1 - Processor Feature Register 0
132+
x--------------------------------------------------x
133+
| Name | bits | visible |
134+
|--------------------------------------------------|
135+
| RES0 | [63-28] | n |
136+
|--------------------------------------------------|
137+
| GIC | [27-24] | n |
138+
|--------------------------------------------------|
139+
| AdvSIMD | [23-20] | y |
140+
|--------------------------------------------------|
141+
| FP | [19-16] | y |
142+
|--------------------------------------------------|
143+
| EL3 | [15-12] | n |
144+
|--------------------------------------------------|
145+
| EL2 | [11-8] | n |
146+
|--------------------------------------------------|
147+
| EL1 | [7-4] | n |
148+
|--------------------------------------------------|
149+
| EL0 | [3-0] | n |
150+
x--------------------------------------------------x
151+
152+
153+
3) MIDR_EL1 - Main ID Register
154+
x--------------------------------------------------x
155+
| Name | bits | visible |
156+
|--------------------------------------------------|
157+
| Implementer | [31-24] | y |
158+
|--------------------------------------------------|
159+
| Variant | [23-20] | y |
160+
|--------------------------------------------------|
161+
| Architecture | [19-16] | y |
162+
|--------------------------------------------------|
163+
| PartNum | [15-4] | y |
164+
|--------------------------------------------------|
165+
| Revision | [3-0] | y |
166+
x--------------------------------------------------x
167+
168+
NOTE: The 'visible' fields of MIDR_EL1 will contain the value
169+
as available on the CPU where it is fetched and is not a system
170+
wide safe value.
171+
172+
Appendix I: Example
173+
---------------------------
174+
175+
/*
176+
* Sample program to demonstrate the MRS emulation ABI.
177+
*
178+
* Copyright (C) 2015-2016, ARM Ltd
179+
*
180+
* Author: Suzuki K Poulose <suzuki.poulose@arm.com>
181+
*
182+
* This program is free software; you can redistribute it and/or modify
183+
* it under the terms of the GNU General Public License version 2 as
184+
* published by the Free Software Foundation.
185+
*
186+
* This program is distributed in the hope that it will be useful,
187+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
188+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
189+
* GNU General Public License for more details.
190+
* This program is free software; you can redistribute it and/or modify
191+
* it under the terms of the GNU General Public License version 2 as
192+
* published by the Free Software Foundation.
193+
*
194+
* This program is distributed in the hope that it will be useful,
195+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
196+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
197+
* GNU General Public License for more details.
198+
*/
199+
200+
#include <asm/hwcap.h>
201+
#include <stdio.h>
202+
#include <sys/auxv.h>
203+
204+
#define get_cpu_ftr(id) ({ \
205+
unsigned long __val; \
206+
asm("mrs %0, "#id : "=r" (__val)); \
207+
printf("%-20s: 0x%016lx\n", #id, __val); \
208+
})
209+
210+
int main(void)
211+
{
212+
213+
if (!(getauxval(AT_HWCAP) & HWCAP_CPUID)) {
214+
fputs("CPUID registers unavailable\n", stderr);
215+
return 1;
216+
}
217+
218+
get_cpu_ftr(ID_AA64ISAR0_EL1);
219+
get_cpu_ftr(ID_AA64ISAR1_EL1);
220+
get_cpu_ftr(ID_AA64MMFR0_EL1);
221+
get_cpu_ftr(ID_AA64MMFR1_EL1);
222+
get_cpu_ftr(ID_AA64PFR0_EL1);
223+
get_cpu_ftr(ID_AA64PFR1_EL1);
224+
get_cpu_ftr(ID_AA64DFR0_EL1);
225+
get_cpu_ftr(ID_AA64DFR1_EL1);
226+
227+
get_cpu_ftr(MIDR_EL1);
228+
get_cpu_ftr(MPIDR_EL1);
229+
get_cpu_ftr(REVIDR_EL1);
230+
231+
#if 0
232+
/* Unexposed register access causes SIGILL */
233+
get_cpu_ftr(ID_MMFR0_EL1);
234+
#endif
235+
236+
return 0;
237+
}
238+
239+
240+

arch/arm64/kernel/cpufeature.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ static bool __maybe_unused
8282
cpufeature_pan_not_uao(const struct arm64_cpu_capabilities *entry, int __unused);
8383

8484

85+
/*
86+
* NOTE: Any changes to the visibility of features should be kept in
87+
* sync with the documentation of the CPU feature register ABI.
88+
*/
8589
static const struct arm64_ftr_bits ftr_id_aa64isar0[] = {
8690
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64ISAR0_RDM_SHIFT, 4, 0),
8791
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR0_ATOMICS_SHIFT, 4, 0),

0 commit comments

Comments
 (0)