aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLarry Bassel <larry.bassel@linaro.org>2014-05-30 15:34:14 -0400
committerCatalin Marinas <catalin.marinas@arm.com>2014-07-10 05:10:20 -0400
commit6ab6463aeb5fbc75fa3227befb508fc33b34dbf1 (patch)
tree02a4aee7b9b8787c6f160fb4b622328bcf149b65
parentc0c264ae5112d1cdb7d37d4e208b7a7e766a7418 (diff)
arm64: adjust el0_sync so that a function can be called
To implement the context tracker properly on arm64, a function call needs to be made after debugging and interrupts are turned on, but before the lr is changed to point to ret_to_user(). If the function call is made after the lr is changed the function will not return to the correct place. For similar reasons, defer the setting of x0 so that it doesn't need to be saved around the function call (save far_el1 in x26 temporarily instead). Acked-by: Will Deacon <will.deacon@arm.com> Reviewed-by: Kevin Hilman <khilman@linaro.org> Tested-by: Kevin Hilman <khilman@linaro.org> Signed-off-by: Larry Bassel <larry.bassel@linaro.org> Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
-rw-r--r--arch/arm64/kernel/entry.S19
1 files changed, 13 insertions, 6 deletions
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 9ce04ba6bcb0..d7230bf68ad1 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -353,7 +353,6 @@ el0_sync:
353 lsr x24, x25, #ESR_EL1_EC_SHIFT // exception class 353 lsr x24, x25, #ESR_EL1_EC_SHIFT // exception class
354 cmp x24, #ESR_EL1_EC_SVC64 // SVC in 64-bit state 354 cmp x24, #ESR_EL1_EC_SVC64 // SVC in 64-bit state
355 b.eq el0_svc 355 b.eq el0_svc
356 adr lr, ret_to_user
357 cmp x24, #ESR_EL1_EC_DABT_EL0 // data abort in EL0 356 cmp x24, #ESR_EL1_EC_DABT_EL0 // data abort in EL0
358 b.eq el0_da 357 b.eq el0_da
359 cmp x24, #ESR_EL1_EC_IABT_EL0 // instruction abort in EL0 358 cmp x24, #ESR_EL1_EC_IABT_EL0 // instruction abort in EL0
@@ -382,7 +381,6 @@ el0_sync_compat:
382 lsr x24, x25, #ESR_EL1_EC_SHIFT // exception class 381 lsr x24, x25, #ESR_EL1_EC_SHIFT // exception class
383 cmp x24, #ESR_EL1_EC_SVC32 // SVC in 32-bit state 382 cmp x24, #ESR_EL1_EC_SVC32 // SVC in 32-bit state
384 b.eq el0_svc_compat 383 b.eq el0_svc_compat
385 adr lr, ret_to_user
386 cmp x24, #ESR_EL1_EC_DABT_EL0 // data abort in EL0 384 cmp x24, #ESR_EL1_EC_DABT_EL0 // data abort in EL0
387 b.eq el0_da 385 b.eq el0_da
388 cmp x24, #ESR_EL1_EC_IABT_EL0 // instruction abort in EL0 386 cmp x24, #ESR_EL1_EC_IABT_EL0 // instruction abort in EL0
@@ -425,22 +423,25 @@ el0_da:
425 /* 423 /*
426 * Data abort handling 424 * Data abort handling
427 */ 425 */
428 mrs x0, far_el1 426 mrs x26, far_el1
429 bic x0, x0, #(0xff << 56)
430 // enable interrupts before calling the main handler 427 // enable interrupts before calling the main handler
431 enable_dbg_and_irq 428 enable_dbg_and_irq
429 bic x0, x26, #(0xff << 56)
432 mov x1, x25 430 mov x1, x25
433 mov x2, sp 431 mov x2, sp
432 adr lr, ret_to_user
434 b do_mem_abort 433 b do_mem_abort
435el0_ia: 434el0_ia:
436 /* 435 /*
437 * Instruction abort handling 436 * Instruction abort handling
438 */ 437 */
439 mrs x0, far_el1 438 mrs x26, far_el1
440 // enable interrupts before calling the main handler 439 // enable interrupts before calling the main handler
441 enable_dbg_and_irq 440 enable_dbg_and_irq
441 mov x0, x26
442 orr x1, x25, #1 << 24 // use reserved ISS bit for instruction aborts 442 orr x1, x25, #1 << 24 // use reserved ISS bit for instruction aborts
443 mov x2, sp 443 mov x2, sp
444 adr lr, ret_to_user
444 b do_mem_abort 445 b do_mem_abort
445el0_fpsimd_acc: 446el0_fpsimd_acc:
446 /* 447 /*
@@ -449,6 +450,7 @@ el0_fpsimd_acc:
449 enable_dbg 450 enable_dbg
450 mov x0, x25 451 mov x0, x25
451 mov x1, sp 452 mov x1, sp
453 adr lr, ret_to_user
452 b do_fpsimd_acc 454 b do_fpsimd_acc
453el0_fpsimd_exc: 455el0_fpsimd_exc:
454 /* 456 /*
@@ -457,16 +459,19 @@ el0_fpsimd_exc:
457 enable_dbg 459 enable_dbg
458 mov x0, x25 460 mov x0, x25
459 mov x1, sp 461 mov x1, sp
462 adr lr, ret_to_user
460 b do_fpsimd_exc 463 b do_fpsimd_exc
461el0_sp_pc: 464el0_sp_pc:
462 /* 465 /*
463 * Stack or PC alignment exception handling 466 * Stack or PC alignment exception handling
464 */ 467 */
465 mrs x0, far_el1 468 mrs x26, far_el1
466 // enable interrupts before calling the main handler 469 // enable interrupts before calling the main handler
467 enable_dbg_and_irq 470 enable_dbg_and_irq
471 mov x0, x26
468 mov x1, x25 472 mov x1, x25
469 mov x2, sp 473 mov x2, sp
474 adr lr, ret_to_user
470 b do_sp_pc_abort 475 b do_sp_pc_abort
471el0_undef: 476el0_undef:
472 /* 477 /*
@@ -475,6 +480,7 @@ el0_undef:
475 // enable interrupts before calling the main handler 480 // enable interrupts before calling the main handler
476 enable_dbg_and_irq 481 enable_dbg_and_irq
477 mov x0, sp 482 mov x0, sp
483 adr lr, ret_to_user
478 b do_undefinstr 484 b do_undefinstr
479el0_dbg: 485el0_dbg:
480 /* 486 /*
@@ -492,6 +498,7 @@ el0_inv:
492 mov x0, sp 498 mov x0, sp
493 mov x1, #BAD_SYNC 499 mov x1, #BAD_SYNC
494 mrs x2, esr_el1 500 mrs x2, esr_el1
501 adr lr, ret_to_user
495 b bad_mode 502 b bad_mode
496ENDPROC(el0_sync) 503ENDPROC(el0_sync)
497 504