From: Catalin Marinas <catalin.marinas@arm.com> To: linux-arm-kernel@lists.infradead.org Cc: Will Deacon <will@kernel.org>, Vincenzo Frascino <vincenzo.frascino@arm.com>, Szabolcs Nagy <szabolcs.nagy@arm.com>, Richard Earnshaw <Richard.Earnshaw@arm.com>, Kevin Brodsky <kevin.brodsky@arm.com>, Andrey Konovalov <andreyknvl@google.com>, Peter Collingbourne <pcc@google.com>, linux-mm@kvack.org, linux-arch@vger.kernel.org Subject: [PATCH v2 17/19] arm64: mte: Allow user control of the generated random tags via prctl() Date: Wed, 26 Feb 2020 18:05:24 +0000 [thread overview] Message-ID: <20200226180526.3272848-18-catalin.marinas@arm.com> (raw) In-Reply-To: <20200226180526.3272848-1-catalin.marinas@arm.com> The IRG, ADDG and SUBG instructions insert a random tag in the resulting address. Certain tags can be excluded via the GCR_EL1.Exclude bitmap when, for example, the user wants a certain colour for freed buffers. Since the GCR_EL1 register is not accessible at EL0, extend the prctl(PR_SET_TAGGED_ADDR_CTRL) interface to include a 16-bit field in the first argument for controlling which tags can be generated by the above instruction (an include rather than exclude mask). Note that by default all non-zero tags are excluded. This setting is per-thread. Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> --- Notes: v2: - Switch from an exclude mask to an include one for the prctl() interface. - Reset the allowed tags mask during flush_thread(). arch/arm64/include/asm/processor.h | 1 + arch/arm64/include/asm/sysreg.h | 7 ++++++ arch/arm64/kernel/mte.c | 35 +++++++++++++++++++++++++++--- arch/arm64/kernel/process.c | 2 +- include/uapi/linux/prctl.h | 3 +++ 5 files changed, 44 insertions(+), 4 deletions(-) diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index 91aa270afc7d..bd215d74275d 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -150,6 +150,7 @@ struct thread_struct { #endif #ifdef CONFIG_ARM64_MTE u64 sctlr_tcf0; + u64 gcr_incl; #endif }; diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index 13f0841b6ed3..dd8d747997be 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -931,6 +931,13 @@ write_sysreg(__scs_new, sysreg); \ } while (0) +#define sysreg_clear_set_s(sysreg, clear, set) do { \ + u64 __scs_val = read_sysreg_s(sysreg); \ + u64 __scs_new = (__scs_val & ~(u64)(clear)) | (set); \ + if (__scs_new != __scs_val) \ + write_sysreg_s(__scs_new, sysreg); \ +} while (0) + #endif #endif /* __ASM_SYSREG_H */ diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c index 4b926d779940..0cd1482b18a0 100644 --- a/arch/arm64/kernel/mte.c +++ b/arch/arm64/kernel/mte.c @@ -31,6 +31,25 @@ static void set_sctlr_el1_tcf0(u64 tcf0) preempt_enable(); } +static void update_gcr_el1_excl(u64 incl) +{ + u64 excl = ~incl & SYS_GCR_EL1_EXCL_MASK; + + /* + * Note that 'incl' is an include mask (controlled by the user via + * prctl()) while GCR_EL1 accepts an exclude mask. + * No need for ISB since this only affects EL0 currently, implicit + * with ERET. + */ + sysreg_clear_set_s(SYS_GCR_EL1, SYS_GCR_EL1_EXCL_MASK, excl); +} + +static void set_gcr_el1_excl(u64 incl) +{ + current->thread.gcr_incl = incl; + update_gcr_el1_excl(incl); +} + void flush_mte_state(void) { if (!system_supports_mte()) @@ -40,6 +59,8 @@ void flush_mte_state(void) clear_thread_flag(TIF_MTE_ASYNC_FAULT); /* disable tag checking */ set_sctlr_el1_tcf0(0); + /* reset tag generation mask */ + set_gcr_el1_excl(0); } void mte_thread_switch(struct task_struct *next) @@ -62,6 +83,7 @@ void mte_thread_switch(struct task_struct *next) /* avoid expensive SCTLR_EL1 accesses if no change */ if (current->thread.sctlr_tcf0 != next->thread.sctlr_tcf0) update_sctlr_el1_tcf0(next->thread.sctlr_tcf0); + update_gcr_el1_excl(next->thread.gcr_incl); } long set_mte_ctrl(unsigned long arg) @@ -86,23 +108,30 @@ long set_mte_ctrl(unsigned long arg) } set_sctlr_el1_tcf0(tcf0); + set_gcr_el1_excl((arg & PR_MTE_TAG_MASK) >> PR_MTE_TAG_SHIFT); return 0; } long get_mte_ctrl(void) { + unsigned long ret; + if (!system_supports_mte()) return 0; + ret = current->thread.gcr_incl << PR_MTE_TAG_SHIFT; + switch (current->thread.sctlr_tcf0) { case SCTLR_EL1_TCF0_NONE: return PR_MTE_TCF_NONE; case SCTLR_EL1_TCF0_SYNC: - return PR_MTE_TCF_SYNC; + ret |= PR_MTE_TCF_SYNC; + break; case SCTLR_EL1_TCF0_ASYNC: - return PR_MTE_TCF_ASYNC; + ret |= PR_MTE_TCF_ASYNC; + break; } - return 0; + return ret; } diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index b3c8cd64b88a..4ac0e90617fc 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -584,7 +584,7 @@ long set_tagged_addr_ctrl(unsigned long arg) return -EINVAL; if (system_supports_mte()) - valid_mask |= PR_MTE_TCF_MASK; + valid_mask |= PR_MTE_TCF_MASK | PR_MTE_TAG_MASK; if (arg & ~valid_mask) return -EINVAL; diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h index 2390ab324afa..7f0827705c9a 100644 --- a/include/uapi/linux/prctl.h +++ b/include/uapi/linux/prctl.h @@ -239,6 +239,9 @@ struct prctl_mm_map { # 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) +/* MTE tag inclusion mask */ +# define PR_MTE_TAG_SHIFT 3 +# define PR_MTE_TAG_MASK (0xffffUL << PR_MTE_TAG_SHIFT) /* Control reclaim behavior when allocating memory */ #define PR_SET_IO_FLUSHER 57
WARNING: multiple messages have this Message-ID (diff)
From: Catalin Marinas <catalin.marinas@arm.com> To: linux-arm-kernel@lists.infradead.org Cc: linux-arch@vger.kernel.org, Richard Earnshaw <Richard.Earnshaw@arm.com>, Szabolcs Nagy <szabolcs.nagy@arm.com>, Andrey Konovalov <andreyknvl@google.com>, Kevin Brodsky <kevin.brodsky@arm.com>, Peter Collingbourne <pcc@google.com>, linux-mm@kvack.org, Vincenzo Frascino <vincenzo.frascino@arm.com>, Will Deacon <will@kernel.org> Subject: [PATCH v2 17/19] arm64: mte: Allow user control of the generated random tags via prctl() Date: Wed, 26 Feb 2020 18:05:24 +0000 [thread overview] Message-ID: <20200226180526.3272848-18-catalin.marinas@arm.com> (raw) In-Reply-To: <20200226180526.3272848-1-catalin.marinas@arm.com> The IRG, ADDG and SUBG instructions insert a random tag in the resulting address. Certain tags can be excluded via the GCR_EL1.Exclude bitmap when, for example, the user wants a certain colour for freed buffers. Since the GCR_EL1 register is not accessible at EL0, extend the prctl(PR_SET_TAGGED_ADDR_CTRL) interface to include a 16-bit field in the first argument for controlling which tags can be generated by the above instruction (an include rather than exclude mask). Note that by default all non-zero tags are excluded. This setting is per-thread. Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> --- Notes: v2: - Switch from an exclude mask to an include one for the prctl() interface. - Reset the allowed tags mask during flush_thread(). arch/arm64/include/asm/processor.h | 1 + arch/arm64/include/asm/sysreg.h | 7 ++++++ arch/arm64/kernel/mte.c | 35 +++++++++++++++++++++++++++--- arch/arm64/kernel/process.c | 2 +- include/uapi/linux/prctl.h | 3 +++ 5 files changed, 44 insertions(+), 4 deletions(-) diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index 91aa270afc7d..bd215d74275d 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -150,6 +150,7 @@ struct thread_struct { #endif #ifdef CONFIG_ARM64_MTE u64 sctlr_tcf0; + u64 gcr_incl; #endif }; diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index 13f0841b6ed3..dd8d747997be 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -931,6 +931,13 @@ write_sysreg(__scs_new, sysreg); \ } while (0) +#define sysreg_clear_set_s(sysreg, clear, set) do { \ + u64 __scs_val = read_sysreg_s(sysreg); \ + u64 __scs_new = (__scs_val & ~(u64)(clear)) | (set); \ + if (__scs_new != __scs_val) \ + write_sysreg_s(__scs_new, sysreg); \ +} while (0) + #endif #endif /* __ASM_SYSREG_H */ diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c index 4b926d779940..0cd1482b18a0 100644 --- a/arch/arm64/kernel/mte.c +++ b/arch/arm64/kernel/mte.c @@ -31,6 +31,25 @@ static void set_sctlr_el1_tcf0(u64 tcf0) preempt_enable(); } +static void update_gcr_el1_excl(u64 incl) +{ + u64 excl = ~incl & SYS_GCR_EL1_EXCL_MASK; + + /* + * Note that 'incl' is an include mask (controlled by the user via + * prctl()) while GCR_EL1 accepts an exclude mask. + * No need for ISB since this only affects EL0 currently, implicit + * with ERET. + */ + sysreg_clear_set_s(SYS_GCR_EL1, SYS_GCR_EL1_EXCL_MASK, excl); +} + +static void set_gcr_el1_excl(u64 incl) +{ + current->thread.gcr_incl = incl; + update_gcr_el1_excl(incl); +} + void flush_mte_state(void) { if (!system_supports_mte()) @@ -40,6 +59,8 @@ void flush_mte_state(void) clear_thread_flag(TIF_MTE_ASYNC_FAULT); /* disable tag checking */ set_sctlr_el1_tcf0(0); + /* reset tag generation mask */ + set_gcr_el1_excl(0); } void mte_thread_switch(struct task_struct *next) @@ -62,6 +83,7 @@ void mte_thread_switch(struct task_struct *next) /* avoid expensive SCTLR_EL1 accesses if no change */ if (current->thread.sctlr_tcf0 != next->thread.sctlr_tcf0) update_sctlr_el1_tcf0(next->thread.sctlr_tcf0); + update_gcr_el1_excl(next->thread.gcr_incl); } long set_mte_ctrl(unsigned long arg) @@ -86,23 +108,30 @@ long set_mte_ctrl(unsigned long arg) } set_sctlr_el1_tcf0(tcf0); + set_gcr_el1_excl((arg & PR_MTE_TAG_MASK) >> PR_MTE_TAG_SHIFT); return 0; } long get_mte_ctrl(void) { + unsigned long ret; + if (!system_supports_mte()) return 0; + ret = current->thread.gcr_incl << PR_MTE_TAG_SHIFT; + switch (current->thread.sctlr_tcf0) { case SCTLR_EL1_TCF0_NONE: return PR_MTE_TCF_NONE; case SCTLR_EL1_TCF0_SYNC: - return PR_MTE_TCF_SYNC; + ret |= PR_MTE_TCF_SYNC; + break; case SCTLR_EL1_TCF0_ASYNC: - return PR_MTE_TCF_ASYNC; + ret |= PR_MTE_TCF_ASYNC; + break; } - return 0; + return ret; } diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index b3c8cd64b88a..4ac0e90617fc 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -584,7 +584,7 @@ long set_tagged_addr_ctrl(unsigned long arg) return -EINVAL; if (system_supports_mte()) - valid_mask |= PR_MTE_TCF_MASK; + valid_mask |= PR_MTE_TCF_MASK | PR_MTE_TAG_MASK; if (arg & ~valid_mask) return -EINVAL; diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h index 2390ab324afa..7f0827705c9a 100644 --- a/include/uapi/linux/prctl.h +++ b/include/uapi/linux/prctl.h @@ -239,6 +239,9 @@ struct prctl_mm_map { # 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) +/* MTE tag inclusion mask */ +# define PR_MTE_TAG_SHIFT 3 +# define PR_MTE_TAG_MASK (0xffffUL << PR_MTE_TAG_SHIFT) /* Control reclaim behavior when allocating memory */ #define PR_SET_IO_FLUSHER 57 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2020-02-26 18:06 UTC|newest] Thread overview: 69+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-02-26 18:05 [PATCH v2 00/19] arm64: Memory Tagging Extension user-space support Catalin Marinas 2020-02-26 18:05 ` Catalin Marinas 2020-02-26 18:05 ` [PATCH v2 01/19] arm64: alternative: Allow alternative_insn to always issue the first instruction Catalin Marinas 2020-02-26 18:05 ` Catalin Marinas 2020-02-26 18:05 ` [PATCH v2 02/19] arm64: mte: system register definitions Catalin Marinas 2020-02-26 18:05 ` Catalin Marinas 2020-02-26 18:05 ` [PATCH v2 03/19] arm64: mte: CPU feature detection and initial sysreg configuration Catalin Marinas 2020-02-26 18:05 ` Catalin Marinas 2020-02-26 18:05 ` [PATCH v2 04/19] arm64: mte: Use Normal Tagged attributes for the linear map Catalin Marinas 2020-02-26 18:05 ` Catalin Marinas 2020-03-05 16:21 ` Steven Price 2020-03-05 16:21 ` Steven Price 2020-03-05 16:38 ` Catalin Marinas 2020-03-05 16:38 ` Catalin Marinas 2020-02-26 18:05 ` [PATCH v2 05/19] arm64: mte: Assembler macros and default architecture for .S files Catalin Marinas 2020-02-26 18:05 ` Catalin Marinas 2020-02-26 18:05 ` [PATCH v2 06/19] arm64: mte: Tags-aware clear_page() implementation Catalin Marinas 2020-02-26 18:05 ` Catalin Marinas 2020-02-26 18:05 ` [PATCH v2 07/19] arm64: mte: Tags-aware copy_page() implementation Catalin Marinas 2020-02-26 18:05 ` Catalin Marinas 2020-02-26 18:05 ` [PATCH v2 08/19] arm64: Tags-aware memcmp_pages() implementation Catalin Marinas 2020-02-26 18:05 ` Catalin Marinas 2020-02-26 18:05 ` [PATCH v2 09/19] arm64: mte: Add specific SIGSEGV codes Catalin Marinas 2020-02-26 18:05 ` Catalin Marinas 2020-02-26 19:05 ` Eric W. Biederman 2020-02-26 19:05 ` Eric W. Biederman 2020-02-26 19:05 ` Eric W. Biederman 2020-02-26 19:26 ` Catalin Marinas 2020-02-26 19:26 ` Catalin Marinas 2020-02-26 22:33 ` kbuild test robot 2020-02-26 22:33 ` kbuild test robot 2020-02-26 22:33 ` kbuild test robot 2020-02-27 11:05 ` Catalin Marinas 2020-02-27 11:05 ` Catalin Marinas 2020-02-27 11:05 ` Catalin Marinas 2020-02-27 15:20 ` Eric W. Biederman 2020-02-27 15:20 ` Eric W. Biederman 2020-02-27 15:20 ` Eric W. Biederman 2020-02-27 15:20 ` Eric W. Biederman 2020-02-26 18:05 ` [PATCH v2 10/19] arm64: mte: Handle synchronous and asynchronous tag check faults Catalin Marinas 2020-02-26 18:05 ` Catalin Marinas 2020-02-27 11:50 ` Catalin Marinas 2020-02-27 11:50 ` Catalin Marinas 2020-02-26 18:05 ` [PATCH v2 11/19] mm: Introduce arch_calc_vm_flag_bits() Catalin Marinas 2020-02-26 18:05 ` Catalin Marinas 2020-02-26 18:05 ` [PATCH v2 12/19] arm64: mte: Add PROT_MTE support to mmap() and mprotect() Catalin Marinas 2020-02-26 18:05 ` Catalin Marinas 2020-02-26 18:05 ` [PATCH v2 13/19] mm: Introduce arch_validate_flags() Catalin Marinas 2020-02-26 18:05 ` Catalin Marinas 2020-02-26 18:05 ` [PATCH v2 14/19] arm64: mte: Validate the PROT_MTE request via arch_validate_flags() Catalin Marinas 2020-02-26 18:05 ` Catalin Marinas 2020-02-26 18:05 ` [PATCH v2 15/19] mm: Allow arm64 mmap(PROT_MTE) on RAM-based files Catalin Marinas 2020-02-26 18:05 ` Catalin Marinas 2020-02-26 18:05 ` [PATCH v2 16/19] arm64: mte: Allow user control of the tag check mode via prctl() Catalin Marinas 2020-02-26 18:05 ` Catalin Marinas 2020-03-09 13:53 ` Kevin Brodsky 2020-03-09 13:53 ` Kevin Brodsky 2020-02-26 18:05 ` Catalin Marinas [this message] 2020-02-26 18:05 ` [PATCH v2 17/19] arm64: mte: Allow user control of the generated random tags " Catalin Marinas 2020-02-26 18:05 ` [PATCH v2 18/19] arm64: mte: Kconfig entry Catalin Marinas 2020-02-26 18:05 ` Catalin Marinas 2020-02-26 18:05 ` [PATCH v2 19/19] arm64: mte: Add Memory Tagging Extension documentation Catalin Marinas 2020-02-26 18:05 ` Catalin Marinas 2020-03-09 14:30 ` Kevin Brodsky 2020-03-09 14:30 ` Kevin Brodsky 2020-03-11 22:17 ` Richard Henderson 2020-03-11 22:17 ` Richard Henderson 2020-03-12 9:50 ` Catalin Marinas 2020-03-12 9:50 ` Catalin Marinas
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20200226180526.3272848-18-catalin.marinas@arm.com \ --to=catalin.marinas@arm.com \ --cc=Richard.Earnshaw@arm.com \ --cc=andreyknvl@google.com \ --cc=kevin.brodsky@arm.com \ --cc=linux-arch@vger.kernel.org \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-mm@kvack.org \ --cc=pcc@google.com \ --cc=szabolcs.nagy@arm.com \ --cc=vincenzo.frascino@arm.com \ --cc=will@kernel.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.