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:
Tao Zeng
2019-10-28 17:22:50 +08:00
parent a8b8b96e53
commit b183f51456
3 changed files with 24 additions and 11 deletions

View File

@@ -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)

View File

@@ -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;

View File

@@ -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;
}