diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2013-05-27 12:13:41 -0400 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2013-06-22 09:53:22 -0400 |
commit | 16f9afe651e8197fb7ce6df0990d8e2ad779e1af (patch) | |
tree | c6482028a0ceced44e7e4819f7741c2fd8084e3e | |
parent | 2fa919045b72ec892e17d56f888e6af4260b7629 (diff) |
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: Vineet Gupta <vgupta@synopsys.com>
-rw-r--r-- | arch/arc/include/asm/entry.h | 14 | ||||
-rw-r--r-- | arch/arc/include/asm/processor.h | 11 | ||||
-rw-r--r-- | arch/arc/include/asm/ptrace.h | 1 | ||||
-rw-r--r-- | arch/arc/include/uapi/asm/ptrace.h | 2 | ||||
-rw-r--r-- | arch/arc/kernel/asm-offsets.c | 1 | ||||
-rw-r--r-- | arch/arc/kernel/ctx_sw.c | 14 | ||||
-rw-r--r-- | arch/arc/kernel/process.c | 4 | ||||
-rw-r--r-- | arch/arc/kernel/ptrace.c | 6 | ||||
-rw-r--r-- | arch/arc/kernel/stacktrace.c | 2 |
9 files changed, 24 insertions, 31 deletions
diff --git a/arch/arc/include/asm/entry.h b/arch/arc/include/asm/entry.h index 5ff7b8dd3d5b..820202af21a5 100644 --- a/arch/arc/include/asm/entry.h +++ b/arch/arc/include/asm/entry.h | |||
@@ -124,8 +124,6 @@ | |||
124 | st.a r25, [sp, -4] | 124 | st.a r25, [sp, -4] |
125 | #endif | 125 | #endif |
126 | 126 | ||
127 | /* move up by 1 word to "create" callee_regs->"stack_place_holder" */ | ||
128 | sub sp, sp, 4 | ||
129 | .endm | 127 | .endm |
130 | 128 | ||
131 | /*-------------------------------------------------------------- | 129 | /*-------------------------------------------------------------- |
@@ -148,10 +146,9 @@ | |||
148 | st.a r23, [sp, -4] | 146 | st.a r23, [sp, -4] |
149 | st.a r24, [sp, -4] | 147 | st.a r24, [sp, -4] |
150 | #ifdef CONFIG_ARC_CURR_IN_REG | 148 | #ifdef CONFIG_ARC_CURR_IN_REG |
151 | sub sp, sp, 8 | 149 | sub sp, sp, 4 |
152 | #else | 150 | #else |
153 | st.a r25, [sp, -4] | 151 | st.a r25, [sp, -4] |
154 | sub sp, sp, 4 | ||
155 | #endif | 152 | #endif |
156 | .endm | 153 | .endm |
157 | 154 | ||
@@ -168,14 +165,11 @@ | |||
168 | *-------------------------------------------------------------*/ | 165 | *-------------------------------------------------------------*/ |
169 | .macro RESTORE_CALLEE_SAVED_KERNEL | 166 | .macro RESTORE_CALLEE_SAVED_KERNEL |
170 | 167 | ||
171 | |||
172 | #ifdef CONFIG_ARC_CURR_IN_REG | 168 | #ifdef CONFIG_ARC_CURR_IN_REG |
173 | add sp, sp, 8 /* skip callee_reg gutter and user r25 placeholder */ | 169 | add sp, sp, 4 /* skip usual r25 placeholder */ |
174 | #else | 170 | #else |
175 | add sp, sp, 4 /* skip "callee_regs->stack_place_holder" */ | ||
176 | ld.ab r25, [sp, 4] | 171 | ld.ab r25, [sp, 4] |
177 | #endif | 172 | #endif |
178 | |||
179 | ld.ab r24, [sp, 4] | 173 | ld.ab r24, [sp, 4] |
180 | ld.ab r23, [sp, 4] | 174 | ld.ab r23, [sp, 4] |
181 | ld.ab r22, [sp, 4] | 175 | ld.ab r22, [sp, 4] |
@@ -203,8 +197,6 @@ | |||
203 | *-------------------------------------------------------------*/ | 197 | *-------------------------------------------------------------*/ |
204 | .macro RESTORE_CALLEE_SAVED_USER | 198 | .macro RESTORE_CALLEE_SAVED_USER |
205 | 199 | ||
206 | add sp, sp, 4 /* skip "callee_regs->stack_place_holder" */ | ||
207 | |||
208 | #ifdef CONFIG_ARC_CURR_IN_REG | 200 | #ifdef CONFIG_ARC_CURR_IN_REG |
209 | ld.ab r12, [sp, 4] | 201 | ld.ab r12, [sp, 4] |
210 | st r12, [r25, TASK_THREAD + THREAD_USER_R25] | 202 | st r12, [r25, TASK_THREAD + THREAD_USER_R25] |
@@ -230,7 +222,7 @@ | |||
230 | * Super FAST Restore callee saved regs by simply re-adjusting SP | 222 | * Super FAST Restore callee saved regs by simply re-adjusting SP |
231 | *-------------------------------------------------------------*/ | 223 | *-------------------------------------------------------------*/ |
232 | .macro DISCARD_CALLEE_SAVED_USER | 224 | .macro DISCARD_CALLEE_SAVED_USER |
233 | add sp, sp, 14 * 4 | 225 | add sp, sp, SZ_CALLEE_REGS |
234 | .endm | 226 | .endm |
235 | 227 | ||
236 | /*-------------------------------------------------------------- | 228 | /*-------------------------------------------------------------- |
diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h index 81efbcae3839..8c77e623c4e5 100644 --- a/arch/arc/include/asm/processor.h +++ b/arch/arc/include/asm/processor.h | |||
@@ -19,6 +19,7 @@ | |||
19 | #ifndef __ASSEMBLY__ | 19 | #ifndef __ASSEMBLY__ |
20 | 20 | ||
21 | #include <asm/arcregs.h> /* for STATUS_E1_MASK et all */ | 21 | #include <asm/arcregs.h> /* for STATUS_E1_MASK et all */ |
22 | #include <asm/ptrace.h> | ||
22 | 23 | ||
23 | /* Arch specific stuff which needs to be saved per task. | 24 | /* Arch specific stuff which needs to be saved per task. |
24 | * However these items are not so important so as to earn a place in | 25 | * 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 | 76 | ||
76 | /* | 77 | /* |
77 | * Where abouts of Task's sp, fp, blink when it was last seen in kernel mode. | 78 | * Where abouts of Task's sp, fp, blink when it was last seen in kernel mode. |
78 | * These can't be derived from pt_regs as that would give correp user-mode val | 79 | * Look in process.c for details of kernel stack layout |
79 | */ | 80 | */ |
80 | #define KSTK_ESP(tsk) (tsk->thread.ksp) | 81 | #define KSTK_ESP(tsk) (tsk->thread.ksp) |
81 | #define KSTK_BLINK(tsk) (*((unsigned int *)((KSTK_ESP(tsk)) + (13+1+1)*4))) | 82 | |
82 | #define KSTK_FP(tsk) (*((unsigned int *)((KSTK_ESP(tsk)) + (13+1)*4))) | 83 | #define KSTK_REG(tsk, off) (*((unsigned int *)(KSTK_ESP(tsk) + \ |
84 | sizeof(struct callee_regs) + off))) | ||
85 | |||
86 | #define KSTK_BLINK(tsk) KSTK_REG(tsk, 4) | ||
87 | #define KSTK_FP(tsk) KSTK_REG(tsk, 0) | ||
83 | 88 | ||
84 | /* | 89 | /* |
85 | * Do necessary setup to start up a newly executed thread. | 90 | * Do necessary setup to start up a newly executed thread. |
diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrace.h index 7491bb7428bd..47801ba135b3 100644 --- a/arch/arc/include/asm/ptrace.h +++ b/arch/arc/include/asm/ptrace.h | |||
@@ -59,7 +59,6 @@ struct pt_regs { | |||
59 | /* Callee saved registers - need to be saved only when you are scheduled out */ | 59 | /* Callee saved registers - need to be saved only when you are scheduled out */ |
60 | 60 | ||
61 | struct callee_regs { | 61 | struct callee_regs { |
62 | long res; /* Again this is not needed */ | ||
63 | long r25; | 62 | long r25; |
64 | long r24; | 63 | long r24; |
65 | long r23; | 64 | long r23; |
diff --git a/arch/arc/include/uapi/asm/ptrace.h b/arch/arc/include/uapi/asm/ptrace.h index e0e8403f181f..4599109f68f2 100644 --- a/arch/arc/include/uapi/asm/ptrace.h +++ b/arch/arc/include/uapi/asm/ptrace.h | |||
@@ -38,8 +38,8 @@ struct user_regs_struct { | |||
38 | long r12, r11, r10, r9, r8, r7, r6, r5, r4, r3, r2, r1, r0; | 38 | long r12, r11, r10, r9, r8, r7, r6, r5, r4, r3, r2, r1, r0; |
39 | long sp; | 39 | long sp; |
40 | } scratch; | 40 | } scratch; |
41 | long pad2; | ||
41 | struct { | 42 | struct { |
42 | long pad; | ||
43 | long r25, r24, r23, r22, r21, r20; | 43 | long r25, r24, r23, r22, r21, r20; |
44 | long r19, r18, r17, r16, r15, r14, r13; | 44 | long r19, r18, r17, r16, r15, r14, r13; |
45 | } callee; | 45 | } callee; |
diff --git a/arch/arc/kernel/asm-offsets.c b/arch/arc/kernel/asm-offsets.c index 7dcda7025241..fdcd76532b70 100644 --- a/arch/arc/kernel/asm-offsets.c +++ b/arch/arc/kernel/asm-offsets.c | |||
@@ -60,5 +60,6 @@ int main(void) | |||
60 | DEFINE(PT_r6, offsetof(struct pt_regs, r6)); | 60 | DEFINE(PT_r6, offsetof(struct pt_regs, r6)); |
61 | DEFINE(PT_r7, offsetof(struct pt_regs, r7)); | 61 | DEFINE(PT_r7, offsetof(struct pt_regs, r7)); |
62 | 62 | ||
63 | DEFINE(SZ_CALLEE_REGS, sizeof(struct callee_regs)); | ||
63 | return 0; | 64 | return 0; |
64 | } | 65 | } |
diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c index 60844dac6132..34410eb1a308 100644 --- a/arch/arc/kernel/ctx_sw.c +++ b/arch/arc/kernel/ctx_sw.c | |||
@@ -23,10 +23,6 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task) | |||
23 | unsigned int tmp; | 23 | unsigned int tmp; |
24 | unsigned int prev = (unsigned int)prev_task; | 24 | unsigned int prev = (unsigned int)prev_task; |
25 | unsigned int next = (unsigned int)next_task; | 25 | unsigned int next = (unsigned int)next_task; |
26 | int num_words_to_skip = 1; | ||
27 | #ifdef CONFIG_ARC_CURR_IN_REG | ||
28 | num_words_to_skip++; | ||
29 | #endif | ||
30 | 26 | ||
31 | __asm__ __volatile__( | 27 | __asm__ __volatile__( |
32 | /* FP/BLINK save generated by gcc (standard function prologue */ | 28 | /* 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 | "st.a r24, [sp, -4] \n\t" | 40 | "st.a r24, [sp, -4] \n\t" |
45 | #ifndef CONFIG_ARC_CURR_IN_REG | 41 | #ifndef CONFIG_ARC_CURR_IN_REG |
46 | "st.a r25, [sp, -4] \n\t" | 42 | "st.a r25, [sp, -4] \n\t" |
43 | #else | ||
44 | "sub sp, sp, 4 \n\t" /* usual r25 placeholder */ | ||
47 | #endif | 45 | #endif |
48 | "sub sp, sp, %4 \n\t" /* create gutter at top */ | ||
49 | 46 | ||
50 | /* set ksp of outgoing task in tsk->thread.ksp */ | 47 | /* set ksp of outgoing task in tsk->thread.ksp */ |
51 | "st.as sp, [%3, %1] \n\t" | 48 | "st.as sp, [%3, %1] \n\t" |
@@ -76,10 +73,10 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task) | |||
76 | 73 | ||
77 | /* start loading it's CALLEE reg file */ | 74 | /* start loading it's CALLEE reg file */ |
78 | 75 | ||
79 | "add sp, sp, %4 \n\t" /* skip gutter at top */ | ||
80 | |||
81 | #ifndef CONFIG_ARC_CURR_IN_REG | 76 | #ifndef CONFIG_ARC_CURR_IN_REG |
82 | "ld.ab r25, [sp, 4] \n\t" | 77 | "ld.ab r25, [sp, 4] \n\t" |
78 | #else | ||
79 | "add sp, sp, 4 \n\t" | ||
83 | #endif | 80 | #endif |
84 | "ld.ab r24, [sp, 4] \n\t" | 81 | "ld.ab r24, [sp, 4] \n\t" |
85 | "ld.ab r23, [sp, 4] \n\t" | 82 | "ld.ab r23, [sp, 4] \n\t" |
@@ -100,8 +97,7 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task) | |||
100 | /* FP/BLINK restore generated by gcc (standard func epilogue */ | 97 | /* FP/BLINK restore generated by gcc (standard func epilogue */ |
101 | 98 | ||
102 | : "=r"(tmp) | 99 | : "=r"(tmp) |
103 | : "n"((TASK_THREAD + THREAD_KSP) / 4), "r"(next), "r"(prev), | 100 | : "n"((TASK_THREAD + THREAD_KSP) / 4), "r"(next), "r"(prev) |
104 | "n"(num_words_to_skip * 4) | ||
105 | : "blink" | 101 | : "blink" |
106 | ); | 102 | ); |
107 | 103 | ||
diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c index 949bfd5d62a0..db868db82944 100644 --- a/arch/arc/kernel/process.c +++ b/arch/arc/kernel/process.c | |||
@@ -55,10 +55,8 @@ asmlinkage void ret_from_fork(void); | |||
55 | * | ... | | 55 | * | ... | |
56 | * | unused | | 56 | * | unused | |
57 | * | | | 57 | * | | |
58 | * ------------------ <==== top of Stack (thread.ksp) | ||
59 | * | UNUSED 1 word| | ||
60 | * ------------------ | 58 | * ------------------ |
61 | * | r25 | | 59 | * | r25 | <==== top of Stack (thread.ksp) |
62 | * ~ ~ | 60 | * ~ ~ |
63 | * | --to-- | (CALLEE Regs of user mode) | 61 | * | --to-- | (CALLEE Regs of user mode) |
64 | * | r13 | | 62 | * | r13 | |
diff --git a/arch/arc/kernel/ptrace.c b/arch/arc/kernel/ptrace.c index 6e467e3585b0..333238564b67 100644 --- a/arch/arc/kernel/ptrace.c +++ b/arch/arc/kernel/ptrace.c | |||
@@ -48,6 +48,7 @@ static int genregs_get(struct task_struct *target, | |||
48 | 48 | ||
49 | REG_O_ZERO(pad); | 49 | REG_O_ZERO(pad); |
50 | REG_O_CHUNK(scratch, callee, ptregs); | 50 | REG_O_CHUNK(scratch, callee, ptregs); |
51 | REG_O_ZERO(pad2); | ||
51 | REG_O_CHUNK(callee, efa, cregs); | 52 | REG_O_CHUNK(callee, efa, cregs); |
52 | REG_O_CHUNK(efa, stop_pc, &target->thread.fault_address); | 53 | REG_O_CHUNK(efa, stop_pc, &target->thread.fault_address); |
53 | 54 | ||
@@ -96,8 +97,9 @@ static int genregs_set(struct task_struct *target, | |||
96 | offsetof(struct user_regs_struct, LOC) + 4); | 97 | offsetof(struct user_regs_struct, LOC) + 4); |
97 | 98 | ||
98 | REG_IGNORE_ONE(pad); | 99 | REG_IGNORE_ONE(pad); |
99 | /* TBD: disallow updates to STATUS32, orig_r8 etc*/ | 100 | /* TBD: disallow updates to STATUS32 etc*/ |
100 | REG_IN_CHUNK(scratch, callee, ptregs); /* pt_regs[bta..orig_r8] */ | 101 | REG_IN_CHUNK(scratch, pad2, ptregs); /* pt_regs[bta..sp] */ |
102 | REG_IGNORE_ONE(pad2); | ||
101 | REG_IN_CHUNK(callee, efa, cregs); /* callee_regs[r25..r13] */ | 103 | REG_IN_CHUNK(callee, efa, cregs); /* callee_regs[r25..r13] */ |
102 | REG_IGNORE_ONE(efa); /* efa update invalid */ | 104 | REG_IGNORE_ONE(efa); /* efa update invalid */ |
103 | REG_IN_ONE(stop_pc, &ptregs->ret); /* stop_pc: PC update */ | 105 | REG_IN_ONE(stop_pc, &ptregs->ret); /* stop_pc: PC update */ |
diff --git a/arch/arc/kernel/stacktrace.c b/arch/arc/kernel/stacktrace.c index ca0207b9d5b6..f8b7d880304d 100644 --- a/arch/arc/kernel/stacktrace.c +++ b/arch/arc/kernel/stacktrace.c | |||
@@ -79,7 +79,7 @@ static void seed_unwind_frame_info(struct task_struct *tsk, | |||
79 | * assembly code | 79 | * assembly code |
80 | */ | 80 | */ |
81 | frame_info->regs.r27 = 0; | 81 | frame_info->regs.r27 = 0; |
82 | frame_info->regs.r28 += 64; | 82 | frame_info->regs.r28 += 60; |
83 | frame_info->call_frame = 0; | 83 | frame_info->call_frame = 0; |
84 | 84 | ||
85 | } else { | 85 | } else { |