aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/Makefile6
-rw-r--r--arch/arm/kernel/apm.c20
-rw-r--r--arch/arm/kernel/armksyms.c22
-rw-r--r--arch/arm/kernel/asm-offsets.c13
-rw-r--r--arch/arm/kernel/calls.S662
-rw-r--r--arch/arm/kernel/compat.c2
-rw-r--r--arch/arm/kernel/compat.h13
-rw-r--r--arch/arm/kernel/dma-isa.c22
-rw-r--r--arch/arm/kernel/dma.c73
-rw-r--r--arch/arm/kernel/ecard.c21
-rw-r--r--arch/arm/kernel/entry-armv.S50
-rw-r--r--arch/arm/kernel/entry-common.S150
-rw-r--r--arch/arm/kernel/entry-header.S1
-rw-r--r--arch/arm/kernel/fiq.c4
-rw-r--r--arch/arm/kernel/head.S9
-rw-r--r--arch/arm/kernel/irq.c17
-rw-r--r--arch/arm/kernel/process.c19
-rw-r--r--arch/arm/kernel/ptrace.c66
-rw-r--r--arch/arm/kernel/semaphore.c17
-rw-r--r--arch/arm/kernel/setup.c27
-rw-r--r--arch/arm/kernel/signal.c29
-rw-r--r--arch/arm/kernel/signal.h2
-rw-r--r--arch/arm/kernel/smp.c5
-rw-r--r--arch/arm/kernel/sys_arm.c2
-rw-r--r--arch/arm/kernel/sys_oabi-compat.c440
-rw-r--r--arch/arm/kernel/time.c13
-rw-r--r--arch/arm/kernel/traps.c15
-rw-r--r--arch/arm/kernel/vmlinux.lds.S12
28 files changed, 1173 insertions, 559 deletions
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index c11169b..2ce0e3a 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -2,15 +2,16 @@
# Makefile for the linux kernel.
#
-AFLAGS_head.o := -DKERNEL_RAM_ADDR=$(TEXTADDR)
+AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
# Object file lists.
-obj-y := compat.o dma.o entry-armv.o entry-common.o irq.o \
+obj-y := compat.o entry-armv.o entry-common.o irq.o \
process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \
time.o traps.o
obj-$(CONFIG_APM) += apm.o
+obj-$(CONFIG_ISA_DMA_API) += dma.o
obj-$(CONFIG_ARCH_ACORN) += ecard.o
obj-$(CONFIG_FOOTBRIDGE) += isa.o
obj-$(CONFIG_FIQ) += fiq.o
@@ -19,6 +20,7 @@ obj-$(CONFIG_ARTHUR) += arthur.o
obj-$(CONFIG_ISA_DMA) += dma-isa.o
obj-$(CONFIG_PCI) += bios32.o
obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o
obj-$(CONFIG_IWMMXT) += iwmmxt.o
AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
diff --git a/arch/arm/kernel/apm.c b/arch/arm/kernel/apm.c
index a2843be..766b6c0 100644
--- a/arch/arm/kernel/apm.c
+++ b/arch/arm/kernel/apm.c
@@ -18,9 +18,9 @@
#include <linux/proc_fs.h>
#include <linux/miscdevice.h>
#include <linux/apm_bios.h>
+#include <linux/capability.h>
#include <linux/sched.h>
#include <linux/pm.h>
-#include <linux/pm_legacy.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/list.h>
@@ -81,6 +81,7 @@ struct apm_user {
*/
static int suspends_pending;
static int apm_disabled;
+static int arm_apm_active;
static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
@@ -477,9 +478,9 @@ static int kapmd(void *arg)
apm_event_t event;
wait_event_interruptible(kapmd_wait,
- !queue_empty(&kapmd_queue) || !pm_active);
+ !queue_empty(&kapmd_queue) || !arm_apm_active);
- if (!pm_active)
+ if (!arm_apm_active)
break;
spin_lock_irq(&kapmd_queue_lock);
@@ -522,16 +523,11 @@ static int __init apm_init(void)
return -ENODEV;
}
- if (PM_IS_ACTIVE()) {
- printk(KERN_NOTICE "apm: overridden by ACPI.\n");
- return -EINVAL;
- }
-
- pm_active = 1;
+ arm_apm_active = 1;
ret = kernel_thread(kapmd, NULL, CLONE_KERNEL);
if (ret < 0) {
- pm_active = 0;
+ arm_apm_active = 0;
return ret;
}
@@ -543,7 +539,7 @@ static int __init apm_init(void)
if (ret != 0) {
remove_proc_entry("apm", NULL);
- pm_active = 0;
+ arm_apm_active = 0;
wake_up(&kapmd_wait);
wait_for_completion(&kapmd_exit);
}
@@ -556,7 +552,7 @@ static void __exit apm_exit(void)
misc_deregister(&apm_device);
remove_proc_entry("apm", NULL);
- pm_active = 0;
+ arm_apm_active = 0;
wake_up(&kapmd_wait);
wait_for_completion(&kapmd_exit);
}
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 9997098..1574941 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -35,6 +35,16 @@ extern void __udivsi3(void);
extern void __umodsi3(void);
extern void __do_div64(void);
+extern void __aeabi_idiv(void);
+extern void __aeabi_idivmod(void);
+extern void __aeabi_lasr(void);
+extern void __aeabi_llsl(void);
+extern void __aeabi_llsr(void);
+extern void __aeabi_lmul(void);
+extern void __aeabi_uidiv(void);
+extern void __aeabi_uidivmod(void);
+extern void __aeabi_ulcmp(void);
+
extern void fpundefinstr(void);
extern void fp_enter(void);
@@ -141,6 +151,18 @@ EXPORT_SYMBOL(__udivsi3);
EXPORT_SYMBOL(__umodsi3);
EXPORT_SYMBOL(__do_div64);
+#ifdef CONFIG_AEABI
+EXPORT_SYMBOL(__aeabi_idiv);
+EXPORT_SYMBOL(__aeabi_idivmod);
+EXPORT_SYMBOL(__aeabi_lasr);
+EXPORT_SYMBOL(__aeabi_llsl);
+EXPORT_SYMBOL(__aeabi_llsr);
+EXPORT_SYMBOL(__aeabi_lmul);
+EXPORT_SYMBOL(__aeabi_uidiv);
+EXPORT_SYMBOL(__aeabi_uidivmod);
+EXPORT_SYMBOL(__aeabi_ulcmp);
+#endif
+
/* bitops */
EXPORT_SYMBOL(_set_bit_le);
EXPORT_SYMBOL(_test_and_set_bit_le);
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 04d3082..b324dca 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -23,20 +23,15 @@
#error Sorry, your compiler targets APCS-26 but this kernel requires APCS-32
#endif
/*
- * GCC 2.95.1, 2.95.2: ignores register clobber list in asm().
* GCC 3.0, 3.1: general bad code generation.
* GCC 3.2.0: incorrect function argument offset calculation.
* GCC 3.2.x: miscompiles NEW_AUX_ENT in fs/binfmt_elf.c
* (http://gcc.gnu.org/PR8896) and incorrect structure
* initialisation in fs/jffs2/erase.c
*/
-#if __GNUC__ < 2 || \
- (__GNUC__ == 2 && __GNUC_MINOR__ < 95) || \
- (__GNUC__ == 2 && __GNUC_MINOR__ == 95 && __GNUC_PATCHLEVEL__ != 0 && \
- __GNUC_PATCHLEVEL__ < 3) || \
- (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
+#if (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
#error Your compiler is too buggy; it is known to miscompile kernels.
-#error Known good compilers: 2.95.3, 2.95.4, 2.96, 3.3
+#error Known good compilers: 3.3
#endif
/* Use marker if you need to separate the values later */
@@ -62,7 +57,9 @@ int main(void)
DEFINE(TI_TP_VALUE, offsetof(struct thread_info, tp_value));
DEFINE(TI_FPSTATE, offsetof(struct thread_info, fpstate));
DEFINE(TI_VFPSTATE, offsetof(struct thread_info, vfpstate));
- DEFINE(TI_IWMMXT_STATE, (offsetof(struct thread_info, fpstate)+4)&~7);
+#ifdef CONFIG_IWMMXT
+ DEFINE(TI_IWMMXT_STATE, offsetof(struct thread_info, fpstate.iwmmxt));
+#endif
BLANK();
DEFINE(S_R0, offsetof(struct pt_regs, ARM_r0));
DEFINE(S_R1, offsetof(struct pt_regs, ARM_r1));
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index 55076a7..3173924 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -7,338 +7,334 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
- * This file is included twice in entry-common.S
+ * This file is included thrice in entry-common.S
*/
-#ifndef NR_syscalls
-#define NR_syscalls 328
-#else
-
-__syscall_start:
-/* 0 */ .long sys_restart_syscall
- .long sys_exit
- .long sys_fork_wrapper
- .long sys_read
- .long sys_write
-/* 5 */ .long sys_open
- .long sys_close
- .long sys_ni_syscall /* was sys_waitpid */
- .long sys_creat
- .long sys_link
-/* 10 */ .long sys_unlink
- .long sys_execve_wrapper
- .long sys_chdir
- .long sys_time /* used by libc4 */
- .long sys_mknod
-/* 15 */ .long sys_chmod
- .long sys_lchown16
- .long sys_ni_syscall /* was sys_break */
- .long sys_ni_syscall /* was sys_stat */
- .long sys_lseek
-/* 20 */ .long sys_getpid
- .long sys_mount
- .long sys_oldumount /* used by libc4 */
- .long sys_setuid16
- .long sys_getuid16
-/* 25 */ .long sys_stime
- .long sys_ptrace
- .long sys_alarm /* used by libc4 */
- .long sys_ni_syscall /* was sys_fstat */
- .long sys_pause
-/* 30 */ .long sys_utime /* used by libc4 */
- .long sys_ni_syscall /* was sys_stty */
- .long sys_ni_syscall /* was sys_getty */
- .long sys_access
- .long sys_nice
-/* 35 */ .long sys_ni_syscall /* was sys_ftime */
- .long sys_sync
- .long sys_kill
- .long sys_rename
- .long sys_mkdir
-/* 40 */ .long sys_rmdir
- .long sys_dup
- .long sys_pipe
- .long sys_times
- .long sys_ni_syscall /* was sys_prof */
-/* 45 */ .long sys_brk
- .long sys_setgid16
- .long sys_getgid16
- .long sys_ni_syscall /* was sys_signal */
- .long sys_geteuid16
-/* 50 */ .long sys_getegid16
- .long sys_acct
- .long sys_umount
- .long sys_ni_syscall /* was sys_lock */
- .long sys_ioctl
-/* 55 */ .long sys_fcntl
- .long sys_ni_syscall /* was sys_mpx */
- .long sys_setpgid
- .long sys_ni_syscall /* was sys_ulimit */
- .long sys_ni_syscall /* was sys_olduname */
-/* 60 */ .long sys_umask
- .long sys_chroot
- .long sys_ustat
- .long sys_dup2
- .long sys_getppid
-/* 65 */ .long sys_getpgrp
- .long sys_setsid
- .long sys_sigaction
- .long sys_ni_syscall /* was sys_sgetmask */
- .long sys_ni_syscall /* was sys_ssetmask */
-/* 70 */ .long sys_setreuid16
- .long sys_setregid16
- .long sys_sigsuspend_wrapper
- .long sys_sigpending
- .long sys_sethostname
-/* 75 */ .long sys_setrlimit
- .long sys_old_getrlimit /* used by libc4 */
- .long sys_getrusage
- .long sys_gettimeofday
- .long sys_settimeofday
-/* 80 */ .long sys_getgroups16
- .long sys_setgroups16
- .long old_select /* used by libc4 */
- .long sys_symlink
- .long sys_ni_syscall /* was sys_lstat */
-/* 85 */ .long sys_readlink
- .long sys_uselib
- .long sys_swapon
- .long sys_reboot
- .long old_readdir /* used by libc4 */
-/* 90 */ .long old_mmap /* used by libc4 */
- .long sys_munmap
- .long sys_truncate
- .long sys_ftruncate
- .long sys_fchmod
-/* 95 */ .long sys_fchown16
- .long sys_getpriority
- .long sys_setpriority
- .long sys_ni_syscall /* was sys_profil */
- .long sys_statfs
-/* 100 */ .long sys_fstatfs
- .long sys_ni_syscall
- .long sys_socketcall
- .long sys_syslog
- .long sys_setitimer
-/* 105 */ .long sys_getitimer
- .long sys_newstat
- .long sys_newlstat
- .long sys_newfstat
- .long sys_ni_syscall /* was sys_uname */
-/* 110 */ .long sys_ni_syscall /* was sys_iopl */
- .long sys_vhangup
- .long sys_ni_syscall
- .long sys_syscall /* call a syscall */
- .long sys_wait4
-/* 115 */ .long sys_swapoff
- .long sys_sysinfo
- .long sys_ipc
- .long sys_fsync
- .long sys_sigreturn_wrapper
-/* 120 */ .long sys_clone_wrapper
- .long sys_setdomainname
- .long sys_newuname
- .long sys_ni_syscall
- .long sys_adjtimex
-/* 125 */ .long sys_mprotect
- .long sys_sigprocmask
- .long sys_ni_syscall /* was sys_create_module */
- .long sys_init_module
- .long sys_delete_module
-/* 130 */ .long sys_ni_syscall /* was sys_get_kernel_syms */
- .long sys_quotactl
- .long sys_getpgid
- .long sys_fchdir
- .long sys_bdflush
-/* 135 */ .long sys_sysfs
- .long sys_personality
- .long sys_ni_syscall /* .long _sys_afs_syscall */
- .long sys_setfsuid16
- .long sys_setfsgid16
-/* 140 */ .long sys_llseek
- .long sys_getdents
- .long sys_select
- .long sys_flock
- .long sys_msync
-/* 145 */ .long sys_readv
- .long sys_writev
- .long sys_getsid
- .long sys_fdatasync
- .long sys_sysctl
-/* 150 */ .long sys_mlock
- .long sys_munlock
- .long sys_mlockall
- .long sys_munlockall
- .long sys_sched_setparam
-/* 155 */ .long sys_sched_getparam
- .long sys_sched_setscheduler
- .long sys_sched_getscheduler
- .long sys_sched_yield
- .long sys_sched_get_priority_max
-/* 160 */ .long sys_sched_get_priority_min
- .long sys_sched_rr_get_interval
- .long sys_nanosleep
- .long sys_arm_mremap
- .long sys_setresuid16
-/* 165 */ .long sys_getresuid16
- .long sys_ni_syscall
- .long sys_ni_syscall /* was sys_query_module */
- .long sys_poll
- .long sys_nfsservctl
-/* 170 */ .long sys_setresgid16
- .long sys_getresgid16
- .long sys_prctl
- .long sys_rt_sigreturn_wrapper
- .long sys_rt_sigaction
-/* 175 */ .long sys_rt_sigprocmask
- .long sys_rt_sigpending
- .long sys_rt_sigtimedwait
- .long sys_rt_sigqueueinfo
- .long sys_rt_sigsuspend_wrapper
-/* 180 */ .long sys_pread64
- .long sys_pwrite64
- .long sys_chown16
- .long sys_getcwd
- .long sys_capget
-/* 185 */ .long sys_capset
- .long sys_sigaltstack_wrapper
- .long sys_sendfile
- .long sys_ni_syscall
- .long sys_ni_syscall
-/* 190 */ .long sys_vfork_wrapper
- .long sys_getrlimit
- .long sys_mmap2
- .long sys_truncate64
- .long sys_ftruncate64
-/* 195 */ .long sys_stat64
- .long sys_lstat64
- .long sys_fstat64
- .long sys_lchown
- .long sys_getuid
-/* 200 */ .long sys_getgid
- .long sys_geteuid
- .long sys_getegid
- .long sys_setreuid
- .long sys_setregid
-/* 205 */ .long sys_getgroups
- .long sys_setgroups
- .long sys_fchown
- .long sys_setresuid
- .long sys_getresuid
-/* 210 */ .long sys_setresgid
- .long sys_getresgid
- .long sys_chown
- .long sys_setuid
- .long sys_setgid
-/* 215 */ .long sys_setfsuid
- .long sys_setfsgid
- .long sys_getdents64
- .long sys_pivot_root
- .long sys_mincore
-/* 220 */ .long sys_madvise
- .long sys_fcntl64
- .long sys_ni_syscall /* TUX */
- .long sys_ni_syscall
- .long sys_gettid
-/* 225 */ .long sys_readahead
- .long sys_setxattr
- .long sys_lsetxattr
- .long sys_fsetxattr
- .long sys_getxattr
-/* 230 */ .long sys_lgetxattr
- .long sys_fgetxattr
- .long sys_listxattr
- .long sys_llistxattr
- .long sys_flistxattr
-/* 235 */ .long sys_removexattr
- .long sys_lremovexattr
- .long sys_fremovexattr
- .long sys_tkill
- .long sys_sendfile64
-/* 240 */ .long sys_futex
- .long sys_sched_setaffinity
- .long sys_sched_getaffinity
- .long sys_io_setup
- .long sys_io_destroy
-/* 245 */ .long sys_io_getevents
- .long sys_io_submit
- .long sys_io_cancel
- .long sys_exit_group
- .long sys_lookup_dcookie
-/* 250 */ .long sys_epoll_create
- .long sys_epoll_ctl
- .long sys_epoll_wait
- .long sys_remap_file_pages
- .long sys_ni_syscall /* sys_set_thread_area */
-/* 255 */ .long sys_ni_syscall /* sys_get_thread_area */
- .long sys_set_tid_address
- .long sys_timer_create
- .long sys_timer_settime
- .long sys_timer_gettime
-/* 260 */ .long sys_timer_getoverrun
- .long sys_timer_delete
- .long sys_clock_settime
- .long sys_clock_gettime
- .long sys_clock_getres
-/* 265 */ .long sys_clock_nanosleep
- .long sys_statfs64
- .long sys_fstatfs64
- .long sys_tgkill
- .long sys_utimes
-/* 270 */ .long sys_arm_fadvise64_64
- .long sys_pciconfig_iobase
- .long sys_pciconfig_read
- .long sys_pciconfig_write
- .long sys_mq_open
-/* 275 */ .long sys_mq_unlink
- .long sys_mq_timedsend
- .long sys_mq_timedreceive
- .long sys_mq_notify
- .long sys_mq_getsetattr
-/* 280 */ .long sys_waitid
- .long sys_socket
- .long sys_bind
- .long sys_connect
- .long sys_listen
-/* 285 */ .long sys_accept
- .long sys_getsockname
- .long sys_getpeername
- .long sys_socketpair
- .long sys_send
-/* 290 */ .long sys_sendto
- .long sys_recv
- .long sys_recvfrom
- .long sys_shutdown
- .long sys_setsockopt
-/* 295 */ .long sys_getsockopt
- .long sys_sendmsg
- .long sys_recvmsg
- .long sys_semop
- .long sys_semget
-/* 300 */ .long sys_semctl
- .long sys_msgsnd
- .long sys_msgrcv
- .long sys_msgget
- .long sys_msgctl
-/* 305 */ .long sys_shmat
- .long sys_shmdt
- .long sys_shmget
- .long sys_shmctl
- .long sys_add_key
-/* 310 */ .long sys_request_key
- .long sys_keyctl
- .long sys_semtimedop
-/* vserver */ .long sys_ni_syscall
- .long sys_ioprio_set
-/* 315 */ .long sys_ioprio_get
- .long sys_inotify_init
- .long sys_inotify_add_watch
- .long sys_inotify_rm_watch
- .long sys_mbind
-/* 320 */ .long sys_get_mempolicy
- .long sys_set_mempolicy
-__syscall_end:
-
- .rept NR_syscalls - (__syscall_end - __syscall_start) / 4
- .long sys_ni_syscall
- .endr
+/* 0 */ CALL(sys_restart_syscall)
+ CALL(sys_exit)
+ CALL(sys_fork_wrapper)
+ CALL(sys_read)
+ CALL(sys_write)
+/* 5 */ CALL(sys_open)
+ CALL(sys_close)
+ CALL(sys_ni_syscall) /* was sys_waitpid */
+ CALL(sys_creat)
+ CALL(sys_link)
+/* 10 */ CALL(sys_unlink)
+ CALL(sys_execve_wrapper)
+ CALL(sys_chdir)
+ CALL(OBSOLETE(sys_time)) /* used by libc4 */
+ CALL(sys_mknod)
+/* 15 */ CALL(sys_chmod)
+ CALL(sys_lchown16)
+ CALL(sys_ni_syscall) /* was sys_break */
+ CALL(sys_ni_syscall) /* was sys_stat */
+ CALL(sys_lseek)
+/* 20 */ CALL(sys_getpid)
+ CALL(sys_mount)
+ CALL(OBSOLETE(sys_oldumount)) /* used by libc4 */
+ CALL(sys_setuid16)
+ CALL(sys_getuid16)
+/* 25 */ CALL(OBSOLETE(sys_stime))
+ CALL(sys_ptrace)
+ CALL(OBSOLETE(sys_alarm)) /* used by libc4 */
+ CALL(sys_ni_syscall) /* was sys_fstat */
+ CALL(sys_pause)
+/* 30 */ CALL(OBSOLETE(sys_utime)) /* used by libc4 */
+ CALL(sys_ni_syscall) /* was sys_stty */
+ CALL(sys_ni_syscall) /* was sys_getty */
+ CALL(sys_access)
+ CALL(sys_nice)
+/* 35 */ CALL(sys_ni_syscall) /* was sys_ftime */
+ CALL(sys_sync)
+ CALL(sys_kill)
+ CALL(sys_rename)
+ CALL(sys_mkdir)
+/* 40 */ CALL(sys_rmdir)
+ CALL(sys_dup)
+ CALL(sys_pipe)
+ CALL(sys_times)
+ CALL(sys_ni_syscall) /* was sys_prof */
+/* 45 */ CALL(sys_brk)
+ CALL(sys_setgid16)
+ CALL(sys_getgid16)
+ CALL(sys_ni_syscall) /* was sys_signal */
+ CALL(sys_geteuid16)
+/* 50 */ CALL(sys_getegid16)
+ CALL(sys_acct)
+ CALL(sys_umount)
+ CALL(sys_ni_syscall) /* was sys_lock */
+ CALL(sys_ioctl)
+/* 55 */ CALL(sys_fcntl)
+ CALL(sys_ni_syscall) /* was sys_mpx */
+ CALL(sys_setpgid)
+ CALL(sys_ni_syscall) /* was sys_ulimit */
+ CALL(sys_ni_syscall) /* was sys_olduname */
+/* 60 */ CALL(sys_umask)
+ CALL(sys_chroot)
+ CALL(sys_ustat)
+ CALL(sys_dup2)
+ CALL(sys_getppid)
+/* 65 */ CALL(sys_getpgrp)
+ CALL(sys_setsid)
+ CALL(sys_sigaction)
+ CALL(sys_ni_syscall) /* was sys_sgetmask */
+ CALL(sys_ni_syscall) /* was sys_ssetmask */
+/* 70 */ CALL(sys_setreuid16)
+ CALL(sys_setregid16)
+ CALL(sys_sigsuspend_wrapper)
+ CALL(sys_sigpending)
+ CALL(sys_sethostname)
+/* 75 */ CALL(sys_setrlimit)
+ CALL(OBSOLETE(sys_old_getrlimit)) /* used by libc4 */
+ CALL(sys_getrusage)
+ CALL(sys_gettimeofday)
+ CALL(sys_settimeofday)
+/* 80 */ CALL(sys_getgroups16)
+ CALL(sys_setgroups16)
+ CALL(OBSOLETE(old_select)) /* used by libc4 */
+ CALL(sys_symlink)
+ CALL(sys_ni_syscall) /* was sys_lstat */
+/* 85 */ CALL(sys_readlink)
+ CALL(sys_uselib)
+ CALL(sys_swapon)
+ CALL(sys_reboot)
+ CALL(OBSOLETE(old_readdir)) /* used by libc4 */
+/* 90 */ CALL(OBSOLETE(old_mmap)) /* used by libc4 */
+ CALL(sys_munmap)
+ CALL(sys_truncate)
+ CALL(sys_ftruncate)
+ CALL(sys_fchmod)
+/* 95 */ CALL(sys_fchown16)
+ CALL(sys_getpriority)
+ CALL(sys_setpriority)
+ CALL(sys_ni_syscall) /* was sys_profil */
+ CALL(sys_statfs)
+/* 100 */ CALL(sys_fstatfs)
+ CALL(sys_ni_syscall)
+ CALL(OBSOLETE(ABI(sys_socketcall, sys_oabi_socketcall)))
+ CALL(sys_syslog)
+ CALL(sys_setitimer)
+/* 105 */ CALL(sys_getitimer)
+ CALL(sys_newstat)
+ CALL(sys_newlstat)
+ CALL(sys_newfstat)
+ CALL(sys_ni_syscall) /* was sys_uname */
+/* 110 */ CALL(sys_ni_syscall) /* was sys_iopl */
+ CALL(sys_vhangup)
+ CALL(sys_ni_syscall)
+ CALL(OBSOLETE(sys_syscall)) /* call a syscall */
+ CALL(sys_wait4)
+/* 115 */ CALL(sys_swapoff)
+ CALL(sys_sysinfo)
+ CALL(OBSOLETE(ABI(sys_ipc, sys_oabi_ipc)))
+ CALL(sys_fsync)
+ CALL(sys_sigreturn_wrapper)
+/* 120 */ CALL(sys_clone_wrapper)
+ CALL(sys_setdomainname)
+ CALL(sys_newuname)
+ CALL(sys_ni_syscall)
+ CALL(sys_adjtimex)
+/* 125 */ CALL(sys_mprotect)
+ CALL(sys_sigprocmask)
+ CALL(sys_ni_syscall) /* was sys_create_module */
+ CALL(sys_init_module)
+ CALL(sys_delete_module)
+/* 130 */ CALL(sys_ni_syscall) /* was sys_get_kernel_syms */
+ CALL(sys_quotactl)
+ CALL(sys_getpgid)
+ CALL(sys_fchdir)
+ CALL(sys_bdflush)
+/* 135 */ CALL(sys_sysfs)
+ CALL(sys_personality)
+ CALL(sys_ni_syscall) /* CALL(_sys_afs_syscall) */
+ CALL(sys_setfsuid16)
+ CALL(sys_setfsgid16)
+/* 140 */ CALL(sys_llseek)
+ CALL(sys_getdents)
+ CALL(sys_select)
+ CALL(sys_flock)
+ CALL(sys_msync)
+/* 145 */ CALL(sys_readv)
+ CALL(sys_writev)
+ CALL(sys_getsid)
+ CALL(sys_fdatasync)
+ CALL(sys_sysctl)
+/* 150 */ CALL(sys_mlock)
+ CALL(sys_munlock)
+ CALL(sys_mlockall)
+ CALL(sys_munlockall)
+ CALL(sys_sched_setparam)
+/* 155 */ CALL(sys_sched_getparam)
+ CALL(sys_sched_setscheduler)
+ CALL(sys_sched_getscheduler)
+ CALL(sys_sched_yield)
+ CALL(sys_sched_get_priority_max)
+/* 160 */ CALL(sys_sched_get_priority_min)
+ CALL(sys_sched_rr_get_interval)
+ CALL(sys_nanosleep)
+ CALL(sys_arm_mremap)
+ CALL(sys_setresuid16)
+/* 165 */ CALL(sys_getresuid16)
+ CALL(sys_ni_syscall)
+ CALL(sys_ni_syscall) /* was sys_query_module */
+ CALL(sys_poll)
+ CALL(sys_nfsservctl)
+/* 170 */ CALL(sys_setresgid16)
+ CALL(sys_getresgid16)
+ CALL(sys_prctl)
+ CALL(sys_rt_sigreturn_wrapper)
+ CALL(sys_rt_sigaction)
+/* 175 */ CALL(sys_rt_sigprocmask)
+ CALL(sys_rt_sigpending)
+ CALL(sys_rt_sigtimedwait)
+ CALL(sys_rt_sigqueueinfo)
+ CALL(sys_rt_sigsuspend_wrapper)
+/* 180 */ CALL(ABI(sys_pread64, sys_oabi_pread64))
+ CALL(ABI(sys_pwrite64, sys_oabi_pwrite64))
+ CALL(sys_chown16)
+ CALL(sys_getcwd)
+ CALL(sys_capget)
+/* 185 */ CALL(sys_capset)
+ CALL(sys_sigaltstack_wrapper)
+ CALL(sys_sendfile)
+ CALL(sys_ni_syscall)
+ CALL(sys_ni_syscall)
+/* 190 */ CALL(sys_vfork_wrapper)
+ CALL(sys_getrlimit)
+ CALL(sys_mmap2)
+ CALL(ABI(sys_truncate64, sys_oabi_truncate64))
+ CALL(ABI(sys_ftruncate64, sys_oabi_ftruncate64))
+/* 195 */ CALL(ABI(sys_stat64, sys_oabi_stat64))
+ CALL(ABI(sys_lstat64, sys_oabi_lstat64))
+ CALL(ABI(sys_fstat64, sys_oabi_fstat64))
+ CALL(sys_lchown)
+ CALL(sys_getuid)
+/* 200 */ CALL(sys_getgid)
+ CALL(sys_geteuid)
+ CALL(sys_getegid)
+ CALL(sys_setreuid)
+ CALL(sys_setregid)
+/* 205 */ CALL(sys_getgroups)
+ CALL(sys_setgroups)
+ CALL(sys_fchown)
+ CALL(sys_setresuid)
+ CALL(sys_getresuid)
+/* 210 */ CALL(sys_setresgid)
+ CALL(sys_getresgid)
+ CALL(sys_chown)
+ CALL(sys_setuid)
+ CALL(sys_setgid)
+/* 215 */ CALL(sys_setfsuid)
+ CALL(sys_setfsgid)
+ CALL(sys_getdents64)
+ CALL(sys_pivot_root)
+ CALL(sys_mincore)
+/* 220 */ CALL(sys_madvise)
+ CALL(ABI(sys_fcntl64, sys_oabi_fcntl64))
+ CALL(sys_ni_syscall) /* TUX */
+ CALL(sys_ni_syscall)
+ CALL(sys_gettid)
+/* 225 */ CALL(ABI(sys_readahead, sys_oabi_readahead))
+ CALL(sys_setxattr)
+ CALL(sys_lsetxattr)
+ CALL(sys_fsetxattr)
+ CALL(sys_getxattr)
+/* 230 */ CALL(sys_lgetxattr)
+ CALL(sys_fgetxattr)
+ CALL(sys_listxattr)
+ CALL(sys_llistxattr)
+ CALL(sys_flistxattr)
+/* 235 */ CALL(sys_removexattr)
+ CALL(sys_lremovexattr)
+ CALL(sys_fremovexattr)
+ CALL(sys_tkill)
+ CALL(sys_sendfile64)
+/* 240 */ CALL(sys_futex)
+ CALL(sys_sched_setaffinity)
+ CALL(sys_sched_getaffinity)
+ CALL(sys_io_setup)
+ CALL(sys_io_destroy)
+/* 245 */ CALL(sys_io_getevents)
+ CALL(sys_io_submit)
+ CALL(sys_io_cancel)
+ CALL(sys_exit_group)
+ CALL(sys_lookup_dcookie)
+/* 250 */ CALL(sys_epoll_create)
+ CALL(ABI(sys_epoll_ctl, sys_oabi_epoll_ctl))
+ CALL(ABI(sys_epoll_wait, sys_oabi_epoll_wait))
+ CALL(sys_remap_file_pages)
+ CALL(sys_ni_syscall) /* sys_set_thread_area */
+/* 255 */ CALL(sys_ni_syscall) /* sys_get_thread_area */
+ CALL(sys_set_tid_address)
+ CALL(sys_timer_create)
+ CALL(sys_timer_settime)
+ CALL(sys_timer_gettime)
+/* 260 */ CALL(sys_timer_getoverrun)
+ CALL(sys_timer_delete)
+ CALL(sys_clock_settime)
+ CALL(sys_clock_gettime)
+ CALL(sys_clock_getres)
+/* 265 */ CALL(sys_clock_nanosleep)
+ CALL(sys_statfs64_wrapper)
+ CALL(sys_fstatfs64_wrapper)
+ CALL(sys_tgkill)
+ CALL(sys_utimes)
+/* 270 */ CALL(sys_arm_fadvise64_64)
+ CALL(sys_pciconfig_iobase)
+ CALL(sys_pciconfig_read)
+ CALL(sys_pciconfig_write)
+ CALL(sys_mq_open)
+/* 275 */ CALL(sys_mq_unlink)
+ CALL(sys_mq_timedsend)
+ CALL(sys_mq_timedreceive)
+ CALL(sys_mq_notify)
+ CALL(sys_mq_getsetattr)
+/* 280 */ CALL(sys_waitid)
+ CALL(sys_socket)
+ CALL(ABI(sys_bind, sys_oabi_bind))
+ CALL(ABI(sys_connect, sys_oabi_connect))
+ CALL(sys_listen)
+/* 285 */ CALL(sys_accept)
+ CALL(sys_getsockname)
+ CALL(sys_getpeername)
+ CALL(sys_socketpair)
+ CALL(sys_send)
+/* 290 */ CALL(ABI(sys_sendto, sys_oabi_sendto))
+ CALL(sys_recv)
+ CALL(sys_recvfrom)
+ CALL(sys_shutdown)
+ CALL(sys_setsockopt)
+/* 295 */ CALL(sys_getsockopt)
+ CALL(ABI(sys_sendmsg, sys_oabi_sendmsg))
+ CALL(sys_recvmsg)
+ CALL(ABI(sys_semop, sys_oabi_semop))
+ CALL(sys_semget)
+/* 300 */ CALL(sys_semctl)
+ CALL(sys_msgsnd)
+ CALL(sys_msgrcv)
+ CALL(sys_msgget)
+ CALL(sys_msgctl)
+/* 305 */ CALL(sys_shmat)
+ CALL(sys_shmdt)
+ CALL(sys_shmget)
+ CALL(sys_shmctl)
+ CALL(sys_add_key)
+/* 310 */ CALL(sys_request_key)
+ CALL(sys_keyctl)
+ CALL(ABI(sys_semtimedop, sys_oabi_semtimedop))
+/* vserver */ CALL(sys_ni_syscall)
+ CALL(sys_ioprio_set)
+/* 315 */ CALL(sys_ioprio_get)
+ CALL(sys_inotify_init)
+ CALL(sys_inotify_add_watch)
+ CALL(sys_inotify_rm_watch)
+ CALL(sys_mbind)
+/* 320 */ CALL(sys_get_mempolicy)
+ CALL(sys_set_mempolicy)
+#ifndef syscalls_counted
+.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
+#define syscalls_counted
#endif
+.rept syscalls_padding
+ CALL(sys_ni_syscall)
+.endr
diff --git a/arch/arm/kernel/compat.c b/arch/arm/kernel/compat.c
index 7195add..60cfa7f 100644
--- a/arch/arm/kernel/compat.c
+++ b/arch/arm/kernel/compat.c
@@ -27,6 +27,8 @@
#include <asm/mach/arch.h>
+#include "compat.h"
+
/*
* Usage:
* - do not go blindly adding fields, add them at the end
diff --git a/arch/arm/kernel/compat.h b/arch/arm/kernel/compat.h
new file mode 100644
index 0000000..27e61a6
--- /dev/null
+++ b/arch/arm/kernel/compat.h
@@ -0,0 +1,13 @@
+/*
+ * linux/arch/arm/kernel/compat.h
+ *
+ * Copyright (C) 2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+extern void convert_to_tag_list(struct tag *tags);
+
+extern void squash_mem_tags(struct tag *tag);
diff --git a/arch/arm/kernel/dma-isa.c b/arch/arm/kernel/dma-isa.c
index e9a3630..0353276 100644
--- a/arch/arm/kernel/dma-isa.c
+++ b/arch/arm/kernel/dma-isa.c
@@ -18,7 +18,7 @@
*/
#include <linux/ioport.h>
#include <linux/init.h>
-#include <linux/pci.h>
+#include <linux/dma-mapping.h>
#include <asm/dma.h>
#include <asm/io.h>
@@ -65,37 +65,41 @@ static void isa_enable_dma(dmach_t channel, dma_t *dma)
{
if (dma->invalid) {
unsigned long address, length;
- unsigned int mode, direction;
+ unsigned int mode;
+ enum dma_data_direction direction;
mode = channel & 3;
switch (dma->dma_mode & DMA_MODE_MASK) {
case DMA_MODE_READ:
mode |= ISA_DMA_MODE_READ;
- direction = PCI_DMA_FROMDEVICE;
+ direction = DMA_FROM_DEVICE;
break;
case DMA_MODE_WRITE:
mode |= ISA_DMA_MODE_WRITE;
- direction = PCI_DMA_TODEVICE;
+ direction = DMA_TO_DEVICE;
break;
case DMA_MODE_CASCADE:
mode |= ISA_DMA_MODE_CASCADE;
- direction = PCI_DMA_BIDIRECTIONAL;
+ direction = DMA_BIDIRECTIONAL;
break;
default:
- direction = PCI_DMA_NONE;
+ direction = DMA_NONE;
break;
}
- if (!dma->using_sg) {
+ if (!dma->sg) {
/*
* Cope with ISA-style drivers which expect cache
* coherence.
*/
- dma->buf.dma_address = pci_map_single(NULL,
- dma->buf.__address, dma->buf.length,
+ dma->sg = &dma->buf;
+ dma->sgcount = 1;
+ dma->buf.length = dma->count;
+ dma->buf.dma_address = dma_map_single(NULL,
+ dma->addr, dma->count,
direction);
}
diff --git a/arch/arm/kernel/dma.c b/arch/arm/kernel/dma.c
index 2b78838..5a0f4bc 100644
--- a/arch/arm/kernel/dma.c
+++ b/arch/arm/kernel/dma.c
@@ -12,8 +12,6 @@
* DMA facilities.
*/
#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/mman.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
@@ -23,8 +21,7 @@
#include <asm/mach/dma.h>
DEFINE_SPINLOCK(dma_spin_lock);
-
-#if MAX_DMA_CHANNELS > 0
+EXPORT_SYMBOL(dma_spin_lock);
static dma_t dma_chan[MAX_DMA_CHANNELS];
@@ -81,6 +78,7 @@ bad_dma:
busy:
return -EBUSY;
}
+EXPORT_SYMBOL(request_dma);
/*
* Free DMA channel
@@ -112,6 +110,7 @@ void free_dma(dmach_t channel)
bad_dma:
printk(KERN_ERR "dma: trying to free DMA%d\n", channel);
}
+EXPORT_SYMBOL(free_dma);
/* Set DMA Scatter-Gather list
*/
@@ -125,15 +124,15 @@ void set_dma_sg (dmach_t channel, struct scatterlist *sg, int nr_sg)
dma->sg = sg;
dma->sgcount = nr_sg;
- dma->using_sg = 1;
dma->invalid = 1;
}
+EXPORT_SYMBOL(set_dma_sg);
/* Set DMA address
*
* Copy address to the structure, and set the invalid bit
*/
-void set_dma_addr (dmach_t channel, unsigned long physaddr)
+void __set_dma_addr (dmach_t channel, void *addr)
{
dma_t *dma = dma_chan + channel;
@@ -141,12 +140,11 @@ void set_dma_addr (dmach_t channel, unsigned long physaddr)
printk(KERN_ERR "dma%d: altering DMA address while "
"DMA active\n", channel);
- dma->sg = &dma->buf;
- dma->sgcount = 1;
- dma->buf.__address = bus_to_virt(physaddr);
- dma->using_sg = 0;
+ dma->sg = NULL;
+ dma->addr = addr;
dma->invalid = 1;
}
+EXPORT_SYMBOL(__set_dma_addr);
/* Set DMA byte count
*
@@ -160,12 +158,11 @@ void set_dma_count (dmach_t channel, unsigned long count)
printk(KERN_ERR "dma%d: altering DMA count while "
"DMA active\n", channel);
- dma->sg = &dma->buf;
- dma->sgcount = 1;
- dma->buf.length = count;
- dma->using_sg = 0;
+ dma->sg = NULL;
+ dma->count = count;
dma->invalid = 1;
}
+EXPORT_SYMBOL(set_dma_count);
/* Set DMA direction mode
*/
@@ -180,6 +177,7 @@ void set_dma_mode (dmach_t channel, dmamode_t mode)
dma->dma_mode = mode;
dma->invalid = 1;
}
+EXPORT_SYMBOL(set_dma_mode);
/* Enable DMA channel
*/
@@ -200,6 +198,7 @@ free_dma:
printk(KERN_ERR "dma%d: trying to enable free DMA\n", channel);
BUG();
}
+EXPORT_SYMBOL(enable_dma);
/* Disable DMA channel
*/
@@ -220,6 +219,7 @@ free_dma:
printk(KERN_ERR "dma%d: trying to disable free DMA\n", channel);
BUG();
}
+EXPORT_SYMBOL(disable_dma);
/*
* Is the specified DMA channel active?
@@ -233,6 +233,7 @@ void set_dma_page(dmach_t channel, char pagenr)
{
printk(KERN_ERR "dma%d: trying to set_dma_page\n", channel);
}
+EXPORT_SYMBOL(set_dma_page);
void set_dma_speed(dmach_t channel, int cycle_ns)
{
@@ -243,6 +244,7 @@ void set_dma_speed(dmach_t channel, int cycle_ns)
ret = dma->d_ops->setspeed(channel, dma, cycle_ns);
dma->speed = ret;
}
+EXPORT_SYMBOL(set_dma_speed);
int get_dma_residue(dmach_t channel)
{
@@ -254,49 +256,12 @@ int get_dma_residue(dmach_t channel)
return ret;
}
+EXPORT_SYMBOL(get_dma_residue);
-void __init init_dma(void)
+static int __init init_dma(void)
{
arch_dma_init(dma_chan);
-}
-
-#else
-
-int request_dma(dmach_t channel, const char *device_id)
-{
- return -EINVAL;
-}
-
-int get_dma_residue(dmach_t channel)
-{
return 0;
}
-#define GLOBAL_ALIAS(_a,_b) asm (".set " #_a "," #_b "; .globl " #_a)
-GLOBAL_ALIAS(disable_dma, get_dma_residue);
-GLOBAL_ALIAS(enable_dma, get_dma_residue);
-GLOBAL_ALIAS(free_dma, get_dma_residue);
-GLOBAL_ALIAS(get_dma_list, get_dma_residue);
-GLOBAL_ALIAS(set_dma_mode, get_dma_residue);
-GLOBAL_ALIAS(set_dma_page, get_dma_residue);
-GLOBAL_ALIAS(set_dma_count, get_dma_residue);
-GLOBAL_ALIAS(set_dma_addr, get_dma_residue);
-GLOBAL_ALIAS(set_dma_sg, get_dma_residue);
-GLOBAL_ALIAS(set_dma_speed, get_dma_residue);
-GLOBAL_ALIAS(init_dma, get_dma_residue);
-
-#endif
-
-EXPORT_SYMBOL(request_dma);
-EXPORT_SYMBOL(free_dma);
-EXPORT_SYMBOL(enable_dma);
-EXPORT_SYMBOL(disable_dma);
-EXPORT_SYMBOL(set_dma_addr);
-EXPORT_SYMBOL(set_dma_count);
-EXPORT_SYMBOL(set_dma_mode);
-EXPORT_SYMBOL(set_dma_page);
-EXPORT_SYMBOL(get_dma_residue);
-EXPORT_SYMBOL(set_dma_sg);
-EXPORT_SYMBOL(set_dma_speed);
-
-EXPORT_SYMBOL(dma_spin_lock);
+core_initcall(init_dma);
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
index dceb826..74ea29c 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -40,6 +40,7 @@
#include <linux/proc_fs.h>
#include <linux/device.h>
#include <linux/init.h>
+#include <linux/mutex.h>
#include <asm/dma.h>
#include <asm/ecard.h>
@@ -206,7 +207,7 @@ static void ecard_task_readbytes(struct ecard_request *req)
static DECLARE_WAIT_QUEUE_HEAD(ecard_wait);
static struct ecard_request *ecard_req;
-static DECLARE_MUTEX(ecard_sem);
+static DEFINE_MUTEX(ecard_mutex);
/*
* Set up the expansion card daemon's page tables.
@@ -299,7 +300,7 @@ static void ecard_call(struct ecard_request *req)
req->complete = &completion;
- down(&ecard_sem);
+ mutex_lock(&ecard_mutex);
ecard_req = req;
wake_up(&ecard_wait);
@@ -307,7 +308,7 @@ static void ecard_call(struct ecard_request *req)
* Now wait for kecardd to run.
*/
wait_for_completion(&completion);
- up(&ecard_sem);
+ mutex_unlock(&ecard_mutex);
}
/* ======================= Mid-level card control ===================== */
@@ -1146,9 +1147,11 @@ static void ecard_drv_shutdown(struct device *dev)
struct ecard_driver *drv = ECARD_DRV(dev->driver);
struct ecard_request req;
- if (drv->shutdown)
- drv->shutdown(ec);
- ecard_release(ec);
+ if (dev->driver) {
+ if (drv->shutdown)
+ drv->shutdown(ec);
+ ecard_release(ec);
+ }
/*
* If this card has a loader, call the reset handler.
@@ -1163,9 +1166,6 @@ static void ecard_drv_shutdown(struct device *dev)
int ecard_register_driver(struct ecard_driver *drv)
{
drv->drv.bus = &ecard_bus_type;
- drv->drv.probe = ecard_drv_probe;
- drv->drv.remove = ecard_drv_remove;
- drv->drv.shutdown = ecard_drv_shutdown;
return driver_register(&drv->drv);
}
@@ -1194,6 +1194,9 @@ struct bus_type ecard_bus_type = {
.name = "ecard",
.dev_attrs = ecard_dev_attrs,
.match = ecard_match,
+ .probe = ecard_drv_probe,
+ .remove = ecard_drv_remove,
+ .shutdown = ecard_drv_shutdown,
};
static int ecard_bus_init(void)
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 2a8d27e..ec48d70 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -3,6 +3,7 @@
*
* Copyright (C) 1996,1997,1998 Russell King.
* ARM700 fix by Matthew Godbolt (linux-user@willothewisp.demon.co.uk)
+ * nommu support by Hyok S. Choi (hyok.choi@samsung.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -18,8 +19,6 @@
#include <asm/memory.h>
#include <asm/glue.h>
#include <asm/vfpmacros.h>
-#include <asm/hardware.h> /* should be moved into entry-macro.S */
-#include <asm/arch/irqs.h> /* should be moved into entry-macro.S */
#include <asm/arch/entry-macro.S>
#include "entry-header.S"
@@ -106,14 +105,24 @@ common_invalid:
/*
* SVC mode handlers
*/
+
+#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5)
+#define SPFIX(code...) code
+#else
+#define SPFIX(code...)
+#endif
+
.macro svc_entry
sub sp, sp, #S_FRAME_SIZE
+ SPFIX( tst sp, #4 )
+ SPFIX( bicne sp, sp, #4 )
stmib sp, {r1 - r12}
ldmia r0, {r1 - r3}
add r5, sp, #S_SP @ here for interlock avoidance
mov r4, #-1 @ "" "" "" ""
add r0, sp, #S_FRAME_SIZE @ "" "" "" ""
+ SPFIX( addne r0, r0, #4 )
str r1, [sp] @ save the "real" r0 copied
@ from the exception stack
@@ -304,7 +313,14 @@ __pabt_svc:
/*
* User mode handlers
+ *
+ * EABI note: sp_svc is always 64-bit aligned here, so should S_FRAME_SIZE
*/
+
+#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5) && (S_FRAME_SIZE & 7)
+#error "sizeof(struct pt_regs) must be a multiple of 8"
+#endif
+
.macro usr_entry
sub sp, sp, #S_FRAME_SIZE
stmib sp, {r1 - r12}
@@ -317,10 +333,14 @@ __pabt_svc:
@ from the exception stack
#if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
+#ifndef CONFIG_MMU
+#warning "NPTL on non MMU needs fixing"
+#else
@ make sure our user space atomic helper is aborted
cmp r2, #TASK_SIZE
bichs r3, r3, #PSR_Z_BIT
#endif
+#endif
@
@ We are now ready to fill in the remaining blanks on the stack:
@@ -540,9 +560,13 @@ ENTRY(__switch_to)
add ip, r1, #TI_CPU_SAVE
ldr r3, [r2, #TI_TP_VALUE]
stmia ip!, {r4 - sl, fp, sp, lr} @ Store most regs on stack
+#ifndef CONFIG_MMU
+ add r2, r2, #TI_CPU_DOMAIN
+#else
ldr r6, [r2, #TI_CPU_DOMAIN]!
+#endif
#if __LINUX_ARM_ARCH__ >= 6
-#ifdef CONFIG_CPU_MPCORE
+#ifdef CONFIG_CPU_32v6K
clrex
#else
strex r5, r4, [ip] @ Clear exclusive monitor
@@ -558,7 +582,9 @@ ENTRY(__switch_to)
mov r4, #0xffff0fff
str r3, [r4, #-15] @ TLS val at 0xffff0ff0
#endif
+#ifdef CONFIG_MMU
mcr p15, 0, r6, c3, c0, 0 @ Set domain register
+#endif
#ifdef CONFIG_VFP
@ Always disable VFP so we can lazily save/restore the old
@ state. This occurs in the context of the previous thread.
@@ -683,7 +709,12 @@ __kuser_memory_barrier: @ 0xffff0fa0
* The C flag is also set if *ptr was changed to allow for assembly
* optimization in the calling code.
*
- * Note: this routine already includes memory barriers as needed.
+ * Notes:
+ *
+ * - This routine already includes memory barriers as needed.
+ *
+ * - A failure might be transient, i.e. it is possible, although unlikely,
+ * that "failure" be returned even if *ptr == oldval.
*
* For example, a user space atomic_add implementation could look like this:
*
@@ -713,8 +744,11 @@ __kuser_cmpxchg: @ 0xffff0fc0
* The kernel itself must perform the operation.
* A special ghost syscall is used for that (see traps.c).
*/
+ stmfd sp!, {r7, lr}
+ mov r7, #0xff00 @ 0xfff0 into r7 for EABI
+ orr r7, r7, #0xf0
swi #0x9ffff0
- mov pc, lr
+ ldmfd sp!, {r7, pc}
#elif __LINUX_ARM_ARCH__ < 6
@@ -731,12 +765,18 @@ __kuser_cmpxchg: @ 0xffff0fc0
* exception happening just after the str instruction which would
* clear the Z flag although the exchange was done.
*/
+#ifdef CONFIG_MMU
teq ip, ip @ set Z flag
ldr ip, [r2] @ load current val
add r3, r2, #1 @ prepare store ptr
teqeq ip, r0 @ compare with oldval if still allowed
streq r1, [r3, #-1]! @ store newval if still allowed
subs r0, r2, r3 @ if r2 == r3 the str occured
+#else
+#warning "NPTL on non MMU needs fixing"
+ mov r0, #-1
+ adds r0, r0, #0
+#endif
mov pc, lr
#else
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index e2b4299..dbcb11a 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -87,7 +87,11 @@ ENTRY(ret_from_fork)
b ret_slow_syscall
+ .equ NR_syscalls,0
+#define CALL(x) .equ NR_syscalls,NR_syscalls+1
#include "calls.S"
+#undef CALL
+#define CALL(x) .long x
/*=============================================================================
* SWI handler
@@ -98,20 +102,14 @@ ENTRY(ret_from_fork)
run on an ARM7 and we can save a couple of instructions.
--pb */
#ifdef CONFIG_CPU_ARM710
- .macro arm710_bug_check, instr, temp
- and \temp, \instr, #0x0f000000 @ check for SWI
- teq \temp, #0x0f000000
- bne .Larm700bug
- .endm
-
-.Larm700bug:
+#define A710(code...) code
+.Larm710bug:
ldmia sp, {r0 - lr}^ @ Get calling r0 - lr
mov r0, r0
add sp, sp, #S_FRAME_SIZE
subs pc, lr, #4
#else
- .macro arm710_bug_check, instr, temp
- .endm
+#define A710(code...)
#endif
.align 5
@@ -129,14 +127,50 @@ ENTRY(vector_swi)
/*
* Get the system call number.
*/
+
+#if defined(CONFIG_OABI_COMPAT)
+
+ /*
+ * If we have CONFIG_OABI_COMPAT then we need to look at the swi
+ * value to determine if it is an EABI or an old ABI call.
+ */
#ifdef CONFIG_ARM_THUMB
+ tst r8, #PSR_T_BIT
+ movne r10, #0 @ no thumb OABI emulation
+ ldreq r10, [lr, #-4] @ get SWI instruction
+#else
+ ldr r10, [lr, #-4] @ get SWI instruction
+ A710( and ip, r10, #0x0f000000 @ check for SWI )
+ A710( teq ip, #0x0f000000 )
+ A710( bne .Larm710bug )
+#endif
+
+#elif defined(CONFIG_AEABI)
+
+ /*
+ * Pure EABI user space always put syscall number into scno (r7).
+ */
+ A710( ldr ip, [lr, #-4] @ get SWI instruction )
+ A710( and ip, ip, #0x0f000000 @ check for SWI )
+ A710( teq ip, #0x0f000000 )
+ A710( bne .Larm710bug )
+
+#elif defined(CONFIG_ARM_THUMB)
+
+ /* Legacy ABI only, possibly thumb mode. */
tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs
addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in
ldreq scno, [lr, #-4]
+
#else
+
+ /* Legacy ABI only. */
ldr scno, [lr, #-4] @ get SWI instruction
+ A710( and ip, scno, #0x0f000000 @ check for SWI )
+ A710( teq ip, #0x0f000000 )
+ A710( bne .Larm710bug )
+
#endif
- arm710_bug_check scno, ip
#ifdef CONFIG_ALIGNMENT_TRAP
ldr ip, __cr_alignment
@@ -145,18 +179,31 @@ ENTRY(vector_swi)
#endif
enable_irq
- stmdb sp!, {r4, r5} @ push fifth and sixth args
-
get_thread_info tsk
+ adr tbl, sys_call_table @ load syscall table pointer
ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing
+
+#if defined(CONFIG_OABI_COMPAT)
+ /*
+ * If the swi argument is zero, this is an EABI call and we do nothing.
+ *
+ * If this is an old ABI call, get the syscall number into scno and
+ * get the old ABI syscall table address.
+ */
+ bics r10, r10, #0xff000000
+ eorne scno, r10, #__NR_OABI_SYSCALL_BASE
+ ldrne tbl, =sys_oabi_call_table
+#elif !defined(CONFIG_AEABI)
bic scno, scno, #0xff000000 @ mask off SWI op-code
eor scno, scno, #__NR_SYSCALL_BASE @ check OS number
- adr tbl, sys_call_table @ load syscall table pointer
+#endif
+
+ stmdb sp!, {r4, r5} @ push fifth and sixth args
tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
bne __sys_trace
- adr lr, ret_fast_syscall @ return address
cmp scno, #NR_syscalls @ check upper syscall limit
+ adr lr, ret_fast_syscall @ return address
ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine
add r1, sp, #S_OFF
@@ -171,11 +218,13 @@ ENTRY(vector_swi)
* context switches, and waiting for our parent to respond.
*/
__sys_trace:
+ mov r2, scno
add r1, sp, #S_OFF
mov r0, #0 @ trace entry [IP = 0]
bl syscall_trace
adr lr, __sys_trace_return @ return address
+ mov scno, r0 @ syscall number (possibly new)
add r1, sp, #S_R0 + S_OFF @ pointer to regs
cmp scno, #NR_syscalls @ check upper syscall limit
ldmccia r1, {r0 - r3} @ have to reload r0 - r3
@@ -184,6 +233,7 @@ __sys_trace:
__sys_trace_return:
str r0, [sp, #S_R0 + S_OFF]! @ save returned r0
+ mov r2, scno
mov r1, sp
mov r0, #1 @ trace exit [IP = 1]
bl syscall_trace
@@ -195,10 +245,24 @@ __sys_trace_return:
__cr_alignment:
.word cr_alignment
#endif
+ .ltorg
+
+/*
+ * This is the syscall table declaration for native ABI syscalls.
+ * With EABI a couple syscalls are obsolete and defined as sys_ni_syscall.
+ */
+#define ABI(native, compat) native
+#ifdef CONFIG_AEABI
+#define OBSOLETE(syscall) sys_ni_syscall
+#else
+#define OBSOLETE(syscall) syscall
+#endif
.type sys_call_table, #object
ENTRY(sys_call_table)
#include "calls.S"
+#undef ABI
+#undef OBSOLETE
/*============================================================================
* Special system call wrappers
@@ -207,7 +271,7 @@ ENTRY(sys_call_table)
@ r8 = syscall table
.type sys_syscall, #function
sys_syscall:
- eor scno, r0, #__NR_SYSCALL_BASE
+ eor scno, r0, #__NR_OABI_SYSCALL_BASE
cmp scno, #__NR_syscall - __NR_SYSCALL_BASE
cmpne scno, #NR_syscalls @ check range
stmloia sp, {r5, r6} @ shuffle args
@@ -255,6 +319,16 @@ sys_sigaltstack_wrapper:
ldr r2, [sp, #S_OFF + S_SP]
b do_sigaltstack
+sys_statfs64_wrapper:
+ teq r1, #88
+ moveq r1, #84
+ b sys_statfs64
+
+sys_fstatfs64_wrapper:
+ teq r1, #88
+ moveq r1, #84
+ b sys_fstatfs64
+
/*
* Note: off_4k (r5) is always units of 4K. If we can't do the requested
* offset, we return EINVAL.
@@ -271,3 +345,49 @@ sys_mmap2:
str r5, [sp, #4]
b do_mmap2
#endif
+
+#ifdef CONFIG_OABI_COMPAT
+
+/*
+ * These are syscalls with argument register differences
+ */
+
+sys_oabi_pread64:
+ stmia sp, {r3, r4}
+ b sys_pread64
+
+sys_oabi_pwrite64:
+ stmia sp, {r3, r4}
+ b sys_pwrite64
+
+sys_oabi_truncate64:
+ mov r3, r2
+ mov r2, r1
+ b sys_truncate64
+
+sys_oabi_ftruncate64:
+ mov r3, r2
+ mov r2, r1
+ b sys_ftruncate64
+
+sys_oabi_readahead:
+ str r3, [sp]
+ mov r3, r2
+ mov r2, r1
+ b sys_readahead
+
+/*
+ * Let's declare a second syscall table for old ABI binaries
+ * using the compatibility syscall entries.
+ */
+#define ABI(native, compat) compat
+#define OBSOLETE(syscall) syscall
+
+ .type sys_oabi_call_table, #object
+ENTRY(sys_oabi_call_table)
+#include "calls.S"
+#undef ABI
+#undef OBSOLETE
+
+#endif
+
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index 648cfff..55c99cd 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -19,6 +19,7 @@
@
@ Most of the stack format comes from struct pt_regs, but with
@ the addition of 8 bytes for storing syscall args 5 and 6.
+@ This _must_ remain a multiple of 8 for EABI.
@
#define S_OFF 8
diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
index 9299dfc..1ec3f7f 100644
--- a/arch/arm/kernel/fiq.c
+++ b/arch/arm/kernel/fiq.c
@@ -101,7 +101,7 @@ void __attribute__((naked)) set_fiq_regs(struct pt_regs *regs)
ldmia %1, {r8 - r14}\n\
msr cpsr_c, %0 @ return to SVC mode\n\
mov r0, r0\n\
- ldmea fp, {fp, sp, pc}"
+ ldmfd sp, {fp, sp, pc}"
: "=&r" (tmp)
: "r" (&regs->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | FIQ_MODE));
}
@@ -119,7 +119,7 @@ void __attribute__((naked)) get_fiq_regs(struct pt_regs *regs)
stmia %1, {r8 - r14}\n\
msr cpsr_c, %0 @ return to SVC mode\n\
mov r0, r0\n\
- ldmea fp, {fp, sp, pc}"
+ ldmfd sp, {fp, sp, pc}"
: "=&r" (tmp)
: "r" (&regs->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | FIQ_MODE));
}
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index d7d69fd..1aca1775 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -33,6 +33,8 @@
#define MACHINFO_PGOFFIO 12
#define MACHINFO_NAME 16
+#define KERNEL_RAM_ADDR (PAGE_OFFSET + TEXT_OFFSET)
+
/*
* swapper_pg_dir is the virtual address of the initial page table.
* We place the page tables 16K below KERNEL_RAM_ADDR. Therefore, we must
@@ -249,12 +251,11 @@ __turn_mmu_on:
* r10 = procinfo
*
* Returns:
- * r0, r3, r5, r6, r7 corrupted
+ * r0, r3, r6, r7 corrupted
* r4 = physical page table address
*/
.type __create_page_tables, %function
__create_page_tables:
- ldr r5, [r8, #MACHINFO_PHYSRAM] @ physram
pgtbl r4 @ page table address
/*
@@ -301,7 +302,7 @@ __create_page_tables:
* Then map first 1MB of ram in case it contains our boot params.
*/
add r0, r4, #PAGE_OFFSET >> 18
- orr r6, r5, r7
+ orr r6, r7, #PHYS_OFFSET
str r6, [r0]
#ifdef CONFIG_XIP_KERNEL
@@ -309,7 +310,7 @@ __create_page_tables:
* Map some ram to cover our .data and .bss areas.
* Mapping 3MB should be plenty.
*/
- sub r3, r4, r5
+ sub r3, r4, #PHYS_OFFSET
mov r3, r3, lsr #20
add r0, r0, r3, lsl #2
add r6, r6, r3, lsl #20
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index d7099db..1d50d2b 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -684,8 +684,12 @@ int setup_irq(unsigned int irq, struct irqaction *new)
spin_lock_irqsave(&irq_controller_lock, flags);
p = &desc->action;
if ((old = *p) != NULL) {
- /* Can't share interrupts unless both agree to */
- if (!(old->flags & new->flags & SA_SHIRQ)) {
+ /*
+ * Can't share interrupts unless both agree to and are
+ * the same type.
+ */
+ if (!(old->flags & new->flags & SA_SHIRQ) ||
+ (~old->flags & new->flags) & SA_TRIGGER_MASK) {
spin_unlock_irqrestore(&irq_controller_lock, flags);
return -EBUSY;
}
@@ -705,6 +709,13 @@ int setup_irq(unsigned int irq, struct irqaction *new)
desc->running = 0;
desc->pending = 0;
desc->disable_depth = 1;
+
+ if (new->flags & SA_TRIGGER_MASK &&
+ desc->chip->set_type) {
+ unsigned int type = new->flags & SA_TRIGGER_MASK;
+ desc->chip->set_type(irq, type);
+ }
+
if (!desc->noautoenable) {
desc->disable_depth = 0;
desc->chip->unmask(irq);
@@ -1027,7 +1038,6 @@ void __init init_irq_proc(void)
void __init init_IRQ(void)
{
struct irqdesc *desc;
- extern void init_dma(void);
int irq;
#ifdef CONFIG_SMP
@@ -1041,7 +1051,6 @@ void __init init_IRQ(void)
}
init_arch_irq();
- init_dma();
}
static int __init noirqdebug_setup(char *str)
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 30494aa..489c069 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -27,11 +27,11 @@
#include <linux/kallsyms.h>
#include <linux/init.h>
#include <linux/cpu.h>
+#include <linux/elfcore.h>
-#include <asm/system.h>
-#include <asm/io.h>
#include <asm/leds.h>
#include <asm/processor.h>
+#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/mach/time.h>
@@ -84,7 +84,7 @@ EXPORT_SYMBOL(pm_power_off);
* This is our default idle handler. We need to disable
* interrupts here to ensure we don't miss a wakeup call.
*/
-void default_idle(void)
+static void default_idle(void)
{
if (hlt_counter)
cpu_relax();
@@ -343,10 +343,10 @@ void flush_thread(void)
void release_thread(struct task_struct *dead_task)
{
#if defined(CONFIG_VFP)
- vfp_release_thread(&dead_task->thread_info->vfpstate);
+ vfp_release_thread(&task_thread_info(dead_task)->vfpstate);
#endif
#if defined(CONFIG_IWMMXT)
- iwmmxt_task_release(dead_task->thread_info);
+ iwmmxt_task_release(task_thread_info(dead_task));
#endif
}
@@ -356,10 +356,9 @@ int
copy_thread(int nr, unsigned long clone_flags, unsigned long stack_start,
unsigned long stk_sz, struct task_struct *p, struct pt_regs *regs)
{
- struct thread_info *thread = p->thread_info;
- struct pt_regs *childregs;
+ struct thread_info *thread = task_thread_info(p);
+ struct pt_regs *childregs = task_pt_regs(p);
- childregs = (void *)thread + THREAD_START_SP - sizeof(*regs);
*childregs = *regs;
childregs->ARM_r0 = 0;
childregs->ARM_sp = stack_start;
@@ -461,8 +460,8 @@ unsigned long get_wchan(struct task_struct *p)
if (!p || p == current || p->state == TASK_RUNNING)
return 0;
- stack_start = (unsigned long)(p->thread_info + 1);
- stack_end = ((unsigned long)p->thread_info) + THREAD_SIZE;
+ stack_start = (unsigned long)end_of_stack(p);
+ stack_end = (unsigned long)task_stack_page(p) + THREAD_SIZE;
fp = thread_saved_fp(p);
do {
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 2b84f78..a1d1b29 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -55,23 +55,6 @@
#endif
/*
- * Get the address of the live pt_regs for the specified task.
- * These are saved onto the top kernel stack when the process
- * is not running.
- *
- * Note: if a user thread is execve'd from kernel space, the
- * kernel stack will not be empty on entry to the kernel, so
- * ptracing these tasks will fail.
- */
-static inline struct pt_regs *
-get_user_regs(struct task_struct *task)
-{
- return (struct pt_regs *)
- ((unsigned long)task->thread_info + THREAD_SIZE -
- 8 - sizeof(struct pt_regs));
-}
-
-/*
* this routine will get a word off of the processes privileged stack.
* the offset is how far from the base addr as stored in the THREAD.
* this routine assumes that all the privileged stacks are in our
@@ -79,7 +62,7 @@ get_user_regs(struct task_struct *task)
*/
static inline long get_user_reg(struct task_struct *task, int offset)
{
- return get_user_regs(task)->uregs[offset];
+ return task_pt_regs(task)->uregs[offset];
}
/*
@@ -91,7 +74,7 @@ static inline long get_user_reg(struct task_struct *task, int offset)
static inline int
put_user_reg(struct task_struct *task, int offset, long data)
{
- struct pt_regs newregs, *regs = get_user_regs(task);
+ struct pt_regs newregs, *regs = task_pt_regs(task);
int ret = -EINVAL;
newregs = *regs;
@@ -421,7 +404,7 @@ void ptrace_set_bpt(struct task_struct *child)
u32 insn;
int res;
- regs = get_user_regs(child);
+ regs = task_pt_regs(child);
pc = instruction_pointer(regs);
if (thumb_mode(regs)) {
@@ -572,7 +555,7 @@ static int ptrace_write_user(struct task_struct *tsk, unsigned long off,
*/
static int ptrace_getregs(struct task_struct *tsk, void __user *uregs)
{
- struct pt_regs *regs = get_user_regs(tsk);
+ struct pt_regs *regs = task_pt_regs(tsk);
return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0;
}
@@ -587,7 +570,7 @@ static int ptrace_setregs(struct task_struct *tsk, void __user *uregs)
ret = -EFAULT;
if (copy_from_user(&newregs, uregs, sizeof(struct pt_regs)) == 0) {
- struct pt_regs *regs = get_user_regs(tsk);
+ struct pt_regs *regs = task_pt_regs(tsk);
ret = -EINVAL;
if (valid_user_regs(&newregs)) {
@@ -604,7 +587,7 @@ static int ptrace_setregs(struct task_struct *tsk, void __user *uregs)
*/
static int ptrace_getfpregs(struct task_struct *tsk, void __user *ufp)
{
- return copy_to_user(ufp, &tsk->thread_info->fpstate,
+ return copy_to_user(ufp, &task_thread_info(tsk)->fpstate,
sizeof(struct user_fp)) ? -EFAULT : 0;
}
@@ -613,7 +596,7 @@ static int ptrace_getfpregs(struct task_struct *tsk, void __user *ufp)
*/
static int ptrace_setfpregs(struct task_struct *tsk, void __user *ufp)
{
- struct thread_info *thread = tsk->thread_info;
+ struct thread_info *thread = task_thread_info(tsk);
thread->used_cp[1] = thread->used_cp[2] = 1;
return copy_from_user(&thread->fpstate, ufp,
sizeof(struct user_fp)) ? -EFAULT : 0;
@@ -626,16 +609,13 @@ static int ptrace_setfpregs(struct task_struct *tsk, void __user *ufp)
*/
static int ptrace_getwmmxregs(struct task_struct *tsk, void __user *ufp)
{
- struct thread_info *thread = tsk->thread_info;
- void *ptr = &thread->fpstate;
+ struct thread_info *thread = task_thread_info(tsk);
if (!test_ti_thread_flag(thread, TIF_USING_IWMMXT))
return -ENODATA;
iwmmxt_task_disable(thread); /* force it to ram */
- /* The iWMMXt state is stored doubleword-aligned. */
- if (((long) ptr) & 4)
- ptr += 4;
- return copy_to_user(ufp, ptr, 0x98) ? -EFAULT : 0;
+ return copy_to_user(ufp, &thread->fpstate.iwmmxt, IWMMXT_SIZE)
+ ? -EFAULT : 0;
}
/*
@@ -643,16 +623,13 @@ static int ptrace_getwmmxregs(struct task_struct *tsk, void __user *ufp)
*/
static int ptrace_setwmmxregs(struct task_struct *tsk, void __user *ufp)
{
- struct thread_info *thread = tsk->thread_info;
- void *ptr = &thread->fpstate;
+ struct thread_info *thread = task_thread_info(tsk);
if (!test_ti_thread_flag(thread, TIF_USING_IWMMXT))
return -EACCES;
iwmmxt_task_release(thread); /* force a reload */
- /* The iWMMXt state is stored doubleword-aligned. */
- if (((long) ptr) & 4)
- ptr += 4;
- return copy_from_user(ptr, ufp, 0x98) ? -EFAULT : 0;
+ return copy_from_user(&thread->fpstate.iwmmxt, ufp, IWMMXT_SIZE)
+ ? -EFAULT : 0;
}
#endif
@@ -779,10 +756,15 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
#endif
case PTRACE_GET_THREAD_AREA:
- ret = put_user(child->thread_info->tp_value,
+ ret = put_user(task_thread_info(child)->tp_value,
(unsigned long __user *) data);
break;
+ case PTRACE_SET_SYSCALL:
+ ret = 0;
+ child->ptrace_message = data;
+ break;
+
default:
ret = ptrace_request(child, request, addr, data);
break;
@@ -791,14 +773,14 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
return ret;
}
-asmlinkage void syscall_trace(int why, struct pt_regs *regs)
+asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
{
unsigned long ip;
if (!test_thread_flag(TIF_SYSCALL_TRACE))
- return;
+ return scno;
if (!(current->ptrace & PT_PTRACED))
- return;
+ return scno;
/*
* Save IP. IP is used to denote syscall entry/exit:
@@ -807,6 +789,8 @@ asmlinkage void syscall_trace(int why, struct pt_regs *regs)
ip = regs->ARM_ip;
regs->ARM_ip = why;
+ current->ptrace_message = scno;
+
/* the 0x80 provides a way for the tracing parent to distinguish
between a syscall stop and SIGTRAP delivery */
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
@@ -821,4 +805,6 @@ asmlinkage void syscall_trace(int why, struct pt_regs *regs)
current->exit_code = 0;
}
regs->ARM_ip = ip;
+
+ return current->ptrace_message;
}
diff --git a/arch/arm/kernel/semaphore.c b/arch/arm/kernel/semaphore.c
index 4c31f29..981fe5c 100644
--- a/arch/arm/kernel/semaphore.c
+++ b/arch/arm/kernel/semaphore.c
@@ -177,41 +177,42 @@ int __down_trylock(struct semaphore * sem)
* ip contains the semaphore pointer on entry. Save the C-clobbered
* registers (r0 to r3 and lr), but not ip, as we use it as a return
* value in some cases..
+ * To remain AAPCS compliant (64-bit stack align) we save r4 as well.
*/
asm(" .section .sched.text,\"ax\",%progbits \n\
.align 5 \n\
.globl __down_failed \n\
__down_failed: \n\
- stmfd sp!, {r0 - r3, lr} \n\
+ stmfd sp!, {r0 - r4, lr} \n\
mov r0, ip \n\
bl __down \n\
- ldmfd sp!, {r0 - r3, pc} \n\
+ ldmfd sp!, {r0 - r4, pc} \n\
\n\
.align 5 \n\
.globl __down_interruptible_failed \n\
__down_interruptible_failed: \n\
- stmfd sp!, {r0 - r3, lr} \n\
+ stmfd sp!, {r0 - r4, lr} \n\
mov r0, ip \n\
bl __down_interruptible \n\
mov ip, r0 \n\
- ldmfd sp!, {r0 - r3, pc} \n\
+ ldmfd sp!, {r0 - r4, pc} \n\
\n\
.align 5 \n\
.globl __down_trylock_failed \n\
__down_trylock_failed: \n\
- stmfd sp!, {r0 - r3, lr} \n\
+ stmfd sp!, {r0 - r4, lr} \n\
mov r0, ip \n\
bl __down_trylock \n\
mov ip, r0 \n\
- ldmfd sp!, {r0 - r3, pc} \n\
+ ldmfd sp!, {r0 - r4, pc} \n\
\n\
.align 5 \n\
.globl __up_wakeup \n\
__up_wakeup: \n\
- stmfd sp!, {r0 - r3, lr} \n\
+ stmfd sp!, {r0 - r4, lr} \n\
mov r0, ip \n\
bl __up \n\
- ldmfd sp!, {r0 - r3, pc} \n\
+ ldmfd sp!, {r0 - r4, pc} \n\
");
EXPORT_SYMBOL(__down_failed);
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 8577416..08974cb 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -23,11 +23,10 @@
#include <linux/root_dev.h>
#include <linux/cpu.h>
#include <linux/interrupt.h>
+#include <linux/smp.h>
#include <asm/cpu.h>
#include <asm/elf.h>
-#include <asm/hardware.h>
-#include <asm/io.h>
#include <asm/procinfo.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
@@ -38,6 +37,8 @@
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
+#include "compat.h"
+
#ifndef MEM_SIZE
#define MEM_SIZE (16*1024*1024)
#endif
@@ -54,10 +55,7 @@ static int __init fpe_setup(char *line)
__setup("fpe=", fpe_setup);
#endif
-extern unsigned int mem_fclk_21285;
extern void paging_init(struct meminfo *, struct machine_desc *desc);
-extern void convert_to_tag_list(struct tag *tags);
-extern void squash_mem_tags(struct tag *tag);
extern void reboot_setup(char *str);
extern int root_mountflags;
extern void _stext, _text, _etext, __data_start, _edata, _end;
@@ -207,7 +205,7 @@ static const char *proc_arch[] = {
"5TE",
"5TEJ",
"6TEJ",
- "?(10)",
+ "7",
"?(11)",
"?(12)",
"?(13)",
@@ -260,14 +258,17 @@ int cpu_architecture(void)
{
int cpu_arch;
- if ((processor_id & 0x0000f000) == 0) {
+ if ((processor_id & 0x0008f000) == 0) {
cpu_arch = CPU_ARCH_UNKNOWN;
- } else if ((processor_id & 0x0000f000) == 0x00007000) {
+ } else if ((processor_id & 0x0008f000) == 0x00007000) {
cpu_arch = (processor_id & (1 << 23)) ? CPU_ARCH_ARMv4T : CPU_ARCH_ARMv3;
- } else {
+ } else if ((processor_id & 0x00080000) == 0x00000000) {
cpu_arch = (processor_id >> 16) & 7;
if (cpu_arch)
cpu_arch += CPU_ARCH_ARMv3;
+ } else {
+ /* the revised CPUID */
+ cpu_arch = ((processor_id >> 12) & 0xf) - 0xb + CPU_ARCH_ARMv6;
}
return cpu_arch;
@@ -770,6 +771,10 @@ void __init setup_arch(char **cmdline_p)
paging_init(&meminfo, mdesc);
request_standard_resources(&meminfo, mdesc);
+#ifdef CONFIG_SMP
+ smp_init_cpus();
+#endif
+
cpu_init();
/*
@@ -865,11 +870,11 @@ static int c_show(struct seq_file *m, void *v)
seq_printf(m, "\nCPU implementer\t: 0x%02x\n", processor_id >> 24);
seq_printf(m, "CPU architecture: %s\n", proc_arch[cpu_architecture()]);
- if ((processor_id & 0x0000f000) == 0x00000000) {
+ if ((processor_id & 0x0008f000) == 0x00000000) {
/* pre-ARM7 */
seq_printf(m, "CPU part\t\t: %07x\n", processor_id >> 4);
} else {
- if ((processor_id & 0x0000f000) == 0x00007000) {
+ if ((processor_id & 0x0008f000) == 0x00007000) {
/* ARM7 */
seq_printf(m, "CPU variant\t: 0x%02x\n",
(processor_id >> 16) & 127);
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 765922b..a0cd0a9 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -30,15 +30,21 @@
#define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn))
/*
+ * With EABI, the syscall number has to be loaded into r7.
+ */
+#define MOV_R7_NR_SIGRETURN (0xe3a07000 | (__NR_sigreturn - __NR_SYSCALL_BASE))
+#define MOV_R7_NR_RT_SIGRETURN (0xe3a07000 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE))
+
+/*
* For Thumb syscalls, we pass the syscall number via r7. We therefore
* need two 16-bit instructions.
*/
#define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_sigreturn - __NR_SYSCALL_BASE))
#define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE))
-const unsigned long sigreturn_codes[4] = {
- SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN,
- SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN
+const unsigned long sigreturn_codes[7] = {
+ MOV_R7_NR_SIGRETURN, SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN,
+ MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN,
};
static int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall);
@@ -189,7 +195,7 @@ struct aux_sigframe {
struct sigframe {
struct sigcontext sc;
unsigned long extramask[_NSIG_WORDS-1];
- unsigned long retcode;
+ unsigned long retcode[2];
struct aux_sigframe aux __attribute__((aligned(8)));
};
@@ -198,7 +204,7 @@ struct rt_sigframe {
void __user *puc;
struct siginfo info;
struct ucontext uc;
- unsigned long retcode;
+ unsigned long retcode[2];
struct aux_sigframe aux __attribute__((aligned(8)));
};
@@ -436,12 +442,13 @@ setup_return(struct pt_regs *regs, struct k_sigaction *ka,
if (ka->sa.sa_flags & SA_RESTORER) {
retcode = (unsigned long)ka->sa.sa_restorer;
} else {
- unsigned int idx = thumb;
+ unsigned int idx = thumb << 1;
if (ka->sa.sa_flags & SA_SIGINFO)
- idx += 2;
+ idx += 3;
- if (__put_user(sigreturn_codes[idx], rc))
+ if (__put_user(sigreturn_codes[idx], rc) ||
+ __put_user(sigreturn_codes[idx+1], rc+1))
return 1;
if (cpsr & MODE32_BIT) {
@@ -456,7 +463,7 @@ setup_return(struct pt_regs *regs, struct k_sigaction *ka,
* the return code written onto the stack.
*/
flush_icache_range((unsigned long)rc,
- (unsigned long)(rc + 1));
+ (unsigned long)(rc + 2));
retcode = ((unsigned long)rc) + thumb;
}
@@ -488,7 +495,7 @@ setup_frame(int usig, struct k_sigaction *ka, sigset_t *set, struct pt_regs *reg
}
if (err == 0)
- err = setup_return(regs, ka, &frame->retcode, frame, usig);
+ err = setup_return(regs, ka, frame->retcode, frame, usig);
return err;
}
@@ -522,7 +529,7 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
if (err == 0)
- err = setup_return(regs, ka, &frame->retcode, frame, usig);
+ err = setup_return(regs, ka, frame->retcode, frame, usig);
if (err == 0) {
/*
diff --git a/arch/arm/kernel/signal.h b/arch/arm/kernel/signal.h
index 91d26fa..9991049 100644
--- a/arch/arm/kernel/signal.h
+++ b/arch/arm/kernel/signal.h
@@ -9,4 +9,4 @@
*/
#define KERN_SIGRETURN_CODE 0xffff0500
-extern const unsigned long sigreturn_codes[4];
+extern const unsigned long sigreturn_codes[7];
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 373c095..02aa300 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -114,7 +114,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
* We need to tell the secondary core where to find
* its stack and the page tables.
*/
- secondary_data.stack = (void *)idle->thread_info + THREAD_START_SP;
+ secondary_data.stack = task_stack_page(idle) + THREAD_START_SP;
secondary_data.pgdir = virt_to_phys(pgd);
wmb();
@@ -245,7 +245,7 @@ void __cpuexit cpu_die(void)
__asm__("mov sp, %0\n"
" b secondary_start_kernel"
:
- : "r" ((void *)current->thread_info + THREAD_SIZE - 8));
+ : "r" (task_stack_page(current) + THREAD_SIZE - 8));
}
#endif /* CONFIG_HOTPLUG_CPU */
@@ -338,7 +338,6 @@ void __init smp_prepare_boot_cpu(void)
per_cpu(cpu_data, cpu).idle = current;
- cpu_set(cpu, cpu_possible_map);
cpu_set(cpu, cpu_present_map);
cpu_set(cpu, cpu_online_map);
}
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
index ea569ba..a491de2 100644
--- a/arch/arm/kernel/sys_arm.c
+++ b/arch/arm/kernel/sys_arm.c
@@ -147,6 +147,7 @@ asmlinkage int old_select(struct sel_arg_struct __user *arg)
return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
}
+#if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT)
/*
* sys_ipc() is the de-multiplexer for the SysV IPC calls..
*
@@ -226,6 +227,7 @@ asmlinkage int sys_ipc(uint call, int first, int second, int third,
return -ENOSYS;
}
}
+#endif
/* Fork a new task - this creates a new program thread.
* This is called indirectly via a small wrapper
diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c
new file mode 100644
index 0000000..8e2f9bc
--- /dev/null
+++ b/arch/arm/kernel/sys_oabi-compat.c
@@ -0,0 +1,440 @@
+/*
+ * arch/arm/kernel/sys_oabi-compat.c
+ *
+ * Compatibility wrappers for syscalls that are used from
+ * old ABI user space binaries with an EABI kernel.
+ *
+ * Author: Nicolas Pitre
+ * Created: Oct 7, 2005
+ * Copyright: MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * The legacy ABI and the new ARM EABI have different rules making some
+ * syscalls incompatible especially with structure arguments.
+ * Most notably, Eabi says 64-bit members should be 64-bit aligned instead of
+ * simply word aligned. EABI also pads structures to the size of the largest
+ * member it contains instead of the invariant 32-bit.
+ *
+ * The following syscalls are affected:
+ *
+ * sys_stat64:
+ * sys_lstat64:
+ * sys_fstat64:
+ *
+ * struct stat64 has different sizes and some members are shifted
+ * Compatibility wrappers are needed for them and provided below.
+ *
+ * sys_fcntl64:
+ *
+ * struct flock64 has different sizes and some members are shifted
+ * A compatibility wrapper is needed and provided below.
+ *
+ * sys_statfs64:
+ * sys_fstatfs64:
+ *
+ * struct statfs64 has extra padding with EABI growing its size from
+ * 84 to 88. This struct is now __attribute__((packed,aligned(4)))
+ * with a small assembly wrapper to force the sz argument to 84 if it is 88
+ * to avoid copying the extra padding over user space unexpecting it.
+ *
+ * sys_newuname:
+ *
+ * struct new_utsname has no padding with EABI. No problem there.
+ *
+ * sys_epoll_ctl:
+ * sys_epoll_wait:
+ *
+ * struct epoll_event has its second member shifted also affecting the
+ * structure size. Compatibility wrappers are needed and provided below.
+ *
+ * sys_ipc:
+ * sys_semop:
+ * sys_semtimedop:
+ *
+ * struct sembuf loses its padding with EABI. Since arrays of them are
+ * used they have to be copyed to remove the padding. Compatibility wrappers
+ * provided below.
+ *
+ * sys_bind:
+ * sys_connect:
+ * sys_sendmsg:
+ * sys_sendto:
+ * sys_socketcall:
+ *
+ * struct sockaddr_un loses its padding with EABI. Since the size of the
+ * structure is used as a validation test in unix_mkname(), we need to
+ * change the length argument to 110 whenever it is 112. Compatibility
+ * wrappers provided below.
+ */
+
+#include <linux/syscalls.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/fcntl.h>
+#include <linux/eventpoll.h>
+#include <linux/sem.h>
+#include <linux/socket.h>
+#include <linux/net.h>
+#include <asm/ipc.h>
+#include <asm/uaccess.h>
+
+struct oldabi_stat64 {
+ unsigned long long st_dev;
+ unsigned int __pad1;
+ unsigned long __st_ino;
+ unsigned int st_mode;
+ unsigned int st_nlink;
+
+ unsigned long st_uid;
+ unsigned long st_gid;
+
+ unsigned long long st_rdev;
+ unsigned int __pad2;
+
+ long long st_size;
+ unsigned long st_blksize;
+ unsigned long long st_blocks;
+
+ unsigned long st_atime;
+ unsigned long st_atime_nsec;
+
+ unsigned long st_mtime;
+ unsigned long st_mtime_nsec;
+
+ unsigned long st_ctime;
+ unsigned long st_ctime_nsec;
+
+ unsigned long long st_ino;
+} __attribute__ ((packed,aligned(4)));
+
+static long cp_oldabi_stat64(struct kstat *stat,
+ struct oldabi_stat64 __user *statbuf)
+{
+ struct oldabi_stat64 tmp;
+
+ tmp.st_dev = huge_encode_dev(stat->dev);
+ tmp.__pad1 = 0;
+ tmp.__st_ino = stat->ino;
+ tmp.st_mode = stat->mode;
+ tmp.st_nlink = stat->nlink;
+ tmp.st_uid = stat->uid;
+ tmp.st_gid = stat->gid;
+ tmp.st_rdev = huge_encode_dev(stat->rdev);
+ tmp.st_size = stat->size;
+ tmp.st_blocks = stat->blocks;
+ tmp.__pad2 = 0;
+ tmp.st_blksize = stat->blksize;
+ tmp.st_atime = stat->atime.tv_sec;
+ tmp.st_atime_nsec = stat->atime.tv_nsec;
+ tmp.st_mtime = stat->mtime.tv_sec;
+ tmp.st_mtime_nsec = stat->mtime.tv_nsec;
+ tmp.st_ctime = stat->ctime.tv_sec;
+ tmp.st_ctime_nsec = stat->ctime.tv_nsec;
+ tmp.st_ino = stat->ino;
+ return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
+}
+
+asmlinkage long sys_oabi_stat64(char __user * filename,
+ struct oldabi_stat64 __user * statbuf)
+{
+ struct kstat stat;
+ int error = vfs_stat(filename, &stat);
+ if (!error)
+ error = cp_oldabi_stat64(&stat, statbuf);
+ return error;
+}
+
+asmlinkage long sys_oabi_lstat64(char __user * filename,
+ struct oldabi_stat64 __user * statbuf)
+{
+ struct kstat stat;
+ int error = vfs_lstat(filename, &stat);
+ if (!error)
+ error = cp_oldabi_stat64(&stat, statbuf);
+ return error;
+}
+
+asmlinkage long sys_oabi_fstat64(unsigned long fd,
+ struct oldabi_stat64 __user * statbuf)
+{
+ struct kstat stat;
+ int error = vfs_fstat(fd, &stat);
+ if (!error)
+ error = cp_oldabi_stat64(&stat, statbuf);
+ return error;
+}
+
+struct oabi_flock64 {
+ short l_type;
+ short l_whence;
+ loff_t l_start;
+ loff_t l_len;
+ pid_t l_pid;
+} __attribute__ ((packed,aligned(4)));
+
+asmlinkage long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd,
+ unsigned long arg)
+{
+ struct oabi_flock64 user;
+ struct flock64 kernel;
+ mm_segment_t fs = USER_DS; /* initialized to kill a warning */
+ unsigned long local_arg = arg;
+ int ret;
+
+ switch (cmd) {
+ case F_GETLK64:
+ case F_SETLK64:
+ case F_SETLKW64:
+ if (copy_from_user(&user, (struct oabi_flock64 __user *)arg,
+ sizeof(user)))
+ return -EFAULT;
+ kernel.l_type = user.l_type;
+ kernel.l_whence = user.l_whence;
+ kernel.l_start = user.l_start;
+ kernel.l_len = user.l_len;
+ kernel.l_pid = user.l_pid;
+ local_arg = (unsigned long)&kernel;
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+ }
+
+ ret = sys_fcntl64(fd, cmd, local_arg);
+
+ switch (cmd) {
+ case F_GETLK64:
+ if (!ret) {
+ user.l_type = kernel.l_type;
+ user.l_whence = kernel.l_whence;
+ user.l_start = kernel.l_start;
+ user.l_len = kernel.l_len;
+ user.l_pid = kernel.l_pid;
+ if (copy_to_user((struct oabi_flock64 __user *)arg,
+ &user, sizeof(user)))
+ ret = -EFAULT;
+ }
+ case F_SETLK64:
+ case F_SETLKW64:
+ set_fs(fs);
+ }
+
+ return ret;
+}
+
+struct oabi_epoll_event {
+ __u32 events;
+ __u64 data;
+} __attribute__ ((packed,aligned(4)));
+
+asmlinkage long sys_oabi_epoll_ctl(int epfd, int op, int fd,
+ struct oabi_epoll_event __user *event)
+{
+ struct oabi_epoll_event user;
+ struct epoll_event kernel;
+ mm_segment_t fs;
+ long ret;
+
+ if (op == EPOLL_CTL_DEL)
+ return sys_epoll_ctl(epfd, op, fd, NULL);
+ if (copy_from_user(&user, event, sizeof(user)))
+ return -EFAULT;
+ kernel.events = user.events;
+ kernel.data = user.data;
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+ ret = sys_epoll_ctl(epfd, op, fd, &kernel);
+ set_fs(fs);
+ return ret;
+}
+
+asmlinkage long sys_oabi_epoll_wait(int epfd,
+ struct oabi_epoll_event __user *events,
+ int maxevents, int timeout)
+{
+ struct epoll_event *kbuf;
+ mm_segment_t fs;
+ long ret, err, i;
+
+ if (maxevents <= 0 || maxevents > (INT_MAX/sizeof(struct epoll_event)))
+ return -EINVAL;
+ kbuf = kmalloc(sizeof(*kbuf) * maxevents, GFP_KERNEL);
+ if (!kbuf)
+ return -ENOMEM;
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+ ret = sys_epoll_wait(epfd, kbuf, maxevents, timeout);
+ set_fs(fs);
+ err = 0;
+ for (i = 0; i < ret; i++) {
+ __put_user_error(kbuf[i].events, &events->events, err);
+ __put_user_error(kbuf[i].data, &events->data, err);
+ events++;
+ }
+ kfree(kbuf);
+ return err ? -EFAULT : ret;
+}
+
+struct oabi_sembuf {
+ unsigned short sem_num;
+ short sem_op;
+ short sem_flg;
+ unsigned short __pad;
+};
+
+asmlinkage long sys_oabi_semtimedop(int semid,
+ struct oabi_sembuf __user *tsops,
+ unsigned nsops,
+ const struct timespec __user *timeout)
+{
+ struct sembuf *sops;
+ struct timespec local_timeout;
+ long err;
+ int i;
+
+ if (nsops < 1)
+ return -EINVAL;
+ sops = kmalloc(sizeof(*sops) * nsops, GFP_KERNEL);
+ if (!sops)
+ return -ENOMEM;
+ err = 0;
+ for (i = 0; i < nsops; i++) {
+ __get_user_error(sops[i].sem_num, &tsops->sem_num, err);
+ __get_user_error(sops[i].sem_op, &tsops->sem_op, err);
+ __get_user_error(sops[i].sem_flg, &tsops->sem_flg, err);
+ tsops++;
+ }
+ if (timeout) {
+ /* copy this as well before changing domain protection */
+ err |= copy_from_user(&local_timeout, timeout, sizeof(*timeout));
+ timeout = &local_timeout;
+ }
+ if (err) {
+ err = -EFAULT;
+ } else {
+ mm_segment_t fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_semtimedop(semid, sops, nsops, timeout);
+ set_fs(fs);
+ }
+ kfree(sops);
+ return err;
+}
+
+asmlinkage long sys_oabi_semop(int semid, struct oabi_sembuf __user *tsops,
+ unsigned nsops)
+{
+ return sys_oabi_semtimedop(semid, tsops, nsops, NULL);
+}
+
+extern asmlinkage int sys_ipc(uint call, int first, int second, int third,
+ void __user *ptr, long fifth);
+
+asmlinkage int sys_oabi_ipc(uint call, int first, int second, int third,
+ void __user *ptr, long fifth)
+{
+ switch (call & 0xffff) {
+ case SEMOP:
+ return sys_oabi_semtimedop(first,
+ (struct oabi_sembuf __user *)ptr,
+ second, NULL);
+ case SEMTIMEDOP:
+ return sys_oabi_semtimedop(first,
+ (struct oabi_sembuf __user *)ptr,
+ second,
+ (const struct timespec __user *)fifth);
+ default:
+ return sys_ipc(call, first, second, third, ptr, fifth);
+ }
+}
+
+asmlinkage long sys_oabi_bind(int fd, struct sockaddr __user *addr, int addrlen)
+{
+ sa_family_t sa_family;
+ if (addrlen == 112 &&
+ get_user(sa_family, &addr->sa_family) == 0 &&
+ sa_family == AF_UNIX)
+ addrlen = 110;
+ return sys_bind(fd, addr, addrlen);
+}
+
+asmlinkage long sys_oabi_connect(int fd, struct sockaddr __user *addr, int addrlen)
+{
+ sa_family_t sa_family;
+ if (addrlen == 112 &&
+ get_user(sa_family, &addr->sa_family) == 0 &&
+ sa_family == AF_UNIX)
+ addrlen = 110;
+ return sys_connect(fd, addr, addrlen);
+}
+
+asmlinkage long sys_oabi_sendto(int fd, void __user *buff,
+ size_t len, unsigned flags,
+ struct sockaddr __user *addr,
+ int addrlen)
+{
+ sa_family_t sa_family;
+ if (addrlen == 112 &&
+ get_user(sa_family, &addr->sa_family) == 0 &&
+ sa_family == AF_UNIX)
+ addrlen = 110;
+ return sys_sendto(fd, buff, len, flags, addr, addrlen);
+}
+
+asmlinkage long sys_oabi_sendmsg(int fd, struct msghdr __user *msg, unsigned flags)
+{
+ struct sockaddr __user *addr;
+ int msg_namelen;
+ sa_family_t sa_family;
+ if (msg &&
+ get_user(msg_namelen, &msg->msg_namelen) == 0 &&
+ msg_namelen == 112 &&
+ get_user(addr, &msg->msg_name) == 0 &&
+ get_user(sa_family, &addr->sa_family) == 0 &&
+ sa_family == AF_UNIX)
+ {
+ /*
+ * HACK ALERT: there is a limit to how much backward bending
+ * we should do for what is actually a transitional
+ * compatibility layer. This already has known flaws with
+ * a few ioctls that we don't intend to fix. Therefore
+ * consider this blatent hack as another one... and take care
+ * to run for cover. In most cases it will "just work fine".
+ * If it doesn't, well, tough.
+ */
+ put_user(110, &msg->msg_namelen);
+ }
+ return sys_sendmsg(fd, msg, flags);
+}
+
+asmlinkage long sys_oabi_socketcall(int call, unsigned long __user *args)
+{
+ unsigned long r = -EFAULT, a[6];
+
+ switch (call) {
+ case SYS_BIND:
+ if (copy_from_user(a, args, 3 * sizeof(long)) == 0)
+ r = sys_oabi_bind(a[0], (struct sockaddr __user *)a[1], a[2]);
+ break;
+ case SYS_CONNECT:
+ if (copy_from_user(a, args, 3 * sizeof(long)) == 0)
+ r = sys_oabi_connect(a[0], (struct sockaddr __user *)a[1], a[2]);
+ break;
+ case SYS_SENDTO:
+ if (copy_from_user(a, args, 6 * sizeof(long)) == 0)
+ r = sys_oabi_sendto(a[0], (void __user *)a[1], a[2], a[3],
+ (struct sockaddr __user *)a[4], a[5]);
+ break;
+ case SYS_SENDMSG:
+ if (copy_from_user(a, args, 3 * sizeof(long)) == 0)
+ r = sys_oabi_sendmsg(a[0], (struct msghdr __user *)a[1], a[2]);
+ break;
+ default:
+ r = sys_socketcall(call, args);
+ }
+
+ return r;
+}
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index fc47291..d6bd435 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -29,9 +29,6 @@
#include <linux/sysdev.h>
#include <linux/timer.h>
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/irq.h>
#include <asm/leds.h>
#include <asm/thread_info.h>
#include <asm/mach/time.h>
@@ -425,12 +422,14 @@ static int timer_dyn_tick_disable(void)
void timer_dyn_reprogram(void)
{
struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick;
+ unsigned long next, seq;
- if (dyn_tick) {
- write_seqlock(&xtime_lock);
- if (dyn_tick->state & DYN_TICK_ENABLED)
+ if (dyn_tick && (dyn_tick->state & DYN_TICK_ENABLED)) {
+ next = next_timer_interrupt();
+ do {
+ seq = read_seqbegin(&xtime_lock);
dyn_tick->reprogram(next_timer_interrupt() - jiffies);
- write_sequnlock(&xtime_lock);
+ } while (read_seqretry(&xtime_lock, seq));
}
}
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 45e9ea6..03924bc 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -19,11 +19,11 @@
#include <linux/personality.h>
#include <linux/ptrace.h>
#include <linux/kallsyms.h>
+#include <linux/delay.h>
#include <linux/init.h>
#include <asm/atomic.h>
#include <asm/cacheflush.h>
-#include <asm/io.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
@@ -165,7 +165,7 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
} else if (verify_stack(fp)) {
printk("invalid frame pointer 0x%08x", fp);
ok = 0;
- } else if (fp < (unsigned long)(tsk->thread_info + 1))
+ } else if (fp < (unsigned long)end_of_stack(tsk))
printk("frame pointer underflow");
printk("\n");
@@ -211,7 +211,7 @@ static void __die(const char *str, int err, struct thread_info *thread, struct p
if (!user_mode(regs) || in_interrupt()) {
dump_mem("Stack: ", regs->ARM_sp,
- THREAD_SIZE + (unsigned long)tsk->thread_info);
+ THREAD_SIZE + (unsigned long)task_stack_page(tsk));
dump_backtrace(regs, tsk);
dump_instr(regs);
}
@@ -232,6 +232,13 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
__die(str, err, thread, regs);
bust_spinlocks(0);
spin_unlock_irq(&die_lock);
+
+ if (panic_on_oops) {
+ printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
+ ssleep(5);
+ panic("Fatal exception");
+ }
+
do_exit(SIGSEGV);
}
@@ -405,7 +412,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
struct thread_info *thread = current_thread_info();
siginfo_t info;
- if ((no >> 16) != 0x9f)
+ if ((no >> 16) != (__ARM_NR_BASE>> 16))
return bad_syscall(no, regs);
switch (no & 0xffff) {
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 9a47770..2b254e8 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -17,15 +17,13 @@ jiffies = jiffies_64;
jiffies = jiffies_64 + 4;
#endif
+SECTIONS
+{
#ifdef CONFIG_XIP_KERNEL
-#define TEXTADDR XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
+ . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR);
#else
-#define TEXTADDR KERNEL_RAM_ADDR
+ . = PAGE_OFFSET + TEXT_OFFSET;
#endif
-
-SECTIONS
-{
- . = TEXTADDR;
.init : { /* Init code and data */
_stext = .;
_sinittext = .;
@@ -104,7 +102,7 @@ SECTIONS
#ifdef CONFIG_XIP_KERNEL
__data_loc = ALIGN(4); /* location in binary */
- . = KERNEL_RAM_ADDR;
+ . = PAGE_OFFSET + TEXT_OFFSET;
#else
. = ALIGN(THREAD_SIZE);
__data_loc = .;