Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f4000cd9 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull arm64 updates from Catalin Marinas:

 - struct thread_info moved off-stack (also touching
   include/linux/thread_info.h and include/linux/restart_block.h)

 - cpus_have_cap() reworked to avoid __builtin_constant_p() for static
   key use (also touching drivers/irqchip/irq-gic-v3.c)

 - uprobes support (currently only for native 64-bit tasks)

 - Emulation of kernel Privileged Access Never (PAN) using TTBR0_EL1
   switching to a reserved page table

 - CPU capacity information passing via DT or sysfs (used by the
   scheduler)

 - support for systems without FP/SIMD (IOW, kernel avoids touching
   these registers; there is no soft-float ABI, nor kernel emulation for
   AArch64 FP/SIMD)

 - handling of hardware watchpoint with unaligned addresses, varied
   lengths and offsets from base

 - use of the page table contiguous hint for kernel mappings

 - hugetlb fixes for sizes involving the contiguous hint

 - remove unnecessary I-cache invalidation in flush_cache_range()

 - CNTHCTL_EL2 access fix for CPUs with VHE support (ARMv8.1)

 - boot-time checks for writable+executable kernel mappings

 - simplify asm/opcodes.h and avoid including the 32-bit ARM counterpart
   and make the arm64 kernel headers self-consistent (Xen headers patch
   merged separately)

 - Workaround for broken .inst support in certain binutils versions

* tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: (60 commits)
  arm64: Disable PAN on uaccess_enable()
  arm64: Work around broken .inst when defective gas is detected
  arm64: Add detection code for broken .inst support in binutils
  arm64: Remove reference to asm/opcodes.h
  arm64: Get rid of asm/opcodes.h
  arm64: smp: Prevent raw_smp_processor_id() recursion
  arm64: head.S: Fix CNTHCTL_EL2 access on VHE system
  arm64: Remove I-cache invalidation from flush_cache_range()
  arm64: Enable HIBERNATION in defconfig
  arm64: Enable CONFIG_ARM64_SW_TTBR0_PAN
  arm64: xen: Enable user access before a privcmd hvc call
  arm64: Handle faults caused by inadvertent user access with PAN enabled
  arm64: Disable TTBR0_EL1 during normal kernel execution
  arm64: Introduce uaccess_{disable,enable} functionality based on TTBR0_EL1
  arm64: Factor out TTBR0_EL1 post-update workaround into a specific asm macro
  arm64: Factor out PAN enabling/disabling into separate uaccess_* macros
  arm64: Update the synchronous external abort fault description
  selftests: arm64: add test for unaligned/inexact watchpoint handling
  arm64: Allow hw watchpoint of length 3,5,6 and 7
  arm64: hw_breakpoint: Handle inexact watchpoint addresses
  ...
parents 2ec4584e 75037120
Loading
Loading
Loading
Loading
+236 −0
Original line number Diff line number Diff line
==========================================
ARM CPUs capacity bindings
==========================================

==========================================
1 - Introduction
==========================================

ARM systems may be configured to have cpus with different power/performance
characteristics within the same chip. In this case, additional information has
to be made available to the kernel for it to be aware of such differences and
take decisions accordingly.

==========================================
2 - CPU capacity definition
==========================================

CPU capacity is a number that provides the scheduler information about CPUs
heterogeneity. Such heterogeneity can come from micro-architectural differences
(e.g., ARM big.LITTLE systems) or maximum frequency at which CPUs can run
(e.g., SMP systems with multiple frequency domains). Heterogeneity in this
context is about differing performance characteristics; this binding tries to
capture a first-order approximation of the relative performance of CPUs.

CPU capacities are obtained by running a suitable benchmark. This binding makes
no guarantees on the validity or suitability of any particular benchmark, the
final capacity should, however, be:

* A "single-threaded" or CPU affine benchmark
* Divided by the running frequency of the CPU executing the benchmark
* Not subject to dynamic frequency scaling of the CPU

For the time being we however advise usage of the Dhrystone benchmark. What
above thus becomes:

CPU capacities are obtained by running the Dhrystone benchmark on each CPU at
max frequency (with caches enabled). The obtained DMIPS score is then divided
by the frequency (in MHz) at which the benchmark has been run, so that
DMIPS/MHz are obtained.  Such values are then normalized w.r.t. the highest
score obtained in the system.

==========================================
3 - capacity-dmips-mhz
==========================================

capacity-dmips-mhz is an optional cpu node [1] property: u32 value
representing CPU capacity expressed in normalized DMIPS/MHz. At boot time, the
maximum frequency available to the cpu is then used to calculate the capacity
value internally used by the kernel.

capacity-dmips-mhz property is all-or-nothing: if it is specified for a cpu
node, it has to be specified for every other cpu nodes, or the system will
fall back to the default capacity value for every CPU. If cpufreq is not
available, final capacities are calculated by directly using capacity-dmips-
mhz values (normalized w.r.t. the highest value found while parsing the DT).

===========================================
4 - Examples
===========================================

