]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ARC: pt_regs cleanup #3: Remove unused gutter at start of callee_regs
authorVineet Gupta <vgupta@synopsys.com>
Mon, 27 May 2013 16:13:41 +0000 (21:43 +0530)
committerVineet Gupta <vgupta@synopsys.com>
Mon, 17 Jun 2013 13:02:19 +0000 (18:32 +0530)
This is trickier than prev two:

* context switching code saves kernel mode callee regs in the format of
  struct callee_regs thus needs adjustment. This also reduces the height
  of topmost kernel stack frame by 1 word.

* Since kernel stack unwinder is sensitive to height of topmost kernel
  stack frame, that needs a word of adjustment too.

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
arch/arc/include/asm/entry.h
arch/arc/include/asm/processor.h
arch/arc/include/asm/ptrace.h
arch/arc/include/uapi/asm/ptrace.h
arch/arc/kernel/asm-offsets.c
arch/arc/kernel/ctx_sw.c
arch/arc/kernel/process.c
arch/arc/kernel/ptrace.c
arch/arc/kernel/stacktrace.c

index 5ff7b8dd3d5b661407ee0294bc92c314ee0a700c..820202af21a5f3512d5417f3d88b77ce581d5056 100644 (file)
        st.a    r25, [sp, -4]
 #endif
 
-       /* move up by 1 word to "create" callee_regs->"stack_place_holder" */
-       sub sp, sp, 4
 .endm
 
 /*--------------------------------------------------------------
        st.a    r23, [sp, -4]
        st.a    r24, [sp, -4]
 #ifdef CONFIG_ARC_CURR_IN_REG
-       sub     sp, sp, 8
+       sub     sp, sp, 4
 #else
        st.a    r25, [sp, -4]
-       sub     sp, sp, 4
 #endif
 .endm
 
  *-------------------------------------------------------------*/
 .macro RESTORE_CALLEE_SAVED_KERNEL
 
-
 #ifdef CONFIG_ARC_CURR_IN_REG
-       add     sp, sp, 8  /* skip callee_reg gutter and user r25 placeholder */
+       add     sp, sp, 4  /* skip usual r25 placeholder */
 #else
-       add     sp, sp, 4   /* skip "callee_regs->stack_place_holder" */
        ld.ab   r25, [sp, 4]
 #endif
-
        ld.ab   r24, [sp, 4]
        ld.ab   r23, [sp, 4]
        ld.ab   r22, [sp, 4]
  *-------------------------------------------------------------*/
 .macro RESTORE_CALLEE_SAVED_USER
 
-       add     sp, sp, 4   /* skip "callee_regs->stack_place_holder" */
-
 #ifdef CONFIG_ARC_CURR_IN_REG
        ld.ab   r12, [sp, 4]
        st      r12, [r25, TASK_THREAD + THREAD_USER_R25]
  * Super FAST Restore callee saved regs by simply re-adjusting SP
  *-------------------------------------------------------------*/
 .macro DISCARD_CALLEE_SAVED_USER
-       add     sp, sp, 14 * 4
+       add     sp, sp, SZ_CALLEE_REGS
 .endm
 
 /*--------------------------------------------------------------
index 81efbcae3839bbb7e1d3d8234269a6d9554da19f..8c77e623c4e5bf908611c3c13f6d5e90a8ba427b 100644 (file)
@@ -19,6 +19,7 @@
 #ifndef __ASSEMBLY__
 
 #include <asm/arcregs.h>       /* for STATUS_E1_MASK et all */
+#include <asm/ptrace.h>
 
 /* Arch specific stuff which needs to be saved per task.
  * However these items are not so important so as to earn a place in
@@ -75,11 +76,15 @@ unsigned long thread_saved_pc(struct task_struct *t);
 
 /*
  * Where abouts of Task's sp, fp, blink when it was last seen in kernel mode.
- * These can't be derived from pt_regs as that would give correp user-mode val
+ * Look in process.c for details of kernel stack layout
  */
 #define KSTK_ESP(tsk)   (tsk->thread.ksp)
-#define KSTK_BLINK(tsk) (*((unsigned int *)((KSTK_ESP(tsk)) + (13+1+1)*4)))
-#define KSTK_FP(tsk)    (*((unsigned int *)((KSTK_ESP(tsk)) + (13+1)*4)))
+
+#define KSTK_REG(tsk, off)     (*((unsigned int *)(KSTK_ESP(tsk) + \
+                                       sizeof(struct callee_regs) + off)))
+
+#define KSTK_BLINK(tsk) KSTK_REG(tsk, 4)
+#define KSTK_FP(tsk)    KSTK_REG(tsk, 0)
 
 /*
  * Do necessary setup to start up a newly executed thread.
index 7491bb7428bdce680051b99c10ef31bcff7e8e56..47801ba135b3b4bf2c0f743b03838454e7748b31 100644 (file)
@@ -59,7 +59,6 @@ struct pt_regs {
 /* Callee saved registers - need to be saved only when you are scheduled out */
 
 struct callee_regs {
-       long res;       /* Again this is not needed */
        long r25;
        long r24;
        long r23;
index 5b0017f785b2df3b2ce9c2c2b435f41669ad3165..2052ae67aed4564792ad51a8dd78cb366d04faae 100644 (file)
@@ -35,8 +35,8 @@ struct user_regs_struct {
                long r12, r11, r10, r9, r8, r7, r6, r5, r4, r3, r2, r1, r0;
                long sp;
        } scratch;
+       long pad2;
        struct {
-               long pad;
                long r25, r24, r23, r22, r21, r20;
                long r19, r18, r17, r16, r15, r14, r13;
        } callee;
index 7dcda70252411949b32f8b9b112c9e37bfec0edc..fdcd76532b7069f81cc4bfa2cf87a349ccf3e637 100644 (file)
@@ -60,5 +60,6 @@ int main(void)
        DEFINE(PT_r6, offsetof(struct pt_regs, r6));
        DEFINE(PT_r7, offsetof(struct pt_regs, r7));
 
+       DEFINE(SZ_CALLEE_REGS, sizeof(struct callee_regs));
        return 0;
 }
