Commit bf587af2 authored by Will Deacon's avatar Will Deacon
Browse files

Merge branch 'for-next/mte' into for-next/core

* for-next/mte:
  docs: sysfs-devices-system-cpu: document "asymm" value for mte_tcf_preferred
  arm64/mte: Remove asymmetric mode from the prctl() interface
  kasan: fix a missing header include of static_keys.h
  arm64/mte: Add userspace interface for enabling asymmetric mode
  arm64/mte: Add hwcap for asymmetric mode
  arm64/mte: Add a little bit of documentation for mte_update_sctlr_user()
  arm64/mte: Document ABI for asymmetric mode
  arm64: mte: avoid clearing PSTATE.TCO on entry unless necessary
  kasan: split kasan_*enabled() functions into a separate header
parents 20fd2ed1 9986c765
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -662,6 +662,7 @@ Description: Preferred MTE tag checking mode

		================  ==============================================
		"sync"	  	  Prefer synchronous mode
		"asymm"	  	  Prefer asymmetric mode
		"async"	  	  Prefer asynchronous mode
		================  ==============================================

+5 −0
Original line number Diff line number Diff line
@@ -259,6 +259,11 @@ HWCAP2_RPRES

    Functionality implied by ID_AA64ISAR2_EL1.RPRES == 0b0001.

HWCAP2_MTE3

    Functionality implied by ID_AA64PFR1_EL1.MTE == 0b0011, as described
    by Documentation/arm64/memory-tagging-extension.rst.

4. Unused AT_HWCAP bits
-----------------------

+18 −8
Original line number Diff line number Diff line
@@ -76,6 +76,9 @@ configurable behaviours:
  with ``.si_code = SEGV_MTEAERR`` and ``.si_addr = 0`` (the faulting
  address is unknown).

- *Asymmetric* - Reads are handled as for synchronous mode while writes
  are handled as for asynchronous mode.

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``
contains any number of the following values in the ``PR_MTE_TCF_MASK``
@@ -140,18 +143,25 @@ tag checking mode as the CPU's preferred tag checking mode.

The preferred tag checking mode for each CPU is controlled by
``/sys/devices/system/cpu/cpu<N>/mte_tcf_preferred``, to which a
privileged user may write the value ``async`` or ``sync``.  The default
preferred mode for each CPU is ``async``.
privileged user may write the value ``async``, ``sync`` or ``asymm``.  The
default preferred mode for each CPU is ``async``.

To allow a program to potentially run in the CPU's preferred tag
checking mode, the user program may set multiple tag check fault mode
bits in the ``flags`` argument to the ``prctl(PR_SET_TAGGED_ADDR_CTRL,
flags, 0, 0, 0)`` system call. If the CPU's preferred tag checking
mode is in the task's set of provided tag checking modes (this will
always be the case at present because the kernel only supports two
tag checking modes, but future kernels may support more modes), that
mode will be selected. Otherwise, one of the modes in the task's mode
set will be selected in a currently unspecified manner.
flags, 0, 0, 0)`` system call. If both synchronous and asynchronous
modes are requested then asymmetric mode may also be selected by the
kernel. If the CPU's preferred tag checking mode is in the task's set
of provided tag checking modes, that mode will be selected. Otherwise,
one of the modes in the task's mode will be selected by the kernel
from the task's mode set using the preference order:

	1. Asynchronous
	2. Asymmetric
	3. Synchronous

Note that there is no way for userspace to request multiple modes and
also disable asymmetric mode.

Initial process state
---------------------
+1 −0
Original line number Diff line number Diff line
@@ -108,6 +108,7 @@
#define KERNEL_HWCAP_ECV		__khwcap2_feature(ECV)
#define KERNEL_HWCAP_AFP		__khwcap2_feature(AFP)
#define KERNEL_HWCAP_RPRES		__khwcap2_feature(RPRES)
#define KERNEL_HWCAP_MTE3		__khwcap2_feature(MTE3)

/*
 * This yields a mask that user programs can use to figure out what
+22 −0
Original line number Diff line number Diff line
@@ -11,7 +11,9 @@
#ifndef __ASSEMBLY__

#include <linux/bitfield.h>
#include <linux/kasan-enabled.h>
#include <linux/page-flags.h>
#include <linux/sched.h>
#include <linux/types.h>

#include <asm/pgtable-types.h>
@@ -86,6 +88,26 @@ static inline int mte_ptrace_copy_tags(struct task_struct *child,

#endif /* CONFIG_ARM64_MTE */

static inline void mte_disable_tco_entry(struct task_struct *task)
{
	if (!system_supports_mte())
		return;

	/*
	 * Re-enable tag checking (TCO set on exception entry). This is only
	 * necessary if MTE is enabled in either the kernel or the userspace
	 * task in synchronous or asymmetric mode (SCTLR_EL1.TCF0 bit 0 is set
	 * for both). With MTE disabled in the kernel and disabled or
	 * asynchronous in userspace, tag check faults (including in uaccesses)
	 * are not reported, therefore there is no need to re-enable checking.
	 * This is beneficial on microarchitectures where re-enabling TCO is
	 * expensive.
	 */
	if (kasan_hw_tags_enabled() ||
	    (task->thread.sctlr_user & (1UL << SCTLR_EL1_TCF0_SHIFT)))
		asm volatile(SET_PSTATE_TCO(0));
}

#ifdef CONFIG_KASAN_HW_TAGS
/* Whether the MTE asynchronous mode is enabled. */
DECLARE_STATIC_KEY_FALSE(mte_async_or_asymm_mode);
Loading