Skip to content

Commit da12d27

Browse files
committed
Merge branches 'for-next/memory-hotremove', 'for-next/arm_sdei', 'for-next/amu', 'for-next/final-cap-helper', 'for-next/cpu_ops-cleanup', 'for-next/misc' and 'for-next/perf' into for-next/core
* for-next/memory-hotremove: : Memory hot-remove support for arm64 arm64/mm: Enable memory hot remove arm64/mm: Hold memory hotplug lock while walking for kernel page table dump * for-next/arm_sdei: : SDEI: fix double locking on return from hibernate and clean-up firmware: arm_sdei: clean up sdei_event_create() firmware: arm_sdei: Use cpus_read_lock() to avoid races with cpuhp firmware: arm_sdei: fix possible double-lock on hibernate error path firmware: arm_sdei: fix double-lock on hibernate with shared events * for-next/amu: : ARMv8.4 Activity Monitors support clocksource/drivers/arm_arch_timer: validate arch_timer_rate arm64: use activity monitors for frequency invariance cpufreq: add function to get the hardware max frequency Documentation: arm64: document support for the AMU extension arm64/kvm: disable access to AMU registers from kvm guests arm64: trap to EL1 accesses to AMU counters from EL0 arm64: add support for the AMU extension v1 * for-next/final-cap-helper: : Introduce cpus_have_final_cap_helper(), migrate arm64 KVM to it arm64: kvm: hyp: use cpus_have_final_cap() arm64: cpufeature: add cpus_have_final_cap() * for-next/cpu_ops-cleanup: : cpu_ops[] access code clean-up arm64: Introduce get_cpu_ops() helper function arm64: Rename cpu_read_ops() to init_cpu_ops() arm64: Declare ACPI parking protocol CPU operation if needed * for-next/misc: : Various fixes and clean-ups arm64: define __alloc_zeroed_user_highpage arm64/kernel: Simplify __cpu_up() by bailing out early arm64: remove redundant blank for '=' operator arm64: kexec_file: Fixed code style. arm64: add blank after 'if' arm64: fix spelling mistake "ca not" -> "cannot" arm64: entry: unmask IRQ in el0_sp() arm64: efi: add efi-entry.o to targets instead of extra-$(CONFIG_EFI) arm64: csum: Optimise IPv6 header checksum arch/arm64: fix typo in a comment arm64: remove gratuitious/stray .ltorg stanzas arm64: Update comment for ASID() macro arm64: mm: convert cpu_do_switch_mm() to C arm64: fix NUMA Kconfig typos * for-next/perf: : arm64 perf updates arm64: perf: Add support for ARMv8.5-PMU 64-bit counters KVM: arm64: limit PMU version to PMUv3 for ARMv8.1 arm64: cpufeature: Extract capped perfmon fields arm64: perf: Clean up enable/disable calls perf: arm-ccn: Use scnprintf() for robustness arm64: perf: Support new DT compatibles arm64: perf: Refactor PMU init callbacks perf: arm_spe: Remove unnecessary zero check on 'nr_pages'
7 parents bbd6ec6 + f7d5ef0 + c265861 + b5475d8 + de58ed5 + c17a290 + 8673e02 commit da12d27

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1154
-371
lines changed

