time: fix fail to read generic timer's counter value correctly [1/1]
authorJiamin Ma <jiamin.ma@amlogic.com>
Mon, 8 Apr 2019 09:06:27 +0000 (17:06 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Tue, 9 Apr 2019 08:59:41 +0000 (01:59 -0700)
PD#SWPL-6837

Problem:
The return value of arch_counter_get_cntvct is always abnormal
when it is in irq stack. In this case, arch_counter_get_cntvct
trys to access a variable in 8Bytes via a 4Bytes aligned addr-
ess, which vialates the rule: The address that is accessed
should be aligned to the size of the data element being
accessed

Solution:
after switching to irq stack, force the base sp value to be
16Bytes aligned. Since the address of variable in irq stack is
based on the base sp and arranged automatically, all the data
accessing in irq stack will be aligned.

Verify:
Ampere

Change-Id: I3b30a56491dd0720d1c885bfaf2ca98d1b103fdd
Signed-off-by: Jiamin Ma <jiamin.ma@amlogic.com>
arch/arm/kernel/unwind.c
drivers/amlogic/memory_ext/vmap_stack.c

index a005a27..98f8fba 100644 (file)
@@ -538,7 +538,7 @@ void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk)
                                sp_irq = (unsigned long)irq_stack[cpu];
                                addr = *((unsigned long *)(sp_irq +
                                        THREAD_INFO_OFFSET - 8 -
-                                       sizeof(addr)));
+                                       sizeof(addr) - 12));
                                pt_regs = (struct pt_regs *)addr;
                                frame.fp = pt_regs->ARM_fp;
                                frame.sp = pt_regs->ARM_sp;
index 664ab24..d199f76 100644 (file)
@@ -159,8 +159,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
                 */
-               sp_irq = sp_irq - sizeof(sp);
+               sp_irq = sp_irq - sizeof(sp) - 12;
                *((unsigned long *)sp_irq) = sp;
                return sp_irq;
        }