Example 1 (ARM 64-bit, 6-cpu system, two clusters):
capacities-dmips-mhz are scaled w.r.t. 1024 (cpu@0 and cpu@1)
supposing cluster0@max-freq=1100 and custer1@max-freq=850,
final capacities are 1024 for cluster0 and 446 for cluster1

cpus {
	#address-cells = <2>;
	#size-cells = <0>;

	cpu-map {
		cluster0 {
			core0 {
				cpu = <&A57_0>;
			};
			core1 {
				cpu = <&A57_1>;
			};
		};

		cluster1 {
			core0 {
				cpu = <&A53_0>;
			};
			core1 {
				cpu = <&A53_1>;
			};
			core2 {
				cpu = <&A53_2>;
			};
			core3 {
				cpu = <&A53_3>;
			};
		};
	};

	idle-states {
		entry-method = "arm,psci";

		CPU_SLEEP_0: cpu-sleep-0 {
			compatible = "arm,idle-state";
			arm,psci-suspend-param = <0x0010000>;
			local-timer-stop;
			entry-latency-us = <100>;
			exit-latency-us = <250>;
			min-residency-us = <150>;
		};

		CLUSTER_SLEEP_0: cluster-sleep-0 {
			compatible = "arm,idle-state";
			arm,psci-suspend-param = <0x1010000>;
			local-timer-stop;
			entry-latency-us = <800>;
			exit-latency-us = <700>;
			min-residency-us = <2500>;
		};
	};

	A57_0: cpu@0 {
		compatible = "arm,cortex-a57","arm,armv8";
		reg = <0x0 0x0>;
		device_type = "cpu";
		enable-method = "psci";
		next-level-cache = <&A57_L2>;
		clocks = <&scpi_dvfs 0>;
		cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
		capacity-dmips-mhz = <1024>;
	};

	A57_1: cpu@1 {
		compatible = "arm,cortex-a57","arm,armv8";
		reg = <0x0 0x1>;
		device_type = "cpu";
		enable-method = "psci";
		next-level-cache = <&A57_L2>;
		clocks = <&scpi_dvfs 0>;
		cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
		capacity-dmips-mhz = <1024>;
	};

	A53_0: cpu@100 {
		compatible = "arm,cortex-a53","arm,armv8";
		reg = <0x0 0x100>;
		device_type = "cpu";
		enable-method = "psci";
		next-level-cache = <&A53_L2>;
		clocks = <&scpi_dvfs 1>;
		cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
		capacity-dmips-mhz = <578>;
	};

	A53_1: cpu@101 {
		compatible = "arm,cortex-a53","arm,armv8";
		reg = <0x0 0x101>;
		device_type = "cpu";
		enable-method = "psci";
		next-level-cache = <&A53_L2>;
		clocks = <&scpi_dvfs 1>;
		cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
		capacity-dmips-mhz = <578>;
	};

	A53_2: cpu@102 {
		compatible = "arm,cortex-a53","arm,armv8";
		reg = <0x0 0x102>;
		device_type = "cpu";
		enable-method = "psci";
		next-level-cache = <&A53_L2>;
		clocks = <&scpi_dvfs 1>;
		cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
		capacity-dmips-mhz = <578>;
	};

	A53_3: cpu@103 {
		compatible = "arm,cortex-a53","arm,armv8";
		reg = <0x0 0x103>;
		device_type = "cpu";
		enable-method = "psci";
		next-level-cache = <&A53_L2>;
		clocks = <&scpi_dvfs 1>;
		cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
		capacity-dmips-mhz = <578>;
	};

	A57_L2: l2-cache0 {
		compatible = "cache";
	};

	A53_L2: l2-cache1 {
		compatible = "cache";
	};
};

Example 2 (ARM 32-bit, 4-cpu system, two clusters,
	   cpus 0,1@1GHz, cpus 2,3@500MHz):
capacities-dmips-mhz are scaled w.r.t. 2 (cpu@0 and cpu@1), this means that first
cpu@0 and cpu@1 are twice fast than cpu@2 and cpu@3 (at the same frequency)

cpus {
	#address-cells = <1>;
	#size-cells = <0>;

	cpu0: cpu@0 {
		device_type = "cpu";
		compatible = "arm,cortex-a15";
		reg = <0>;
		capacity-dmips-mhz = <2>;
	};

	cpu1: cpu@1 {
		device_type = "cpu";
		compatible = "arm,cortex-a15";
		reg = <1>;
		capacity-dmips-mhz = <2>;
	};

	cpu2: cpu@2 {
		device_type = "cpu";
		compatible = "arm,cortex-a15";
		reg = <0x100>;
		capacity-dmips-mhz = <1>;
	};

	cpu3: cpu@3 {
		device_type = "cpu";
		compatible = "arm,cortex-a15";
		reg = <0x101>;
		capacity-dmips-mhz = <1>;
	};
};

===========================================
5 - References
===========================================

[1] ARM Linux Kernel documentation - CPUs bindings
    Documentation/devicetree/bindings/arm/cpus.txt
