aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/kernel/entry-common.S35
-rw-r--r--arch/arm/kernel/traps.c2
-rw-r--r--include/asm-arm/unistd.h48
3 files changed, 48 insertions, 37 deletions
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index e2b42997ad33..34826bcceb7a 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -98,20 +98,14 @@ ENTRY(ret_from_fork)
98 run on an ARM7 and we can save a couple of instructions. 98 run on an ARM7 and we can save a couple of instructions.
99 --pb */ 99 --pb */
100#ifdef CONFIG_CPU_ARM710 100#ifdef CONFIG_CPU_ARM710
101 .macro arm710_bug_check, instr, temp 101#define A710(code...) code
102 and \temp, \instr, #0x0f000000 @ check for SWI 102.Larm710bug:
103 teq \temp, #0x0f000000
104 bne .Larm700bug
105 .endm
106
107.Larm700bug:
108 ldmia sp, {r0 - lr}^ @ Get calling r0 - lr 103 ldmia sp, {r0 - lr}^ @ Get calling r0 - lr
109 mov r0, r0 104 mov r0, r0
110 add sp, sp, #S_FRAME_SIZE 105 add sp, sp, #S_FRAME_SIZE
111 subs pc, lr, #4 106 subs pc, lr, #4
112#else 107#else
113 .macro arm710_bug_check, instr, temp 108#define A710(code...)
114 .endm
115#endif 109#endif
116 110
117 .align 5 111 .align 5
@@ -129,14 +123,24 @@ ENTRY(vector_swi)
129 /* 123 /*
130 * Get the system call number. 124 * Get the system call number.
131 */ 125 */
132#ifdef CONFIG_ARM_THUMB 126#if defined(CONFIG_AEABI)
127
128 @ syscall number is in scno (r7) already.
129
130 A710( ldr ip, [lr, #-4] @ get SWI instruction )
131 A710( and ip, ip, #0x0f000000 @ check for SWI )
132 A710( teq ip, #0x0f000000 )
133 A710( bne .Larm710bug )
134#elif defined(CONFIG_ARM_THUMB)
133 tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs 135 tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs
134 addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in 136 addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in
135 ldreq scno, [lr, #-4] 137 ldreq scno, [lr, #-4]
136#else 138#else
137 ldr scno, [lr, #-4] @ get SWI instruction 139 ldr scno, [lr, #-4] @ get SWI instruction
140 A710( and ip, scno, #0x0f000000 @ check for SWI )
141 A710( teq ip, #0x0f000000 )
142 A710( bne .Larm710bug )
138#endif 143#endif
139 arm710_bug_check scno, ip
140 144
141#ifdef CONFIG_ALIGNMENT_TRAP 145#ifdef CONFIG_ALIGNMENT_TRAP
142 ldr ip, __cr_alignment 146 ldr ip, __cr_alignment
@@ -145,18 +149,19 @@ ENTRY(vector_swi)
145#endif 149#endif
146 enable_irq 150 enable_irq
147 151
148 stmdb sp!, {r4, r5} @ push fifth and sixth args
149
150 get_thread_info tsk 152 get_thread_info tsk
151 ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing 153 ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing
154#ifndef CONFIG_AEABI
152 bic scno, scno, #0xff000000 @ mask off SWI op-code 155 bic scno, scno, #0xff000000 @ mask off SWI op-code
153 eor scno, scno, #__NR_SYSCALL_BASE @ check OS number 156 eor scno, scno, #__NR_SYSCALL_BASE @ check OS number
157#endif
154 adr tbl, sys_call_table @ load syscall table pointer 158 adr tbl, sys_call_table @ load syscall table pointer
159 stmdb sp!, {r4, r5} @ push fifth and sixth args
155 tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? 160 tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
156 bne __sys_trace 161 bne __sys_trace
157 162
158 adr lr, ret_fast_syscall @ return address
159 cmp scno, #NR_syscalls @ check upper syscall limit 163 cmp scno, #NR_syscalls @ check upper syscall limit
164 adr lr, ret_fast_syscall @ return address
160 ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine 165 ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine
161 166
162 add r1, sp, #S_OFF 167 add r1, sp, #S_OFF
@@ -207,6 +212,7 @@ ENTRY(sys_call_table)
207@ r8 = syscall table 212@ r8 = syscall table
208 .type sys_syscall, #function 213 .type sys_syscall, #function
209sys_syscall: 214sys_syscall:
215#ifndef CONFIG_AEABI
210 eor scno, r0, #__NR_SYSCALL_BASE 216 eor scno, r0, #__NR_SYSCALL_BASE
211 cmp scno, #__NR_syscall - __NR_SYSCALL_BASE 217 cmp scno, #__NR_syscall - __NR_SYSCALL_BASE
212 cmpne scno, #NR_syscalls @ check range 218 cmpne scno, #NR_syscalls @ check range
@@ -216,6 +222,7 @@ sys_syscall:
216 movlo r2, r3 222 movlo r2, r3
217 movlo r3, r4 223 movlo r3, r4
218 ldrlo pc, [tbl, scno, lsl #2] 224 ldrlo pc, [tbl, scno, lsl #2]
225#endif
219 b sys_ni_syscall 226 b sys_ni_syscall
220 227
221sys_fork_wrapper: 228sys_fork_wrapper:
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 93cfd3ffcc72..10235b01582e 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -404,7 +404,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
404 struct thread_info *thread = current_thread_info(); 404 struct thread_info *thread = current_thread_info();
405 siginfo_t info; 405 siginfo_t info;
406 406
407 if ((no >> 16) != 0x9f) 407 if ((no >> 16) != (__ARM_NR_BASE>> 16))
408 return bad_syscall(no, regs); 408 return bad_syscall(no, regs);
409 409
410 switch (no & 0xffff) { 410 switch (no & 0xffff) {
diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h
index d626e70faded..c9e087fe7e11 100644
--- a/include/asm-arm/unistd.h
+++ b/include/asm-arm/unistd.h
@@ -15,10 +15,12 @@
15 15
16#include <linux/linkage.h> 16#include <linux/linkage.h>
17 17
18#if defined(__thumb__) 18#define __NR_OABI_SYSCALL_BASE 0x900000
19
20#if defined(__thumb__) || defined(__ARM_EABI__)
19#define __NR_SYSCALL_BASE 0 21#define __NR_SYSCALL_BASE 0
20#else 22#else
21#define __NR_SYSCALL_BASE 0x900000 23#define __NR_SYSCALL_BASE __NR_OABI_SYSCALL_BASE
22#endif 24#endif
23 25
24/* 26/*
@@ -373,13 +375,13 @@
373#define __sys1(x) __sys2(x) 375#define __sys1(x) __sys2(x)
374 376
375#ifndef __syscall 377#ifndef __syscall
376#if defined(__thumb__) 378#if defined(__thumb__) || defined(__ARM_EABI__)
377#define __syscall(name) \ 379#define __SYS_REG(name) register long __sysreg __asm__("r7") = __NR_##name;
378 "push {r7}\n\t" \ 380#define __SYS_REG_LIST(regs...) "r" (__sysreg) , ##regs
379 "mov r7, #" __sys1(__NR_##name) "\n\t" \ 381#define __syscall(name) "swi\t0"
380 "swi 0\n\t" \
381 "pop {r7}"
382#else 382#else
383#define __SYS_REG(name)
384#define __SYS_REG_LIST(regs...) regs
383#define __syscall(name) "swi\t" __sys1(__NR_##name) "" 385#define __syscall(name) "swi\t" __sys1(__NR_##name) ""
384#endif 386#endif
385#endif 387#endif
@@ -395,33 +397,34 @@ do { \
395 397
396#define _syscall0(type,name) \ 398#define _syscall0(type,name) \
397type name(void) { \ 399type name(void) { \
400 __SYS_REG(name) \
398 register long __res_r0 __asm__("r0"); \ 401 register long __res_r0 __asm__("r0"); \
399 long __res; \ 402 long __res; \
400 __asm__ __volatile__ ( \ 403 __asm__ __volatile__ ( \
401 __syscall(name) \ 404 __syscall(name) \
402 : "=r" (__res_r0) \ 405 : "=r" (__res_r0) \
403 : \ 406 : __SYS_REG_LIST() ); \
404 : "lr"); \
405 __res = __res_r0; \ 407 __res = __res_r0; \
406 __syscall_return(type,__res); \ 408 __syscall_return(type,__res); \
407} 409}
408 410
409#define _syscall1(type,name,type1,arg1) \ 411#define _syscall1(type,name,type1,arg1) \
410type name(type1 arg1) { \ 412type name(type1 arg1) { \
413 __SYS_REG(name) \
411 register long __r0 __asm__("r0") = (long)arg1; \ 414 register long __r0 __asm__("r0") = (long)arg1; \
412 register long __res_r0 __asm__("r0"); \ 415 register long __res_r0 __asm__("r0"); \
413 long __res; \ 416 long __res; \
414 __asm__ __volatile__ ( \ 417 __asm__ __volatile__ ( \
415 __syscall(name) \ 418 __syscall(name) \
416 : "=r" (__res_r0) \ 419 : "=r" (__res_r0) \
417 : "r" (__r0) \ 420 : __SYS_REG_LIST( "0" (__r0) ) ); \
418 : "lr"); \
419 __res = __res_r0; \ 421 __res = __res_r0; \
420 __syscall_return(type,__res); \ 422 __syscall_return(type,__res); \
421} 423}
422 424
423#define _syscall2(type,name,type1,arg1,type2,arg2) \ 425#define _syscall2(type,name,type1,arg1,type2,arg2) \
424type name(type1 arg1,type2 arg2) { \ 426type name(type1 arg1,type2 arg2) { \
427 __SYS_REG(name) \
425 register long __r0 __asm__("r0") = (long)arg1; \ 428 register long __r0 __asm__("r0") = (long)arg1; \
426 register long __r1 __asm__("r1") = (long)arg2; \ 429 register long __r1 __asm__("r1") = (long)arg2; \
427 register long __res_r0 __asm__("r0"); \ 430 register long __res_r0 __asm__("r0"); \
@@ -429,8 +432,7 @@ type name(type1 arg1,type2 arg2) { \
429 __asm__ __volatile__ ( \ 432 __asm__ __volatile__ ( \
430 __syscall(name) \ 433 __syscall(name) \
431 : "=r" (__res_r0) \ 434 : "=r" (__res_r0) \
432 : "r" (__r0),"r" (__r1) \ 435 : __SYS_REG_LIST( "0" (__r0), "r" (__r1) ) ); \
433 : "lr"); \
434 __res = __res_r0; \ 436 __res = __res_r0; \
435 __syscall_return(type,__res); \ 437 __syscall_return(type,__res); \
436} 438}
@@ -438,6 +440,7 @@ type name(type1 arg1,type2 arg2) { \
438 440
439#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ 441#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
440type name(type1 arg1,type2 arg2,type3 arg3) { \ 442type name(type1 arg1,type2 arg2,type3 arg3) { \
443 __SYS_REG(name) \
441 register long __r0 __asm__("r0") = (long)arg1; \ 444 register long __r0 __asm__("r0") = (long)arg1; \
442 register long __r1 __asm__("r1") = (long)arg2; \ 445 register long __r1 __asm__("r1") = (long)arg2; \
443 register long __r2 __asm__("r2") = (long)arg3; \ 446 register long __r2 __asm__("r2") = (long)arg3; \
@@ -446,8 +449,7 @@ type name(type1 arg1,type2 arg2,type3 arg3) { \
446 __asm__ __volatile__ ( \ 449 __asm__ __volatile__ ( \
447 __syscall(name) \ 450 __syscall(name) \
448 : "=r" (__res_r0) \ 451 : "=r" (__res_r0) \
449 : "r" (__r0),"r" (__r1),"r" (__r2) \ 452 : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2) ) ); \
450 : "lr"); \
451 __res = __res_r0; \ 453 __res = __res_r0; \
452 __syscall_return(type,__res); \ 454 __syscall_return(type,__res); \
453} 455}
@@ -455,6 +457,7 @@ type name(type1 arg1,type2 arg2,type3 arg3) { \
455 457
456#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)\ 458#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)\
457type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ 459type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
460 __SYS_REG(name) \
458 register long __r0 __asm__("r0") = (long)arg1; \ 461 register long __r0 __asm__("r0") = (long)arg1; \
459 register long __r1 __asm__("r1") = (long)arg2; \ 462 register long __r1 __asm__("r1") = (long)arg2; \
460 register long __r2 __asm__("r2") = (long)arg3; \ 463 register long __r2 __asm__("r2") = (long)arg3; \
@@ -464,8 +467,7 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
464 __asm__ __volatile__ ( \ 467 __asm__ __volatile__ ( \
465 __syscall(name) \ 468 __syscall(name) \
466 : "=r" (__res_r0) \ 469 : "=r" (__res_r0) \
467 : "r" (__r0),"r" (__r1),"r" (__r2),"r" (__r3) \ 470 : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) ) ); \
468 : "lr"); \
469 __res = __res_r0; \ 471 __res = __res_r0; \
470 __syscall_return(type,__res); \ 472 __syscall_return(type,__res); \
471} 473}
@@ -473,6 +475,7 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
473 475
474#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ 476#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
475type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) { \ 477type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) { \
478 __SYS_REG(name) \
476 register long __r0 __asm__("r0") = (long)arg1; \ 479 register long __r0 __asm__("r0") = (long)arg1; \
477 register long __r1 __asm__("r1") = (long)arg2; \ 480 register long __r1 __asm__("r1") = (long)arg2; \
478 register long __r2 __asm__("r2") = (long)arg3; \ 481 register long __r2 __asm__("r2") = (long)arg3; \
@@ -483,14 +486,15 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) { \
483 __asm__ __volatile__ ( \ 486 __asm__ __volatile__ ( \
484 __syscall(name) \ 487 __syscall(name) \
485 : "=r" (__res_r0) \ 488 : "=r" (__res_r0) \
486 : "r" (__r0),"r" (__r1),"r" (__r2),"r" (__r3),"r" (__r4) \ 489 : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2), \
487 : "lr"); \ 490 "r" (__r3), "r" (__r4) ) ); \
488 __res = __res_r0; \ 491 __res = __res_r0; \
489 __syscall_return(type,__res); \ 492 __syscall_return(type,__res); \
490} 493}
491 494
492#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \ 495#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \
493type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) { \ 496type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) { \
497 __SYS_REG(name) \
494 register long __r0 __asm__("r0") = (long)arg1; \ 498 register long __r0 __asm__("r0") = (long)arg1; \
495 register long __r1 __asm__("r1") = (long)arg2; \ 499 register long __r1 __asm__("r1") = (long)arg2; \
496 register long __r2 __asm__("r2") = (long)arg3; \ 500 register long __r2 __asm__("r2") = (long)arg3; \
@@ -502,8 +506,8 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6
502 __asm__ __volatile__ ( \ 506 __asm__ __volatile__ ( \
503 __syscall(name) \ 507 __syscall(name) \
504 : "=r" (__res_r0) \ 508 : "=r" (__res_r0) \
505 : "r" (__r0),"r" (__r1),"r" (__r2),"r" (__r3), "r" (__r4),"r" (__r5) \ 509 : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2), \
506 : "lr"); \ 510 "r" (__r3), "r" (__r4), "r" (__r5) ) ); \
507 __res = __res_r0; \ 511 __res = __res_r0; \
508 __syscall_return(type,__res); \ 512 __syscall_return(type,__res); \
509} 513}