Documentation/arm64/amu.rst

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
=======================================================
2+
Activity Monitors Unit (AMU) extension in AArch64 Linux
3+
=======================================================
4+
5+
Author: Ionela Voinescu <[email protected]>
6+
7+
Date: 2019-09-10
8+
9+
This document briefly describes the provision of Activity Monitors Unit
10+
support in AArch64 Linux.
11+
12+
13+
Architecture overview
14+
---------------------
15+
16+
The activity monitors extension is an optional extension introduced by the
17+
ARMv8.4 CPU architecture.
18+
19+
The activity monitors unit, implemented in each CPU, provides performance
20+
counters intended for system management use. The AMU extension provides a
21+
system register interface to the counter registers and also supports an
22+
optional external memory-mapped interface.
23+
24+
Version 1 of the Activity Monitors architecture implements a counter group
25+
of four fixed and architecturally defined 64-bit event counters.
26+
- CPU cycle counter: increments at the frequency of the CPU.
27+
- Constant counter: increments at the fixed frequency of the system
28+
clock.
29+
- Instructions retired: increments with every architecturally executed
30+
instruction.
31+
- Memory stall cycles: counts instruction dispatch stall cycles caused by
32+
misses in the last level cache within the clock domain.
33+
34+
When in WFI or WFE these counters do not increment.
35+
36+
The Activity Monitors architecture provides space for up to 16 architected
37+
event counters. Future versions of the architecture may use this space to
38+
implement additional architected event counters.
39+
40+
Additionally, version 1 implements a counter group of up to 16 auxiliary
41+
64-bit event counters.
42+
43+
On cold reset all counters reset to 0.
44+
45+
46+
Basic support
47+
-------------
48+
49+
The kernel can safely run a mix of CPUs with and without support for the
50+
activity monitors extension. Therefore, when CONFIG_ARM64_AMU_EXTN is
51+
selected we unconditionally enable the capability to allow any late CPU
52+
(secondary or hotplugged) to detect and use the feature.
53+
54+
When the feature is detected on a CPU, we flag the availability of the
55+
feature but this does not guarantee the correct functionality of the
56+
counters, only the presence of the extension.
57+
58+
Firmware (code running at higher exception levels, e.g. arm-tf) support is
59+
needed to:
60+
- Enable access for lower exception levels (EL2 and EL1) to the AMU
61+
registers.
62+
- Enable the counters. If not enabled these will read as 0.
63+
- Save/restore the counters before/after the CPU is being put/brought up
64+
from the 'off' power state.
65+
66+
When using kernels that have this feature enabled but boot with broken
67+
firmware the user may experience panics or lockups when accessing the
68+
counter registers. Even if these symptoms are not observed, the values
69+
returned by the register reads might not correctly reflect reality. Most
70+
commonly, the counters will read as 0, indicating that they are not
71+
enabled.
72+
73+
If proper support is not provided in firmware it's best to disable
74+
CONFIG_ARM64_AMU_EXTN. To be noted that for security reasons, this does not
75+
bypass the setting of AMUSERENR_EL0 to trap accesses from EL0 (userspace) to
76+
EL1 (kernel). Therefore, firmware should still ensure accesses to AMU registers
77+
are not trapped in EL2/EL3.
78+
79+
The fixed counters of AMUv1 are accessible though the following system
80+
register definitions:
81+
- SYS_AMEVCNTR0_CORE_EL0
82+
- SYS_AMEVCNTR0_CONST_EL0
83+
- SYS_AMEVCNTR0_INST_RET_EL0
84+
- SYS_AMEVCNTR0_MEM_STALL_EL0
85+
86+
Auxiliary platform specific counters can be accessed using
87+
SYS_AMEVCNTR1_EL0(n), where n is a value between 0 and 15.
88+
89+
Details can be found in: arch/arm64/include/asm/sysreg.h.
90+
91+
92+
Userspace access
93+
----------------
94+
95+
Currently, access from userspace to the AMU registers is disabled due to:
96+
- Security reasons: they might expose information about code executed in
97+
secure mode.
98+
- Purpose: AMU counters are intended for system management use.
99+
100+
Also, the presence of the feature is not visible to userspace.
101+
102+
103+
Virtualization
104+
--------------
105+
106+
Currently, access from userspace (EL0) and kernelspace (EL1) on the KVM
107+
guest side is disabled due to:
108+
- Security reasons: they might expose information about code executed
109+
by other guests or the host.
110+
111+
Any attempt to access the AMU registers will result in an UNDEFINED
112+
exception being injected into the guest.

Documentation/arm64/booting.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,20 @@ Before jumping into the kernel, the following conditions must be met:
248248
- HCR_EL2.APK (bit 40) must be initialised to 0b1
249249
- HCR_EL2.API (bit 41) must be initialised to 0b1
250250

