aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/kernel/process.c
diff options
context:
space:
mode:
authorMark Rutland <mark.rutland@arm.com>2016-09-08 08:55:38 -0400
committerWill Deacon <will.deacon@arm.com>2016-09-09 06:43:50 -0400
commitadf7589997927b1d84a5d003027b866bbef61ef2 (patch)
treef3bb449f2bda4e8992983b5d87e7dab1415fa17e /arch/arm64/kernel/process.c
parent1f3d8699be82583c713e2a1099c597a740ebaf4d (diff)
arm64: simplify sysreg manipulation
A while back we added {read,write}_sysreg accessors to handle accesses to system registers, without the usual boilerplate asm volatile, temporary variable, etc. This patch makes use of these across arm64 to make code shorter and clearer. For sequences with a trailing ISB, the existing isb() macro is also used so that asm blocks can be removed entirely. A few uses of inline assembly for msr/mrs are left as-is. Those manipulating sp_el0 for the current thread_info value have special clobber requiremends. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Will Deacon <will.deacon@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arch/arm64/kernel/process.c')
-rw-r--r--arch/arm64/kernel/process.c14
1 files changed, 6 insertions, 8 deletions
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 6cd2612236dc..a4f5f766af08 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -202,7 +202,7 @@ void show_regs(struct pt_regs * regs)
202 202
203static void tls_thread_flush(void) 203static void tls_thread_flush(void)
204{ 204{
205 asm ("msr tpidr_el0, xzr"); 205 write_sysreg(0, tpidr_el0);
206 206
207 if (is_compat_task()) { 207 if (is_compat_task()) {
208 current->thread.tp_value = 0; 208 current->thread.tp_value = 0;
@@ -213,7 +213,7 @@ static void tls_thread_flush(void)
213 * with a stale shadow state during context switch. 213 * with a stale shadow state during context switch.
214 */ 214 */
215 barrier(); 215 barrier();
216 asm ("msr tpidrro_el0, xzr"); 216 write_sysreg(0, tpidrro_el0);
217 } 217 }
218} 218}
219 219
@@ -253,7 +253,7 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
253 * Read the current TLS pointer from tpidr_el0 as it may be 253 * Read the current TLS pointer from tpidr_el0 as it may be
254 * out-of-sync with the saved value. 254 * out-of-sync with the saved value.
255 */ 255 */
256 asm("mrs %0, tpidr_el0" : "=r" (*task_user_tls(p))); 256 *task_user_tls(p) = read_sysreg(tpidr_el0);
257 257
258 if (stack_start) { 258 if (stack_start) {
259 if (is_compat_thread(task_thread_info(p))) 259 if (is_compat_thread(task_thread_info(p)))
@@ -289,17 +289,15 @@ static void tls_thread_switch(struct task_struct *next)
289{ 289{
290 unsigned long tpidr, tpidrro; 290 unsigned long tpidr, tpidrro;
291 291
292 asm("mrs %0, tpidr_el0" : "=r" (tpidr)); 292 tpidr = read_sysreg(tpidr_el0);
293 *task_user_tls(current) = tpidr; 293 *task_user_tls(current) = tpidr;
294 294
295 tpidr = *task_user_tls(next); 295 tpidr = *task_user_tls(next);
296 tpidrro = is_compat_thread(task_thread_info(next)) ? 296 tpidrro = is_compat_thread(task_thread_info(next)) ?
297 next->thread.tp_value : 0; 297 next->thread.tp_value : 0;
298 298
299 asm( 299 write_sysreg(tpidr, tpidr_el0);
300 " msr tpidr_el0, %0\n" 300 write_sysreg(tpidrro, tpidrro_el0);
301 " msr tpidrro_el0, %1"
302 : : "r" (tpidr), "r" (tpidrro));
303} 301}
304 302
305/* Restore the UAO state depending on next's addr_limit */ 303/* Restore the UAO state depending on next's addr_limit */