summaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/Kconfig4
-rw-r--r--arch/s390/defconfig9
-rw-r--r--arch/s390/kernel/compat_linux.c103
-rw-r--r--arch/s390/kernel/compat_signal.c3
-rw-r--r--arch/s390/kernel/compat_wrapper.S14
-rw-r--r--arch/s390/kernel/machine_kexec.c5
-rw-r--r--arch/s390/kernel/process.c4
-rw-r--r--arch/s390/kernel/setup.c2
-rw-r--r--arch/s390/kernel/smp.c73
-rw-r--r--arch/s390/kernel/sys_s390.c4
-rw-r--r--arch/s390/kernel/syscalls.S3
-rw-r--r--arch/s390/kernel/traps.c2
-rw-r--r--arch/s390/lib/delay.c2
-rw-r--r--arch/s390/lib/spinlock.c15
-rw-r--r--arch/s390/lib/uaccess.S6
-rw-r--r--arch/s390/lib/uaccess64.S6
-rw-r--r--arch/s390/mm/cmm.c10
17 files changed, 171 insertions, 94 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index b66602ad7b3..b7ca5bf9acf 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -80,6 +80,10 @@ config HOTPLUG_CPU
can be controlled through /sys/devices/system/cpu/cpu#.
Say N if you want to disable CPU hotplug.
+config DEFAULT_MIGRATION_COST
+ int
+ default "1000000"
+
config MATHEMU
bool "IEEE FPU emulation"
depends on MARCH_G5
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index 3525c91204d..f8d0cd540a0 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc1
-# Thu Jan 19 10:58:53 2006
+# Linux kernel version: 2.6.16-rc2
+# Wed Feb 8 10:44:39 2006
#
CONFIG_MMU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
@@ -12,7 +12,6 @@ CONFIG_S390=y
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
@@ -154,6 +153,7 @@ CONFIG_NET=y
#
# Networking options
#
+# CONFIG_NETDEBUG is not set
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -607,6 +607,7 @@ CONFIG_MSDOS_PARTITION=y
# Instrumentation Support
#
# CONFIG_PROFILING is not set
+# CONFIG_STATISTICS is not set
#
# Kernel hacking
@@ -624,7 +625,7 @@ CONFIG_DEBUG_MUTEXES=y
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
# CONFIG_DEBUG_VM is not set
CONFIG_FORCED_INLINING=y
# CONFIG_RCU_TORTURE_TEST is not set
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index bf9a7a361b3..cc058dc3bc8 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -100,12 +100,12 @@
#define SET_STAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid)
#define SET_STAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid)
-asmlinkage long sys32_chown16(const char * filename, u16 user, u16 group)
+asmlinkage long sys32_chown16(const char __user * filename, u16 user, u16 group)
{
return sys_chown(filename, low2highuid(user), low2highgid(group));
}
-asmlinkage long sys32_lchown16(const char * filename, u16 user, u16 group)
+asmlinkage long sys32_lchown16(const char __user * filename, u16 user, u16 group)
{
return sys_lchown(filename, low2highuid(user), low2highgid(group));
}
@@ -141,7 +141,7 @@ asmlinkage long sys32_setresuid16(u16 ruid, u16 euid, u16 suid)
low2highuid(suid));
}
-asmlinkage long sys32_getresuid16(u16 *ruid, u16 *euid, u16 *suid)
+asmlinkage long sys32_getresuid16(u16 __user *ruid, u16 __user *euid, u16 __user *suid)
{
int retval;
@@ -158,7 +158,7 @@ asmlinkage long sys32_setresgid16(u16 rgid, u16 egid, u16 sgid)
low2highgid(sgid));
}
-asmlinkage long sys32_getresgid16(u16 *rgid, u16 *egid, u16 *sgid)
+asmlinkage long sys32_getresgid16(u16 __user *rgid, u16 __user *egid, u16 __user *sgid)
{
int retval;
@@ -179,7 +179,7 @@ asmlinkage long sys32_setfsgid16(u16 gid)
return sys_setfsgid((gid_t)gid);
}
-static int groups16_to_user(u16 *grouplist, struct group_info *group_info)
+static int groups16_to_user(u16 __user *grouplist, struct group_info *group_info)
{
int i;
u16 group;
@@ -193,7 +193,7 @@ static int groups16_to_user(u16 *grouplist, struct group_info *group_info)
return 0;
}
-static int groups16_from_user(struct group_info *group_info, u16 *grouplist)
+static int groups16_from_user(struct group_info *group_info, u16 __user *grouplist)
{
int i;
u16 group;
@@ -207,7 +207,7 @@ static int groups16_from_user(struct group_info *group_info, u16 *grouplist)
return 0;
}
-asmlinkage long sys32_getgroups16(int gidsetsize, u16 *grouplist)
+asmlinkage long sys32_getgroups16(int gidsetsize, u16 __user *grouplist)
{
int i;
@@ -231,7 +231,7 @@ out:
return i;
}
-asmlinkage long sys32_setgroups16(int gidsetsize, u16 *grouplist)
+asmlinkage long sys32_setgroups16(int gidsetsize, u16 __user *grouplist)
{
struct group_info *group_info;
int retval;
@@ -278,14 +278,14 @@ asmlinkage long sys32_getegid16(void)
/* 32-bit timeval and related flotsam. */
-static inline long get_tv32(struct timeval *o, struct compat_timeval *i)
+static inline long get_tv32(struct timeval *o, struct compat_timeval __user *i)
{
return (!access_ok(VERIFY_READ, o, sizeof(*o)) ||
(__get_user(o->tv_sec, &i->tv_sec) ||
__get_user(o->tv_usec, &i->tv_usec)));
}
-static inline long put_tv32(struct compat_timeval *o, struct timeval *i)
+static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i)
{
return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
(__put_user(i->tv_sec, &o->tv_sec) ||
@@ -341,7 +341,7 @@ asmlinkage long sys32_ipc(u32 call, int first, int second, int third, u32 ptr)
return -ENOSYS;
}
-asmlinkage long sys32_truncate64(const char * path, unsigned long high, unsigned long low)
+asmlinkage long sys32_truncate64(const char __user * path, unsigned long high, unsigned long low)
{
if ((int)high < 0)
return -EINVAL;
@@ -357,7 +357,7 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned
return sys_ftruncate(fd, (high << 32) | low);
}
-int cp_compat_stat(struct kstat *stat, struct compat_stat *statbuf)
+int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
{
int err;
@@ -591,7 +591,7 @@ sys32_delete_module(const char __user *name_user, unsigned int flags)
extern struct timezone sys_tz;
-asmlinkage long sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz)
+asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
{
if (tv) {
struct timeval ktv;
@@ -606,7 +606,7 @@ asmlinkage long sys32_gettimeofday(struct compat_timeval *tv, struct timezone *t
return 0;
}
-static inline long get_ts32(struct timespec *o, struct compat_timeval *i)
+static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
{
long usec;
@@ -620,7 +620,7 @@ static inline long get_ts32(struct timespec *o, struct compat_timeval *i)
return 0;
}
-asmlinkage long sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz)
+asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
{
struct timespec kts;
struct timezone ktz;
@@ -645,7 +645,7 @@ asmlinkage long sys32_pause(void)
return -ERESTARTNOHAND;
}
-asmlinkage long sys32_pread64(unsigned int fd, char *ubuf,
+asmlinkage long sys32_pread64(unsigned int fd, char __user *ubuf,
size_t count, u32 poshi, u32 poslo)
{
if ((compat_ssize_t) count < 0)
@@ -653,7 +653,7 @@ asmlinkage long sys32_pread64(unsigned int fd, char *ubuf,
return sys_pread64(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
}
-asmlinkage long sys32_pwrite64(unsigned int fd, const char *ubuf,
+asmlinkage long sys32_pwrite64(unsigned int fd, const char __user *ubuf,
size_t count, u32 poshi, u32 poslo)
{
if ((compat_ssize_t) count < 0)
@@ -666,7 +666,7 @@ asmlinkage compat_ssize_t sys32_readahead(int fd, u32 offhi, u32 offlo, s32 coun
return sys_readahead(fd, ((loff_t)AA(offhi) << 32) | AA(offlo), count);
}
-asmlinkage long sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset, size_t count)
+asmlinkage long sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, size_t count)
{
mm_segment_t old_fs = get_fs();
int ret;
@@ -686,7 +686,7 @@ asmlinkage long sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset, size
}
asmlinkage long sys32_sendfile64(int out_fd, int in_fd,
- compat_loff_t *offset, s32 count)
+ compat_loff_t __user *offset, s32 count)
{
mm_segment_t old_fs = get_fs();
int ret;
@@ -722,7 +722,7 @@ struct timex32 {
extern int do_adjtimex(struct timex *);
-asmlinkage long sys32_adjtimex(struct timex32 *utp)
+asmlinkage long sys32_adjtimex(struct timex32 __user *utp)
{
struct timex txc;
int ret;
@@ -789,12 +789,13 @@ struct __sysctl_args32 {
u32 __unused[4];
};
-asmlinkage long sys32_sysctl(struct __sysctl_args32 *args)
+asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
{
struct __sysctl_args32 tmp;
int error;
- size_t oldlen, *oldlenp = NULL;
- unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7;
+ size_t oldlen;
+ size_t __user *oldlenp = NULL;
+ unsigned long addr = (((unsigned long)&args->__unused[0]) + 7) & ~7;
if (copy_from_user(&tmp, args, sizeof(tmp)))
return -EFAULT;
@@ -806,20 +807,20 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 *args)
basically copy the whole sysctl.c here, and
glibc's __sysctl uses rw memory for the structure
anyway. */
- if (get_user(oldlen, (u32 *)A(tmp.oldlenp)) ||
- put_user(oldlen, (size_t *)addr))
+ if (get_user(oldlen, (u32 __user *)compat_ptr(tmp.oldlenp)) ||
+ put_user(oldlen, (size_t __user *)addr))
return -EFAULT;
- oldlenp = (size_t *)addr;
+ oldlenp = (size_t __user *)addr;
}
lock_kernel();
- error = do_sysctl((int *)A(tmp.name), tmp.nlen, (void *)A(tmp.oldval),
- oldlenp, (void *)A(tmp.newval), tmp.newlen);
+ error = do_sysctl(compat_ptr(tmp.name), tmp.nlen, compat_ptr(tmp.oldval),
+ oldlenp, compat_ptr(tmp.newval), tmp.newlen);
unlock_kernel();
if (oldlenp) {
if (!error) {
- if (get_user(oldlen, (size_t *)addr) ||
- put_user(oldlen, (u32 *)A(tmp.oldlenp)))
+ if (get_user(oldlen, (size_t __user *)addr) ||
+ put_user(oldlen, (u32 __user *)compat_ptr(tmp.oldlenp)))
error = -EFAULT;
}
copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
@@ -853,7 +854,7 @@ struct stat64_emu31 {
unsigned long st_ino;
};
-static int cp_stat64(struct stat64_emu31 *ubuf, struct kstat *stat)
+static int cp_stat64(struct stat64_emu31 __user *ubuf, struct kstat *stat)
{
struct stat64_emu31 tmp;
@@ -877,7 +878,7 @@ static int cp_stat64(struct stat64_emu31 *ubuf, struct kstat *stat)
return copy_to_user(ubuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
}
-asmlinkage long sys32_stat64(char * filename, struct stat64_emu31 * statbuf)
+asmlinkage long sys32_stat64(char __user * filename, struct stat64_emu31 __user * statbuf)
{
struct kstat stat;
int ret = vfs_stat(filename, &stat);
@@ -886,7 +887,7 @@ asmlinkage long sys32_stat64(char * filename, struct stat64_emu31 * statbuf)
return ret;
}
-asmlinkage long sys32_lstat64(char * filename, struct stat64_emu31 * statbuf)
+asmlinkage long sys32_lstat64(char __user * filename, struct stat64_emu31 __user * statbuf)
{
struct kstat stat;
int ret = vfs_lstat(filename, &stat);
@@ -895,7 +896,7 @@ asmlinkage long sys32_lstat64(char * filename, struct stat64_emu31 * statbuf)
return ret;
}
-asmlinkage long sys32_fstat64(unsigned long fd, struct stat64_emu31 * statbuf)
+asmlinkage long sys32_fstat64(unsigned long fd, struct stat64_emu31 __user * statbuf)
{
struct kstat stat;
int ret = vfs_fstat(fd, &stat);
@@ -904,6 +905,26 @@ asmlinkage long sys32_fstat64(unsigned long fd, struct stat64_emu31 * statbuf)
return ret;
}
+asmlinkage long sys32_fstatat64(unsigned int dfd, char __user *filename,
+ struct stat64_emu31 __user* statbuf, int flag)
+{
+ struct kstat stat;
+ int error = -EINVAL;
+
+ if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
+ goto out;
+
+ if (flag & AT_SYMLINK_NOFOLLOW)
+ error = vfs_lstat_fd(dfd, filename, &stat);
+ else
+ error = vfs_stat_fd(dfd, filename, &stat);
+
+ if (!error)
+ error = cp_stat64(statbuf, &stat);
+out:
+ return error;
+}
+
/*
* Linux/i386 didn't use to be able to handle more than
* 4 system call parameters, so these system calls used a memory
@@ -952,7 +973,7 @@ out:
asmlinkage unsigned long
-old32_mmap(struct mmap_arg_struct_emu31 *arg)
+old32_mmap(struct mmap_arg_struct_emu31 __user *arg)
{
struct mmap_arg_struct_emu31 a;
int error = -EFAULT;
@@ -970,7 +991,7 @@ out:
}
asmlinkage long
-sys32_mmap2(struct mmap_arg_struct_emu31 *arg)
+sys32_mmap2(struct mmap_arg_struct_emu31 __user *arg)
{
struct mmap_arg_struct_emu31 a;
int error = -EFAULT;
@@ -982,7 +1003,7 @@ out:
return error;
}
-asmlinkage long sys32_read(unsigned int fd, char * buf, size_t count)
+asmlinkage long sys32_read(unsigned int fd, char __user * buf, size_t count)
{
if ((compat_ssize_t) count < 0)
return -EINVAL;
@@ -990,7 +1011,7 @@ asmlinkage long sys32_read(unsigned int fd, char * buf, size_t count)
return sys_read(fd, buf, count);
}
-asmlinkage long sys32_write(unsigned int fd, char * buf, size_t count)
+asmlinkage long sys32_write(unsigned int fd, char __user * buf, size_t count)
{
if ((compat_ssize_t) count < 0)
return -EINVAL;
@@ -1002,12 +1023,12 @@ asmlinkage long sys32_clone(struct pt_regs regs)
{
unsigned long clone_flags;
unsigned long newsp;
- int *parent_tidptr, *child_tidptr;
+ int __user *parent_tidptr, *child_tidptr;
clone_flags = regs.gprs[3] & 0xffffffffUL;
newsp = regs.orig_gpr2 & 0x7fffffffUL;
- parent_tidptr = (int *) (regs.gprs[4] & 0x7fffffffUL);
- child_tidptr = (int *) (regs.gprs[5] & 0x7fffffffUL);
+ parent_tidptr = compat_ptr(regs.gprs[4]);
+ child_tidptr = compat_ptr(regs.gprs[5]);
if (!newsp)
newsp = regs.gprs[15];
return do_fork(clone_flags, newsp, &regs, 0,
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index ef706694a0c..5291b5f8788 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -195,9 +195,6 @@ sys32_sigaction(int sig, const struct old_sigaction32 __user *act,
return ret;
}
-int
-do_sigaction(int sig, const struct k_sigaction *act, struct k_sigaction *oact);
-
asmlinkage long
sys32_rt_sigaction(int sig, const struct sigaction32 __user *act,
struct sigaction32 __user *oact, size_t sigsetsize)
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
index 83b33fe1923..50e80138e7a 100644
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -1523,13 +1523,13 @@ compat_sys_futimesat_wrapper:
llgtr %r4,%r4 # struct timeval *
jg compat_sys_futimesat
- .globl compat_sys_newfstatat_wrapper
-compat_sys_newfstatat_wrapper:
+ .globl sys32_fstatat64_wrapper
+sys32_fstatat64_wrapper:
llgfr %r2,%r2 # unsigned int
llgtr %r3,%r3 # char *
- llgtr %r4,%r4 # struct stat *
+ llgtr %r4,%r4 # struct stat64 *
lgfr %r5,%r5 # int
- jg compat_sys_newfstatat
+ jg sys32_fstatat64
.globl sys_unlinkat_wrapper
sys_unlinkat_wrapper:
@@ -1552,6 +1552,7 @@ sys_linkat_wrapper:
llgtr %r3,%r3 # const char *
lgfr %r4,%r4 # int
llgtr %r5,%r5 # const char *
+ lgfr %r6,%r6 # int
jg sys_linkat
.globl sys_symlinkat_wrapper
@@ -1602,3 +1603,8 @@ compat_sys_ppoll_wrapper:
llgtr %r5,%r5 # const sigset_t *
llgfr %r6,%r6 # size_t
jg compat_sys_ppoll
+
+ .globl sys_unshare_wrapper
+sys_unshare_wrapper:
+ llgfr %r2,%r2 # unsigned long
+ jg sys_unshare
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c
index f0ed5c642c7..bad81b5832d 100644
--- a/arch/s390/kernel/machine_kexec.c
+++ b/arch/s390/kernel/machine_kexec.c
@@ -12,15 +12,16 @@
* on the S390 architecture.
*/
-#include <asm/cio.h>
-#include <asm/setup.h>
#include <linux/device.h>
#include <linux/mm.h>
#include <linux/kexec.h>
#include <linux/delay.h>
+#include <asm/cio.h>
+#include <asm/setup.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
#include <asm/system.h>
+#include <asm/smp.h>
static void kexec_halt_all_cpus(void *);
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 008c74526fd..da6fbae8df9 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -128,8 +128,10 @@ void default_idle(void)
__ctl_set_bit(8, 15);
#ifdef CONFIG_HOTPLUG_CPU
- if (cpu_is_offline(cpu))
+ if (cpu_is_offline(cpu)) {
+ preempt_enable_no_resched();
cpu_die();
+ }
#endif
local_mcck_disable();
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index de878426747..24f62f16c0e 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -600,6 +600,7 @@ setup_arch(char **cmdline_p)
init_mm.brk = (unsigned long) &_end;
parse_cmdline_early(cmdline_p);
+ parse_early_param();
setup_memory();
setup_resources();
@@ -607,6 +608,7 @@ setup_arch(char **cmdline_p)
cpu_init();
__cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr;
+ smp_setup_cpu_possible_map();
/*
* Create kernel page tables and switch to virtual addressing.
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index cbfcfd02a43..7dbe00c76c6 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -1,8 +1,7 @@
/*
* arch/s390/kernel/smp.c
*
- * S390 version
- * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Copyright (C) IBM Corp. 1999,2006
* Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
* Martin Schwidefsky (schwidefsky@de.ibm.com)
* Heiko Carstens (heiko.carstens@de.ibm.com)
@@ -41,8 +40,6 @@
#include <asm/cpcmd.h>
#include <asm/tlbflush.h>
-/* prototypes */
-
extern volatile int __cpu_logical_map[];
/*
@@ -51,13 +48,11 @@ extern volatile int __cpu_logical_map[];
struct _lowcore *lowcore_ptr[NR_CPUS];
-cpumask_t cpu_online_map;
-cpumask_t cpu_possible_map;
+cpumask_t cpu_online_map = CPU_MASK_NONE;
+cpumask_t cpu_possible_map = CPU_MASK_NONE;
static struct task_struct *current_set[NR_CPUS];
-EXPORT_SYMBOL(cpu_online_map);
-
/*
* Reboot, halt and power_off routines for SMP.
*/
@@ -490,10 +485,10 @@ void smp_ctl_clear_bit(int cr, int bit) {
* Lets check how many CPUs we have.
*/
-void
-__init smp_check_cpus(unsigned int max_cpus)
+static unsigned int
+__init smp_count_cpus(void)
{
- int cpu, num_cpus;
+ unsigned int cpu, num_cpus;
__u16 boot_cpu_addr;
/*
@@ -503,22 +498,20 @@ __init smp_check_cpus(unsigned int max_cpus)
boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
current_thread_info()->cpu = 0;
num_cpus = 1;
- for (cpu = 0; cpu <= 65535 && num_cpus < max_cpus; cpu++) {
+ for (cpu = 0; cpu <= 65535; cpu++) {
if ((__u16) cpu == boot_cpu_addr)
continue;
- __cpu_logical_map[num_cpus] = (__u16) cpu;
- if (signal_processor(num_cpus, sigp_sense) ==
+ __cpu_logical_map[1] = (__u16) cpu;
+ if (signal_processor(1, sigp_sense) ==
sigp_not_operational)
continue;
- cpu_set(num_cpus, cpu_present_map);
num_cpus++;
}
- for (cpu = 1; cpu < max_cpus; cpu++)
- cpu_set(cpu, cpu_possible_map);
-
printk("Detected %d CPU's\n",(int) num_cpus);
printk("Boot cpu address %2X\n", boot_cpu_addr);
+
+ return num_cpus;
}
/*
@@ -679,6 +672,44 @@ __cpu_up(unsigned int cpu)
return 0;
}
+static unsigned int __initdata additional_cpus;
+static unsigned int __initdata possible_cpus;
+
+void __init smp_setup_cpu_possible_map(void)
+{
+ unsigned int phy_cpus, pos_cpus, cpu;
+
+ phy_cpus = smp_count_cpus();
+ pos_cpus = min(phy_cpus + additional_cpus, (unsigned int) NR_CPUS);
+
+ if (possible_cpus)
+ pos_cpus = min(possible_cpus, (unsigned int) NR_CPUS);
+
+ for (cpu = 0; cpu < pos_cpus; cpu++)
+ cpu_set(cpu, cpu_possible_map);
+
+ phy_cpus = min(phy_cpus, pos_cpus);
+
+ for (cpu = 0; cpu < phy_cpus; cpu++)
+ cpu_set(cpu, cpu_present_map);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+static int __init setup_additional_cpus(char *s)
+{
+ additional_cpus = simple_strtoul(s, NULL, 0);
+ return 0;
+}
+early_param("additional_cpus", setup_additional_cpus);
+
+static int __init setup_possible_cpus(char *s)
+{
+ possible_cpus = simple_strtoul(s, NULL, 0);
+ return 0;
+}
+early_param("possible_cpus", setup_possible_cpus);
+
int
__cpu_disable(void)
{
@@ -747,6 +778,8 @@ cpu_die(void)
for(;;);
}
+#endif /* CONFIG_HOTPLUG_CPU */
+
/*
* Cycle through the processors and setup structures.
*/
@@ -760,7 +793,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
/* request the 0x1201 emergency signal external interrupt */
if (register_external_interrupt(0x1201, do_ext_call_interrupt) != 0)
panic("Couldn't request external interrupt 0x1201");
- smp_check_cpus(max_cpus);
memset(lowcore_ptr,0,sizeof(lowcore_ptr));
/*
* Initialize prefix pages and stacks for all possible cpus
@@ -809,8 +841,6 @@ void __devinit smp_prepare_boot_cpu(void)
BUG_ON(smp_processor_id() != 0);
cpu_set(0, cpu_online_map);
- cpu_set(0, cpu_present_map);
- cpu_set(0, cpu_possible_map);
S390_lowcore.percpu_offset = __per_cpu_offset[0];
current_set[0] = current;
}
@@ -849,6 +879,7 @@ static int __init topology_init(void)
subsys_initcall(topology_init);
+EXPORT_SYMBOL(cpu_online_map);
EXPORT_SYMBOL(cpu_possible_map);
EXPORT_SYMBOL(lowcore_ptr);
EXPORT_SYMBOL(smp_ctl_set_bit);
diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c
index 6a63553493c..e351780bb66 100644
--- a/arch/s390/kernel/sys_s390.c
+++ b/arch/s390/kernel/sys_s390.c
@@ -122,8 +122,8 @@ out:
#ifndef CONFIG_64BIT
struct sel_arg_struct {
unsigned long n;
- fd_set *inp, *outp, *exp;
- struct timeval *tvp;
+ fd_set __user *inp, *outp, *exp;
+ struct timeval __user *tvp;
};
asmlinkage long old_select(struct sel_arg_struct __user *arg)
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S
index 3280345efac..7c88d85c359 100644
--- a/arch/s390/kernel/syscalls.S
+++ b/arch/s390/kernel/syscalls.S
@@ -301,7 +301,7 @@ SYSCALL(sys_mkdirat,sys_mkdirat,sys_mkdirat_wrapper)
SYSCALL(sys_mknodat,sys_mknodat,sys_mknodat_wrapper) /* 290 */
SYSCALL(sys_fchownat,sys_fchownat,sys_fchownat_wrapper)
SYSCALL(sys_futimesat,sys_futimesat,compat_sys_futimesat_wrapper)
-SYSCALL(sys_newfstatat,sys_newfstatat,compat_sys_newfstatat_wrapper)
+SYSCALL(sys_fstatat64,sys_newfstatat,sys32_fstatat64_wrapper)
SYSCALL(sys_unlinkat,sys_unlinkat,sys_unlinkat_wrapper)
SYSCALL(sys_renameat,sys_renameat,sys_renameat_wrapper) /* 295 */
SYSCALL(sys_linkat,sys_linkat,sys_linkat_wrapper)
@@ -311,3 +311,4 @@ SYSCALL(sys_fchmodat,sys_fchmodat,sys_fchmodat_wrapper)
SYSCALL(sys_faccessat,sys_faccessat,sys_faccessat_wrapper) /* 300 */
SYSCALL(sys_pselect6,sys_pselect6,compat_sys_pselect6_wrapper)
SYSCALL(sys_ppoll,sys_ppoll,compat_sys_ppoll_wrapper)
+SYSCALL(sys_unshare,sys_unshare,sys_unshare_wrapper)
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 5d21e9e6e7b..a46793beedd 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -486,7 +486,7 @@ asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code)
info.si_signo = signal;
info.si_errno = 0;
info.si_code = ILL_ILLOPC;
- info.si_addr = (void *) location;
+ info.si_addr = (void __user *) location;
do_trap(interruption_code, signal,
"illegal operation", regs, &info);
}
diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c
index e96c35bddac..71f0a2fb307 100644
--- a/arch/s390/lib/delay.c
+++ b/arch/s390/lib/delay.c
@@ -30,7 +30,7 @@ void __delay(unsigned long loops)
*/
__asm__ __volatile__(
"0: brct %0,0b"
- : /* no outputs */ : "r" (loops/2) );
+ : /* no outputs */ : "r" ((loops/2) + 1));
}
/*
diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c
index 60f80a4eed4..b9b7958a226 100644
--- a/arch/s390/lib/spinlock.c
+++ b/arch/s390/lib/spinlock.c
@@ -2,8 +2,7 @@
* arch/s390/lib/spinlock.c
* Out of line spinlock code.
*
- * S390 version
- * Copyright (C) 2004 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Copyright (C) IBM Corp. 2004, 2006
* Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
*/
@@ -44,6 +43,8 @@ _raw_spin_lock_wait(raw_spinlock_t *lp, unsigned int pc)
_diag44();
count = spin_retry;
}
+ if (__raw_spin_is_locked(lp))
+ continue;
if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0)
return;
}
@@ -56,6 +57,8 @@ _raw_spin_trylock_retry(raw_spinlock_t *lp, unsigned int pc)
int count = spin_retry;
while (count-- > 0) {
+ if (__raw_spin_is_locked(lp))
+ continue;
if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0)
return 1;
}
@@ -74,6 +77,8 @@ _raw_read_lock_wait(raw_rwlock_t *rw)
_diag44();
count = spin_retry;
}
+ if (!__raw_read_can_lock(rw))
+ continue;
old = rw->lock & 0x7fffffffU;
if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old)
return;
@@ -88,6 +93,8 @@ _raw_read_trylock_retry(raw_rwlock_t *rw)
int count = spin_retry;
while (count-- > 0) {
+ if (!__raw_read_can_lock(rw))
+ continue;
old = rw->lock & 0x7fffffffU;
if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old)
return 1;
@@ -106,6 +113,8 @@ _raw_write_lock_wait(raw_rwlock_t *rw)
_diag44();
count = spin_retry;
}
+ if (!__raw_write_can_lock(rw))
+ continue;
if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0)
return;
}
@@ -118,6 +127,8 @@ _raw_write_trylock_retry(raw_rwlock_t *rw)
int count = spin_retry;
while (count-- > 0) {
+ if (!__raw_write_can_lock(rw))
+ continue;
if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0)
return 1;
}
diff --git a/arch/s390/lib/uaccess.S b/arch/s390/lib/uaccess.S
index 88fc94fe648..5d59e262504 100644
--- a/arch/s390/lib/uaccess.S
+++ b/arch/s390/lib/uaccess.S
@@ -198,12 +198,12 @@ __strnlen_user_asm:
0: srst %r2,%r1
jo 0b
sacf 0
- jh 1f # \0 found in string ?
ahi %r2,1 # strnlen_user result includes the \0
-1: slr %r2,%r3
+ # or return count+1 if \0 not found
+ slr %r2,%r3
br %r14
2: sacf 0
- lhi %r2,-EFAULT
+ slr %r2,%r2 # return 0 on exception
br %r14
.section __ex_table,"a"
.long 0b,2b
diff --git a/arch/s390/lib/uaccess64.S b/arch/s390/lib/uaccess64.S
index 50219786fc7..19b41a33c23 100644
--- a/arch/s390/lib/uaccess64.S
+++ b/arch/s390/lib/uaccess64.S
@@ -194,12 +194,12 @@ __strnlen_user_asm:
0: srst %r2,%r1
jo 0b
sacf 0
- jh 1f # \0 found in string ?
aghi %r2,1 # strnlen_user result includes the \0
-1: slgr %r2,%r3
+ # or return count+1 if \0 not found
+ slgr %r2,%r3
br %r14
2: sacf 0
- lghi %r2,-EFAULT
+ slgr %r2,%r2 # return 0 on exception
br %r14
.section __ex_table,"a"
.quad 0b,2b
diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c
index 2d5cb138575..b075ab499d0 100644
--- a/arch/s390/mm/cmm.c
+++ b/arch/s390/mm/cmm.c
@@ -42,8 +42,8 @@ static volatile long cmm_timed_pages_target = 0;
static long cmm_timeout_pages = 0;
static long cmm_timeout_seconds = 0;
-static struct cmm_page_array *cmm_page_list = 0;
-static struct cmm_page_array *cmm_timed_page_list = 0;
+static struct cmm_page_array *cmm_page_list = NULL;
+static struct cmm_page_array *cmm_timed_page_list = NULL;
static unsigned long cmm_thread_active = 0;
static struct work_struct cmm_thread_starter;
@@ -259,7 +259,7 @@ static struct ctl_table cmm_table[];
static int
cmm_pages_handler(ctl_table *ctl, int write, struct file *filp,
- void *buffer, size_t *lenp, loff_t *ppos)
+ void __user *buffer, size_t *lenp, loff_t *ppos)
{
char buf[16], *p;
long pages;
@@ -300,7 +300,7 @@ cmm_pages_handler(ctl_table *ctl, int write, struct file *filp,
static int
cmm_timeout_handler(ctl_table *ctl, int write, struct file *filp,
- void *buffer, size_t *lenp, loff_t *ppos)
+ void __user *buffer, size_t *lenp, loff_t *ppos)
{
char buf[64], *p;
long pages, seconds;
@@ -419,7 +419,7 @@ cmm_init (void)
#ifdef CONFIG_CMM_IUCV
smsg_register_callback(SMSG_PREFIX, cmm_smsg_target);
#endif
- INIT_WORK(&cmm_thread_starter, (void *) cmm_start_thread, 0);
+ INIT_WORK(&cmm_thread_starter, (void *) cmm_start_thread, NULL);
init_waitqueue_head(&cmm_thread_wait);
init_timer(&cmm_timer);
return 0;