| From foo@baz Thu Apr 5 21:39:27 CEST 2018 |
| From: Mark Rutland <mark.rutland@arm.com> |
| Date: Tue, 3 Apr 2018 12:09:08 +0100 |
| Subject: arm64: tls: Avoid unconditional zeroing of tpidrro_el0 for native tasks |
| To: stable@vger.kernel.org |
| Cc: mark.brown@linaro.org, ard.biesheuvel@linaro.org, marc.zyngier@arm.com, will.deacon@arm.com |
| Message-ID: <20180403110923.43575-13-mark.rutland@arm.com> |
| |
| From: Will Deacon <will.deacon@arm.com> |
| |
| commit 18011eac28c7 upstream. |
| |
| When unmapping the kernel at EL0, we use tpidrro_el0 as a scratch register |
| during exception entry from native tasks and subsequently zero it in |
| the kernel_ventry macro. We can therefore avoid zeroing tpidrro_el0 |
| in the context-switch path for native tasks using the entry trampoline. |
| |
| Reviewed-by: Mark Rutland <mark.rutland@arm.com> |
| Tested-by: Laura Abbott <labbott@redhat.com> |
| Tested-by: Shanker Donthineni <shankerd@codeaurora.org> |
| Signed-off-by: Will Deacon <will.deacon@arm.com> |
| Signed-off-by: Alex Shi <alex.shi@linaro.org> [v4.9 backport] |
| Signed-off-by: Mark Rutland <mark.rutland@arm.com> [v4.9 backport] |
| Tested-by: Will Deacon <will.deacon@arm.com> |
| Tested-by: Greg Hackmann <ghackmann@google.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/arm64/kernel/process.c | 12 ++++++------ |
| 1 file changed, 6 insertions(+), 6 deletions(-) |
| |
| --- a/arch/arm64/kernel/process.c |
| +++ b/arch/arm64/kernel/process.c |
| @@ -306,17 +306,17 @@ int copy_thread(unsigned long clone_flag |
| |
| static void tls_thread_switch(struct task_struct *next) |
| { |
| - unsigned long tpidr, tpidrro; |
| + unsigned long tpidr; |
| |
| tpidr = read_sysreg(tpidr_el0); |
| *task_user_tls(current) = tpidr; |
| |
| - tpidr = *task_user_tls(next); |
| - tpidrro = is_compat_thread(task_thread_info(next)) ? |
| - next->thread.tp_value : 0; |
| + if (is_compat_thread(task_thread_info(next))) |
| + write_sysreg(next->thread.tp_value, tpidrro_el0); |
| + else if (!arm64_kernel_unmapped_at_el0()) |
| + write_sysreg(0, tpidrro_el0); |
| |
| - write_sysreg(tpidr, tpidr_el0); |
| - write_sysreg(tpidrro, tpidrro_el0); |
| + write_sysreg(*task_user_tls(next), tpidr_el0); |
| } |
| |
| /* Restore the UAO state depending on next's addr_limit */ |