From ec758f98328da3eb933a25dc7a2eed01ef44d849 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Thu, 31 Jan 2013 21:44:28 +0000 Subject: parisc: add CONFIG_MLONGCALLS option to enable linkage of huge vmlinux executables When building a 64bit kernel which includes all necessary drivers and filesystems the vmlinux kernel often gets so huge, that the linker won't be able to resolve the branch stubs. This patch overcomes this limit by providing an option to compile the kernel with the -mlong-calls compiler option. Signed-off-by: Helge Deller --- arch/parisc/Kconfig | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'arch/parisc/Kconfig') diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index b77feffbadea..3df1c35a217a 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -161,6 +161,23 @@ config PREFETCH def_bool y depends on PA8X00 || PA7200 +config MLONGCALLS + bool "Enable the -mlong-calls compiler option for big kernels" + def_bool y if (!MODULES) + depends on PA8X00 + help + If you configure the kernel to include many drivers built-in instead + as modules, the kernel executable may become too big, so that the + linker will not be able to resolve some long branches and fails to link + your vmlinux kernel. In that case enabling this option will help you + to overcome this limit by using the -mlong-calls compiler option. + + Usually you want to say N here, unless you e.g. want to build + a kernel which includes all necessary drivers built-in and which can + be used for TFTP booting without the need to have an initrd ramdisk. + + Enabling this option will probably slow down your kernel. + config 64BIT bool "64-bit kernel" depends on PA8X00 -- cgit v1.2.3 From bf581e15a443fa3569d9def96b512315ba509d6f Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Tue, 19 Feb 2013 20:47:37 +0100 Subject: parisc: convert msgrcv and msgsnd syscalls to use compat layer Switch over to use the existing compat_* implementation for msgrcv() and msgsnd(). Existing code was even partly buggy since it returned on some paths different error codes than the standard. Signed-off-by: Helge Deller --- arch/parisc/Kconfig | 4 +++ arch/parisc/include/asm/compat.h | 61 ++++++++++++++++++++++++++++++++++++++ arch/parisc/kernel/sys_parisc32.c | 58 ------------------------------------ arch/parisc/kernel/syscall_table.S | 4 +-- 4 files changed, 67 insertions(+), 60 deletions(-) (limited to 'arch/parisc/Kconfig') diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 3df1c35a217a..af48d26ce287 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -272,6 +272,10 @@ config COMPAT def_bool y depends on 64BIT +config SYSVIPC_COMPAT + def_bool y + depends on COMPAT && SYSVIPC + config HPUX bool "Support for HP-UX binaries" depends on !64BIT diff --git a/arch/parisc/include/asm/compat.h b/arch/parisc/include/asm/compat.h index db7a662691a8..94710cfc1ce8 100644 --- a/arch/parisc/include/asm/compat.h +++ b/arch/parisc/include/asm/compat.h @@ -28,6 +28,7 @@ typedef u16 compat_nlink_t; typedef u16 compat_ipc_pid_t; typedef s32 compat_daddr_t; typedef u32 compat_caddr_t; +typedef s32 compat_key_t; typedef s32 compat_timer_t; typedef s32 compat_int_t; @@ -188,6 +189,66 @@ typedef struct compat_siginfo { #define COMPAT_OFF_T_MAX 0x7fffffff #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL +struct compat_ipc64_perm { + compat_key_t key; + __compat_uid_t uid; + __compat_gid_t gid; + __compat_uid_t cuid; + __compat_gid_t cgid; + unsigned short int __pad1; + compat_mode_t mode; + unsigned short int __pad2; + unsigned short int seq; + unsigned int __pad3; + unsigned long __unused1; /* yes they really are 64bit pads */ + unsigned long __unused2; +}; + +struct compat_semid64_ds { + struct compat_ipc64_perm sem_perm; + compat_time_t sem_otime; + unsigned int __unused1; + compat_time_t sem_ctime; + unsigned int __unused2; + compat_ulong_t sem_nsems; + compat_ulong_t __unused3; + compat_ulong_t __unused4; +}; + +struct compat_msqid64_ds { + struct compat_ipc64_perm msg_perm; + unsigned int __unused1; + compat_time_t msg_stime; + unsigned int __unused2; + compat_time_t msg_rtime; + unsigned int __unused3; + compat_time_t msg_ctime; + compat_ulong_t msg_cbytes; + compat_ulong_t msg_qnum; + compat_ulong_t msg_qbytes; + compat_pid_t msg_lspid; + compat_pid_t msg_lrpid; + compat_ulong_t __unused4; + compat_ulong_t __unused5; +}; + +struct compat_shmid64_ds { + struct compat_ipc64_perm shm_perm; + unsigned int __unused1; + compat_time_t shm_atime; + unsigned int __unused2; + compat_time_t shm_dtime; + unsigned int __unused3; + compat_time_t shm_ctime; + unsigned int __unused4; + compat_size_t shm_segsz; + compat_pid_t shm_cpid; + compat_pid_t shm_lpid; + compat_ulong_t shm_nattch; + compat_ulong_t __unused5; + compat_ulong_t __unused6; +}; + /* * A pointer passed in from user mode. This should not * be used for syscall parameters, just declare them diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c index 9cfdaa19ab63..cee60f77fc1f 100644 --- a/arch/parisc/kernel/sys_parisc32.c +++ b/arch/parisc/kernel/sys_parisc32.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -73,63 +72,6 @@ asmlinkage long sys32_sched_rr_get_interval(pid_t pid, return ret; } -struct msgbuf32 { - int mtype; - char mtext[1]; -}; - -asmlinkage long sys32_msgsnd(int msqid, - struct msgbuf32 __user *umsgp32, - size_t msgsz, int msgflg) -{ - struct msgbuf *mb; - struct msgbuf32 mb32; - int err; - - if ((mb = kmalloc(msgsz + sizeof *mb + 4, GFP_KERNEL)) == NULL) - return -ENOMEM; - - err = get_user(mb32.mtype, &umsgp32->mtype); - mb->mtype = mb32.mtype; - err |= copy_from_user(mb->mtext, &umsgp32->mtext, msgsz); - - if (err) - err = -EFAULT; - else - KERNEL_SYSCALL(err, sys_msgsnd, msqid, (struct msgbuf __user *)mb, msgsz, msgflg); - - kfree(mb); - return err; -} - -asmlinkage long sys32_msgrcv(int msqid, - struct msgbuf32 __user *umsgp32, - size_t msgsz, long msgtyp, int msgflg) -{ - struct msgbuf *mb; - struct msgbuf32 mb32; - int err, len; - - if ((mb = kmalloc(msgsz + sizeof *mb + 4, GFP_KERNEL)) == NULL) - return -ENOMEM; - - KERNEL_SYSCALL(err, sys_msgrcv, msqid, (struct msgbuf __user *)mb, msgsz, msgtyp, msgflg); - - if (err >= 0) { - len = err; - mb32.mtype = mb->mtype; - err = put_user(mb32.mtype, &umsgp32->mtype); - err |= copy_to_user(&umsgp32->mtext, mb->mtext, len); - if (err) - err = -EFAULT; - else - err = len; - } - - kfree(mb); - return err; -} - asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, s32 count) { mm_segment_t old_fs = get_fs(); diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index e5fcd4c605e2..773b4ee1e1d3 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -286,8 +286,8 @@ ENTRY_SAME(semop) /* 185 */ ENTRY_SAME(semget) ENTRY_DIFF(semctl) - ENTRY_DIFF(msgsnd) - ENTRY_DIFF(msgrcv) + ENTRY_COMP(msgsnd) + ENTRY_COMP(msgrcv) ENTRY_SAME(msgget) /* 190 */ ENTRY_SAME(msgctl) ENTRY_SAME(shmat) -- cgit v1.2.3