Dear all,
There's a question in the arch/arm64/kernel/entry.S as following, /* * EL1 mode handlers. */ el1_sync: kernel_entry 1 mrs x1, esr_el1 // read the syndrome register lsr x24, x1, #ESR_EL1_EC_SHIFT // exception class cmp x24, #ESR_EL1_EC_DABT_EL1 // data abort in EL1 b.eq el1_da cmp x24, #ESR_EL1_EC_SYS64 // configurable trap b.eq el1_undef cmp x24, #ESR_EL1_EC_SP_ALIGN // stack alignment exception b.eq el1_sp_pc
el1_sp_pc: /* * Stack or PC alignment exception handling */ mrs x0, far_el1 - mov x1, x25 ==> this is an extra operation mov x2, sp b do_sp_pc_abort //Jump to C Exception handler
/**The C Exception Handler/ asmlinkage void __exception do_sp_pc_abort(unsigned long addr, unsigned int esr, struct pt_regs *regs) { ... }
We use x1 register to store the value of ESR, and check the value to identify which exception handler to jump, And there's a weird part In stack alignment exception handler(el1_sp_pc),
Why do we need to move x25 to x1? The ESR has been stored into x1, and should be directly pass to do_sp_pc_abort function "MOV x1, x25" is an extra operation and do_sp_pc_abort would get the wrong value of esr...
I'm not sure whether I'm right or not, hope someone can take a look at it, thx
BRs andy
On Wed, May 28, 2014 at 12:00:14AM +0800, ChiaHao wrote:
There's a question in the arch/arm64/kernel/entry.S as following, /* * EL1 mode handlers. */ el1_sync: kernel_entry 1 mrs x1, esr_el1 // read the syndrome register lsr x24, x1, #ESR_EL1_EC_SHIFT // exception class cmp x24, #ESR_EL1_EC_DABT_EL1 // data abort in EL1 b.eq el1_da cmp x24, #ESR_EL1_EC_SYS64 // configurable trap b.eq el1_undef cmp x24, #ESR_EL1_EC_SP_ALIGN // stack alignment exception b.eq el1_sp_pc
el1_sp_pc: /* * Stack or PC alignment exception handling */ mrs x0, far_el1 - mov x1, x25 ==> this is an extra operation mov x2, sp b do_sp_pc_abort //Jump to C Exception handler /**The C Exception Handler/ asmlinkage void __exception do_sp_pc_abort(unsigned long addr, unsigned int esr, struct pt_regs *regs) { ... }
We use x1 register to store the value of ESR, and check the value to identify which exception handler to jump, And there's a weird part In stack alignment exception handler(el1_sp_pc),
Why do we need to move x25 to x1? The ESR has been stored into x1, and should be directly pass to do_sp_pc_abort function "MOV x1, x25" is an extra operation and do_sp_pc_abort would get the wrong value of esr...
It's a bug, thanks for reporting. Would you mind sending a patch?
Thanks.
linaro-kernel@lists.linaro.org