251+
For CPUs with Activity Monitors Unit v1 (AMUv1) extension present:
252+
- If EL3 is present:
253+
CPTR_EL3.TAM (bit 30) must be initialised to 0b0
254+
CPTR_EL2.TAM (bit 30) must be initialised to 0b0
255+
AMCNTENSET0_EL0 must be initialised to 0b1111
256+
AMCNTENSET1_EL0 must be initialised to a platform specific value
257+
having 0b1 set for the corresponding bit for each of the auxiliary
258+
counters present.
259+
- If the kernel is entered at EL1:
260+
AMCNTENSET0_EL0 must be initialised to 0b1111
261+
AMCNTENSET1_EL0 must be initialised to a platform specific value
262+
having 0b1 set for the corresponding bit for each of the auxiliary
263+
counters present.
264+
251265
The requirements described above for CPU mode, caches, MMUs, architected
252266
timers, coherency and system registers apply to all CPUs. All CPUs must
253267
enter the kernel in the same exception level.

Documentation/arm64/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ ARM64 Architecture
66
:maxdepth: 1
77

88
acpi_object_usage
9+
amu
910
arm-acpi
1011
booting
1112
cpu-feature-registers

arch/arm64/Kconfig

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -955,11 +955,11 @@ config HOTPLUG_CPU
955955

956956
# Common NUMA Features
957957
config NUMA
958-
bool "Numa Memory Allocation and Scheduler Support"
958+
bool "NUMA Memory Allocation and Scheduler Support"
959959
select ACPI_NUMA if ACPI
960960
select OF_NUMA
961961
help
962-
Enable NUMA (Non Uniform Memory Access) support.
962+
Enable NUMA (Non-Uniform Memory Access) support.
963963

964964
The kernel will try to allocate memory used by a CPU on the
965965
local memory of the CPU and add some more
@@ -1520,6 +1520,33 @@ config ARM64_PTR_AUTH
15201520

15211521
endmenu
15221522

1523+
menu "ARMv8.4 architectural features"
1524+
1525+
config ARM64_AMU_EXTN
1526+
bool "Enable support for the Activity Monitors Unit CPU extension"
1527+
default y
1528+
help
1529+
The activity monitors extension is an optional extension introduced
1530+
by the ARMv8.4 CPU architecture. This enables support for version 1
1531+
of the activity monitors architecture, AMUv1.
1532+
1533+
To enable the use of this extension on CPUs that implement it, say Y.
1534+
1535+
Note that for architectural reasons, firmware _must_ implement AMU
1536+
support when running on CPUs that present the activity monitors
1537+
extension. The required support is present in:
1538+
* Version 1.5 and later of the ARM Trusted Firmware
1539+
1540+
For kernels that have this configuration enabled but boot with broken
1541+
firmware, you may need to say N here until the firmware is fixed.
1542+
Otherwise you may experience firmware panics or lockups when
1543+
accessing the counter registers. Even if you are not observing these
1544+
symptoms, the values returned by the register reads might not
1545+
correctly reflect reality. Most commonly, the value read will be 0,
1546+
indicating that the counter is not enabled.
1547+
1548+
endmenu
1549+
15231550
menu "ARMv8.5 architectural features"
15241551

15251552
config ARM64_E0PD

