| From 2b1ec6ffa87f73f4262093136a20066a4b74e637 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 14 Jul 2021 15:38:41 +0100 |
| Subject: arm64: mte: fix restoration of GCR_EL1 from suspend |
| |
| From: Mark Rutland <mark.rutland@arm.com> |
| |
| [ Upstream commit 59f44069e0527523f27948da7b77599a73dab157 ] |
| |
| Since commit: |
| |
| bad1e1c663e0a72f ("arm64: mte: switch GCR_EL1 in kernel entry and exit") |
| |
| we saved/restored the user GCR_EL1 value at exception boundaries, and |
| update_gcr_el1_excl() is no longer used for this. However it is used to |
| restore the kernel's GCR_EL1 value when returning from a suspend state. |
| Thus, the comment is misleading (and an ISB is necessary). |
| |
| When restoring the kernel's GCR value, we need an ISB to ensure this is |
| used by subsequent instructions. We don't necessarily get an ISB by |
| other means (e.g. if the kernel is built without support for pointer |
| authentication). As __cpu_setup() initialised GCR_EL1.Exclude to 0xffff, |
| until a context synchronization event, allocation tag 0 may be used |
| rather than the desired set of tags. |
| |
| This patch drops the misleading comment, adds the missing ISB, and for |
| clarity folds update_gcr_el1_excl() into its only user. |
| |
| Fixes: bad1e1c663e0 ("arm64: mte: switch GCR_EL1 in kernel entry and exit") |
| Signed-off-by: Mark Rutland <mark.rutland@arm.com> |
| Cc: Andrey Konovalov <andreyknvl@gmail.com> |
| Cc: Catalin Marinas <catalin.marinas@arm.com> |
| Cc: Vincenzo Frascino <vincenzo.frascino@arm.com> |
| Cc: Will Deacon <will@kernel.org> |
| Link: https://lore.kernel.org/r/20210714143843.56537-2-mark.rutland@arm.com |
| Signed-off-by: Will Deacon <will@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| arch/arm64/kernel/mte.c | 15 ++------------- |
| 1 file changed, 2 insertions(+), 13 deletions(-) |
| |
| diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c |
| index 125a10e413e9..23e9879a6e78 100644 |
| --- a/arch/arm64/kernel/mte.c |
| +++ b/arch/arm64/kernel/mte.c |
| @@ -185,18 +185,6 @@ void mte_check_tfsr_el1(void) |
| } |
| #endif |
| |
| -static void update_gcr_el1_excl(u64 excl) |
| -{ |
| - |
| - /* |
| - * Note that the mask controlled by the user via prctl() is an |
| - * include 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 excl) |
| { |
| current->thread.gcr_user_excl = excl; |
| @@ -257,7 +245,8 @@ void mte_suspend_exit(void) |
| if (!system_supports_mte()) |
| return; |
| |
| - update_gcr_el1_excl(gcr_kernel_excl); |
| + sysreg_clear_set_s(SYS_GCR_EL1, SYS_GCR_EL1_EXCL_MASK, gcr_kernel_excl); |
| + isb(); |
| } |
| |
| long set_mte_ctrl(struct task_struct *task, unsigned long arg) |
| -- |
| 2.30.2 |
| |