Commit 16f9afe6 authored by Vineet Gupta's avatar Vineet Gupta

ARC: pt_regs update #3: Remove unused gutter at start of callee_regs

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.

ptrace needs a bit of updating since pt_regs now diverges from
user_regs_struct.
Signed-off-by: default avatarVineet Gupta <vgupta@synopsys.com>
parent 2fa91904
...@@ -124,8 +124,6 @@ ...@@ -124,8 +124,6 @@
st.a r25, [sp, -4] st.a r25, [sp, -4]
#endif #endif
/* move up by 1 word to "create" callee_regs->"stack_place_holder" */
sub sp, sp, 4
.endm .endm
/*-------------------------------------------------------------- /*--------------------------------------------------------------
...@@ -148,10 +146,9 @@ ...@@ -148,10 +146,9 @@
st.a r23, [sp, -4] st.a r23, [sp, -4]
st.a r24, [sp, -4] st.a r24, [sp, -4]
#ifdef CONFIG_ARC_CURR_IN_REG #ifdef CONFIG_ARC_CURR_IN_REG
sub sp, sp, 8 sub sp, sp, 4
#else #else
st.a r25, [sp, -4] st.a r25, [sp, -4]
sub sp, sp, 4
#endif #endif
.endm .endm
...@@ -168,14 +165,11 @@ ...@@ -168,14 +165,11 @@
*-------------------------------------------------------------*/ *-------------------------------------------------------------*/
.macro RESTORE_CALLEE_SAVED_KERNEL .macro RESTORE_CALLEE_SAVED_KERNEL
#ifdef CONFIG_ARC_CURR_IN_REG #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 #else
add sp, sp, 4 /* skip "callee_regs->stack_place_holder" */
ld.ab r25, [sp, 4] ld.ab r25, [sp, 4]
#endif #endif
ld.ab r24, [sp, 4] ld.ab r24, [sp, 4]
ld.ab r23, [sp, 4] ld.ab r23, [sp, 4]
ld.ab r22, [sp, 4] ld.ab r22, [sp, 4]
...@@ -203,8 +197,6 @@ ...@@ -203,8 +197,6 @@
*-------------------------------------------------------------*/ *-------------------------------------------------------------*/
.macro RESTORE_CALLEE_SAVED_USER .macro RESTORE_CALLEE_SAVED_USER
add sp, sp, 4 /* skip "callee_regs->stack_place_holder" */
#ifdef CONFIG_ARC_CURR_IN_REG #ifdef CONFIG_ARC_CURR_IN_REG
ld.ab r12, [sp, 4] ld.ab r12, [sp, 4]
st r12, [r25, TASK_THREAD + THREAD_USER_R25] st r12, [r25, TASK_THREAD + THREAD_USER_R25]
...@@ -230,7 +222,7 @@ ...@@ -230,7 +222,7 @@
* Super FAST Restore callee saved regs by simply re-adjusting SP * Super FAST Restore callee saved regs by simply re-adjusting SP
*-------------------------------------------------------------*/ *-------------------------------------------------------------*/
.macro DISCARD_CALLEE_SAVED_USER .macro DISCARD_CALLEE_SAVED_USER
add sp, sp, 14 * 4 add sp, sp, SZ_CALLEE_REGS
.endm .endm
/*-------------------------------------------------------------- /*--------------------------------------------------------------
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <asm/arcregs.h> /* for STATUS_E1_MASK et all */ #include <asm/arcregs.h> /* for STATUS_E1_MASK et all */
#include <asm/ptrace.h>
/* Arch specific stuff which needs to be saved per task. /* Arch specific stuff which needs to be saved per task.
* However these items are not so important so as to earn a place in * 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); ...@@ -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. * 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_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. * Do necessary setup to start up a newly executed thread.
......
...@@ -59,7 +59,6 @@ struct pt_regs { ...@@ -59,7 +59,6 @@ struct pt_regs {
/* Callee saved registers - need to be saved only when you are scheduled out */ /* Callee saved registers - need to be saved only when you are scheduled out */
struct callee_regs { struct callee_regs {
long res; /* Again this is not needed */
long r25; long r25;
long r24; long r24;
long r23; long r23;
......
...@@ -38,8 +38,8 @@ struct user_regs_struct { ...@@ -38,8 +38,8 @@ struct user_regs_struct {
long r12, r11, r10, r9, r8, r7, r6, r5, r4, r3, r2, r1, r0; long r12, r11, r10, r9, r8, r7, r6, r5, r4, r3, r2, r1, r0;
long sp; long sp;
} scratch; } scratch;
long pad2;
struct { struct {
long pad;
long r25, r24, r23, r22, r21, r20; long r25, r24, r23, r22, r21, r20;
long r19, r18, r17, r16, r15, r14, r13; long r19, r18, r17, r16, r15, r14, r13;
} callee; } callee;
......
...@@ -60,5 +60,6 @@ int main(void) ...@@ -60,5 +60,6 @@ int main(void)
DEFINE(PT_r6, offsetof(struct pt_regs, r6)); DEFINE(PT_r6, offsetof(struct pt_regs, r6));
DEFINE(PT_r7, offsetof(struct pt_regs, r7)); DEFINE(PT_r7, offsetof(struct pt_regs, r7));
DEFINE(SZ_CALLEE_REGS, sizeof(struct callee_regs));
return 0; return 0;
} }
...@@ -23,10 +23,6 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task) ...@@ -23,10 +23,6 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
unsigned int tmp; unsigned int tmp;
unsigned int prev = (unsigned int)prev_task; unsigned int prev = (unsigned int)prev_task;
unsigned int next = (unsigned int)next_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__( __asm__ __volatile__(
/* FP/BLINK save generated by gcc (standard function prologue */ /* 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) ...@@ -44,8 +40,9 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
"st.a r24, [sp, -4] \n\t" "st.a r24, [sp, -4] \n\t"
#ifndef CONFIG_ARC_CURR_IN_REG #ifndef CONFIG_ARC_CURR_IN_REG
"st.a r25, [sp, -4] \n\t" "st.a r25, [sp, -4] \n\t"
#else
"sub sp, sp, 4 \n\t" /* usual r25 placeholder */
#endif #endif
"sub sp, sp, %4 \n\t" /* create gutter at top */
/* set ksp of outgoing task in tsk->thread.ksp */ /* set ksp of outgoing task in tsk->thread.ksp */
"st.as sp, [%3, %1] \n\t" "st.as sp, [%3, %1] \n\t"
...@@ -76,10 +73,10 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task) ...@@ -76,10 +73,10 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
/* start loading it's CALLEE reg file */ /* start loading it's CALLEE reg file */
"add sp, sp, %4 \n\t" /* skip gutter at top */
#ifndef CONFIG_ARC_CURR_IN_REG #ifndef CONFIG_ARC_CURR_IN_REG
"ld.ab r25, [sp, 4] \n\t" "ld.ab r25, [sp, 4] \n\t"
#else
"add sp, sp, 4 \n\t"
#endif #endif
"ld.ab r24, [sp, 4] \n\t" "ld.ab r24, [sp, 4] \n\t"
"ld.ab r23, [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) ...@@ -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 */ /* FP/BLINK restore generated by gcc (standard func epilogue */
: "=r"(tmp) : "=r"(tmp)
: "n"((TASK_THREAD + THREAD_KSP) / 4), "r"(next), "r"(prev), : "n"((TASK_THREAD + THREAD_KSP) / 4), "r"(next), "r"(prev)
"n"(num_words_to_skip * 4)
: "blink" : "blink"
); );
......
...@@ -55,10 +55,8 @@ asmlinkage void ret_from_fork(void); ...@@ -55,10 +55,8 @@ asmlinkage void ret_from_fork(void);
* | ... | * | ... |
* | unused | * | unused |
* | | * | |
* ------------------ <==== top of Stack (thread.ksp)
* | UNUSED 1 word|
* ------------------ * ------------------
* | r25 | * | r25 | <==== top of Stack (thread.ksp)
* ~ ~ * ~ ~
* | --to-- | (CALLEE Regs of user mode) * | --to-- | (CALLEE Regs of user mode)
* | r13 | * | r13 |
......
...@@ -48,6 +48,7 @@ static int genregs_get(struct task_struct *target, ...@@ -48,6 +48,7 @@ static int genregs_get(struct task_struct *target,
REG_O_ZERO(pad); REG_O_ZERO(pad);
REG_O_CHUNK(scratch, callee, ptregs); REG_O_CHUNK(scratch, callee, ptregs);
REG_O_ZERO(pad2);
REG_O_CHUNK(callee, efa, cregs); REG_O_CHUNK(callee, efa, cregs);
REG_O_CHUNK(efa, stop_pc, &target->thread.fault_address); REG_O_CHUNK(efa, stop_pc, &target->thread.fault_address);
...@@ -96,8 +97,9 @@ static int genregs_set(struct task_struct *target, ...@@ -96,8 +97,9 @@ static int genregs_set(struct task_struct *target,
offsetof(struct user_regs_struct, LOC) + 4); offsetof(struct user_regs_struct, LOC) + 4);
REG_IGNORE_ONE(pad); REG_IGNORE_ONE(pad);
/* TBD: disallow updates to STATUS32, orig_r8 etc*/ /* TBD: disallow updates to STATUS32 etc*/
REG_IN_CHUNK(scratch, callee, ptregs); /* pt_regs[bta..orig_r8] */ 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_IN_CHUNK(callee, efa, cregs); /* callee_regs[r25..r13] */
REG_IGNORE_ONE(efa); /* efa update invalid */ REG_IGNORE_ONE(efa); /* efa update invalid */
REG_IN_ONE(stop_pc, &ptregs->ret); /* stop_pc: PC update */ REG_IN_ONE(stop_pc, &ptregs->ret); /* stop_pc: PC update */
......
...@@ -79,7 +79,7 @@ static void seed_unwind_frame_info(struct task_struct *tsk, ...@@ -79,7 +79,7 @@ static void seed_unwind_frame_info(struct task_struct *tsk,
* assembly code * assembly code
*/ */
frame_info->regs.r27 = 0; frame_info->regs.r27 = 0;
frame_info->regs.r28 += 64; frame_info->regs.r28 += 60;
frame_info->call_frame = 0; frame_info->call_frame = 0;
} else { } else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment