diff options
-rw-r--r-- | arch/s390/include/asm/elf.h | 22 | ||||
-rw-r--r-- | arch/s390/include/asm/syscall.h | 1 | ||||
-rw-r--r-- | arch/s390/include/asm/thread_info.h | 1 | ||||
-rw-r--r-- | arch/s390/kernel/asm-offsets.c | 1 | ||||
-rw-r--r-- | arch/s390/kernel/entry.S | 3 | ||||
-rw-r--r-- | arch/s390/kernel/entry64.S | 9 |
6 files changed, 24 insertions, 13 deletions
diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h index 27ec2c3f95ac..78f4f8711d58 100644 --- a/arch/s390/include/asm/elf.h +++ b/arch/s390/include/asm/elf.h | |||
@@ -120,6 +120,7 @@ | |||
120 | 120 | ||
121 | #include <asm/ptrace.h> | 121 | #include <asm/ptrace.h> |
122 | #include <asm/compat.h> | 122 | #include <asm/compat.h> |
123 | #include <asm/syscall.h> | ||
123 | #include <asm/user.h> | 124 | #include <asm/user.h> |
124 | 125 | ||
125 | typedef s390_fp_regs elf_fpregset_t; | 126 | typedef s390_fp_regs elf_fpregset_t; |
@@ -181,18 +182,31 @@ extern unsigned long elf_hwcap; | |||
181 | extern char elf_platform[]; | 182 | extern char elf_platform[]; |
182 | #define ELF_PLATFORM (elf_platform) | 183 | #define ELF_PLATFORM (elf_platform) |
183 | 184 | ||
184 | #ifdef CONFIG_64BIT | 185 | #ifndef CONFIG_COMPAT |
186 | #define SET_PERSONALITY(ex) \ | ||
187 | do { \ | ||
188 | set_personality(PER_LINUX | \ | ||
189 | (current->personality & (~PER_MASK))); \ | ||
190 | current_thread_info()->sys_call_table = \ | ||
191 | (unsigned long) &sys_call_table; \ | ||
192 | } while (0) | ||
193 | #else /* CONFIG_COMPAT */ | ||
185 | #define SET_PERSONALITY(ex) \ | 194 | #define SET_PERSONALITY(ex) \ |
186 | do { \ | 195 | do { \ |
187 | if (personality(current->personality) != PER_LINUX32) \ | 196 | if (personality(current->personality) != PER_LINUX32) \ |
188 | set_personality(PER_LINUX | \ | 197 | set_personality(PER_LINUX | \ |
189 | (current->personality & ~PER_MASK)); \ | 198 | (current->personality & ~PER_MASK)); \ |
190 | if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ | 199 | if ((ex).e_ident[EI_CLASS] == ELFCLASS32) { \ |
191 | set_thread_flag(TIF_31BIT); \ | 200 | set_thread_flag(TIF_31BIT); \ |
192 | else \ | 201 | current_thread_info()->sys_call_table = \ |
202 | (unsigned long) &sys_call_table_emu; \ | ||
203 | } else { \ | ||
193 | clear_thread_flag(TIF_31BIT); \ | 204 | clear_thread_flag(TIF_31BIT); \ |
205 | current_thread_info()->sys_call_table = \ | ||
206 | (unsigned long) &sys_call_table; \ | ||
207 | } \ | ||
194 | } while (0) | 208 | } while (0) |
195 | #endif /* CONFIG_64BIT */ | 209 | #endif /* CONFIG_COMPAT */ |
196 | 210 | ||
197 | #define STACK_RND_MASK 0x7ffUL | 211 | #define STACK_RND_MASK 0x7ffUL |
198 | 212 | ||
diff --git a/arch/s390/include/asm/syscall.h b/arch/s390/include/asm/syscall.h index fe7b99759e12..cd29d2f4e4f3 100644 --- a/arch/s390/include/asm/syscall.h +++ b/arch/s390/include/asm/syscall.h | |||
@@ -23,6 +23,7 @@ | |||
23 | * type here is what we want [need] for both 32 bit and 64 bit systems. | 23 | * type here is what we want [need] for both 32 bit and 64 bit systems. |
24 | */ | 24 | */ |
25 | extern const unsigned int sys_call_table[]; | 25 | extern const unsigned int sys_call_table[]; |
26 | extern const unsigned int sys_call_table_emu[]; | ||
26 | 27 | ||
27 | static inline long syscall_get_nr(struct task_struct *task, | 28 | static inline long syscall_get_nr(struct task_struct *task, |
28 | struct pt_regs *regs) | 29 | struct pt_regs *regs) |
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h index 9e2cfe0349c3..51035e5d86cb 100644 --- a/arch/s390/include/asm/thread_info.h +++ b/arch/s390/include/asm/thread_info.h | |||
@@ -41,6 +41,7 @@ struct thread_info { | |||
41 | struct task_struct *task; /* main task structure */ | 41 | struct task_struct *task; /* main task structure */ |
42 | struct exec_domain *exec_domain; /* execution domain */ | 42 | struct exec_domain *exec_domain; /* execution domain */ |
43 | unsigned long flags; /* low level flags */ | 43 | unsigned long flags; /* low level flags */ |
44 | unsigned long sys_call_table; /* System call table address */ | ||
44 | unsigned int cpu; /* current CPU */ | 45 | unsigned int cpu; /* current CPU */ |
45 | int preempt_count; /* 0 => preemptable, <0 => BUG */ | 46 | int preempt_count; /* 0 => preemptable, <0 => BUG */ |
46 | struct restart_block restart_block; | 47 | struct restart_block restart_block; |
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index fface87056eb..7a82f9f70100 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c | |||
@@ -35,6 +35,7 @@ int main(void) | |||
35 | DEFINE(__TI_task, offsetof(struct thread_info, task)); | 35 | DEFINE(__TI_task, offsetof(struct thread_info, task)); |
36 | DEFINE(__TI_domain, offsetof(struct thread_info, exec_domain)); | 36 | DEFINE(__TI_domain, offsetof(struct thread_info, exec_domain)); |
37 | DEFINE(__TI_flags, offsetof(struct thread_info, flags)); | 37 | DEFINE(__TI_flags, offsetof(struct thread_info, flags)); |
38 | DEFINE(__TI_sysc_table, offsetof(struct thread_info, sys_call_table)); | ||
38 | DEFINE(__TI_cpu, offsetof(struct thread_info, cpu)); | 39 | DEFINE(__TI_cpu, offsetof(struct thread_info, cpu)); |
39 | DEFINE(__TI_precount, offsetof(struct thread_info, preempt_count)); | 40 | DEFINE(__TI_precount, offsetof(struct thread_info, preempt_count)); |
40 | DEFINE(__TI_user_timer, offsetof(struct thread_info, user_timer)); | 41 | DEFINE(__TI_user_timer, offsetof(struct thread_info, user_timer)); |
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 17d5cc057893..4d5e6f8a7978 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
@@ -188,6 +188,7 @@ sysc_vtime: | |||
188 | mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC | 188 | mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC |
189 | sysc_do_svc: | 189 | sysc_do_svc: |
190 | oi __TI_flags+3(%r12),_TIF_SYSCALL | 190 | oi __TI_flags+3(%r12),_TIF_SYSCALL |
191 | l %r10,__TI_sysc_table(%r12) # 31 bit system call table | ||
191 | lh %r8,__PT_INT_CODE+2(%r11) | 192 | lh %r8,__PT_INT_CODE+2(%r11) |
192 | sla %r8,2 # shift and test for svc0 | 193 | sla %r8,2 # shift and test for svc0 |
193 | jnz sysc_nr_ok | 194 | jnz sysc_nr_ok |
@@ -198,7 +199,6 @@ sysc_do_svc: | |||
198 | lr %r8,%r1 | 199 | lr %r8,%r1 |
199 | sla %r8,2 | 200 | sla %r8,2 |
200 | sysc_nr_ok: | 201 | sysc_nr_ok: |
201 | l %r10,BASED(.Lsys_call_table) # 31 bit system call table | ||
202 | xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) | 202 | xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) |
203 | st %r2,__PT_ORIG_GPR2(%r11) | 203 | st %r2,__PT_ORIG_GPR2(%r11) |
204 | st %r7,STACK_FRAME_OVERHEAD(%r15) | 204 | st %r7,STACK_FRAME_OVERHEAD(%r15) |
@@ -906,7 +906,6 @@ cleanup_idle_wait: | |||
906 | .Ltrace_enter: .long do_syscall_trace_enter | 906 | .Ltrace_enter: .long do_syscall_trace_enter |
907 | .Ltrace_exit: .long do_syscall_trace_exit | 907 | .Ltrace_exit: .long do_syscall_trace_exit |
908 | .Lschedule_tail: .long schedule_tail | 908 | .Lschedule_tail: .long schedule_tail |
909 | .Lsys_call_table: .long sys_call_table | ||
910 | .Lsysc_per: .long sysc_per + 0x80000000 | 909 | .Lsysc_per: .long sysc_per + 0x80000000 |
911 | #ifdef CONFIG_TRACE_IRQFLAGS | 910 | #ifdef CONFIG_TRACE_IRQFLAGS |
912 | .Lhardirqs_on: .long trace_hardirqs_on_caller | 911 | .Lhardirqs_on: .long trace_hardirqs_on_caller |
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 72f230baf5d1..4c17eece707e 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
@@ -216,6 +216,7 @@ sysc_vtime: | |||
216 | mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC | 216 | mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC |
217 | sysc_do_svc: | 217 | sysc_do_svc: |
218 | oi __TI_flags+7(%r12),_TIF_SYSCALL | 218 | oi __TI_flags+7(%r12),_TIF_SYSCALL |
219 | lg %r10,__TI_sysc_table(%r12) # address of system call table | ||
219 | llgh %r8,__PT_INT_CODE+2(%r11) | 220 | llgh %r8,__PT_INT_CODE+2(%r11) |
220 | slag %r8,%r8,2 # shift and test for svc 0 | 221 | slag %r8,%r8,2 # shift and test for svc 0 |
221 | jnz sysc_nr_ok | 222 | jnz sysc_nr_ok |
@@ -226,13 +227,6 @@ sysc_do_svc: | |||
226 | sth %r1,__PT_INT_CODE+2(%r11) | 227 | sth %r1,__PT_INT_CODE+2(%r11) |
227 | slag %r8,%r1,2 | 228 | slag %r8,%r1,2 |
228 | sysc_nr_ok: | 229 | sysc_nr_ok: |
229 | larl %r10,sys_call_table # 64 bit system call table | ||
230 | #ifdef CONFIG_COMPAT | ||
231 | tm __TI_flags+5(%r12),(_TIF_31BIT>>16) | ||
232 | jno sysc_noemu | ||
233 | larl %r10,sys_call_table_emu # 31 bit system call table | ||
234 | sysc_noemu: | ||
235 | #endif | ||
236 | xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) | 230 | xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) |
237 | stg %r2,__PT_ORIG_GPR2(%r11) | 231 | stg %r2,__PT_ORIG_GPR2(%r11) |
238 | stg %r7,STACK_FRAME_OVERHEAD(%r15) | 232 | stg %r7,STACK_FRAME_OVERHEAD(%r15) |
@@ -1005,6 +999,7 @@ sys_call_table: | |||
1005 | #ifdef CONFIG_COMPAT | 999 | #ifdef CONFIG_COMPAT |
1006 | 1000 | ||
1007 | #define SYSCALL(esa,esame,emu) .long emu | 1001 | #define SYSCALL(esa,esame,emu) .long emu |
1002 | .globl sys_call_table_emu | ||
1008 | sys_call_table_emu: | 1003 | sys_call_table_emu: |
1009 | #include "syscalls.S" | 1004 | #include "syscalls.S" |
1010 | #undef SYSCALL | 1005 | #undef SYSCALL |