Skip to content

Commit 6164988

Browse files
author
Martin Schwidefsky
committed
s390: system call path micro optimization
Add a pointer to the system call table to the thread_info structure. The TIF_31BIT bit is set or cleared by SET_PERSONALITY exactly once for the lifetime of a process. With the pointer to the correct system call table in thread_info the system call code in entry64.S path can drop the check for TIF_31BIT which saves a couple of instructions. Signed-off-by: Martin Schwidefsky <[email protected]>
1 parent dc7ee00 commit 6164988

File tree

6 files changed

+24
-13
lines changed

6 files changed

+24
-13
lines changed

arch/s390/include/asm/elf.h

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@
120120

121121
#include <asm/ptrace.h>
122122
#include <asm/compat.h>
123+
#include <asm/syscall.h>
123124
#include <asm/user.h>
124125

125126
typedef s390_fp_regs elf_fpregset_t;
@@ -181,18 +182,31 @@ extern unsigned long elf_hwcap;
181182
extern char elf_platform[];
182183
#define ELF_PLATFORM (elf_platform)
183184

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 */
185194
#define SET_PERSONALITY(ex) \
186195
do { \
187196
if (personality(current->personality) != PER_LINUX32) \
188197
set_personality(PER_LINUX | \
189198
(current->personality & ~PER_MASK)); \
190-
if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
199+
if ((ex).e_ident[EI_CLASS] == ELFCLASS32) { \
191200
set_thread_flag(TIF_31BIT); \
192-
else \
201+
current_thread_info()->sys_call_table = \
202+
(unsigned long) &sys_call_table_emu; \
203+
} else { \
193204
clear_thread_flag(TIF_31BIT); \
205+
current_thread_info()->sys_call_table = \
206+
(unsigned long) &sys_call_table; \
207+
} \
194208
} while (0)
195-
#endif /* CONFIG_64BIT */
209+
#endif /* CONFIG_COMPAT */
196210

197211
#define STACK_RND_MASK 0x7ffUL
198212

arch/s390/include/asm/syscall.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
* type here is what we want [need] for both 32 bit and 64 bit systems.
2424
*/
2525
extern const unsigned int sys_call_table[];
26+
extern const unsigned int sys_call_table_emu[];
2627

2728
static inline long syscall_get_nr(struct task_struct *task,
2829
struct pt_regs *regs)

arch/s390/include/asm/thread_info.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ struct thread_info {
4141
struct task_struct *task; /* main task structure */
4242
struct exec_domain *exec_domain; /* execution domain */
4343
unsigned long flags; /* low level flags */
44+
unsigned long sys_call_table; /* System call table address */
4445
unsigned int cpu; /* current CPU */
4546
int preempt_count; /* 0 => preemptable, <0 => BUG */
4647
struct restart_block restart_block;

arch/s390/kernel/asm-offsets.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ int main(void)
3535
DEFINE(__TI_task, offsetof(struct thread_info, task));
3636
DEFINE(__TI_domain, offsetof(struct thread_info, exec_domain));
3737
DEFINE(__TI_flags, offsetof(struct thread_info, flags));
38+
DEFINE(__TI_sysc_table, offsetof(struct thread_info, sys_call_table));
3839
DEFINE(__TI_cpu, offsetof(struct thread_info, cpu));
3940
DEFINE(__TI_precount, offsetof(struct thread_info, preempt_count));
4041
DEFINE(__TI_user_timer, offsetof(struct thread_info, user_timer));

arch/s390/kernel/entry.S

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ sysc_vtime:
188188
mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC
189189
sysc_do_svc:
190190
oi __TI_flags+3(%r12),_TIF_SYSCALL
191+
l %r10,__TI_sysc_table(%r12) # 31 bit system call table
191192
lh %r8,__PT_INT_CODE+2(%r11)
192193
sla %r8,2 # shift and test for svc0
193194
jnz sysc_nr_ok
@@ -198,7 +199,6 @@ sysc_do_svc:
198199
lr %r8,%r1
199200
sla %r8,2
200201
sysc_nr_ok:
201-
l %r10,BASED(.Lsys_call_table) # 31 bit system call table
202202
xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
203203
st %r2,__PT_ORIG_GPR2(%r11)
204204
st %r7,STACK_FRAME_OVERHEAD(%r15)
@@ -906,7 +906,6 @@ cleanup_idle_wait:
906906
.Ltrace_enter: .long do_syscall_trace_enter
907907
.Ltrace_exit: .long do_syscall_trace_exit
908908
.Lschedule_tail: .long schedule_tail
909-
.Lsys_call_table: .long sys_call_table
910909
.Lsysc_per: .long sysc_per + 0x80000000
911910
#ifdef CONFIG_TRACE_IRQFLAGS
912911
.Lhardirqs_on: .long trace_hardirqs_on_caller

arch/s390/kernel/entry64.S

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ sysc_vtime:
216216
mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC
217217
sysc_do_svc:
218218
oi __TI_flags+7(%r12),_TIF_SYSCALL
219+
lg %r10,__TI_sysc_table(%r12) # address of system call table
219220
llgh %r8,__PT_INT_CODE+2(%r11)
220221
slag %r8,%r8,2 # shift and test for svc 0
221222
jnz sysc_nr_ok
@@ -226,13 +227,6 @@ sysc_do_svc:
226227
sth %r1,__PT_INT_CODE+2(%r11)
227228
slag %r8,%r1,2
228229
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
236230
xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
237231
stg %r2,__PT_ORIG_GPR2(%r11)
238232
stg %r7,STACK_FRAME_OVERHEAD(%r15)
@@ -1005,6 +999,7 @@ sys_call_table:
1005999
#ifdef CONFIG_COMPAT
10061000

10071001
#define SYSCALL(esa,esame,emu) .long emu
1002+
.globl sys_call_table_emu
10081003
sys_call_table_emu:
10091004
#include "syscalls.S"
10101005
#undef SYSCALL

0 commit comments

Comments
 (0)