arch/arm64/include/asm/assembler.h

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -256,12 +256,6 @@ alternative_endif
256256
ldr \rd, [\rn, #VMA_VM_MM]
257257
.endm
258258

259-
/*
260-
* mmid - get context id from mm pointer (mm->context.id)
261-
*/
262-
.macro mmid, rd, rn
263-
ldr \rd, [\rn, #MM_CONTEXT_ID]
264-
.endm
265259
/*
266260
* read_ctr - read CTR_EL0. If the system has mismatched register fields,
267261
* provide the system wide safe value from arm64_ftr_reg_ctrel0.sys_val
@@ -430,6 +424,16 @@ USER(\label, ic ivau, \tmp2) // invalidate I line PoU
430424
9000:
431425
.endm
432426

427+
/*
428+
* reset_amuserenr_el0 - reset AMUSERENR_EL0 if AMUv1 present
429+
*/
430+
.macro reset_amuserenr_el0, tmpreg
431+
mrs \tmpreg, id_aa64pfr0_el1 // Check ID_AA64PFR0_EL1
432+
ubfx \tmpreg, \tmpreg, #ID_AA64PFR0_AMU_SHIFT, #4
433+
cbz \tmpreg, .Lskip_\@ // Skip if no AMU present
434+
msr_s SYS_AMUSERENR_EL0, xzr // Disable AMU access from EL0
435+
.Lskip_\@:
436+
.endm
433437
/*
434438
* copy_page - copy src to dest using temp registers t1-t8
435439
*/

arch/arm64/include/asm/checksum.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@
55
#ifndef __ASM_CHECKSUM_H
66
#define __ASM_CHECKSUM_H
77

8-
#include <linux/types.h>
8+
#include <linux/in6.h>
9+
10+
#define _HAVE_ARCH_IPV6_CSUM
11+
__sum16 csum_ipv6_magic(const struct in6_addr *saddr,
12+
const struct in6_addr *daddr,
13+
__u32 len, __u8 proto, __wsum sum);
914

1015
static inline __sum16 csum_fold(__wsum csum)
1116
{

arch/arm64/include/asm/cpu_ops.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,12 @@ struct cpu_operations {
5555
#endif
5656
};
5757

58-
extern const struct cpu_operations *cpu_ops[NR_CPUS];
59-
int __init cpu_read_ops(int cpu);
58+
int __init init_cpu_ops(int cpu);
59+
extern const struct cpu_operations *get_cpu_ops(int cpu);
6060

61-
static inline void __init cpu_read_bootcpu_ops(void)
61+
static inline void __init init_bootcpu_ops(void)
6262
{
63-
cpu_read_ops(0);
63+
init_cpu_ops(0);
6464
}
6565

6666
#endif /* ifndef __ASM_CPU_OPS_H */

arch/arm64/include/asm/cpucaps.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@
5858
#define ARM64_WORKAROUND_SPECULATIVE_AT_NVHE 48
5959
#define ARM64_HAS_E0PD 49
6060
#define ARM64_HAS_RNG 50
61+
#define ARM64_HAS_AMU_EXTN 51
6162

62-
#define ARM64_NCAPS 51
63+
#define ARM64_NCAPS 52
6364

6465
#endif /* __ASM_CPUCAPS_H */

arch/arm64/include/asm/cpufeature.h

Lines changed: 75 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -390,29 +390,70 @@ unsigned long cpu_get_elf_hwcap2(void);
390390
#define cpu_set_named_feature(name) cpu_set_feature(cpu_feature(name))
391391
#define cpu_have_named_feature(name) cpu_have_feature(cpu_feature(name))
392392

393-
/* System capability check for constant caps */
394-
static __always_inline bool __cpus_have_const_cap(int num)
393+
static __always_inline bool system_capabilities_finalized(void)
395394
{
396-
if (num >= ARM64_NCAPS)
397-
return false;
398-
return static_branch_unlikely(&cpu_hwcap_keys[num]);
395+
return static_branch_likely(&arm64_const_caps_ready);
399396
}
400397

398+
/*
399+
* Test for a capability with a runtime check.
400+
*
401+
* Before the capability is detected, this returns false.
402+
*/
401403
static inline bool cpus_have_cap(unsigned int num)
402404
{
403405
if (num >= ARM64_NCAPS)
404406
return false;
405407
return test_bit(num, cpu_hwcaps);
406408
}
407409

410+
/*
411+
* Test for a capability without a runtime check.
412+
*
413+
* Before capabilities are finalized, this returns false.
414+
* After capabilities are finalized, this is patched to avoid a runtime check.
415+
*
416+
* @num must be a compile-time constant.
417+
*/
418+
static __always_inline bool __cpus_have_const_cap(int num)
419+
{
420+
if (num >= ARM64_NCAPS)
421+
return false;
422+
return static_branch_unlikely(&cpu_hwcap_keys[num]);
423+
}
424+
425+
/*
426+
* Test for a capability, possibly with a runtime check.
427+
*
428+
* Before capabilities are finalized, this behaves as cpus_have_cap().
429+
* After capabilities are finalized, this is patched to avoid a runtime check.
430+
*
431+
* @num must be a compile-time constant.
432+
*/
408433
static __always_inline bool cpus_have_const_cap(int num)
409434
{
410-
if (static_branch_likely(&arm64_const_caps_ready))
435+
if (system_capabilities_finalized())
411436
return __cpus_have_const_cap(num);
412437
else
413438
return cpus_have_cap(num);
414439
}
415440

441+
/*
442+
* Test for a capability without a runtime check.
443+
*
444+
* Before capabilities are finalized, this will BUG().
445+
* After capabilities are finalized, this is patched to avoid a runtime check.
446+
*
447+
* @num must be a compile-time constant.
448+
*/
449+
static __always_inline bool cpus_have_final_cap(int num)
450+
{
451+
if (system_capabilities_finalized())
452+
return __cpus_have_const_cap(num);
453+
else
454+
BUG();
455+
}
456+
416457
static inline void cpus_set_cap(unsigned int num)
417458
{
418459
if (num >= ARM64_NCAPS) {
@@ -447,6 +488,29 @@ cpuid_feature_extract_unsigned_field(u64 features, int field)
447488
return cpuid_feature_extract_unsigned_field_width(features, field, 4);
448489
}
449490

491+
/*
492+
* Fields that identify the version of the Performance Monitors Extension do
493+
* not follow the standard ID scheme. See ARM DDI 0487E.a page D13-2825,
494+
* "Alternative ID scheme used for the Performance Monitors Extension version".
495+
*/
496+
static inline u64 __attribute_const__
497+
cpuid_feature_cap_perfmon_field(u64 features, int field, u64 cap)
498+
{
499+
u64 val = cpuid_feature_extract_unsigned_field(features, field);
500+
u64 mask = GENMASK_ULL(field + 3, field);
501+
502+
/* Treat IMPLEMENTATION DEFINED functionality as unimplemented */
503+
if (val == 0xf)
504+
val = 0;
505+
506+
if (val > cap) {
507+
features &= ~mask;
508+
features |= (cap << field) & mask;
509+
}
510+
511+
return features;
512+
}
513+
450514
static inline u64 arm64_ftr_mask(const struct arm64_ftr_bits *ftrp)
451515
{
452516
return (u64)GENMASK(ftrp->shift + ftrp->width - 1, ftrp->shift);
@@ -613,11 +677,6 @@ static inline bool system_has_prio_mask_debugging(void)
613677
system_uses_irq_prio_masking();
614678
}
615679

616-
static inline bool system_capabilities_finalized(void)
617-
{
618-
return static_branch_likely(&arm64_const_caps_ready);
619-
}
620-
621680
#define ARM64_BP_HARDEN_UNKNOWN -1
622681
#define ARM64_BP_HARDEN_WA_NEEDED 0
623682
#define ARM64_BP_HARDEN_NOT_REQUIRED 1
@@ -678,6 +737,11 @@ static inline bool cpu_has_hw_af(void)
678737
ID_AA64MMFR1_HADBS_SHIFT);
679738
}
680739

740+
#ifdef CONFIG_ARM64_AMU_EXTN
741+
/* Check whether the cpu supports the Activity Monitors Unit (AMU) */
742+
extern bool cpu_has_amu_feat(int cpu);
743+
#endif
744+
681745
#endif /* __ASSEMBLY__ */
682746

683747
#endif

0 commit comments

Comments
 (0)