index 60844dac6132a0c689d53351603ac448295598bb..34410eb1a308e7d801abbc6ece893db54975f9c7 100644 (file)
@@ -23,10 +23,6 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
        unsigned int tmp;
        unsigned int prev = (unsigned int)prev_task;
        unsigned int next = (unsigned int)next_task;
-       int num_words_to_skip = 1;
-#ifdef CONFIG_ARC_CURR_IN_REG
-       num_words_to_skip++;
-#endif
 
        __asm__ __volatile__(
                /* FP/BLINK save generated by gcc (standard function prologue */
@@ -44,8 +40,9 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
                "st.a    r24, [sp, -4]   \n\t"
 #ifndef CONFIG_ARC_CURR_IN_REG
                "st.a    r25, [sp, -4]   \n\t"
+#else
+               "sub     sp, sp, 4      \n\t"   /* usual r25 placeholder */
 #endif
-               "sub     sp, sp, %4      \n\t"  /* create gutter at top */
 
                /* set ksp of outgoing task in tsk->thread.ksp */
                "st.as   sp, [%3, %1]    \n\t"
@@ -76,10 +73,10 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
 
                /* start loading it's CALLEE reg file */
 
-               "add    sp, sp, %4     \n\t"    /* skip gutter at top */
-
 #ifndef CONFIG_ARC_CURR_IN_REG
                "ld.ab   r25, [sp, 4]   \n\t"
+#else
+               "add    sp, sp, 4       \n\t"
 #endif
                "ld.ab   r24, [sp, 4]   \n\t"
                "ld.ab   r23, [sp, 4]   \n\t"
@@ -100,8 +97,7 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
                /* FP/BLINK restore generated by gcc (standard func epilogue */
 
                : "=r"(tmp)
-               : "n"((TASK_THREAD + THREAD_KSP) / 4), "r"(next), "r"(prev),
-                 "n"(num_words_to_skip * 4)
+               : "n"((TASK_THREAD + THREAD_KSP) / 4), "r"(next), "r"(prev)
                : "blink"
        );
 
index 949bfd5d62a09a62d788b6a553f43b0b8dac7334..db868db82944d5e6bf74fc59d4453836866b38c7 100644 (file)
@@ -55,10 +55,8 @@ asmlinkage void ret_from_fork(void);
  * |     ...        |
  * |    unused      |
  * |                |
- * ------------------  <==== top of Stack (thread.ksp)
- * |   UNUSED 1 word|
  * ------------------
- * |     r25        |
+ * |     r25        |   <==== top of Stack (thread.ksp)
  * ~                ~
  * |    --to--      |   (CALLEE Regs of user mode)
  * |     r13        |
index 6e467e3585b0b64ea224994db754145edbf636ea..333238564b67f1239afde4ab4d584f16d8a48572 100644 (file)
@@ -48,6 +48,7 @@ static int genregs_get(struct task_struct *target,
 
        REG_O_ZERO(pad);
        REG_O_CHUNK(scratch, callee, ptregs);
+       REG_O_ZERO(pad2);
        REG_O_CHUNK(callee, efa, cregs);
        REG_O_CHUNK(efa, stop_pc, &target->thread.fault_address);
 
@@ -96,8 +97,9 @@ static int genregs_set(struct task_struct *target,
                        offsetof(struct user_regs_struct, LOC) + 4);
 
        REG_IGNORE_ONE(pad);
-       /* TBD: disallow updates to STATUS32, orig_r8 etc*/
-       REG_IN_CHUNK(scratch, callee, ptregs);  /* pt_regs[bta..orig_r8] */
+       /* TBD: disallow updates to STATUS32 etc*/
+       REG_IN_CHUNK(scratch, pad2, ptregs);    /* pt_regs[bta..sp] */
+       REG_IGNORE_ONE(pad2);
        REG_IN_CHUNK(callee, efa, cregs);       /* callee_regs[r25..r13] */
        REG_IGNORE_ONE(efa);                    /* efa update invalid */
        REG_IN_ONE(stop_pc, &ptregs->ret);      /* stop_pc: PC update */
index ca0207b9d5b6f14d668be5f68735b52ccde1f54d..f8b7d880304dcc777db967a0d344515b2e6d2453 100644 (file)
@@ -79,7 +79,7 @@ static void seed_unwind_frame_info(struct task_struct *tsk,
                 * assembly code
                 */
                frame_info->regs.r27 = 0;
-               frame_info->regs.r28 += 64;
+               frame_info->regs.r28 += 60;
                frame_info->call_frame = 0;
 
        } else {