Skip to content

Commit cfca4b5

Browse files
committed
ARC: entry: use gp to cache task pointer (vs. r25)
The motivation is eventual ABI considerations for ARCv3 but even without it this change us worthwhile as diffstat reduces 100 net lines r25 is a callee saved register, normally not saved by entry code in pt_regs. However because of its usage in CONFIG_ARC_CURR_IN_REG it needs to be. This in turn requires a whole bunch of special casing when we need to access r25. Then there is distinction between user mode r25 vs. kernel mode r25 - hence distinct SAVE_CALLEE_SAVED_{USER,KERNEL} Instead use gp which is a scratch register and thus saved already in entry code. This cleans things up significantly and much nocer on eyes: - SAVE_CALLEE_SAVED_{USER,KERNEL} are now exactly same - no special user_r25 slot in pt_reggs Note that typical global asm registers are callee-saved (r25), but gp is not callee-saved thus needs additional -ffixed-<reg> toggle Signed-off-by: Vineet Gupta <[email protected]>
1 parent fad84e3 commit cfca4b5

File tree

13 files changed

+58
-154
lines changed

13 files changed

+58
-154
lines changed

arch/arc/Kconfig

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -492,11 +492,11 @@ config ARC_KVADDR_SIZE
492492
kernel-user gutter)
493493

494494
config ARC_CURR_IN_REG
495-
bool "Dedicate Register r25 for current_task pointer"
495+
bool "cache current task pointer in gp"
496496
default y
497497
help
498-
This reserved Register R25 to point to Current Task in
499-
kernel mode. This saves memory access for each such access
498+
This reserves gp register to point to Current Task in
499+
kernel mode eliding memory access for each access
500500

501501

502502
config ARC_EMUL_UNALIGNED

arch/arc/Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ cflags-y += $(tune-mcpu-def-y)
2828
endif
2929
endif
3030

31-
3231
ifdef CONFIG_ARC_CURR_IN_REG
3332
# For a global register definition, make sure it gets passed to every file
3433
# We had a customer reported bug where some code built in kernel was NOT using
35-
# any kernel headers, and missing the r25 global register
34+
# any kernel headers, and missing the global register
3635
# Can't do unconditionally because of recursive include issues
3736
# due to <linux/thread_info.h>
3837
LINUXINCLUDE += -include $(srctree)/arch/arc/include/asm/current.h
38+
cflags-y += -ffixed-gp
3939
endif
4040

4141
cflags-y += -fsection-anchors
@@ -67,7 +67,7 @@ cflags-$(CONFIG_ARC_DW2_UNWIND) += -fasynchronous-unwind-tables $(cfi)
6767
# small data is default for elf32 tool-chain. If not usable, disable it
6868
# This also allows repurposing GP as scratch reg to gcc reg allocator
6969
disable_small_data := y
70-
cflags-$(disable_small_data) += -mno-sdata -fcall-used-gp
70+
cflags-$(disable_small_data) += -mno-sdata
7171

7272
cflags-$(CONFIG_CPU_BIG_ENDIAN) += -mbig-endian
7373
ldflags-$(CONFIG_CPU_BIG_ENDIAN) += -EB

arch/arc/include/asm/current.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
#ifdef CONFIG_ARC_CURR_IN_REG
1515

16-
register struct task_struct *curr_arc asm("r25");
16+
register struct task_struct *curr_arc asm("gp");
1717
#define current (curr_arc)
1818

1919
#else

arch/arc/include/asm/entry-arcv2.h

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
* | orig_r0 |
1919
* | event/ECR |
2020
* | bta |
21-
* | user_r25 |
2221
* | gp |
2322
* | fp |
2423
* | sp |
@@ -56,7 +55,7 @@
5655
; hardware does even if CONFIG_ARC_IRQ_NO_AUTOSAVE
5756
; 4. Auto save: (optional) r0-r11, blink, LPE,LPS,LPC, JLI,LDI,EI
5857
;
59-
; (B) Manually saved some regs: r12,r25,r30, sp,fp,gp, ACCL pair
58+
; (B) Manually saved some regs: r12,r30, sp,fp,gp, ACCL pair
6059

