Message ID | 20211215230240.604489-1-scott@os.amperecomputing.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | arm64: errata: Fix exec handling in erratum 1418040 workaround | expand |
On Wed, 15 Dec 2021 23:02:40 +0000, D Scott Phillips <scott@os.amperecomputing.com> wrote: > > The erratum 1418040 workaround changes vct access trapping when switching > between compat and non-compat threads. The workaround logic assumes that > the hardware vct trapping state matches the previous task's compat-ness. > However, when a non-compat task execs a compat binary or vice versa, the > cntkctl state and task compat-ness get out of sync. Keep the hardware > trapping state in sync with the task personality. > > Fixes: d49f7d7376d0 ("arm64: Move handling of erratum 1418040 into C code") > Signed-off-by: D Scott Phillips <scott@os.amperecomputing.com> > Cc: <stable@vger.kernel.org> # 5.4.x > --- > arch/arm64/include/asm/elf.h | 20 ++++++++++++++++++++ > 1 file changed, 20 insertions(+) > > diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h > index 97932fbf973d..463ff8f00aa7 100644 > --- a/arch/arm64/include/asm/elf.h > +++ b/arch/arm64/include/asm/elf.h > @@ -160,8 +160,18 @@ typedef struct user_fpsimd_state elf_fpregset_t; > > #define SET_PERSONALITY(ex) \ > ({ \ > + if (IS_ENABLED(CONFIG_ARM64_ERRATUM_1418040)) \ > + preempt_disable(); \ > clear_thread_flag(TIF_32BIT); \ > current->personality &= ~READ_IMPLIES_EXEC; \ > + if (this_cpu_has_cap(ARM64_WORKAROUND_1418040)) { \ > + u64 val; \ > + val = read_sysreg(cntkctl_el1); \ > + val |= ARCH_TIMER_USR_VCT_ACCESS_EN; \ > + write_sysreg(val, cntkctl_el1); \ > + } \ > + if (IS_ENABLED(CONFIG_ARM64_ERRATUM_1418040)) \ > + preempt_enable(); \ > }) > > /* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */ > @@ -223,7 +233,17 @@ int compat_elf_check_arch(const struct elf32_hdr *); > */ > #define COMPAT_SET_PERSONALITY(ex) \ > ({ \ > + if (IS_ENABLED(CONFIG_ARM64_ERRATUM_1418040)) \ > + preempt_disable(); \ > set_thread_flag(TIF_32BIT); \ > + if (this_cpu_has_cap(ARM64_WORKAROUND_1418040)) { \ > + u64 val; \ > + val = read_sysreg(cntkctl_el1); \ > + val &= ~ARCH_TIMER_USR_VCT_ACCESS_EN; \ > + write_sysreg(val, cntkctl_el1); \ > + } \ > + if (IS_ENABLED(CONFIG_ARM64_ERRATUM_1418040)) \ > + preempt_enable(); \ > }) > #ifdef CONFIG_COMPAT_VDSO > #define COMPAT_ARCH_DLINFO \ I'd have opted for the use of sysreg_clear_set() instead of the open-coded RMW, as it would elide the write-back in most cases. This looks otherwise OK to me. With that fixed: Reviewed-by: Marc Zyngier <maz@kernel.org> M.
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h index 97932fbf973d..463ff8f00aa7 100644 --- a/arch/arm64/include/asm/elf.h +++ b/arch/arm64/include/asm/elf.h @@ -160,8 +160,18 @@ typedef struct user_fpsimd_state elf_fpregset_t; #define SET_PERSONALITY(ex) \ ({ \ + if (IS_ENABLED(CONFIG_ARM64_ERRATUM_1418040)) \ + preempt_disable(); \ clear_thread_flag(TIF_32BIT); \ current->personality &= ~READ_IMPLIES_EXEC; \ + if (this_cpu_has_cap(ARM64_WORKAROUND_1418040)) { \ + u64 val; \ + val = read_sysreg(cntkctl_el1); \ + val |= ARCH_TIMER_USR_VCT_ACCESS_EN; \ + write_sysreg(val, cntkctl_el1); \ + } \ + if (IS_ENABLED(CONFIG_ARM64_ERRATUM_1418040)) \ + preempt_enable(); \ }) /* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */ @@ -223,7 +233,17 @@ int compat_elf_check_arch(const struct elf32_hdr *); */ #define COMPAT_SET_PERSONALITY(ex) \ ({ \ + if (IS_ENABLED(CONFIG_ARM64_ERRATUM_1418040)) \ + preempt_disable(); \ set_thread_flag(TIF_32BIT); \ + if (this_cpu_has_cap(ARM64_WORKAROUND_1418040)) { \ + u64 val; \ + val = read_sysreg(cntkctl_el1); \ + val &= ~ARCH_TIMER_USR_VCT_ACCESS_EN; \ + write_sysreg(val, cntkctl_el1); \ + } \ + if (IS_ENABLED(CONFIG_ARM64_ERRATUM_1418040)) \ + preempt_enable(); \ }) #ifdef CONFIG_COMPAT_VDSO #define COMPAT_ARCH_DLINFO \
The erratum 1418040 workaround changes vct access trapping when switching between compat and non-compat threads. The workaround logic assumes that the hardware vct trapping state matches the previous task's compat-ness. However, when a non-compat task execs a compat binary or vice versa, the cntkctl state and task compat-ness get out of sync. Keep the hardware trapping state in sync with the task personality. Fixes: d49f7d7376d0 ("arm64: Move handling of erratum 1418040 into C code") Signed-off-by: D Scott Phillips <scott@os.amperecomputing.com> Cc: <stable@vger.kernel.org> # 5.4.x --- arch/arm64/include/asm/elf.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)