aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arc
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2013-11-01 01:16:40 -0400
committerVineet Gupta <vgupta@synopsys.com>2013-11-06 00:11:46 -0500
commit57e26e57454fae4f1d15c2e9fa965b7a8046ab34 (patch)
tree8100ec071f56fbd4cd3a01747ce971235118f6f3 /arch/arc
parent3aa4f80e410b3c14d987c42a90c31023c3081b46 (diff)
ARC: [SMP] Fix build failures for large NR_CPUS
ST.as only takes S9 (255) for offset. This was going out of range when accessing a task_struct field with 4k NR_CPUS (due to 128b of coumaks itself in there). Workaround by using an intermediate register to do the address scaling. There is some duplication of fix for ctx_sw.c and ctx_sw_asm.S however given that C version will go away soon I'm not bothering to factor out the common code. Reported-by: Noam Camus <noamc@ezchip.com> Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Diffstat (limited to 'arch/arc')
-rw-r--r--arch/arc/kernel/ctx_sw.c13
-rw-r--r--arch/arc/kernel/ctx_sw_asm.S11
2 files changed, 21 insertions, 3 deletions
diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c
index 34410eb1a308..c14a5bea0c76 100644
--- a/arch/arc/kernel/ctx_sw.c
+++ b/arch/arc/kernel/ctx_sw.c
@@ -17,6 +17,8 @@
17#include <asm/asm-offsets.h> 17#include <asm/asm-offsets.h>
18#include <linux/sched.h> 18#include <linux/sched.h>
19 19
20#define KSP_WORD_OFF ((TASK_THREAD + THREAD_KSP) / 4)
21
20struct task_struct *__sched 22struct task_struct *__sched
21__switch_to(struct task_struct *prev_task, struct task_struct *next_task) 23__switch_to(struct task_struct *prev_task, struct task_struct *next_task)
22{ 24{
@@ -45,7 +47,16 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
45#endif 47#endif
46 48
47 /* set ksp of outgoing task in tsk->thread.ksp */ 49 /* set ksp of outgoing task in tsk->thread.ksp */
50#if KSP_WORD_OFF <= 255
48 "st.as sp, [%3, %1] \n\t" 51 "st.as sp, [%3, %1] \n\t"
52#else
53 /*
54 * Workaround for NR_CPUS=4k
55 * %1 is bigger than 255 (S9 offset for st.as)
56 */
57 "add2 r24, %3, %1 \n\t"
58 "st sp, [r24] \n\t"
59#endif
49 60
50 "sync \n\t" 61 "sync \n\t"
51 62
@@ -97,7 +108,7 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
97 /* FP/BLINK restore generated by gcc (standard func epilogue */ 108 /* FP/BLINK restore generated by gcc (standard func epilogue */
98 109
99 : "=r"(tmp) 110 : "=r"(tmp)
100 : "n"((TASK_THREAD + THREAD_KSP) / 4), "r"(next), "r"(prev) 111 : "n"(KSP_WORD_OFF), "r"(next), "r"(prev)
101 : "blink" 112 : "blink"
102 ); 113 );
103 114
diff --git a/arch/arc/kernel/ctx_sw_asm.S b/arch/arc/kernel/ctx_sw_asm.S
index d8972345e4c2..65690e7fcc8c 100644
--- a/arch/arc/kernel/ctx_sw_asm.S
+++ b/arch/arc/kernel/ctx_sw_asm.S
@@ -14,6 +14,8 @@
14#include <asm/asm-offsets.h> 14#include <asm/asm-offsets.h>
15#include <asm/linkage.h> 15#include <asm/linkage.h>
16 16
17#define KSP_WORD_OFF ((TASK_THREAD + THREAD_KSP) / 4)
18
17;################### Low Level Context Switch ########################## 19;################### Low Level Context Switch ##########################
18 20
19 .section .sched.text,"ax",@progbits 21 .section .sched.text,"ax",@progbits
@@ -28,8 +30,13 @@ __switch_to:
28 SAVE_CALLEE_SAVED_KERNEL 30 SAVE_CALLEE_SAVED_KERNEL
29 31
30 /* Save the now KSP in task->thread.ksp */ 32 /* Save the now KSP in task->thread.ksp */
31 st.as sp, [r0, (TASK_THREAD + THREAD_KSP)/4] 33#if KSP_WORD_OFF <= 255
32 34 st.as sp, [r0, KSP_WORD_OFF]
35#else
36 /* Workaround for NR_CPUS=4k as ST.as can only take s9 offset */
37 add2 r24, r0, KSP_WORD_OFF
38 st sp, [r24]
39#endif
33 /* 40 /*
34 * Return last task in r0 (return reg) 41 * Return last task in r0 (return reg)
35 * On ARC, Return reg = First Arg reg = r0. 42 * On ARC, Return reg = First Arg reg = r0.