mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 12:57:06 +09:00
mm: fix crash in vmap stack [1/1]
PD#SWPL-12145 Problem: When switch IRQ stack, there is a 16 bytes miss match of irq stack. This may cause context not match some times; Solution: Save sp to right place Verify: X301 Change-Id: I75dfa5208cb3cec050c1568ac78ae2e783ca106b Signed-off-by: Tao Zeng <tao.zeng@amlogic.com>
This commit is contained in:
@@ -51,11 +51,7 @@
|
||||
#endif
|
||||
#ifdef CONFIG_MULTI_IRQ_HANDLER
|
||||
ldr r1, =handle_arch_irq
|
||||
#ifdef CONFIG_AMLOGIC_VMAP
|
||||
mov r0, r8
|
||||
#else
|
||||
mov r0, sp
|
||||
#endif
|
||||
badr lr, 9997f
|
||||
ldr pc, [r1]
|
||||
#else
|
||||
@@ -416,10 +412,28 @@ ENDPROC(__und_svc)
|
||||
|
||||
.align 5
|
||||
__pabt_svc:
|
||||
#ifdef CONFIG_AMLOGIC_VMAP
|
||||
svc_entry vmap=1 /* keep using abt stack */
|
||||
/* re-build context for normal abort handler */
|
||||
ldr r0, [sp, #(SVC_REGS_SIZE + TI_VMAP_BACK_SP)]
|
||||
sub r0, #SVC_REGS_SIZE
|
||||
mov r1, sp
|
||||
mov r2, #SVC_REGS_SIZE
|
||||
#ifdef CONFIG_AMLOGIC_KASAN32
|
||||
bl __memcpy /* copy back sp */
|
||||
#else
|
||||
bl memcpy /* copy back sp */
|
||||
#endif
|
||||
mov sp, r0
|
||||
mov r2, sp @ regs
|
||||
pabt_helper
|
||||
svc_exit r5 @ return from exception
|
||||
#else
|
||||
svc_entry
|
||||
mov r2, sp @ regs
|
||||
pabt_helper
|
||||
svc_exit r5 @ return from exception
|
||||
#endif
|
||||
UNWIND(.fnend )
|
||||
ENDPROC(__pabt_svc)
|
||||
|
||||
|
||||
@@ -541,11 +541,10 @@ void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk)
|
||||
unsigned long sp_irq;
|
||||
|
||||
keep = 1;
|
||||
sp_irq = (unsigned long)irq_stack[cpu];
|
||||
addr = *((unsigned long *)(sp_irq +
|
||||
THREAD_INFO_OFFSET - 8 -
|
||||
sizeof(addr) - 12));
|
||||
pt_regs = (struct pt_regs *)addr;
|
||||
sp_irq = (unsigned long)irq_stack[cpu];
|
||||
addr = *((unsigned long *)(sp_irq +
|
||||
THREAD_INFO_OFFSET - 8));
|
||||
pt_regs = (struct pt_regs *)addr;
|
||||
frame.fp = pt_regs->ARM_fp;
|
||||
frame.sp = pt_regs->ARM_sp;
|
||||
frame.lr = pt_regs->ARM_lr;
|
||||
|
||||
@@ -165,9 +165,9 @@ unsigned long notrace irq_stack_entry(unsigned long sp)
|
||||
sp_irq = (unsigned long)dst - 8;
|
||||
/*
|
||||
* save start addr of the interrupted task's context
|
||||
* minus an extra 12 to force base sp 16Bytes aligned
|
||||
* used to back trace stack call from irq
|
||||
* Note: sp_irq must be aligned to 16 bytes
|
||||
*/
|
||||
sp_irq = sp_irq - sizeof(sp) - 12;
|
||||
*((unsigned long *)sp_irq) = sp;
|
||||
return sp_irq;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user