Commit da12d273 authored by Catalin Marinas's avatar Catalin Marinas
Browse files

Merge branches 'for-next/memory-hotremove', 'for-next/arm_sdei',...

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'
Loading
Loading
Loading
Loading
+112 −0
Original line number Diff line number Diff line
=======================================================
Activity Monitors Unit (AMU) extension in AArch64 Linux
=======================================================

Author: Ionela Voinescu <ionela.voinescu@arm.com>

Date: 2019-09-10

This document briefly describes the provision of Activity Monitors Unit
support in AArch64 Linux.


Architecture overview
---------------------

The activity monitors extension is an optional extension introduced by the
ARMv8.4 CPU architecture.

The activity monitors unit, implemented in each CPU, provides performance
counters intended for system management use. The AMU extension provides a
system register interface to the counter registers and also supports an
optional external memory-mapped interface.

Version 1 of the Activity Monitors architecture implements a counter group
of four fixed and architecturally defined 64-bit event counters.
  - CPU cycle counter: increments at the frequency of the CPU.
  - Constant counter: increments at the fixed frequency of the system
    clock.
  - Instructions retired: increments with every architecturally executed
    instruction.
  - Memory stall cycles: counts instruction dispatch stall cycles caused by
    misses in the last level cache within the clock domain.

When in WFI or WFE these counters do not increment.

The Activity Monitors architecture provides space for up to 16 architected
event counters. Future versions of the architecture may use this space to
implement additional architected event counters.

Additionally, version 1 implements a counter group of up to 16 auxiliary
64-bit event counters.

On cold reset all counters reset to 0.


Basic support
-------------

The kernel can safely run a mix of CPUs with and without support for the
activity monitors extension. Therefore, when CONFIG_ARM64_AMU_EXTN is
selected we unconditionally enable the capability to allow any late CPU
(secondary or hotplugged) to detect and use the feature.

When the feature is detected on a CPU, we flag the availability of the
feature but this does not guarantee the correct functionality of the
counters, only the presence of the extension.

Firmware (code running at higher exception levels, e.g. arm-tf) support is
needed to:
 - Enable access for lower exception levels (EL2 and EL1) to the AMU
   registers.
 - Enable the counters. If not enabled these will read as 0.
 - Save/restore the counters before/after the CPU is being put/brought up
   from the 'off' power state.

When using kernels that have this feature enabled but boot with broken
firmware the user may experience panics or lockups when accessing the
counter registers. Even if these symptoms are not observed, the values
returned by the register reads might not correctly reflect reality. Most
commonly, the counters will read as 0, indicating that they are not
enabled.

If proper support is not provided in firmware it's best to disable
CONFIG_ARM64_AMU_EXTN. To be noted that for security reasons, this does not
bypass the setting of AMUSERENR_EL0 to trap accesses from EL0 (userspace) to
EL1 (kernel). Therefore, firmware should still ensure accesses to AMU registers
are not trapped in EL2/EL3.

The fixed counters of AMUv1 are accessible though the following system
register definitions:
 - SYS_AMEVCNTR0_CORE_EL0
 - SYS_AMEVCNTR0_CONST_EL0
 - SYS_AMEVCNTR0_INST_RET_EL0
 - SYS_AMEVCNTR0_MEM_STALL_EL0

Auxiliary platform specific counters can be accessed using
SYS_AMEVCNTR1_EL0(n), where n is a value between 0 and 15.

Details can be found in: arch/arm64/include/asm/sysreg.h.


Userspace access
----------------

Currently, access from userspace to the AMU registers is disabled due to:
 - Security reasons: they might expose information about code executed in
   secure mode.
 - Purpose: AMU counters are intended for system management use.

Also, the presence of the feature is not visible to userspace.


Virtualization
--------------

Currently, access from userspace (EL0) and kernelspace (EL1) on the KVM
guest side is disabled due to:
 - Security reasons: they might expose information about code executed
   by other guests or the host.

