You've already forked linux-rockchip
mirror of
https://github.com/armbian/linux-rockchip.git
synced 2026-01-06 11:08:10 -08:00
Merge tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull arm64 updates from Will Deacon:
"There's quite a lot of code here, but much of it is due to the
addition of a new PMU driver as well as some arm64-specific selftests
which is an area where we've traditionally been lagging a bit.
In terms of exciting features, this includes support for the Memory
Tagging Extension which narrowly missed 5.9, hopefully allowing
userspace to run with use-after-free detection in production on CPUs
that support it. Work is ongoing to integrate the feature with KASAN
for 5.11.
Another change that I'm excited about (assuming they get the hardware
right) is preparing the ASID allocator for sharing the CPU page-table
with the SMMU. Those changes will also come in via Joerg with the
IOMMU pull.
We do stray outside of our usual directories in a few places, mostly
due to core changes required by MTE. Although much of this has been
Acked, there were a couple of places where we unfortunately didn't get
any review feedback.
Other than that, we ran into a handful of minor conflicts in -next,
but nothing that should post any issues.
Summary:
- Userspace support for the Memory Tagging Extension introduced by
Armv8.5. Kernel support (via KASAN) is likely to follow in 5.11.
- Selftests for MTE, Pointer Authentication and FPSIMD/SVE context
switching.
- Fix and subsequent rewrite of our Spectre mitigations, including
the addition of support for PR_SPEC_DISABLE_NOEXEC.
- Support for the Armv8.3 Pointer Authentication enhancements.
- Support for ASID pinning, which is required when sharing
page-tables with the SMMU.
- MM updates, including treating flush_tlb_fix_spurious_fault() as a
no-op.
- Perf/PMU driver updates, including addition of the ARM CMN PMU
driver and also support to handle CPU PMU IRQs as NMIs.
- Allow prefetchable PCI BARs to be exposed to userspace using normal
non-cacheable mappings.
- Implementation of ARCH_STACKWALK for unwinding.
- Improve reporting of unexpected kernel traps due to BPF JIT
failure.
- Improve robustness of user-visible HWCAP strings and their
corresponding numerical constants.
- Removal of TEXT_OFFSET.
- Removal of some unused functions, parameters and prototypes.
- Removal of MPIDR-based topology detection in favour of firmware
description.
- Cleanups to handling of SVE and FPSIMD register state in
preparation for potential future optimisation of handling across
syscalls.
- Cleanups to the SDEI driver in preparation for support in KVM.
- Miscellaneous cleanups and refactoring work"
* tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: (148 commits)
Revert "arm64: initialize per-cpu offsets earlier"
arm64: random: Remove no longer needed prototypes
arm64: initialize per-cpu offsets earlier
kselftest/arm64: Check mte tagged user address in kernel
kselftest/arm64: Verify KSM page merge for MTE pages
kselftest/arm64: Verify all different mmap MTE options
kselftest/arm64: Check forked child mte memory accessibility
kselftest/arm64: Verify mte tag inclusion via prctl
kselftest/arm64: Add utilities and a test to validate mte memory
perf: arm-cmn: Fix conversion specifiers for node type
perf: arm-cmn: Fix unsigned comparison to less than zero
arm64: dbm: Invalidate local TLB when setting TCR_EL1.HD
arm64: mm: Make flush_tlb_fix_spurious_fault() a no-op
arm64: Add support for PR_SPEC_DISABLE_NOEXEC prctl() option
arm64: Pull in task_stack_page() to Spectre-v4 mitigation code
KVM: arm64: Allow patching EL2 vectors even with KASLR is not enabled
arm64: Get rid of arm64_ssbd_state
KVM: arm64: Convert ARCH_WORKAROUND_2 to arm64_get_spectre_v4_state()
KVM: arm64: Get rid of kvm_arm_have_ssbd()
KVM: arm64: Simplify handling of ARCH_WORKAROUND_2
...
This commit is contained in:
65
Documentation/admin-guide/perf/arm-cmn.rst
Normal file
65
Documentation/admin-guide/perf/arm-cmn.rst
Normal file
@@ -0,0 +1,65 @@
|
||||
=============================
|
||||
Arm Coherent Mesh Network PMU
|
||||
=============================
|
||||
|
||||
CMN-600 is a configurable mesh interconnect consisting of a rectangular
|
||||
grid of crosspoints (XPs), with each crosspoint supporting up to two
|
||||
device ports to which various AMBA CHI agents are attached.
|
||||
|
||||
CMN implements a distributed PMU design as part of its debug and trace
|
||||
functionality. This consists of a local monitor (DTM) at every XP, which
|
||||
counts up to 4 event signals from the connected device nodes and/or the
|
||||
XP itself. Overflow from these local counters is accumulated in up to 8
|
||||
global counters implemented by the main controller (DTC), which provides
|
||||
overall PMU control and interrupts for global counter overflow.
|
||||
|
||||
PMU events
|
||||
----------
|
||||
|
||||
The PMU driver registers a single PMU device for the whole interconnect,
|
||||
see /sys/bus/event_source/devices/arm_cmn. Multi-chip systems may link
|
||||
more than one CMN together via external CCIX links - in this situation,
|
||||
each mesh counts its own events entirely independently, and additional
|
||||
PMU devices will be named arm_cmn_{1..n}.
|
||||
|
||||
Most events are specified in a format based directly on the TRM
|
||||
definitions - "type" selects the respective node type, and "eventid" the
|
||||
event number. Some events require an additional occupancy ID, which is
|
||||
specified by "occupid".
|
||||
|
||||
* Since RN-D nodes do not have any distinct events from RN-I nodes, they
|
||||
are treated as the same type (0xa), and the common event templates are
|
||||
named "rnid_*".
|
||||
|
||||
* The cycle counter is treated as a synthetic event belonging to the DTC
|
||||
node ("type" == 0x3, "eventid" is ignored).
|
||||
|
||||
* XP events also encode the port and channel in the "eventid" field, to
|
||||
match the underlying pmu_event0_id encoding for the pmu_event_sel
|
||||
register. The event templates are named with prefixes to cover all
|
||||
permutations.
|
||||
|
||||
By default each event provides an aggregate count over all nodes of the
|
||||
given type. To target a specific node, "bynodeid" must be set to 1 and
|
||||
"nodeid" to the appropriate value derived from the CMN configuration
|
||||
(as defined in the "Node ID Mapping" section of the TRM).
|
||||
|
||||
Watchpoints
|
||||
-----------
|
||||
|
||||
The PMU can also count watchpoint events to monitor specific flit
|
||||
traffic. Watchpoints are treated as a synthetic event type, and like PMU
|
||||
events can be global or targeted with a particular XP's "nodeid" value.
|
||||
Since the watchpoint direction is otherwise implicit in the underlying
|
||||
register selection, separate events are provided for flit uploads and
|
||||
downloads.
|
||||
|
||||
The flit match value and mask are passed in config1 and config2 ("val"
|
||||
and "mask" respectively). "wp_dev_sel", "wp_chn_sel", "wp_grp" and
|
||||
"wp_exclusive" are specified per the TRM definitions for dtm_wp_config0.
|
||||
Where a watchpoint needs to match fields from both match groups on the
|
||||
REQ or SNP channel, it can be specified as two events - one for each
|
||||
group - with the same nonzero "combine" value. The count for such a
|
||||
pair of combined events will be attributed to the primary match.
|
||||
Watchpoint events with a "combine" value of 0 are considered independent
|
||||
and will count individually.
|
||||
@@ -12,6 +12,7 @@ Performance monitor support
|
||||
qcom_l2_pmu
|
||||
qcom_l3_pmu
|
||||
arm-ccn
|
||||
arm-cmn
|
||||
xgene-pmu
|
||||
arm_dsu_pmu
|
||||
thunderx2-pmu
|
||||
|
||||
@@ -175,6 +175,8 @@ infrastructure:
|
||||
+------------------------------+---------+---------+
|
||||
| Name | bits | visible |
|
||||
+------------------------------+---------+---------+
|
||||
| MTE | [11-8] | y |
|
||||
+------------------------------+---------+---------+
|
||||
| SSBS | [7-4] | y |
|
||||
+------------------------------+---------+---------+
|
||||
| BT | [3-0] | y |
|
||||
|
||||
@@ -240,6 +240,10 @@ HWCAP2_BTI
|
||||
|
||||
Functionality implied by ID_AA64PFR0_EL1.BT == 0b0001.
|
||||
|
||||
HWCAP2_MTE
|
||||
|
||||
Functionality implied by ID_AA64PFR1_EL1.MTE == 0b0010, as described
|
||||
by Documentation/arm64/memory-tagging-extension.rst.
|
||||
|
||||
4. Unused AT_HWCAP bits
|
||||
-----------------------
|
||||
|
||||
@@ -14,6 +14,7 @@ ARM64 Architecture
|
||||
hugetlbpage
|
||||
legacy_instructions
|
||||
memory
|
||||
memory-tagging-extension
|
||||
perf
|
||||
pointer-authentication
|
||||
silicon-errata
|
||||
|
||||
305
Documentation/arm64/memory-tagging-extension.rst
Normal file
305
Documentation/arm64/memory-tagging-extension.rst
Normal file
@@ -0,0 +1,305 @@
|
||||
===============================================
|
||||
Memory Tagging Extension (MTE) in AArch64 Linux
|
||||
===============================================
|
||||
|
||||
Authors: Vincenzo Frascino <vincenzo.frascino@arm.com>
|
||||
Catalin Marinas <catalin.marinas@arm.com>
|
||||
|
||||
Date: 2020-02-25
|
||||
|
||||
This document describes the provision of the Memory Tagging Extension
|
||||
functionality in AArch64 Linux.
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
ARMv8.5 based processors introduce the Memory Tagging Extension (MTE)
|
||||
feature. MTE is built on top of the ARMv8.0 virtual address tagging TBI
|
||||
(Top Byte Ignore) feature and allows software to access a 4-bit
|
||||
allocation tag for each 16-byte granule in the physical address space.
|
||||
Such memory range must be mapped with the Normal-Tagged memory
|
||||
attribute. A logical tag is derived from bits 59-56 of the virtual
|
||||
address used for the memory access. A CPU with MTE enabled will compare
|
||||
the logical tag against the allocation tag and potentially raise an
|
||||
exception on mismatch, subject to system registers configuration.
|
||||
|
||||
Userspace Support
|
||||
=================
|
||||
|
||||
When ``CONFIG_ARM64_MTE`` is selected and Memory Tagging Extension is
|
||||
supported by the hardware, the kernel advertises the feature to
|
||||
userspace via ``HWCAP2_MTE``.
|
||||
|
||||
PROT_MTE
|
||||
--------
|
||||
|
||||
To access the allocation tags, a user process must enable the Tagged
|
||||
memory attribute on an address range using a new ``prot`` flag for
|
||||
``mmap()`` and ``mprotect()``:
|
||||
|
||||
``PROT_MTE`` - Pages allow access to the MTE allocation tags.
|
||||
|
||||
The allocation tag is set to 0 when such pages are first mapped in the
|
||||
user address space and preserved on copy-on-write. ``MAP_SHARED`` is
|
||||
supported and the allocation tags can be shared between processes.
|
||||
|
||||
**Note**: ``PROT_MTE`` is only supported on ``MAP_ANONYMOUS`` and
|
||||
RAM-based file mappings (``tmpfs``, ``memfd``). Passing it to other
|
||||
types of mapping will result in ``-EINVAL`` returned by these system
|
||||
calls.
|
||||
|
||||
**Note**: The ``PROT_MTE`` flag (and corresponding memory type) cannot
|
||||
be cleared by ``mprotect()``.
|
||||
|
||||
**Note**: ``madvise()`` memory ranges with ``MADV_DONTNEED`` and
|
||||
``MADV_FREE`` may have the allocation tags cleared (set to 0) at any
|
||||
point after the system call.
|
||||
|
||||
Tag Check Faults
|
||||
----------------
|
||||
|
||||
When ``PROT_MTE`` is enabled on an address range and a mismatch between
|
||||
the logical and allocation tags occurs on access, there are three
|
||||
configurable behaviours:
|
||||
|
||||
- *Ignore* - This is the default mode. The CPU (and kernel) ignores the
|
||||
tag check fault.
|
||||
|
||||
- *Synchronous* - The kernel raises a ``SIGSEGV`` synchronously, with
|
||||
``.si_code = SEGV_MTESERR`` and ``.si_addr = <fault-address>``. The
|
||||
memory access is not performed. If ``SIGSEGV`` is ignored or blocked
|
||||
by the offending thread, the containing process is terminated with a
|
||||
``coredump``.
|
||||
|
||||
- *Asynchronous* - The kernel raises a ``SIGSEGV``, in the offending
|
||||
thread, asynchronously following one or multiple tag check faults,
|
||||
with ``.si_code = SEGV_MTEAERR`` and ``.si_addr = 0`` (the faulting
|
||||
address is unknown).
|
||||
|
||||
The user can select the above modes, per thread, using the
|
||||
``prctl(PR_SET_TAGGED_ADDR_CTRL, flags, 0, 0, 0)`` system call where
|
||||
``flags`` contain one of the following values in the ``PR_MTE_TCF_MASK``
|
||||
bit-field:
|
||||
|
||||
- ``PR_MTE_TCF_NONE`` - *Ignore* tag check faults
|
||||
- ``PR_MTE_TCF_SYNC`` - *Synchronous* tag check fault mode
|
||||
- ``PR_MTE_TCF_ASYNC`` - *Asynchronous* tag check fault mode
|
||||
|
||||
The current tag check fault mode can be read using the
|
||||
``prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0)`` system call.
|
||||
|
||||
Tag checking can also be disabled for a user thread by setting the
|
||||
``PSTATE.TCO`` bit with ``MSR TCO, #1``.
|
||||
|
||||
**Note**: Signal handlers are always invoked with ``PSTATE.TCO = 0``,
|
||||
irrespective of the interrupted context. ``PSTATE.TCO`` is restored on
|
||||
``sigreturn()``.
|
||||
|
||||
**Note**: There are no *match-all* logical tags available for user
|
||||
applications.
|
||||
|
||||
**Note**: Kernel accesses to the user address space (e.g. ``read()``
|
||||
system call) are not checked if the user thread tag checking mode is
|
||||
``PR_MTE_TCF_NONE`` or ``PR_MTE_TCF_ASYNC``. If the tag checking mode is
|
||||
``PR_MTE_TCF_SYNC``, the kernel makes a best effort to check its user
|
||||
address accesses, however it cannot always guarantee it.
|
||||
|
||||
Excluding Tags in the ``IRG``, ``ADDG`` and ``SUBG`` instructions
|
||||
-----------------------------------------------------------------
|
||||
|
||||
The architecture allows excluding certain tags to be randomly generated
|
||||
via the ``GCR_EL1.Exclude`` register bit-field. By default, Linux
|
||||
excludes all tags other than 0. A user thread can enable specific tags
|
||||
in the randomly generated set using the ``prctl(PR_SET_TAGGED_ADDR_CTRL,
|
||||
flags, 0, 0, 0)`` system call where ``flags`` contains the tags bitmap
|
||||
in the ``PR_MTE_TAG_MASK`` bit-field.
|
||||
|
||||
**Note**: The hardware uses an exclude mask but the ``prctl()``
|
||||
interface provides an include mask. An include mask of ``0`` (exclusion
|
||||
mask ``0xffff``) results in the CPU always generating tag ``0``.
|
||||
|
||||
Initial process state
|
||||
---------------------
|
||||
|
||||
On ``execve()``, the new process has the following configuration:
|
||||
|
||||
- ``PR_TAGGED_ADDR_ENABLE`` set to 0 (disabled)
|
||||
- Tag checking mode set to ``PR_MTE_TCF_NONE``
|
||||
- ``PR_MTE_TAG_MASK`` set to 0 (all tags excluded)
|
||||
- ``PSTATE.TCO`` set to 0
|
||||
- ``PROT_MTE`` not set on any of the initial memory maps
|
||||
|
||||
On ``fork()``, the new process inherits the parent's configuration and
|
||||
memory map attributes with the exception of the ``madvise()`` ranges
|
||||
with ``MADV_WIPEONFORK`` which will have the data and tags cleared (set
|
||||
to 0).
|
||||
|
||||
The ``ptrace()`` interface
|
||||
--------------------------
|
||||
|
||||
``PTRACE_PEEKMTETAGS`` and ``PTRACE_POKEMTETAGS`` allow a tracer to read
|
||||
the tags from or set the tags to a tracee's address space. The
|
||||
``ptrace()`` system call is invoked as ``ptrace(request, pid, addr,
|
||||
data)`` where:
|
||||
|
||||
- ``request`` - one of ``PTRACE_PEEKMTETAGS`` or ``PTRACE_POKEMTETAGS``.
|
||||
- ``pid`` - the tracee's PID.
|
||||
- ``addr`` - address in the tracee's address space.
|
||||
- ``data`` - pointer to a ``struct iovec`` where ``iov_base`` points to
|
||||
a buffer of ``iov_len`` length in the tracer's address space.
|
||||
|
||||
The tags in the tracer's ``iov_base`` buffer are represented as one
|
||||
4-bit tag per byte and correspond to a 16-byte MTE tag granule in the
|
||||
tracee's address space.
|
||||
|
||||
**Note**: If ``addr`` is not aligned to a 16-byte granule, the kernel
|
||||
will use the corresponding aligned address.
|
||||
|
||||
``ptrace()`` return value:
|
||||
|
||||
- 0 - tags were copied, the tracer's ``iov_len`` was updated to the
|
||||
number of tags transferred. This may be smaller than the requested
|
||||
``iov_len`` if the requested address range in the tracee's or the
|
||||
tracer's space cannot be accessed or does not have valid tags.
|
||||
- ``-EPERM`` - the specified process cannot be traced.
|
||||
- ``-EIO`` - the tracee's address range cannot be accessed (e.g. invalid
|
||||
address) and no tags copied. ``iov_len`` not updated.
|
||||
- ``-EFAULT`` - fault on accessing the tracer's memory (``struct iovec``
|
||||
or ``iov_base`` buffer) and no tags copied. ``iov_len`` not updated.
|
||||
- ``-EOPNOTSUPP`` - the tracee's address does not have valid tags (never
|
||||
mapped with the ``PROT_MTE`` flag). ``iov_len`` not updated.
|
||||
|
||||
**Note**: There are no transient errors for the requests above, so user
|
||||
programs should not retry in case of a non-zero system call return.
|
||||
|
||||
``PTRACE_GETREGSET`` and ``PTRACE_SETREGSET`` with ``addr ==
|
||||
``NT_ARM_TAGGED_ADDR_CTRL`` allow ``ptrace()`` access to the tagged
|
||||
address ABI control and MTE configuration of a process as per the
|
||||
``prctl()`` options described in
|
||||
Documentation/arm64/tagged-address-abi.rst and above. The corresponding
|
||||
``regset`` is 1 element of 8 bytes (``sizeof(long))``).
|
||||
|
||||
Example of correct usage
|
||||
========================
|
||||
|
||||
*MTE Example code*
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
/*
|
||||
* To be compiled with -march=armv8.5-a+memtag
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/auxv.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/prctl.h>
|
||||
|
||||
/*
|
||||
* From arch/arm64/include/uapi/asm/hwcap.h
|
||||
*/
|
||||
#define HWCAP2_MTE (1 << 18)
|
||||
|
||||
/*
|
||||
* From arch/arm64/include/uapi/asm/mman.h
|
||||
*/
|
||||
#define PROT_MTE 0x20
|
||||
|
||||
/*
|
||||
* From include/uapi/linux/prctl.h
|
||||
*/
|
||||
#define PR_SET_TAGGED_ADDR_CTRL 55
|
||||
#define PR_GET_TAGGED_ADDR_CTRL 56
|
||||
# define PR_TAGGED_ADDR_ENABLE (1UL << 0)
|
||||
# define PR_MTE_TCF_SHIFT 1
|
||||
# define PR_MTE_TCF_NONE (0UL << PR_MTE_TCF_SHIFT)
|
||||
# define PR_MTE_TCF_SYNC (1UL << PR_MTE_TCF_SHIFT)
|
||||
# define PR_MTE_TCF_ASYNC (2UL << PR_MTE_TCF_SHIFT)
|
||||
# define PR_MTE_TCF_MASK (3UL << PR_MTE_TCF_SHIFT)
|
||||
# define PR_MTE_TAG_SHIFT 3
|
||||
# define PR_MTE_TAG_MASK (0xffffUL << PR_MTE_TAG_SHIFT)
|
||||
|
||||
/*
|
||||
* Insert a random logical tag into the given pointer.
|
||||
*/
|
||||
#define insert_random_tag(ptr) ({ \
|
||||
uint64_t __val; \
|
||||
asm("irg %0, %1" : "=r" (__val) : "r" (ptr)); \
|
||||
__val; \
|
||||
})
|
||||
|
||||
/*
|
||||
* Set the allocation tag on the destination address.
|
||||
*/
|
||||
#define set_tag(tagged_addr) do { \
|
||||
asm volatile("stg %0, [%0]" : : "r" (tagged_addr) : "memory"); \
|
||||
} while (0)
|
||||
|
||||
int main()
|
||||
{
|
||||
unsigned char *a;
|
||||
unsigned long page_sz = sysconf(_SC_PAGESIZE);
|
||||
unsigned long hwcap2 = getauxval(AT_HWCAP2);
|
||||
|
||||
/* check if MTE is present */
|
||||
if (!(hwcap2 & HWCAP2_MTE))
|
||||
return EXIT_FAILURE;
|
||||
|
||||
/*
|
||||
* Enable the tagged address ABI, synchronous MTE tag check faults and
|
||||
* allow all non-zero tags in the randomly generated set.
|
||||
*/
|
||||
if (prctl(PR_SET_TAGGED_ADDR_CTRL,
|
||||
PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC | (0xfffe << PR_MTE_TAG_SHIFT),
|
||||
0, 0, 0)) {
|
||||
perror("prctl() failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
a = mmap(0, page_sz, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
if (a == MAP_FAILED) {
|
||||
perror("mmap() failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable MTE on the above anonymous mmap. The flag could be passed
|
||||
* directly to mmap() and skip this step.
|
||||
*/
|
||||
if (mprotect(a, page_sz, PROT_READ | PROT_WRITE | PROT_MTE)) {
|
||||
perror("mprotect() failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* access with the default tag (0) */
|
||||
a[0] = 1;
|
||||
a[1] = 2;
|
||||
|
||||
printf("a[0] = %hhu a[1] = %hhu\n", a[0], a[1]);
|
||||
|
||||
/* set the logical and allocation tags */
|
||||
a = (unsigned char *)insert_random_tag(a);
|
||||
set_tag(a);
|
||||
|
||||
printf("%p\n", a);
|
||||
|
||||
/* non-zero tag access */
|
||||
a[0] = 3;
|
||||
printf("a[0] = %hhu a[1] = %hhu\n", a[0], a[1]);
|
||||
|
||||
/*
|
||||
* If MTE is enabled correctly the next instruction will generate an
|
||||
* exception.
|
||||
*/
|
||||
printf("Expecting SIGSEGV...\n");
|
||||
a[16] = 0xdd;
|
||||
|
||||
/* this should not be printed in the PR_MTE_TCF_SYNC mode */
|
||||
printf("...haven't got one\n");
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
57
Documentation/devicetree/bindings/perf/arm,cmn.yaml
Normal file
57
Documentation/devicetree/bindings/perf/arm,cmn.yaml
Normal file
@@ -0,0 +1,57 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
# Copyright 2020 Arm Ltd.
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/perf/arm,cmn.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Arm CMN (Coherent Mesh Network) Performance Monitors
|
||||
|
||||
maintainers:
|
||||
- Robin Murphy <robin.murphy@arm.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: arm,cmn-600
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: Physical address of the base (PERIPHBASE) and
|
||||
size (up to 64MB) of the configuration address space.
|
||||
|
||||
interrupts:
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
items:
|
||||
- description: Overflow interrupt for DTC0
|
||||
- description: Overflow interrupt for DTC1
|
||||
- description: Overflow interrupt for DTC2
|
||||
- description: Overflow interrupt for DTC3
|
||||
description: One interrupt for each DTC domain implemented must
|
||||
be specified, in order. DTC0 is always present.
|
||||
|
||||
arm,root-node:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Offset from PERIPHBASE of the configuration
|
||||
discovery node (see TRM definition of ROOTNODEBASE).
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- arm,root-node
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
pmu@50000000 {
|
||||
compatible = "arm,cmn-600";
|
||||
reg = <0x50000000 0x4000000>;
|
||||
/* 4x2 mesh with one DTC, and CFG node at 0,1,1,0 */
|
||||
interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
|
||||
arm,root-node = <0x104000>;
|
||||
};
|
||||
...
|
||||
@@ -54,9 +54,9 @@ these functions (see arch/arm{,64}/include/asm/virt.h):
|
||||
x3 = x1's value when entering the next payload (arm64)
|
||||
x4 = x2's value when entering the next payload (arm64)
|
||||
|
||||
Mask all exceptions, disable the MMU, move the arguments into place
|
||||
(arm64 only), and jump to the restart address while at HYP/EL2. This
|
||||
hypercall is not expected to return to its caller.
|
||||
Mask all exceptions, disable the MMU, clear I+D bits, move the arguments
|
||||
into place (arm64 only), and jump to the restart address while at HYP/EL2.
|
||||
This hypercall is not expected to return to its caller.
|
||||
|
||||
Any other value of r0/x0 triggers a hypervisor-specific handling,
|
||||
which is not documented here.
|
||||
|
||||
@@ -29,6 +29,7 @@ config ARM64
|
||||
select ARCH_HAS_SETUP_DMA_OPS
|
||||
select ARCH_HAS_SET_DIRECT_MAP
|
||||
select ARCH_HAS_SET_MEMORY
|
||||
select ARCH_STACKWALK
|
||||
select ARCH_HAS_STRICT_KERNEL_RWX
|
||||
select ARCH_HAS_STRICT_MODULE_RWX
|
||||
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
|
||||
@@ -211,12 +212,18 @@ config ARM64_PAGE_SHIFT
|
||||
default 14 if ARM64_16K_PAGES
|
||||
default 12
|
||||
|
||||
config ARM64_CONT_SHIFT
|
||||
config ARM64_CONT_PTE_SHIFT
|
||||
int
|
||||
default 5 if ARM64_64K_PAGES
|
||||
default 7 if ARM64_16K_PAGES
|
||||
default 4
|
||||
|
||||
config ARM64_CONT_PMD_SHIFT
|
||||
int
|
||||
default 5 if ARM64_64K_PAGES
|
||||
default 5 if ARM64_16K_PAGES
|
||||
default 4
|
||||
|
||||
config ARCH_MMAP_RND_BITS_MIN
|
||||
default 14 if ARM64_64K_PAGES
|
||||
default 16 if ARM64_16K_PAGES
|
||||
@@ -1165,32 +1172,6 @@ config UNMAP_KERNEL_AT_EL0
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config HARDEN_BRANCH_PREDICTOR
|
||||
bool "Harden the branch predictor against aliasing attacks" if EXPERT
|
||||
default y
|
||||
help
|
||||
Speculation attacks against some high-performance processors rely on
|
||||
being able to manipulate the branch predictor for a victim context by
|
||||
executing aliasing branches in the attacker context. Such attacks
|
||||
can be partially mitigated against by clearing internal branch
|
||||
predictor state and limiting the prediction logic in some situations.
|
||||
|
||||
This config option will take CPU-specific actions to harden the
|
||||
branch predictor against aliasing attacks and may rely on specific
|
||||
instruction sequences or control bits being set by the system
|
||||
firmware.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config ARM64_SSBD
|
||||
bool "Speculative Store Bypass Disable" if EXPERT
|
||||
default y
|
||||
help
|
||||
This enables mitigation of the bypassing of previous stores
|
||||
by speculative loads.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config RODATA_FULL_DEFAULT_ENABLED
|
||||
bool "Apply r/o permissions of VM areas also to their linear aliases"
|
||||
default y
|
||||
@@ -1664,6 +1645,39 @@ config ARCH_RANDOM
|
||||
provides a high bandwidth, cryptographically secure
|
||||
hardware random number generator.
|
||||
|
||||
config ARM64_AS_HAS_MTE
|
||||
# Initial support for MTE went in binutils 2.32.0, checked with
|
||||
# ".arch armv8.5-a+memtag" below. However, this was incomplete
|
||||
# as a late addition to the final architecture spec (LDGM/STGM)
|
||||
# is only supported in the newer 2.32.x and 2.33 binutils
|
||||
# versions, hence the extra "stgm" instruction check below.
|
||||
def_bool $(as-instr,.arch armv8.5-a+memtag\nstgm xzr$(comma)[x0])
|
||||
|
||||
config ARM64_MTE
|
||||
bool "Memory Tagging Extension support"
|
||||
default y
|
||||
depends on ARM64_AS_HAS_MTE && ARM64_TAGGED_ADDR_ABI
|
||||
select ARCH_USES_HIGH_VMA_FLAGS
|
||||
help
|
||||
Memory Tagging (part of the ARMv8.5 Extensions) provides
|
||||
architectural support for run-time, always-on detection of
|
||||
various classes of memory error to aid with software debugging
|
||||
to eliminate vulnerabilities arising from memory-unsafe
|
||||
languages.
|
||||
|
||||
This option enables the support for the Memory Tagging
|
||||
Extension at EL0 (i.e. for userspace).
|
||||
|
||||
Selecting this option allows the feature to be detected at
|
||||
runtime. Any secondary CPU not implementing this feature will
|
||||
not be allowed a late bring-up.
|
||||
|
||||
Userspace binaries that want to use this feature must
|
||||
explicitly opt in. The mechanism for the userspace is
|
||||
described in:
|
||||
|
||||
Documentation/arm64/memory-tagging-extension.rst.
|
||||
|
||||
endmenu
|
||||
|
||||
config ARM64_SVE
|
||||
@@ -1876,6 +1890,10 @@ config ARCH_ENABLE_HUGEPAGE_MIGRATION
|
||||
def_bool y
|
||||
depends on HUGETLB_PAGE && MIGRATION
|
||||
|
||||
config ARCH_ENABLE_THP_MIGRATION
|
||||
def_bool y
|
||||
depends on TRANSPARENT_HUGEPAGE
|
||||
|
||||
menu "Power management options"
|
||||
|
||||
source "kernel/power/Kconfig"
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
# Copyright (C) 1995-2001 by Russell King
|
||||
|
||||
LDFLAGS_vmlinux :=--no-undefined -X
|
||||
CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET)
|
||||
|
||||
ifeq ($(CONFIG_RELOCATABLE), y)
|
||||
# Pass --no-apply-dynamic-relocs to restore pre-binutils-2.27 behaviour
|
||||
@@ -132,9 +131,6 @@ endif
|
||||
# Default value
|
||||
head-y := arch/arm64/kernel/head.o
|
||||
|
||||
# The byte offset of the kernel image in RAM from the start of RAM.
|
||||
TEXT_OFFSET := 0x0
|
||||
|
||||
ifeq ($(CONFIG_KASAN_SW_TAGS), y)
|
||||
KASAN_SHADOW_SCALE_SHIFT := 4
|
||||
else
|
||||
@@ -145,8 +141,6 @@ KBUILD_CFLAGS += -DKASAN_SHADOW_SCALE_SHIFT=$(KASAN_SHADOW_SCALE_SHIFT)
|
||||
KBUILD_CPPFLAGS += -DKASAN_SHADOW_SCALE_SHIFT=$(KASAN_SHADOW_SCALE_SHIFT)
|
||||
KBUILD_AFLAGS += -DKASAN_SHADOW_SCALE_SHIFT=$(KASAN_SHADOW_SCALE_SHIFT)
|
||||
|
||||
export TEXT_OFFSET
|
||||
|
||||
core-y += arch/arm64/
|
||||
libs-y := arch/arm64/lib/ $(libs-y)
|
||||
libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
|
||||
|
||||
@@ -79,10 +79,5 @@ arch_get_random_seed_long_early(unsigned long *v)
|
||||
}
|
||||
#define arch_get_random_seed_long_early arch_get_random_seed_long_early
|
||||
|
||||
#else
|
||||
|
||||
static inline bool __arm64_rndr(unsigned long *v) { return false; }
|
||||
static inline bool __init __early_cpu_has_rndr(void) { return false; }
|
||||
|
||||
#endif /* CONFIG_ARCH_RANDOM */
|
||||
#endif /* _ASM_ARCHRANDOM_H */
|
||||
|
||||
@@ -13,8 +13,7 @@
|
||||
#define MAX_FDT_SIZE SZ_2M
|
||||
|
||||
/*
|
||||
* arm64 requires the kernel image to placed
|
||||
* TEXT_OFFSET bytes beyond a 2 MB aligned base
|
||||
* arm64 requires the kernel image to placed at a 2 MB aligned base address
|
||||
*/
|
||||
#define MIN_KIMG_ALIGN SZ_2M
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
* mechanism for doing so, tests whether it is possible to boot
|
||||
* the given CPU.
|
||||
* @cpu_boot: Boots a cpu into the kernel.
|
||||
* @cpu_postboot: Optionally, perform any post-boot cleanup or necesary
|
||||
* @cpu_postboot: Optionally, perform any post-boot cleanup or necessary
|
||||
* synchronisation. Called from the cpu being booted.
|
||||
* @cpu_can_disable: Determines whether a CPU can be disabled based on
|
||||
* mechanism-specific information.
|
||||
|
||||
@@ -31,13 +31,13 @@
|
||||
#define ARM64_HAS_DCPOP 21
|
||||
#define ARM64_SVE 22
|
||||
#define ARM64_UNMAP_KERNEL_AT_EL0 23
|
||||
#define ARM64_HARDEN_BRANCH_PREDICTOR 24
|
||||
#define ARM64_SPECTRE_V2 24
|
||||
#define ARM64_HAS_RAS_EXTN 25
|
||||
#define ARM64_WORKAROUND_843419 26
|
||||
#define ARM64_HAS_CACHE_IDC 27
|
||||
#define ARM64_HAS_CACHE_DIC 28
|
||||
#define ARM64_HW_DBM 29
|
||||
#define ARM64_SSBD 30
|
||||
#define ARM64_SPECTRE_V4 30
|
||||
#define ARM64_MISMATCHED_CACHE_TYPE 31
|
||||
#define ARM64_HAS_STAGE2_FWB 32
|
||||
#define ARM64_HAS_CRC32 33
|
||||
@@ -64,7 +64,8 @@
|
||||
#define ARM64_BTI 54
|
||||
#define ARM64_HAS_ARMv8_4_TTL 55
|
||||
#define ARM64_HAS_TLB_RANGE 56
|
||||
#define ARM64_MTE 57
|
||||
|
||||
#define ARM64_NCAPS 57
|
||||
#define ARM64_NCAPS 58
|
||||
|
||||
#endif /* __ASM_CPUCAPS_H */
|
||||
|
||||
@@ -358,7 +358,7 @@ static inline int cpucap_default_scope(const struct arm64_cpu_capabilities *cap)
|
||||
}
|
||||
|
||||
/*
|
||||
* Generic helper for handling capabilties with multiple (match,enable) pairs
|
||||
* Generic helper for handling capabilities with multiple (match,enable) pairs
|
||||
* of call backs, sharing the same capability bit.
|
||||
* Iterate over each entry to see if at least one matches.
|
||||
*/
|
||||
@@ -681,6 +681,12 @@ static __always_inline bool system_uses_irq_prio_masking(void)
|
||||
cpus_have_const_cap(ARM64_HAS_IRQ_PRIO_MASKING);
|
||||
}
|
||||
|
||||
static inline bool system_supports_mte(void)
|
||||
{
|
||||
return IS_ENABLED(CONFIG_ARM64_MTE) &&
|
||||
cpus_have_const_cap(ARM64_MTE);
|
||||
}
|
||||
|
||||
static inline bool system_has_prio_mask_debugging(void)
|
||||
{
|
||||
return IS_ENABLED(CONFIG_ARM64_DEBUG_PRIORITY_MASKING) &&
|
||||
@@ -698,30 +704,6 @@ static inline bool system_supports_tlb_range(void)
|
||||
cpus_have_const_cap(ARM64_HAS_TLB_RANGE);
|
||||
}
|
||||
|
||||
#define ARM64_BP_HARDEN_UNKNOWN -1
|
||||
#define ARM64_BP_HARDEN_WA_NEEDED 0
|
||||
#define ARM64_BP_HARDEN_NOT_REQUIRED 1
|
||||
|
||||
int get_spectre_v2_workaround_state(void);
|
||||
|
||||
#define ARM64_SSBD_UNKNOWN -1
|
||||
#define ARM64_SSBD_FORCE_DISABLE 0
|
||||
#define ARM64_SSBD_KERNEL 1
|
||||
#define ARM64_SSBD_FORCE_ENABLE 2
|
||||
#define ARM64_SSBD_MITIGATED 3
|
||||
|
||||
static inline int arm64_get_ssbd_state(void)
|
||||
{
|
||||
#ifdef CONFIG_ARM64_SSBD
|
||||
extern int ssbd_state;
|
||||
return ssbd_state;
|
||||
#else
|
||||
return ARM64_SSBD_UNKNOWN;
|
||||
#endif
|
||||
}
|
||||
|
||||
void arm64_set_ssbd_mitigation(bool state);
|
||||
|
||||
extern int do_emulate_mrs(struct pt_regs *regs, u32 sys_reg, u32 rt);
|
||||
|
||||
static inline u32 id_aa64mmfr0_parange_to_phys_shift(int parange)
|
||||
|
||||
@@ -35,7 +35,9 @@
|
||||
#define ESR_ELx_EC_SYS64 (0x18)
|
||||
#define ESR_ELx_EC_SVE (0x19)
|
||||
#define ESR_ELx_EC_ERET (0x1a) /* EL2 only */
|
||||
/* Unallocated EC: 0x1b - 0x1E */
|
||||
/* Unallocated EC: 0x1B */
|
||||
#define ESR_ELx_EC_FPAC (0x1C) /* EL1 and above */
|
||||
/* Unallocated EC: 0x1D - 0x1E */
|
||||
#define ESR_ELx_EC_IMP_DEF (0x1f) /* EL3 only */
|
||||
#define ESR_ELx_EC_IABT_LOW (0x20)
|
||||
#define ESR_ELx_EC_IABT_CUR (0x21)
|
||||
|
||||
@@ -47,4 +47,5 @@ void bad_el0_sync(struct pt_regs *regs, int reason, unsigned int esr);
|
||||
void do_cp15instr(unsigned int esr, struct pt_regs *regs);
|
||||
void do_el0_svc(struct pt_regs *regs);
|
||||
void do_el0_svc_compat(struct pt_regs *regs);
|
||||
void do_ptrauth_fault(struct pt_regs *regs, unsigned int esr);
|
||||
#endif /* __ASM_EXCEPTION_H */
|
||||
|
||||
@@ -22,6 +22,15 @@ struct exception_table_entry
|
||||
|
||||
#define ARCH_HAS_RELATIVE_EXTABLE
|
||||
|
||||
static inline bool in_bpf_jit(struct pt_regs *regs)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_BPF_JIT))
|
||||
return false;
|
||||
|
||||
return regs->pc >= BPF_JIT_REGION_START &&
|
||||
regs->pc < BPF_JIT_REGION_END;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BPF_JIT
|
||||
int arm64_bpf_fixup_exception(const struct exception_table_entry *ex,
|
||||
struct pt_regs *regs);
|
||||
|
||||
@@ -69,6 +69,9 @@ static inline void *sve_pffr(struct thread_struct *thread)
|
||||
extern void sve_save_state(void *state, u32 *pfpsr);
|
||||
extern void sve_load_state(void const *state, u32 const *pfpsr,
|
||||
unsigned long vq_minus_1);
|
||||
extern void sve_flush_live(void);
|
||||
extern void sve_load_from_fpsimd_state(struct user_fpsimd_state const *state,
|
||||
unsigned long vq_minus_1);
|
||||
extern unsigned int sve_get_vl(void);
|
||||
|
||||
struct arm64_cpu_capabilities;
|
||||
|
||||
@@ -164,25 +164,59 @@
|
||||
| ((\np) << 5)
|
||||
.endm
|
||||
|
||||
/* PFALSE P\np.B */
|
||||
.macro _sve_pfalse np
|
||||
_sve_check_preg \np
|
||||
.inst 0x2518e400 \
|
||||
| (\np)
|
||||
.endm
|
||||
|
||||
.macro __for from:req, to:req
|
||||
.if (\from) == (\to)
|
||||
_for__body \from
|
||||
_for__body %\from
|
||||
.else
|
||||
__for \from, (\from) + ((\to) - (\from)) / 2
|
||||
__for (\from) + ((\to) - (\from)) / 2 + 1, \to
|
||||
__for %\from, %((\from) + ((\to) - (\from)) / 2)
|
||||
__for %((\from) + ((\to) - (\from)) / 2 + 1), %\to
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro _for var:req, from:req, to:req, insn:vararg
|
||||
.macro _for__body \var:req
|
||||
.noaltmacro
|
||||
\insn
|
||||
.altmacro
|
||||
.endm
|
||||
|
||||
.altmacro
|
||||
__for \from, \to
|
||||
.noaltmacro
|
||||
|
||||
.purgem _for__body
|
||||
.endm
|
||||
|
||||
/* Update ZCR_EL1.LEN with the new VQ */
|
||||
.macro sve_load_vq xvqminus1, xtmp, xtmp2
|
||||
mrs_s \xtmp, SYS_ZCR_EL1
|
||||
bic \xtmp2, \xtmp, ZCR_ELx_LEN_MASK
|
||||
orr \xtmp2, \xtmp2, \xvqminus1
|
||||
cmp \xtmp2, \xtmp
|
||||
b.eq 921f
|
||||
msr_s SYS_ZCR_EL1, \xtmp2 //self-synchronising
|
||||
921:
|
||||
.endm
|
||||
|
||||
/* Preserve the first 128-bits of Znz and zero the rest. */
|
||||
.macro _sve_flush_z nz
|
||||
_sve_check_zreg \nz
|
||||
mov v\nz\().16b, v\nz\().16b
|
||||
.endm
|
||||
|
||||
.macro sve_flush
|
||||
_for n, 0, 31, _sve_flush_z \n
|
||||
_for n, 0, 15, _sve_pfalse \n
|
||||
_sve_wrffr 0
|
||||
.endm
|
||||
|
||||
.macro sve_save nxbase, xpfpsr, nxtmp
|
||||
_for n, 0, 31, _sve_str_v \n, \nxbase, \n - 34
|
||||
_for n, 0, 15, _sve_str_p \n, \nxbase, \n - 16
|
||||
@@ -197,13 +231,7 @@
|
||||
.endm
|
||||
|
||||
.macro sve_load nxbase, xpfpsr, xvqminus1, nxtmp, xtmp2
|
||||
mrs_s x\nxtmp, SYS_ZCR_EL1
|
||||
bic \xtmp2, x\nxtmp, ZCR_ELx_LEN_MASK
|
||||
orr \xtmp2, \xtmp2, \xvqminus1
|
||||
cmp \xtmp2, x\nxtmp
|
||||
b.eq 921f
|
||||
msr_s SYS_ZCR_EL1, \xtmp2 // self-synchronising
|
||||
921:
|
||||
sve_load_vq \xvqminus1, x\nxtmp, \xtmp2
|
||||
_for n, 0, 31, _sve_ldr_v \n, \nxbase, \n - 34
|
||||
_sve_ldr_p 0, \nxbase
|
||||
_sve_wrffr 0
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user