+10 −0
Original line number Diff line number Diff line
@@ -241,6 +241,14 @@ nodes to be present and contain the properties described below.
			# List of phandles to idle state nodes supported
			  by this cpu [3].

	- capacity-dmips-mhz
		Usage: Optional
		Value type: <u32>
		Definition:
			# u32 value representing CPU capacity [3] in
			  DMIPS/MHz, relative to highest capacity-dmips-mhz
			  in the system.

	- rockchip,pmu
		Usage: optional for systems that have an "enable-method"
		       property value of "rockchip,rk3066-smp"
@@ -464,3 +472,5 @@ cpus {
[2] arm/msm/qcom,kpss-acc.txt
[3] ARM Linux kernel documentation - idle states bindings
    Documentation/devicetree/bindings/arm/idle-states.txt
[3] ARM Linux kernel documentation - cpu capacity bindings
    Documentation/devicetree/bindings/arm/cpu-capacity.txt
+12 −0
Original line number Diff line number Diff line
@@ -110,6 +110,7 @@ config ARM64
	select POWER_SUPPLY
	select SPARSE_IRQ
	select SYSCTL_EXCEPTION_TRACE
	select THREAD_INFO_IN_TASK
	help
	  ARM 64-bit (AArch64) Linux support.

@@ -239,6 +240,9 @@ config PGTABLE_LEVELS
	default 3 if ARM64_16K_PAGES && ARM64_VA_BITS_47
	default 4 if !ARM64_64K_PAGES && ARM64_VA_BITS_48

config ARCH_SUPPORTS_UPROBES
	def_bool y

source "init/Kconfig"

source "kernel/Kconfig.freezer"
@@ -791,6 +795,14 @@ config SETEND_EMULATION
	  If unsure, say Y
endif

config ARM64_SW_TTBR0_PAN
	bool "Emulate Privileged Access Never using TTBR0_EL1 switching"
	help
	  Enabling this option prevents the kernel from accessing
	  user-space memory directly by pointing TTBR0_EL1 to a reserved
	  zeroed area and reserved ASID. The user access routines
	  restore the valid TTBR0_EL1 temporarily.

menu "ARMv8.1 architectural features"

config ARM64_HW_AFDBM
+34 −1
Original line number Diff line number Diff line
@@ -2,9 +2,13 @@ menu "Kernel hacking"

source "lib/Kconfig.debug"

config ARM64_PTDUMP
config ARM64_PTDUMP_CORE
	def_bool n

config ARM64_PTDUMP_DEBUGFS
	bool "Export kernel pagetable layout to userspace via debugfs"
	depends on DEBUG_KERNEL
	select ARM64_PTDUMP_CORE
	select DEBUG_FS
        help
	  Say Y here if you want to show the kernel pagetable layout in a
@@ -38,6 +42,35 @@ config ARM64_RANDOMIZE_TEXT_OFFSET
	  of TEXT_OFFSET and platforms must not require a specific
	  value.

config DEBUG_WX
	bool "Warn on W+X mappings at boot"
	select ARM64_PTDUMP_CORE
	---help---
	  Generate a warning if any W+X mappings are found at boot.

	  This is useful for discovering cases where the kernel is leaving
	  W+X mappings after applying NX, as such mappings are a security risk.
	  This check also includes UXN, which should be set on all kernel
	  mappings.

	  Look for a message in dmesg output like this:

	    arm64/mm: Checked W+X mappings: passed, no W+X pages found.

	  or like this, if the check failed:

	    arm64/mm: Checked W+X mappings: FAILED, <N> W+X pages found.

	  Note that even if the check fails, your kernel is possibly
	  still fine, as W+X mappings are not a security hole in
	  themselves, what they do is that they make the exploitation
	  of other unfixed kernel bugs easier.

	  There is no runtime or memory usage effect of this option
	  once the kernel has booted up - it's a one time check.

	  If in doubt, say "Y".

config DEBUG_SET_MODULE_RONX
	bool "Set loadable kernel module data as NX and text as RO"
	depends on MODULES
+8 −2
Original line number Diff line number Diff line
@@ -37,10 +37,16 @@ $(warning LSE atomics not supported by binutils)
  endif
endif

KBUILD_CFLAGS	+= -mgeneral-regs-only $(lseinstr)
brokengasinst := $(call as-instr,1:\n.inst 0\n.rept . - 1b\n\nnop\n.endr\n,,-DCONFIG_BROKEN_GAS_INST=1)

ifneq ($(brokengasinst),)
$(warning Detected assembler with broken .inst; disassembly will be unreliable)
endif

KBUILD_CFLAGS	+= -mgeneral-regs-only $(lseinstr) $(brokengasinst)
KBUILD_CFLAGS	+= -fno-asynchronous-unwind-tables
KBUILD_CFLAGS	+= $(call cc-option, -mpc-relative-literal-loads)
KBUILD_AFLAGS	+= $(lseinstr)
KBUILD_AFLAGS	+= $(lseinstr) $(brokengasinst)

ifeq ($(CONFIG_CPU_BIG_ENDIAN), y)
KBUILD_CPPFLAGS	+= -mbig-endian
Loading