Any attempt to access the AMU registers will result in an UNDEFINED
exception being injected into the guest.
+14 −0
Original line number Diff line number Diff line
@@ -248,6 +248,20 @@ Before jumping into the kernel, the following conditions must be met:
    - HCR_EL2.APK (bit 40) must be initialised to 0b1
    - HCR_EL2.API (bit 41) must be initialised to 0b1

  For CPUs with Activity Monitors Unit v1 (AMUv1) extension present:
  - If EL3 is present:
    CPTR_EL3.TAM (bit 30) must be initialised to 0b0
    CPTR_EL2.TAM (bit 30) must be initialised to 0b0
    AMCNTENSET0_EL0 must be initialised to 0b1111
    AMCNTENSET1_EL0 must be initialised to a platform specific value
    having 0b1 set for the corresponding bit for each of the auxiliary
    counters present.
  - If the kernel is entered at EL1:
    AMCNTENSET0_EL0 must be initialised to 0b1111
    AMCNTENSET1_EL0 must be initialised to a platform specific value
    having 0b1 set for the corresponding bit for each of the auxiliary
    counters present.

The requirements described above for CPU mode, caches, MMUs, architected
timers, coherency and system registers apply to all CPUs.  All CPUs must
enter the kernel in the same exception level.
+1 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ ARM64 Architecture
    :maxdepth: 1

    acpi_object_usage
    amu
    arm-acpi
    booting
    cpu-feature-registers
+29 −2
Original line number Diff line number Diff line
@@ -955,11 +955,11 @@ config HOTPLUG_CPU

# Common NUMA Features
config NUMA
	bool "Numa Memory Allocation and Scheduler Support"
	bool "NUMA Memory Allocation and Scheduler Support"
	select ACPI_NUMA if ACPI
	select OF_NUMA
	help
	  Enable NUMA (Non Uniform Memory Access) support.
	  Enable NUMA (Non-Uniform Memory Access) support.

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

endmenu

menu "ARMv8.4 architectural features"

config ARM64_AMU_EXTN
	bool "Enable support for the Activity Monitors Unit CPU extension"
	default y
	help
	  The activity monitors extension is an optional extension introduced
	  by the ARMv8.4 CPU architecture. This enables support for version 1
	  of the activity monitors architecture, AMUv1.

	  To enable the use of this extension on CPUs that implement it, say Y.

	  Note that for architectural reasons, firmware _must_ implement AMU
	  support when running on CPUs that present the activity monitors
	  extension. The required support is present in:
	    * Version 1.5 and later of the ARM Trusted Firmware

	  For kernels that have this configuration enabled but boot with broken
	  firmware, you may need to say N here until the firmware is fixed.
	  Otherwise you may experience firmware panics or lockups when
	  accessing the counter registers. Even if you are not observing these
	  symptoms, the values returned by the register reads might not
	  correctly reflect reality. Most commonly, the value read will be 0,
	  indicating that the counter is not enabled.

endmenu

menu "ARMv8.5 architectural features"

config ARM64_E0PD
+10 −6
Original line number Diff line number Diff line
@@ -256,12 +256,6 @@ alternative_endif
	ldr	\rd, [\rn, #VMA_VM_MM]
	.endm

/*
 * mmid - get context id from mm pointer (mm->context.id)
 */
	.macro	mmid, rd, rn
	ldr	\rd, [\rn, #MM_CONTEXT_ID]
	.endm
/*
 * read_ctr - read CTR_EL0. If the system has mismatched register fields,
 * 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
9000:
	.endm

/*
 * reset_amuserenr_el0 - reset AMUSERENR_EL0 if AMUv1 present
 */
	.macro	reset_amuserenr_el0, tmpreg
	mrs	\tmpreg, id_aa64pfr0_el1	// Check ID_AA64PFR0_EL1
	ubfx	\tmpreg, \tmpreg, #ID_AA64PFR0_AMU_SHIFT, #4
	cbz	\tmpreg, .Lskip_\@		// Skip if no AMU present
	msr_s	SYS_AMUSERENR_EL0, xzr		// Disable AMU access from EL0
.Lskip_\@:
	.endm
/*
 * copy_page - copy src to dest using temp registers t1-t8
 */
Loading