Module: xenomai-3 Branch: next Commit: 410b376b82a28208d5640bc5037f2c43a6706d02 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=410b376b82a28208d5640bc5037f2c43a6706d02
Author: Philippe Gerum <r...@xenomai.org> Date: Thu Oct 16 14:21:56 2014 +0200 cobalt/x86: enable 32bit syscall emulation --- kernel/cobalt/arch/x86/Kconfig | 5 +- .../cobalt/arch/x86/include/asm/xenomai/syscall.h | 8 +- .../arch/x86/include/asm/xenomai/syscall32-table.h | 54 ++++--- .../arch/x86/include/asm/xenomai/syscall32.h | 147 ++++++++++++++++++-- 4 files changed, 180 insertions(+), 34 deletions(-) diff --git a/kernel/cobalt/arch/x86/Kconfig b/kernel/cobalt/arch/x86/Kconfig index 72e539a..9adbbf7 100644 --- a/kernel/cobalt/arch/x86/Kconfig +++ b/kernel/cobalt/arch/x86/Kconfig @@ -1,9 +1,8 @@ config XENO_ARCH_FPU def_bool y -config XENO_ARCH_X32 - def_bool X86_X32 - select XENO_OPT_SYS3264 +config XENO_ARCH_SYS3264 + def_bool IA32_EMULATION source "kernel/xenomai/Kconfig" source "drivers/xenomai/Kconfig" diff --git a/kernel/cobalt/arch/x86/include/asm/xenomai/syscall.h b/kernel/cobalt/arch/x86/include/asm/xenomai/syscall.h index ddbb3df..5901e4d 100644 --- a/kernel/cobalt/arch/x86/include/asm/xenomai/syscall.h +++ b/kernel/cobalt/arch/x86/include/asm/xenomai/syscall.h @@ -42,8 +42,12 @@ #define __xn_reg_sp(regs) ((regs)->sp) #define __xn_syscall_p(regs) (__xn_reg_sys(regs) & __COBALT_SYSCALL_BIT) -#define __xn_syscall(regs) (__xn_reg_sys(regs) & \ - ~(__COBALT_SYSCALL_BIT|__COBALT_SYSCALL_MASK)) +#ifdef CONFIG_XENO_ARCH_SYS3264 +#define __xn_syscall(regs) __COBALT_CALL32_SYSNR(__xn_reg_sys(regs) \ + & ~__COBALT_SYSCALL_BIT) +#else +#define __xn_syscall(regs) (__xn_reg_sys(regs) & ~__COBALT_SYSCALL_BIT) +#endif static inline void __xn_success_return(struct pt_regs *regs, int v) { diff --git a/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32-table.h b/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32-table.h index b7da23b..1c84ef3 100644 --- a/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32-table.h +++ b/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32-table.h @@ -24,22 +24,42 @@ * table. Only preprocessor stuff and syscall entries here. */ -#ifdef CONFIG_X86_X32 - -/* - * When x32 support is enabled, we need thunks for dealing with - * 32<->64 argument conversion. An additional entry for each - * __COBALT_CALL_X32 syscall is generated into the table, at a - * position equal to the original syscall number + __COBALT_X32_BASE - * as defined in asm/xenomai/syscall32.h. - */ - -#define __sysx32__(__name) \ - ((cobalt_syshand)(cobalt32x_ ## __name)) - -#define __COBALT_CALL_X32(__name) \ - [sc_cobalt_ ## __name + __COBALT_X32_BASE] = __sysx32__(__name), - -#endif +__COBALT_CALL32emu_THUNK(thread_create) +__COBALT_CALL32emu_THUNK(thread_setschedparam_ex) +__COBALT_CALL32emu_THUNK(thread_getschedparam_ex) +__COBALT_CALL32emu_THUNK(sem_open) +__COBALT_CALL32emu_THUNK(sem_timedwait) +__COBALT_CALL32emu_THUNK(clock_getres) +__COBALT_CALL32emu_THUNK(clock_gettime) +__COBALT_CALL32emu_THUNK(clock_settime) +__COBALT_CALL32emu_THUNK(clock_nanosleep) +__COBALT_CALL32emu_THUNK(mutex_timedlock) +__COBALT_CALL32emu_THUNK(cond_wait_prologue) +__COBALT_CALL32emu_THUNK(mq_open) +__COBALT_CALL32emu_THUNK(mq_getattr) +__COBALT_CALL32emu_THUNK(mq_setattr) +__COBALT_CALL32emu_THUNK(mq_timedsend) +__COBALT_CALL32emu_THUNK(mq_timedreceive) +__COBALT_CALL32emu_THUNK(mq_notify) +__COBALT_CALL32emu_THUNK(sched_weightprio) +__COBALT_CALL32emu_THUNK(sched_setconfig_np) +__COBALT_CALL32emu_THUNK(sched_getconfig_np) +__COBALT_CALL32emu_THUNK(timer_create) +__COBALT_CALL32emu_THUNK(timer_settime) +__COBALT_CALL32emu_THUNK(timer_gettime) +__COBALT_CALL32emu_THUNK(timerfd_settime) +__COBALT_CALL32emu_THUNK(timerfd_gettime) +__COBALT_CALL32emu_THUNK(sigwait) +__COBALT_CALL32emu_THUNK(sigtimedwait) +__COBALT_CALL32emu_THUNK(sigwaitinfo) +__COBALT_CALL32emu_THUNK(sigpending) +__COBALT_CALL32emu_THUNK(sigqueue) +__COBALT_CALL32emu_THUNK(monitor_wait) +__COBALT_CALL32emu_THUNK(event_wait) +__COBALT_CALL32emu_THUNK(select) +__COBALT_CALL32emu_THUNK(recvmsg) +__COBALT_CALL32emu_THUNK(sendmsg) +__COBALT_CALL32emu_THUNK(mmap) +__COBALT_CALL32emu_THUNK(backtrace) #endif /* !_COBALT_X86_ASM_SYSCALL32_TABLE_H */ diff --git a/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32.h b/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32.h index b83aaf4..e4890a6 100644 --- a/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32.h +++ b/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32.h @@ -19,26 +19,50 @@ #ifndef _COBALT_X86_ASM_SYSCALL32_H #define _COBALT_X86_ASM_SYSCALL32_H +#include <asm/unistd.h> + #ifdef CONFIG_X86_X32 -#include <linux/compat.h> +#define __COBALT_X32_BASE 128 + +#define __COBALT_SYSNR32x(__reg) \ + ({ \ + long __nr = __reg; \ + if (__nr & __X32_SYSCALL_BIT) { \ + __nr &= ~__X32_SYSCALL_BIT; \ + __nr += __COBALT_X32_BASE; \ + } \ + __nr; \ + }) -#define __COBALT_X32_BASE 128 -#define __COBALT_SYSCALL_MASK __X32_SYSCALL_BIT +#define __COBALT_COMPAT32x(__reg) \ + (((__reg) & __X32_SYSCALL_BIT) ? __COBALT_COMPATX_BIT : 0) -#if __NR_COBALT_SYSCALLS >= __COBALT_X32_BASE -#error "__NR_COBALT_SYSCALLS >= __COBALT_X32_BASE" +#if __NR_COBALT_SYSCALLS > __COBALT_X32_BASE +#error "__NR_COBALT_SYSCALLS > __COBALT_X32_BASE" #endif -/* 32bit call entry, assigning __handler to call #__name. */ -#define __COBALT_CALL32_ENTRY(__name, __handler) \ +#define __syshand32x__(__name) ((cobalt_syshand)(cobalt32x_ ## __name)) + +#define __COBALT_CALL32x_INITHAND(__handler) \ + , [__COBALT_X32_BASE ... __COBALT_X32_BASE + __NR_COBALT_SYSCALLS-1] = __handler + +#define __COBALT_CALL32x_INITMODE(__mode) \ + , [__COBALT_X32_BASE ... __COBALT_X32_BASE + __NR_COBALT_SYSCALLS-1] = __mode + +/* x32 default entry (no thunk) */ +#define __COBALT_CALL32x_ENTRY(__name, __handler) \ , [sc_cobalt_ ## __name + __COBALT_X32_BASE] = __handler -/* 32bit thunk implementation. */ +/* x32 thunk installation */ +#define __COBALT_CALL32x_THUNK(__name) \ + __COBALT_CALL32x_ENTRY(__name, __syshand32x__(__name)) + +/* x32 thunk implementation. */ #define COBALT_SYSCALL32x(__name, __mode, __type, __args) \ __typeof__(__type) cobalt32x_ ## __name __args -/* 32bit thunk declaration. */ +/* x32 thunk declaration. */ #define COBALT_SYSCALL32x_DECL(__name, __type, __args) \ __typeof__(__type) cobalt32x_ ## __name __args @@ -46,14 +70,113 @@ /* x32 support disabled. */ -#define __COBALT_CALL32_ENTRY(__name, __handler) +#define __COBALT_SYSNR32x(__reg) (__reg) + +#define __COBALT_COMPAT32x(__reg) 0 + +#define __COBALT_CALL32x_INITHAND(__handler) + +#define __COBALT_CALL32x_INITMODE(__mode) + +#define __COBALT_CALL32x_ENTRY(__name, __handler) + +#define __COBALT_CALL32x_THUNK(__name) #define COBALT_SYSCALL32x_DECL(__name, __type, __args) #endif /* !CONFIG_X86_X32 */ -#ifndef __COBALT_SYSCALL_MASK -#define __COBALT_SYSCALL_MASK 0 +#ifdef CONFIG_IA32_EMULATION + +#define __COBALT_IA32_BASE 256 /* Power of two. */ + +#define __COBALT_SYSNR32emu(__reg) \ + ({ \ + long __nr = __reg; \ + if (current_thread_info()->status & TS_COMPAT) \ + __nr += __COBALT_IA32_BASE; \ + __nr; \ + }) + +#define __COBALT_COMPAT32emu(__reg) \ + ((current_thread_info()->status & TS_COMPAT) ? __COBALT_COMPAT_BIT : 0) + +#if __NR_COBALT_SYSCALLS > __COBALT_IA32_BASE +#error "__NR_COBALT_SYSCALLS > __COBALT_IA32_BASE" #endif +#define __syshand32emu__(__name) ((cobalt_syshand)(cobalt32emu_ ## __name)) + +#define __COBALT_CALL32emu_INITHAND(__handler) \ + , [__COBALT_IA32_BASE ... __COBALT_IA32_BASE + __NR_COBALT_SYSCALLS-1] = __handler + +#define __COBALT_CALL32emu_INITMODE(__mode) \ + , [__COBALT_IA32_BASE ... __COBALT_IA32_BASE + __NR_COBALT_SYSCALLS-1] = __mode + +/* ia32 default entry (no thunk) */ +#define __COBALT_CALL32emu_ENTRY(__name, __handler) \ + , [sc_cobalt_ ## __name + __COBALT_IA32_BASE] = __handler + +/* ia32 thunk installation */ +#define __COBALT_CALL32emu_THUNK(__name) \ + __COBALT_CALL32emu_ENTRY(__name, __syshand32emu__(__name)) + +/* ia32 thunk implementation. */ +#define COBALT_SYSCALL32emu(__name, __mode, __type, __args) \ + __typeof__(__type) cobalt32emu_ ## __name __args + +/* ia32 thunk declaration. */ +#define COBALT_SYSCALL32emu_DECL(__name, __type, __args) \ + __typeof__(__type) cobalt32emu_ ## __name __args + +#else /* !CONFIG_IA32_EMULATION */ + +/* ia32 emulation support disabled. */ + +#define __COBALT_SYSNR32emu(__reg) (__reg) + +#define __COBALT_COMPAT32emu(__reg) 0 + +#define __COBALT_CALL32emu_INITHAND(__handler) + +#define __COBALT_CALL32emu_INITMODE(__mode) + +#define __COBALT_CALL32emu_ENTRY(__name, __handler) + +#define __COBALT_CALL32emu_THUNK(__name) + +#define COBALT_SYSCALL32emu_DECL(__name, __type, __args) + +#endif /* !CONFIG_IA32_EMULATION */ + +#define __COBALT_CALL32_ENTRY(__name, __handler) \ + __COBALT_CALL32x_ENTRY(__name, __handler) \ + __COBALT_CALL32emu_ENTRY(__name, __handler) + +#define __COBALT_CALL32_INITHAND(__handler) \ + __COBALT_CALL32x_INITHAND(__handler) \ + __COBALT_CALL32emu_INITHAND(__handler) + +#define __COBALT_CALL32_INITMODE(__mode) \ + __COBALT_CALL32x_INITMODE(__mode) \ + __COBALT_CALL32emu_INITMODE(__mode) + +/* Already checked for __COBALT_SYSCALL_BIT */ +#define __COBALT_CALL32_SYSNR(__reg) \ + ({ \ + long __nr; \ + __nr = __COBALT_SYSNR32x(__reg); \ + if (__nr == (__reg)) \ + __nr = __COBALT_SYSNR32emu(__reg); \ + __nr; \ + }) + +#define __COBALT_CALL_COMPAT(__reg) \ + ({ \ + int __ret = __COBALT_COMPAT32x(__reg); \ + if (__ret == 0) \ + __ret = __COBALT_COMPAT32emu(__reg); \ + __ret; \ + }) + #endif /* !_COBALT_X86_ASM_SYSCALL32_H */ _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://www.xenomai.org/mailman/listinfo/xenomai-git