6160
#ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE
6261
; carve pt_regs on stack (case #3), PC/STAT32 already on stack
@@ -157,17 +156,17 @@
157156

158157
st r10, [sp, PT_sp] ; SP (pt_regs->sp)
159158

160-
#ifdef CONFIG_ARC_CURR_IN_REG
161-
st r25, [sp, PT_user_r25]
162-
GET_CURR_TASK_ON_CPU r25
163-
#endif
164-
165159
#ifdef CONFIG_ARC_HAS_ACCL_REGS
166160
ST2 r58, r59, PT_r58
167161
#endif
168162

169163
/* clobbers r10, r11 registers pair */
170164
DSP_SAVE_REGFILE_IRQ
165+
166+
#ifdef CONFIG_ARC_CURR_IN_REG
167+
GET_CURR_TASK_ON_CPU gp
168+
#endif
169+
171170
.endm
172171

173172
/*------------------------------------------------------------------------*/
@@ -188,10 +187,6 @@
188187
sr r10, [AUX_USER_SP]
189188
1:
190189

191-
#ifdef CONFIG_ARC_CURR_IN_REG
192-
ld r25, [sp, PT_user_r25]
193-
#endif
194-
195190
/* clobbers r10, r11 registers pair */
196191
DSP_RESTORE_REGFILE_IRQ
197192

arch/arc/include/asm/entry-compact.h

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -151,14 +151,6 @@
151151
/* ARC700 doesn't provide auto-stack switching */
152152
SWITCH_TO_KERNEL_STK
153153

154-
#ifdef CONFIG_ARC_CURR_IN_REG
155-
/* Treat r25 as scratch reg (save on stack) and load with "current" */
156-
PUSH r25
157-
GET_CURR_TASK_ON_CPU r25
158-
#else
159-
sub sp, sp, 4
160-
#endif
161-
162154
st.a r0, [sp, -8] /* orig_r0 needed for syscall (skip ECR slot) */
163155
sub sp, sp, 4 /* skip pt_regs->sp, already saved above */
164156

@@ -179,6 +171,11 @@
179171

180172
lr r10, [ecr]
181173
st r10, [sp, PT_event] /* EV_Trap expects r10 to have ECR */
174+
175+
#ifdef CONFIG_ARC_CURR_IN_REG
176+
/* gp already saved on stack: now load with "current" */
177+
GET_CURR_TASK_ON_CPU gp
178+
#endif
182179
.endm
183180

184181
/*--------------------------------------------------------------
@@ -208,11 +205,8 @@
208205
POP gp
209206
RESTORE_R12_TO_R0
210207

211-
#ifdef CONFIG_ARC_CURR_IN_REG
212-
ld r25, [sp, 12]
213-
#endif
214208
ld sp, [sp] /* restore original sp */
215-
/* orig_r0, ECR, user_r25 skipped automatically */
209+
/* orig_r0, ECR skipped automatically */
216210
.endm
217211

218212
/* Dummy ECR values for Interrupts */
@@ -229,13 +223,6 @@
229223

230224
SWITCH_TO_KERNEL_STK
231225

232-
#ifdef CONFIG_ARC_CURR_IN_REG
233-
/* Treat r25 as scratch reg (save on stack) and load with "current" */
234-
PUSH r25
235-
GET_CURR_TASK_ON_CPU r25
236-
#else
237-
sub sp, sp, 4
238-
#endif
239226

240227
PUSH 0x003\LVL\()abcd /* Dummy ECR */
241228
sub sp, sp, 8 /* skip orig_r0 (not needed)
@@ -255,6 +242,10 @@
255242
PUSHAX lp_start
256243
PUSHAX bta_l\LVL\()
257244

245+
#ifdef CONFIG_ARC_CURR_IN_REG
246+
/* gp already saved on stack: now load with "current" */
247+
GET_CURR_TASK_ON_CPU gp
248+
#endif
258249
.endm
259250

260251
/*--------------------------------------------------------------
@@ -282,11 +273,7 @@
282273
POP gp
283274
RESTORE_R12_TO_R0
284275

285-
#ifdef CONFIG_ARC_CURR_IN_REG
286-
ld r25, [sp, 12]
287-
#endif
288-
ld sp, [sp] /* restore original sp */
289-
/* orig_r0, ECR, user_r25 skipped automatically */
276+
ld sp, [sp] /* restore original sp; orig_r0, ECR skipped implicitly */
290277
.endm
291278

292279
/* Get thread_info of "current" tsk */

arch/arc/include/asm/entry.h

Lines changed: 29 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191
* Helpers to save/restore callee-saved regs:
9292
* used by several macros below
9393
*-------------------------------------------------------------*/
94-
.macro SAVE_R13_TO_R24
94+
.macro SAVE_R13_TO_R25
9595
PUSH r13
9696
PUSH r14
9797
PUSH r15
@@ -104,9 +104,11 @@
104104
PUSH r22
105105
PUSH r23
106106
PUSH r24
107+
PUSH r25
107108
.endm
108109

109-
.macro RESTORE_R24_TO_R13
110+
.macro RESTORE_R25_TO_R13
111+
POP r25
110112
POP r24
111113
POP r23
112114
POP r22
@@ -121,81 +123,31 @@
121123
POP r13
122124
.endm
123125

124-
/*--------------------------------------------------------------
125-
* Collect User Mode callee regs as struct callee_regs - needed by
126-
* fork/do_signal/unaligned-access-emulation.
127-
* (By default only scratch regs are saved on entry to kernel)
128-
*
129-
* Special handling for r25 if used for caching Task Pointer.
130-
* It would have been saved in task->thread.user_r25 already, but to keep
131-
* the interface same it is copied into regular r25 placeholder in
132-
* struct callee_regs.
133-
*-------------------------------------------------------------*/
126+
/*
127+
* save user mode callee regs as struct callee_regs
128+
* - needed by fork/do_signal/unaligned-access-emulation.
129+
*/
134130
.macro SAVE_CALLEE_SAVED_USER
131+
SAVE_R13_TO_R25
132+
.endm
135133

136-
mov r12, sp ; save SP as ref to pt_regs
137-
SAVE_R13_TO_R24
138-
139-
#ifdef CONFIG_ARC_CURR_IN_REG
140-
; Retrieve orig r25 and save it with rest of callee_regs
141-
ld r12, [r12, PT_user_r25]
142-
PUSH r12
143-
#else
144-
PUSH r25
145-
#endif
146-
134+
/*
135+
* restore user mode callee regs as struct callee_regs
136+
* - could have been changed by ptrace tracer or unaligned-access fixup
137+
*/
138+
.macro RESTORE_CALLEE_SAVED_USER
139+
RESTORE_R25_TO_R13
147140
.endm
148141

149-
/*--------------------------------------------------------------
150-
* Save kernel Mode callee regs at the time of Contect Switch.
151-
*
152-
* Special handling for r25 if used for caching Task Pointer.
153-
* Kernel simply skips saving it since it will be loaded with
154-
* incoming task pointer anyways
155-
*-------------------------------------------------------------*/
142+
/*
143+
* save/restore kernel mode callee regs at the time of context switch
144+
*/
156145
.macro SAVE_CALLEE_SAVED_KERNEL
157-
158-
SAVE_R13_TO_R24
159-
160-
#ifdef CONFIG_ARC_CURR_IN_REG
161-
sub sp, sp, 4
162-
#else
163-
PUSH r25
164-
#endif
146+
SAVE_R13_TO_R25
165147
.endm
166148

167-
/*--------------------------------------------------------------
168-
* Opposite of SAVE_CALLEE_SAVED_KERNEL
169-
*-------------------------------------------------------------*/
170149
.macro RESTORE_CALLEE_SAVED_KERNEL
171-
172-
#ifdef CONFIG_ARC_CURR_IN_REG
173-
add sp, sp, 4 /* skip usual r25 placeholder */
174-
#else
175-
POP r25
176-
#endif
177-
RESTORE_R24_TO_R13
178-
.endm
179-
180-
/*--------------------------------------------------------------
181-
* Opposite of SAVE_CALLEE_SAVED_USER
182-
*
183-
* ptrace tracer or unaligned-access fixup might have changed a user mode
184-
* callee reg which is saved back to usual r25 storage location
185-
*-------------------------------------------------------------*/
186-
.macro RESTORE_CALLEE_SAVED_USER
187-
188-
#ifdef CONFIG_ARC_CURR_IN_REG
189-
POP r12
190-
#else
191-
POP r25
192-
#endif
193-
RESTORE_R24_TO_R13
194-
195-
; SP is back to start of pt_regs
196-
#ifdef CONFIG_ARC_CURR_IN_REG
197-
st r12, [sp, PT_user_r25]
198-
#endif
150+
RESTORE_R25_TO_R13
199151
.endm
200152

201153
/*--------------------------------------------------------------
@@ -231,10 +183,10 @@
231183

232184
#ifdef CONFIG_SMP
233185

234-
/*-------------------------------------------------
186+
/*
235187
* Retrieve the current running task on this CPU
236-
* 1. Determine curr CPU id.
237-
* 2. Use it to index into _current_task[ ]
188+
* - loads it from backing _current_task[] (and can't use the
189+
* caching reg for current task
238190
*/
239191
.macro GET_CURR_TASK_ON_CPU reg
240192
GET_CPU_ID \reg
@@ -256,7 +208,7 @@
256208
add2 \tmp, @_current_task, \tmp
257209
st \tsk, [\tmp]
258210
#ifdef CONFIG_ARC_CURR_IN_REG
259-
mov r25, \tsk
211+
mov gp, \tsk
260212
#endif
261213

262214
.endm
@@ -271,21 +223,20 @@
271223
.macro SET_CURR_TASK_ON_CPU tsk, tmp
272224
st \tsk, [@_current_task]
273225
#ifdef CONFIG_ARC_CURR_IN_REG
274-
mov r25, \tsk
226+
mov gp, \tsk
275227
#endif
276228
.endm
277229

278230
#endif /* SMP / UNI */
279231

280-
/* ------------------------------------------------------------------
232+
/*
281233
* Get the ptr to some field of Current Task at @off in task struct
282-
* -Uses r25 for Current task ptr if that is enabled
234+
* - Uses current task cached in reg if enabled
283235
*/
284-
285236
#ifdef CONFIG_ARC_CURR_IN_REG
286237

287238
.macro GET_CURR_TASK_FIELD_PTR off, reg
288-
add \reg, r25, \off
239+
add \reg, gp, \off
289240
.endm
290241

291242
#else

arch/arc/include/asm/ptrace.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,9 @@ struct pt_regs {
5252
};
5353
unsigned long event;
5454
};
55-
56-
unsigned long user_r25;
5755
};
5856

59-
#define MAX_REG_OFFSET offsetof(struct pt_regs, user_r25)
57+
#define MAX_REG_OFFSET offsetof(struct pt_regs, event)
6058

6159
#else
6260

@@ -79,8 +77,6 @@ struct pt_regs {
7977

8078
unsigned long bta; /* bta_l1, bta_l2, erbta */
8179

82-
unsigned long user_r25;
83-
8480
unsigned long r26; /* gp */
8581
unsigned long fp;
8682
unsigned long sp; /* user/kernel sp depending on where we came from */

arch/arc/kernel/asm-offsets.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,6 @@ int main(void)
6363
DEFINE(PT_blink, offsetof(struct pt_regs, blink));
6464
DEFINE(PT_lpe, offsetof(struct pt_regs, lp_end));
6565
DEFINE(PT_lpc, offsetof(struct pt_regs, lp_count));
66-
DEFINE(PT_user_r25, offsetof(struct pt_regs, user_r25));
67-
6866
DEFINE(SZ_CALLEE_REGS, sizeof(struct callee_regs));
6967
DEFINE(SZ_PT_REGS, sizeof(struct pt_regs));
7068

0 commit comments

Comments
 (0)