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 <schwidefsky@de.ibm.com>
This commit is contained in:
Родитель
dc7ee00d47
Коммит
616498813b
|
@ -120,6 +120,7 @@
|
|||
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/compat.h>
|
||||
#include <asm/syscall.h>
|
||||
#include <asm/user.h>
|
||||
|
||||
typedef s390_fp_regs elf_fpregset_t;
|
||||
|
@ -181,18 +182,31 @@ extern unsigned long elf_hwcap;
|
|||
extern char elf_platform[];
|
||||
#define ELF_PLATFORM (elf_platform)
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
#ifndef CONFIG_COMPAT
|
||||
#define SET_PERSONALITY(ex) \
|
||||
do { \
|
||||
set_personality(PER_LINUX | \
|
||||
(current->personality & (~PER_MASK))); \
|
||||
current_thread_info()->sys_call_table = \
|
||||
(unsigned long) &sys_call_table; \
|
||||
} while (0)
|
||||
#else /* CONFIG_COMPAT */
|
||||
#define SET_PERSONALITY(ex) \
|
||||
do { \
|
||||
if (personality(current->personality) != PER_LINUX32) \
|
||||
set_personality(PER_LINUX | \
|
||||
(current->personality & ~PER_MASK)); \
|
||||
if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
|
||||
if ((ex).e_ident[EI_CLASS] == ELFCLASS32) { \
|
||||
set_thread_flag(TIF_31BIT); \
|
||||
else \
|
||||
current_thread_info()->sys_call_table = \
|
||||
(unsigned long) &sys_call_table_emu; \
|
||||
} else { \
|
||||
clear_thread_flag(TIF_31BIT); \
|
||||
current_thread_info()->sys_call_table = \
|
||||
(unsigned long) &sys_call_table; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif /* CONFIG_64BIT */
|
||||
#endif /* CONFIG_COMPAT */
|
||||
|
||||
#define STACK_RND_MASK 0x7ffUL
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
* type here is what we want [need] for both 32 bit and 64 bit systems.
|
||||
*/
|
||||
extern const unsigned int sys_call_table[];
|
||||
extern const unsigned int sys_call_table_emu[];
|
||||
|
||||
static inline long syscall_get_nr(struct task_struct *task,
|
||||
struct pt_regs *regs)
|
||||
|
|
|
@ -41,6 +41,7 @@ struct thread_info {
|
|||
struct task_struct *task; /* main task structure */
|
||||
struct exec_domain *exec_domain; /* execution domain */
|
||||
unsigned long flags; /* low level flags */
|
||||
unsigned long sys_call_table; /* System call table address */
|
||||
unsigned int cpu; /* current CPU */
|
||||
int preempt_count; /* 0 => preemptable, <0 => BUG */
|
||||
struct restart_block restart_block;
|
||||
|
|
|
@ -35,6 +35,7 @@ int main(void)
|
|||
DEFINE(__TI_task, offsetof(struct thread_info, task));
|
||||
DEFINE(__TI_domain, offsetof(struct thread_info, exec_domain));
|
||||
DEFINE(__TI_flags, offsetof(struct thread_info, flags));
|
||||
DEFINE(__TI_sysc_table, offsetof(struct thread_info, sys_call_table));
|
||||
DEFINE(__TI_cpu, offsetof(struct thread_info, cpu));
|
||||
DEFINE(__TI_precount, offsetof(struct thread_info, preempt_count));
|
||||
DEFINE(__TI_user_timer, offsetof(struct thread_info, user_timer));
|
||||
|
|
|
@ -188,6 +188,7 @@ sysc_vtime:
|
|||
mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC
|
||||
sysc_do_svc:
|
||||
oi __TI_flags+3(%r12),_TIF_SYSCALL
|
||||
l %r10,__TI_sysc_table(%r12) # 31 bit system call table
|
||||
lh %r8,__PT_INT_CODE+2(%r11)
|
||||
sla %r8,2 # shift and test for svc0
|
||||
jnz sysc_nr_ok
|
||||
|
@ -198,7 +199,6 @@ sysc_do_svc:
|
|||
lr %r8,%r1
|
||||
sla %r8,2
|
||||
sysc_nr_ok:
|
||||
l %r10,BASED(.Lsys_call_table) # 31 bit system call table
|
||||
xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
|
||||
st %r2,__PT_ORIG_GPR2(%r11)
|
||||
st %r7,STACK_FRAME_OVERHEAD(%r15)
|
||||
|
@ -906,7 +906,6 @@ cleanup_idle_wait:
|
|||
.Ltrace_enter: .long do_syscall_trace_enter
|
||||
.Ltrace_exit: .long do_syscall_trace_exit
|
||||
.Lschedule_tail: .long schedule_tail
|
||||
.Lsys_call_table: .long sys_call_table
|
||||
.Lsysc_per: .long sysc_per + 0x80000000
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
.Lhardirqs_on: .long trace_hardirqs_on_caller
|
||||
|
|
|
@ -216,6 +216,7 @@ sysc_vtime:
|
|||
mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC
|
||||
sysc_do_svc:
|
||||
oi __TI_flags+7(%r12),_TIF_SYSCALL
|
||||
lg %r10,__TI_sysc_table(%r12) # address of system call table
|
||||
llgh %r8,__PT_INT_CODE+2(%r11)
|
||||
slag %r8,%r8,2 # shift and test for svc 0
|
||||
jnz sysc_nr_ok
|
||||
|
@ -226,13 +227,6 @@ sysc_do_svc:
|
|||
sth %r1,__PT_INT_CODE+2(%r11)
|
||||
slag %r8,%r1,2
|
||||
sysc_nr_ok:
|
||||
larl %r10,sys_call_table # 64 bit system call table
|
||||
#ifdef CONFIG_COMPAT
|
||||
tm __TI_flags+5(%r12),(_TIF_31BIT>>16)
|
||||
jno sysc_noemu
|
||||
larl %r10,sys_call_table_emu # 31 bit system call table
|
||||
sysc_noemu:
|
||||
#endif
|
||||
xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
|
||||
stg %r2,__PT_ORIG_GPR2(%r11)
|
||||
stg %r7,STACK_FRAME_OVERHEAD(%r15)
|
||||
|
@ -1005,6 +999,7 @@ sys_call_table:
|
|||
#ifdef CONFIG_COMPAT
|
||||
|
||||
#define SYSCALL(esa,esame,emu) .long emu
|
||||
.globl sys_call_table_emu
|
||||
sys_call_table_emu:
|
||||
#include "syscalls.S"
|
||||
#undef SYSCALL
|
||||
|
|
Загрузка…
Ссылка в новой задаче