summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@shinybook.infradead.org>2005-05-03 07:14:09 (GMT)
committerDavid Woodhouse <dwmw2@shinybook.infradead.org>2005-05-03 07:14:09 (GMT)
commit27b030d58c8e72fc7a95187a791bd9406e350f02 (patch)
treeab3bab7f39a5ce5bab65578a7e08fa4dfdeb198c /arch
parent79d20b14a0d651f15b0ef9a22b6cf12d284a6d38 (diff)
parent6628465e33ca694bd8fd5c3cf4eb7ff9177bc694 (diff)
downloadlinux-27b030d58c8e72fc7a95187a791bd9406e350f02.tar.xz
Merge with master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/kernel/osf_sys.c16
-rw-r--r--arch/alpha/kernel/ptrace.c5
-rw-r--r--arch/alpha/kernel/systbls.S2
-rw-r--r--arch/arm/common/rtctime.c29
-rw-r--r--arch/arm/configs/ixdp2800_defconfig2
-rw-r--r--arch/arm/kernel/entry-armv.S213
-rw-r--r--arch/arm/kernel/ptrace.c5
-rw-r--r--arch/arm/kernel/sys_arm.c12
-rw-r--r--arch/arm/kernel/traps.c58
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c17
-rw-r--r--arch/arm/mach-integrator/time.c17
-rw-r--r--arch/arm/mach-ixp2000/ixdp2800.c147
-rw-r--r--arch/arm/mach-ixp2000/pci.c8
-rw-r--r--arch/arm/mach-pxa/generic.c25
-rw-r--r--arch/arm/mm/Kconfig14
-rw-r--r--arch/arm/mm/abort-ev6.S16
-rw-r--r--arch/arm/mm/mm-armv.c5
-rw-r--r--arch/arm26/kernel/ptrace.c5
-rw-r--r--arch/arm26/mm/small_page.c6
-rw-r--r--arch/cris/arch-v10/kernel/ptrace.c5
-rw-r--r--arch/frv/kernel/ptrace.c5
-rw-r--r--arch/h8300/kernel/ptrace.c5
-rw-r--r--arch/i386/Kconfig18
-rw-r--r--arch/i386/Makefile7
-rw-r--r--arch/i386/boot/compressed/misc.c1
-rw-r--r--arch/i386/boot/setup.S6
-rw-r--r--arch/i386/kernel/Makefile1
-rw-r--r--arch/i386/kernel/apic.c2
-rw-r--r--arch/i386/kernel/cpu/mtrr/generic.c4
-rw-r--r--arch/i386/kernel/cpu/mtrr/main.c14
-rw-r--r--arch/i386/kernel/cpu/proc.c2
-rw-r--r--arch/i386/kernel/entry.S304
-rw-r--r--arch/i386/kernel/head.S2
-rw-r--r--arch/i386/kernel/io_apic.c2
-rw-r--r--arch/i386/kernel/nmi.c11
-rw-r--r--arch/i386/kernel/process.c4
-rw-r--r--arch/i386/kernel/ptrace.c5
-rw-r--r--arch/i386/kernel/reboot.c2
-rw-r--r--arch/i386/kernel/reboot_fixups.c56
-rw-r--r--arch/i386/kernel/smpboot.c3
-rw-r--r--arch/i386/kernel/syscall_table.S291
-rw-r--r--arch/i386/kernel/time.c2
-rw-r--r--arch/i386/kernel/time_hpet.c48
-rw-r--r--arch/i386/kernel/timers/timer_hpet.c11
-rw-r--r--arch/i386/kernel/timers/timer_tsc.c2
-rw-r--r--arch/i386/kernel/traps.c6
-rw-r--r--arch/i386/kernel/vm86.c21
-rw-r--r--arch/i386/oprofile/nmi_timer_int.c2
-rw-r--r--arch/i386/pci/irq.c2
-rw-r--r--arch/ia64/kernel/entry.S2
-rw-r--r--arch/ia64/kernel/ptrace.c5
-rw-r--r--arch/ia64/kernel/sys_ia64.c14
-rw-r--r--arch/m32r/kernel/ptrace.c5
-rw-r--r--arch/m68k/kernel/ptrace.c5
-rw-r--r--arch/m68knommu/kernel/ptrace.c5
-rw-r--r--arch/mips/kernel/ptrace.c3
-rw-r--r--arch/mips/kernel/ptrace32.c3
-rw-r--r--arch/mips/kernel/syscall.c16
-rw-r--r--arch/parisc/kernel/ptrace.c7
-rw-r--r--arch/parisc/kernel/sys_parisc.c11
-rw-r--r--arch/parisc/kernel/syscall_table.S2
-rw-r--r--arch/ppc/Kconfig4
-rw-r--r--arch/ppc/Makefile1
-rw-r--r--arch/ppc/boot/images/Makefile3
-rw-r--r--arch/ppc/kernel/Makefile1
-rw-r--r--arch/ppc/kernel/align.c12
-rw-r--r--arch/ppc/kernel/cpu_setup_6xx.S42
-rw-r--r--arch/ppc/kernel/entry.S59
-rw-r--r--arch/ppc/kernel/fpu.S133
-rw-r--r--arch/ppc/kernel/head.S163
-rw-r--r--arch/ppc/kernel/head_44x.S6
-rw-r--r--arch/ppc/kernel/head_booke.h7
-rw-r--r--arch/ppc/kernel/head_fsl_booke.S8
-rw-r--r--arch/ppc/kernel/misc.S12
-rw-r--r--arch/ppc/kernel/ptrace.c5
-rw-r--r--arch/ppc/kernel/traps.c2
-rw-r--r--arch/ppc/platforms/pmac_cache.S54
-rw-r--r--arch/ppc/platforms/pmac_feature.c216
-rw-r--r--arch/ppc/platforms/pmac_sleep.S4
-rw-r--r--arch/ppc/platforms/radstone_ppc7d.c60
-rw-r--r--arch/ppc/platforms/radstone_ppc7d.h1
-rw-r--r--arch/ppc/syslib/cpm2_pic.c5
-rw-r--r--arch/ppc64/boot/addnote.c60
-rw-r--r--arch/ppc64/kernel/HvLpEvent.c2
-rw-r--r--arch/ppc64/kernel/nvram.c17
-rw-r--r--arch/ppc64/kernel/pSeries_hvCall.S8
-rw-r--r--arch/ppc64/kernel/prom.c4
-rw-r--r--arch/ppc64/kernel/prom_init.c115
-rw-r--r--arch/ppc64/kernel/ptrace.c5
-rw-r--r--arch/ppc64/kernel/ptrace32.c5
-rw-r--r--arch/ppc64/kernel/signal32.c4
-rw-r--r--arch/ppc64/kernel/smp.c12
-rw-r--r--arch/ppc64/kernel/time.c12
-rw-r--r--arch/ppc64/kernel/vdso32/Makefile2
-rw-r--r--arch/ppc64/kernel/vdso32/note.S25
-rw-r--r--arch/ppc64/kernel/vdso32/vdso32.lds.S3
-rw-r--r--arch/ppc64/kernel/vdso64/Makefile2
-rw-r--r--arch/ppc64/kernel/vdso64/note.S1
-rw-r--r--arch/ppc64/kernel/vdso64/vdso64.lds.S5
-rw-r--r--arch/ppc64/mm/hash_low.S9
-rw-r--r--arch/ppc64/mm/hugetlbpage.c45
-rw-r--r--arch/ppc64/mm/init.c198
-rw-r--r--arch/ppc64/mm/slb.c9
-rw-r--r--arch/s390/defconfig19
-rw-r--r--arch/s390/kernel/compat_ioctl.c7
-rw-r--r--arch/s390/kernel/ptrace.c5
-rw-r--r--arch/s390/kernel/s390_ksyms.c1
-rw-r--r--arch/s390/kernel/setup.c401
-rw-r--r--arch/s390/kernel/time.c12
-rw-r--r--arch/s390/kernel/vtime.c25
-rw-r--r--arch/s390/mm/cmm.c9
-rw-r--r--arch/s390/mm/init.c15
-rw-r--r--arch/sh/kernel/ptrace.c5
-rw-r--r--arch/sh64/kernel/ptrace.c5
-rw-r--r--arch/sh64/kernel/sys_sh64.c15
-rw-r--r--arch/sh64/kernel/syscalls.S2
-rw-r--r--arch/sparc/kernel/ptrace.c3
-rw-r--r--arch/sparc64/kernel/ptrace.c3
-rw-r--r--arch/um/Kconfig1
-rw-r--r--arch/um/Kconfig_i3866
-rw-r--r--arch/um/Kconfig_x86_646
-rw-r--r--arch/um/Makefile-i3862
-rw-r--r--arch/um/defconfig10
-rw-r--r--arch/um/drivers/chan_kern.c16
-rw-r--r--arch/um/drivers/line.c318
-rw-r--r--arch/um/drivers/ssl.c25
-rw-r--r--arch/um/drivers/stdio_console.c19
-rw-r--r--arch/um/drivers/ubd_kern.c14
-rw-r--r--arch/um/include/line.h36
-rw-r--r--arch/um/include/sysdep-i386/syscalls.h99
-rw-r--r--arch/um/include/sysdep-x86_64/syscalls.h59
-rw-r--r--arch/um/kernel/Makefile5
-rw-r--r--arch/um/kernel/process_kern.c4
-rw-r--r--arch/um/kernel/ptrace.c4
-rw-r--r--arch/um/kernel/skas/include/uaccess-skas.h2
-rw-r--r--arch/um/kernel/skas/uaccess.c4
-rw-r--r--arch/um/kernel/sys_call_table.c276
-rw-r--r--arch/um/kernel/tt/include/uaccess-tt.h2
-rw-r--r--arch/um/os-Linux/sys-i386/registers.c7
-rw-r--r--arch/um/sys-i386/Makefile3
-rw-r--r--arch/um/sys-i386/sys_call_table.S16
-rw-r--r--arch/um/sys-x86_64/Makefile2
-rw-r--r--arch/um/sys-x86_64/syscall_table.c59
-rw-r--r--arch/um/sys-x86_64/syscalls.c12
-rw-r--r--arch/v850/kernel/ptrace.c3
-rw-r--r--arch/x86_64/boot/setup.S6
-rw-r--r--arch/x86_64/kernel/e820.c26
-rw-r--r--arch/x86_64/kernel/early_printk.c2
-rw-r--r--arch/x86_64/kernel/entry.S5
-rw-r--r--arch/x86_64/kernel/head64.c7
-rw-r--r--arch/x86_64/kernel/io_apic.c2
-rw-r--r--arch/x86_64/kernel/nmi.c9
-rw-r--r--arch/x86_64/kernel/process.c12
-rw-r--r--arch/x86_64/kernel/ptrace.c5
-rw-r--r--arch/x86_64/kernel/setup.c12
-rw-r--r--arch/x86_64/kernel/setup64.c3
-rw-r--r--arch/x86_64/kernel/sys_x86_64.c6
157 files changed, 2595 insertions, 1902 deletions
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index b5d0fd2..64e450d 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -457,22 +457,6 @@ osf_getdomainname(char __user *name, int namelen)
return 0;
}
-asmlinkage long
-osf_shmat(int shmid, void __user *shmaddr, int shmflg)
-{
- unsigned long raddr;
- long err;
-
- err = do_shmat(shmid, shmaddr, shmflg, &raddr);
-
- /*
- * This works because all user-level addresses are
- * non-negative longs!
- */
- return err ? err : (long)raddr;
-}
-
-
/*
* The following stuff should move into a header file should it ever
* be labeled "officially supported." Right now, there is just enough
diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c
index d005831..bbd3753 100644
--- a/arch/alpha/kernel/ptrace.c
+++ b/arch/alpha/kernel/ptrace.c
@@ -14,6 +14,7 @@
#include <linux/user.h>
#include <linux/slab.h>
#include <linux/security.h>
+#include <linux/signal.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
@@ -335,7 +336,7 @@ do_sys_ptrace(long request, long pid, long addr, long data,
/* continue and stop at next (return from) syscall */
case PTRACE_CONT: /* restart after signal. */
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
if (request == PTRACE_SYSCALL)
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -365,7 +366,7 @@ do_sys_ptrace(long request, long pid, long addr, long data,
case PTRACE_SINGLESTEP: /* execute single instruction. */
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
/* Mark single stepping. */
child->thread_info->bpt_nsaved = -1;
diff --git a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S
index 3864b33..0521208 100644
--- a/arch/alpha/kernel/systbls.S
+++ b/arch/alpha/kernel/systbls.S
@@ -227,7 +227,7 @@ sys_call_table:
.quad sys_semop
.quad osf_utsname
.quad sys_lchown
- .quad osf_shmat
+ .quad sys_shmat
.quad sys_shmctl /* 210 */
.quad sys_shmdt
.quad sys_shmget
diff --git a/arch/arm/common/rtctime.c b/arch/arm/common/rtctime.c
index c397e71..72b03f2 100644
--- a/arch/arm/common/rtctime.c
+++ b/arch/arm/common/rtctime.c
@@ -141,10 +141,10 @@ void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc
next->tm_sec = alrm->tm_sec;
}
-static inline void rtc_read_time(struct rtc_ops *ops, struct rtc_time *tm)
+static inline int rtc_read_time(struct rtc_ops *ops, struct rtc_time *tm)
{
memset(tm, 0, sizeof(struct rtc_time));
- ops->read_time(tm);
+ return ops->read_time(tm);
}
static inline int rtc_set_time(struct rtc_ops *ops, struct rtc_time *tm)
@@ -163,8 +163,7 @@ static inline int rtc_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm)
int ret = -EINVAL;
if (ops->read_alarm) {
memset(alrm, 0, sizeof(struct rtc_wkalrm));
- ops->read_alarm(alrm);
- ret = 0;
+ ret = ops->read_alarm(alrm);
}
return ret;
}
@@ -283,7 +282,9 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
break;
case RTC_RD_TIME:
- rtc_read_time(ops, &tm);
+ ret = rtc_read_time(ops, &tm);
+ if (ret)
+ break;
ret = copy_to_user(uarg, &tm, sizeof(tm));
if (ret)
ret = -EFAULT;
@@ -424,15 +425,15 @@ static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eo
struct rtc_time tm;
char *p = page;
- rtc_read_time(ops, &tm);
-
- p += sprintf(p,
- "rtc_time\t: %02d:%02d:%02d\n"
- "rtc_date\t: %04d-%02d-%02d\n"
- "rtc_epoch\t: %04lu\n",
- tm.tm_hour, tm.tm_min, tm.tm_sec,
- tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
- rtc_epoch);
+ if (rtc_read_time(ops, &tm) == 0) {
+ p += sprintf(p,
+ "rtc_time\t: %02d:%02d:%02d\n"
+ "rtc_date\t: %04d-%02d-%02d\n"
+ "rtc_epoch\t: %04lu\n",
+ tm.tm_hour, tm.tm_min, tm.tm_sec,
+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
+ rtc_epoch);
+ }
if (rtc_read_alarm(ops, &alrm) == 0) {
p += sprintf(p, "alrm_time\t: ");
diff --git a/arch/arm/configs/ixdp2800_defconfig b/arch/arm/configs/ixdp2800_defconfig
index d36f991..7be3521 100644
--- a/arch/arm/configs/ixdp2800_defconfig
+++ b/arch/arm/configs/ixdp2800_defconfig
@@ -133,7 +133,7 @@ CONFIG_ALIGNMENT_TRAP=y
#
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,9600 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware"
+CONFIG_CMDLINE="console=ttyS0,9600 root=/dev/nfs ip=bootp mem=64M@0x0"
# CONFIG_XIP_KERNEL is not set
#
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 2a5c3fe..080df90 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -269,6 +269,12 @@ __pabt_svc:
add r5, sp, #S_PC
ldmia r7, {r2 - r4} @ Get USR pc, cpsr
+#if __LINUX_ARM_ARCH__ < 6
+ @ make sure our user space atomic helper is aborted
+ cmp r2, #VIRT_OFFSET
+ bichs r3, r3, #PSR_Z_BIT
+#endif
+
@
@ We are now ready to fill in the remaining blanks on the stack:
@
@@ -499,8 +505,12 @@ ENTRY(__switch_to)
mra r4, r5, acc0
stmia ip, {r4, r5}
#endif
+#ifdef CONFIG_HAS_TLS_REG
+ mcr p15, 0, r3, c13, c0, 3 @ set TLS register
+#else
mov r4, #0xffff0fff
- str r3, [r4, #-3] @ Set TLS ptr
+ str r3, [r4, #-15] @ TLS val at 0xffff0ff0
+#endif
mcr p15, 0, r6, c3, c0, 0 @ Set domain register
#ifdef CONFIG_VFP
@ Always disable VFP so we can lazily save/restore the old
@@ -519,6 +529,207 @@ ENTRY(__switch_to)
ldmib r2, {r4 - sl, fp, sp, pc} @ Load all regs saved previously
__INIT
+
+/*
+ * User helpers.
+ *
+ * These are segment of kernel provided user code reachable from user space
+ * at a fixed address in kernel memory. This is used to provide user space
+ * with some operations which require kernel help because of unimplemented
+ * native feature and/or instructions in many ARM CPUs. The idea is for
+ * this code to be executed directly in user mode for best efficiency but
+ * which is too intimate with the kernel counter part to be left to user
+ * libraries. In fact this code might even differ from one CPU to another
+ * depending on the available instruction set and restrictions like on
+ * SMP systems. In other words, the kernel reserves the right to change
+ * this code as needed without warning. Only the entry points and their
+ * results are guaranteed to be stable.
+ *
+ * Each segment is 32-byte aligned and will be moved to the top of the high
+ * vector page. New segments (if ever needed) must be added in front of
+ * existing ones. This mechanism should be used only for things that are
+ * really small and justified, and not be abused freely.
+ *
+ * User space is expected to implement those things inline when optimizing
+ * for a processor that has the necessary native support, but only if such
+ * resulting binaries are already to be incompatible with earlier ARM
+ * processors due to the use of unsupported instructions other than what
+ * is provided here. In other words don't make binaries unable to run on
+ * earlier processors just for the sake of not using these kernel helpers
+ * if your compiled code is not going to use the new instructions for other
+ * purpose.
+ */
+
+ .align 5
+ .globl __kuser_helper_start
+__kuser_helper_start:
+
+/*
+ * Reference prototype:
+ *
+ * int __kernel_cmpxchg(int oldval, int newval, int *ptr)
+ *
+ * Input:
+ *
+ * r0 = oldval
+ * r1 = newval
+ * r2 = ptr
+ * lr = return address
+ *
+ * Output:
+ *
+ * r0 = returned value (zero or non-zero)
+ * C flag = set if r0 == 0, clear if r0 != 0
+ *
+ * Clobbered:
+ *
+ * r3, ip, flags
+ *
+ * Definition and user space usage example:
+ *
+ * typedef int (__kernel_cmpxchg_t)(int oldval, int newval, int *ptr);
+ * #define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0)
+ *
+ * Atomically store newval in *ptr if *ptr is equal to oldval for user space.
+ * Return zero if *ptr was changed or non-zero if no exchange happened.
+ * The C flag is also set if *ptr was changed to allow for assembly
+ * optimization in the calling code.
+ *
+ * For example, a user space atomic_add implementation could look like this:
+ *
+ * #define atomic_add(ptr, val) \
+ * ({ register unsigned int *__ptr asm("r2") = (ptr); \
+ * register unsigned int __result asm("r1"); \
+ * asm volatile ( \
+ * "1: @ atomic_add\n\t" \
+ * "ldr r0, [r2]\n\t" \
+ * "mov r3, #0xffff0fff\n\t" \
+ * "add lr, pc, #4\n\t" \
+ * "add r1, r0, %2\n\t" \
+ * "add pc, r3, #(0xffff0fc0 - 0xffff0fff)\n\t" \
+ * "bcc 1b" \
+ * : "=&r" (__result) \
+ * : "r" (__ptr), "rIL" (val) \
+ * : "r0","r3","ip","lr","cc","memory" ); \
+ * __result; })
+ */
+
+__kuser_cmpxchg: @ 0xffff0fc0
+
+#if __LINUX_ARM_ARCH__ < 6
+
+#ifdef CONFIG_SMP /* sanity check */
+#error "CONFIG_SMP on a machine supporting pre-ARMv6 processors?"
+#endif
+
+ /*
+ * Theory of operation:
+ *
+ * We set the Z flag before loading oldval. If ever an exception
+ * occurs we can not be sure the loaded value will still be the same
+ * when the exception returns, therefore the user exception handler
+ * will clear the Z flag whenever the interrupted user code was
+ * actually from the kernel address space (see the usr_entry macro).
+ *
+ * The post-increment on the str is used to prevent a race with an
+ * exception happening just after the str instruction which would
+ * clear the Z flag although the exchange was done.
+ */
+ 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
+ mov pc, lr
+
+#else
+
+ ldrex r3, [r2]
+ subs r3, r3, r0
+ strexeq r3, r1, [r2]
+ rsbs r0, r3, #0
+ mov pc, lr
+
+#endif
+
+ .align 5
+
+/*
+ * Reference prototype:
+ *
+ * int __kernel_get_tls(void)
+ *
+ * Input:
+ *
+ * lr = return address
+ *
+ * Output:
+ *
+ * r0 = TLS value
+ *
+ * Clobbered:
+ *
+ * the Z flag might be lost
+ *
+ * Definition and user space usage example:
+ *
+ * typedef int (__kernel_get_tls_t)(void);
+ * #define __kernel_get_tls (*(__kernel_get_tls_t *)0xffff0fe0)
+ *
+ * Get the TLS value as previously set via the __ARM_NR_set_tls syscall.
+ *
+ * This could be used as follows:
+ *
+ * #define __kernel_get_tls() \
+ * ({ register unsigned int __val asm("r0"); \
+ * asm( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #31" \
+ * : "=r" (__val) : : "lr","cc" ); \
+ * __val; })
+ */
+
+__kuser_get_tls: @ 0xffff0fe0
+
+#ifndef CONFIG_HAS_TLS_REG
+
+#ifdef CONFIG_SMP /* sanity check */
+#error "CONFIG_SMP without CONFIG_HAS_TLS_REG is wrong"
+#endif
+
+ ldr r0, [pc, #(16 - 8)] @ TLS stored at 0xffff0ff0
+ mov pc, lr
+
+#else
+
+ mrc p15, 0, r0, c13, c0, 3 @ read TLS register
+ mov pc, lr
+
+#endif
+
+ .rep 5
+ .word 0 @ pad up to __kuser_helper_version
+ .endr
+
+/*
+ * Reference declaration:
+ *
+ * extern unsigned int __kernel_helper_version;
+ *
+ * Definition and user space usage example:
+ *
+ * #define __kernel_helper_version (*(unsigned int *)0xffff0ffc)
+ *
+ * User space may read this to determine the curent number of helpers
+ * available.
+ */
+
+__kuser_helper_version: @ 0xffff0ffc
+ .word ((__kuser_helper_end - __kuser_helper_start) >> 5)
+
+ .globl __kuser_helper_end
+__kuser_helper_end:
+
+
/*
* Vector stubs.
*
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index efd7a34..cd99b83 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -19,6 +19,7 @@
#include <linux/user.h>
#include <linux/security.h>
#include <linux/init.h>
+#include <linux/signal.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
@@ -693,7 +694,7 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
case PTRACE_SYSCALL:
case PTRACE_CONT:
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
if (request == PTRACE_SYSCALL)
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -728,7 +729,7 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
*/
case PTRACE_SINGLESTEP:
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
child->ptrace |= PT_SINGLESTEP;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
index 7ba6342..ef32577 100644
--- a/arch/arm/kernel/sys_arm.c
+++ b/arch/arm/kernel/sys_arm.c
@@ -227,18 +227,6 @@ asmlinkage int sys_ipc(uint call, int first, int second, int third,
}
}
-asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg,
- unsigned long __user *addr)
-{
- unsigned long ret;
- long err;
-
- err = do_shmat(shmid, shmaddr, shmflg, &ret);
- if (err == 0)
- err = put_user(ret, addr);
- return err;
-}
-
/* Fork a new task - this creates a new program thread.
* This is called indirectly via a small wrapper
*/
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 0078aeb..3a001fe 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -450,13 +450,17 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
case NR(set_tls):
thread->tp_value = regs->ARM_r0;
+#ifdef CONFIG_HAS_TLS_REG
+ asm ("mcr p15, 0, %0, c13, c0, 3" : : "r" (regs->ARM_r0) );
+#else
/*
- * Our user accessible TLS ptr is located at 0xffff0ffc.
- * On SMP read access to this address must raise a fault
- * and be emulated from the data abort handler.
- * m
+ * User space must never try to access this directly.
+ * Expect your app to break eventually if you do so.
+ * The user helper at 0xffff0fe0 must be used instead.
+ * (see entry-armv.S for details)
*/
- *((unsigned long *)0xffff0ffc) = thread->tp_value;
+ *((unsigned int *)0xffff0ff0) = regs->ARM_r0;
+#endif
return 0;
default:
@@ -493,6 +497,41 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
return 0;
}
+#if defined(CONFIG_CPU_32v6) && !defined(CONFIG_HAS_TLS_REG)
+
+/*
+ * We might be running on an ARMv6+ processor which should have the TLS
+ * register, but for some reason we can't use it and have to emulate it.
+ */
+
+static int get_tp_trap(struct pt_regs *regs, unsigned int instr)
+{
+ int reg = (instr >> 12) & 15;
+ if (reg == 15)
+ return 1;
+ regs->uregs[reg] = current_thread_info()->tp_value;
+ regs->ARM_pc += 4;
+ return 0;
+}
+
+static struct undef_hook arm_mrc_hook = {
+ .instr_mask = 0x0fff0fff,
+ .instr_val = 0x0e1d0f70,
+ .cpsr_mask = PSR_T_BIT,
+ .cpsr_val = 0,
+ .fn = get_tp_trap,
+};
+
+static int __init arm_mrc_hook_init(void)
+{
+ register_undef_hook(&arm_mrc_hook);
+ return 0;
+}
+
+late_initcall(arm_mrc_hook_init);
+
+#endif
+
void __bad_xchg(volatile void *ptr, int size)
{
printk("xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n",
@@ -580,14 +619,17 @@ void __init trap_init(void)
{
extern char __stubs_start[], __stubs_end[];
extern char __vectors_start[], __vectors_end[];
+ extern char __kuser_helper_start[], __kuser_helper_end[];
+ int kuser_sz = __kuser_helper_end - __kuser_helper_start;
/*
- * Copy the vectors and stubs (in entry-armv.S) into the
- * vector page, mapped at 0xffff0000, and ensure these are
- * visible to the instruction stream.
+ * Copy the vectors, stubs and kuser helpers (in entry-armv.S)
+ * into the vector page, mapped at 0xffff0000, and ensure these
+ * are visible to the instruction stream.
*/
memcpy((void *)0xffff0000, __vectors_start, __vectors_end - __vectors_start);
memcpy((void *)0xffff0200, __stubs_start, __stubs_end - __stubs_start);
+ memcpy((void *)0xffff1000 - kuser_sz, __kuser_helper_start, kuser_sz);
flush_icache_range(0xffff0000, 0xffff0000 + PAGE_SIZE);
modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
}
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 68e15c3..3b948e8 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -420,7 +420,22 @@ static struct clcd_panel vga = {
*/
static void cp_clcd_enable(struct clcd_fb *fb)
{
- cm_control(CM_CTRL_LCDMUXSEL_MASK, CM_CTRL_LCDMUXSEL_VGA);
+ u32 val;
+
+ if (fb->fb.var.bits_per_pixel <= 8)
+ val = CM_CTRL_LCDMUXSEL_VGA_8421BPP;
+ else if (fb->fb.var.bits_per_pixel <= 16)
+ val = CM_CTRL_LCDMUXSEL_VGA_16BPP;
+ else
+ val = 0; /* no idea for this, don't trust the docs */
+
+ cm_control(CM_CTRL_LCDMUXSEL_MASK|
+ CM_CTRL_LCDEN0|
+ CM_CTRL_LCDEN1|
+ CM_CTRL_STATIC1|
+ CM_CTRL_STATIC2|
+ CM_CTRL_STATIC|
+ CM_CTRL_n24BITEN, val);
}
static unsigned long framesize = SZ_1M;
diff --git a/arch/arm/mach-integrator/time.c b/arch/arm/mach-integrator/time.c
index 20729de..1a844ca 100644
--- a/arch/arm/mach-integrator/time.c
+++ b/arch/arm/mach-integrator/time.c
@@ -40,25 +40,32 @@ static int integrator_set_rtc(void)
return 1;
}
-static void rtc_read_alarm(struct rtc_wkalrm *alrm)
+static int rtc_read_alarm(struct rtc_wkalrm *alrm)
{
rtc_time_to_tm(readl(rtc_base + RTC_MR), &alrm->time);
+ return 0;
}
-static int rtc_set_alarm(struct rtc_wkalrm *alrm)
+static inline int rtc_set_alarm(struct rtc_wkalrm *alrm)
{
unsigned long time;
int ret;
- ret = rtc_tm_to_time(&alrm->time, &time);
+ /*
+ * At the moment, we can only deal with non-wildcarded alarm times.
+ */
+ ret = rtc_valid_tm(&alrm->time);
+ if (ret == 0)
+ ret = rtc_tm_to_time(&alrm->time, &time);
if (ret == 0)
writel(time, rtc_base + RTC_MR);
return ret;
}
-static void rtc_read_time(struct rtc_time *tm)
+static int rtc_read_time(struct rtc_time *tm)
{
rtc_time_to_tm(readl(rtc_base + RTC_DR), tm);
+ return 0;
}
/*
@@ -69,7 +76,7 @@ static void rtc_read_time(struct rtc_time *tm)
* edge of the 1Hz clock, we must write the time one second
* in advance.
*/
-static int rtc_set_time(struct rtc_time *tm)
+static inline int rtc_set_time(struct rtc_time *tm)
{
unsigned long time;
int ret;
diff --git a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c
index c4683aa..aec13c7 100644
--- a/arch/arm/mach-ixp2000/ixdp2800.c
+++ b/arch/arm/mach-ixp2000/ixdp2800.c
@@ -65,19 +65,102 @@ static struct sys_timer ixdp2800_timer = {
/*************************************************************************
* IXDP2800 PCI
*************************************************************************/
+static void __init ixdp2800_slave_disable_pci_master(void)
+{
+ *IXP2000_PCI_CMDSTAT &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
+}
+
+static void __init ixdp2800_master_wait_for_slave(void)
+{
+ volatile u32 *addr;
+
+ printk(KERN_INFO "IXDP2800: waiting for slave NPU to configure "
+ "its BAR sizes\n");
+
+ addr = ixp2000_pci_config_addr(0, IXDP2X00_SLAVE_NPU_DEVFN,
+ PCI_BASE_ADDRESS_1);
+ do {
+ *addr = 0xffffffff;
+ cpu_relax();
+ } while (*addr != 0xfe000008);
+
+ addr = ixp2000_pci_config_addr(0, IXDP2X00_SLAVE_NPU_DEVFN,
+ PCI_BASE_ADDRESS_2);
+ do {
+ *addr = 0xffffffff;
+ cpu_relax();
+ } while (*addr != 0xc0000008);
+
+ /*
+ * Configure the slave's SDRAM BAR by hand.
+ */
+ *addr = 0x40000008;
+}
+
+static void __init ixdp2800_slave_wait_for_master_enable(void)
+{
+ printk(KERN_INFO "IXDP2800: waiting for master NPU to enable us\n");
+
+ while ((*IXP2000_PCI_CMDSTAT & PCI_COMMAND_MASTER) == 0)
+ cpu_relax();
+}
+
void __init ixdp2800_pci_preinit(void)
{
printk("ixdp2x00_pci_preinit called\n");
- *IXP2000_PCI_ADDR_EXT = 0x0000e000;
+ *IXP2000_PCI_ADDR_EXT = 0x0001e000;
+
+ if (!ixdp2x00_master_npu())
+ ixdp2800_slave_disable_pci_master();
- *IXP2000_PCI_DRAM_BASE_ADDR_MASK = (0x40000000 - 1) & ~0xfffff;
*IXP2000_PCI_SRAM_BASE_ADDR_MASK = (0x2000000 - 1) & ~0x3ffff;
+ *IXP2000_PCI_DRAM_BASE_ADDR_MASK = (0x40000000 - 1) & ~0xfffff;
ixp2000_pci_preinit();
+
+ if (ixdp2x00_master_npu()) {
+ /*
+ * Wait until the slave set its SRAM/SDRAM BAR sizes
+ * correctly before we proceed to scan and enumerate
+ * the bus.
+ */
+ ixdp2800_master_wait_for_slave();
+
+ /*
+ * We configure the SDRAM BARs by hand because they
+ * are 1G and fall outside of the regular allocated
+ * PCI address space.
+ */
+ *IXP2000_PCI_SDRAM_BAR = 0x00000008;
+ } else {
+ /*
+ * Wait for the master to complete scanning the bus
+ * and assigning resources before we proceed to scan
+ * the bus ourselves. Set pci=firmware to honor the
+ * master's resource assignment.
+ */
+ ixdp2800_slave_wait_for_master_enable();
+ pcibios_setup("firmware");
+ }
}
-int ixdp2800_pci_setup(int nr, struct pci_sys_data *sys)
+/*
+ * We assign the SDRAM BARs for the two IXP2800 CPUs by hand, outside
+ * of the regular PCI window, because there's only 512M of outbound PCI
+ * memory window on each IXP, while we need 1G for each of the BARs.
+ */
+static void __devinit ixp2800_pci_fixup(struct pci_dev *dev)
+{
+ if (machine_is_ixdp2800()) {
+ dev->resource[2].start = 0;
+ dev->resource[2].end = 0;
+ dev->resource[2].flags = 0;
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IXP2800, ixp2800_pci_fixup);
+
+static int __init ixdp2800_pci_setup(int nr, struct pci_sys_data *sys)
{
sys->mem_offset = 0x00000000;
@@ -129,22 +212,47 @@ static int __init ixdp2800_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
} else return IRQ_IXP2000_PCIB; /* Slave NIC interrupt */
}
-static void ixdp2800_pci_postinit(void)
+static void __init ixdp2800_master_enable_slave(void)
{
- struct pci_dev *dev;
+ volatile u32 *addr;
- if (ixdp2x00_master_npu()) {
- dev = pci_find_slot(1, IXDP2800_SLAVE_ENET_DEVFN);
- pci_remove_bus_device(dev);
- } else {
- dev = pci_find_slot(1, IXDP2800_MASTER_ENET_DEVFN);
- pci_remove_bus_device(dev);
+ printk(KERN_INFO "IXDP2800: enabling slave NPU\n");
+
+ addr = (volatile u32 *)ixp2000_pci_config_addr(0,
+ IXDP2X00_SLAVE_NPU_DEVFN,
+ PCI_COMMAND);
+
+ *addr |= PCI_COMMAND_MASTER;
+}
+static void __init ixdp2800_master_wait_for_slave_bus_scan(void)
+{
+ volatile u32 *addr;
+
+ printk(KERN_INFO "IXDP2800: waiting for slave to finish bus scan\n");
+
+ addr = (volatile u32 *)ixp2000_pci_config_addr(0,
+ IXDP2X00_SLAVE_NPU_DEVFN,
+ PCI_COMMAND);
+ while ((*addr & PCI_COMMAND_MEMORY) == 0)
+ cpu_relax();
+}
+
+static void __init ixdp2800_slave_signal_bus_scan_completion(void)
+{
+ printk(KERN_INFO "IXDP2800: bus scan done, signaling master\n");
+ *IXP2000_PCI_CMDSTAT |= PCI_COMMAND_MEMORY;
+}
+
+static void __init ixdp2800_pci_postinit(void)
+{
+ if (!ixdp2x00_master_npu()) {
ixdp2x00_slave_pci_postinit();
+ ixdp2800_slave_signal_bus_scan_completion();
}
}
-struct hw_pci ixdp2800_pci __initdata = {
+struct __initdata hw_pci ixdp2800_pci __initdata = {
.nr_controllers = 1,
.setup = ixdp2800_pci_setup,
.preinit = ixdp2800_pci_preinit,
@@ -155,8 +263,21 @@ struct hw_pci ixdp2800_pci __initdata = {
int __init ixdp2800_pci_init(void)
{
- if (machine_is_ixdp2800())
+ if (machine_is_ixdp2800()) {
+ struct pci_dev *dev;
+
pci_common_init(&ixdp2800_pci);
+ if (ixdp2x00_master_npu()) {
+ dev = pci_find_slot(1, IXDP2800_SLAVE_ENET_DEVFN);
+ pci_remove_bus_device(dev);
+
+ ixdp2800_master_enable_slave();
+ ixdp2800_master_wait_for_slave_bus_scan();
+ } else {
+ dev = pci_find_slot(1, IXDP2800_MASTER_ENET_DEVFN);
+ pci_remove_bus_device(dev);
+ }
+ }
return 0;
}
diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c
index 831f8ff..5ff2f27 100644
--- a/arch/arm/mach-ixp2000/pci.c
+++ b/arch/arm/mach-ixp2000/pci.c
@@ -37,7 +37,7 @@ static int pci_master_aborts = 0;
static int clear_master_aborts(void);
-static u32 *
+u32 *
ixp2000_pci_config_addr(unsigned int bus_nr, unsigned int devfn, int where)
{
u32 *paddress;
@@ -208,15 +208,15 @@ ixp2000_pci_preinit(void)
* use our own resource space.
*/
static struct resource ixp2000_pci_mem_space = {
- .start = 0x00000000,
+ .start = 0xe0000000,
.end = 0xffffffff,
.flags = IORESOURCE_MEM,
.name = "PCI Mem Space"
};
static struct resource ixp2000_pci_io_space = {
- .start = 0x00000000,
- .end = 0xffffffff,
+ .start = 0x00010000,
+ .end = 0x0001ffff,
.flags = IORESOURCE_IO,
.name = "PCI I/O Space"
};
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index b1575b8..a45aaa1 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -220,6 +220,30 @@ static struct platform_device stuart_device = {
.id = 2,
};
+static struct resource i2c_resources[] = {
+ {
+ .start = 0x40301680,
+ .end = 0x403016a3,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_I2C,
+ .end = IRQ_I2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device i2c_device = {
+ .name = "pxa2xx-i2c",
+ .id = 0,
+ .resource = i2c_resources,
+ .num_resources = ARRAY_SIZE(i2c_resources),
+};
+
+void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info)
+{
+ i2c_device.dev.platform_data = info;
+}
+
static struct platform_device *devices[] __initdata = {
&pxamci_device,
&udc_device,
@@ -227,6 +251,7 @@ static struct platform_device *devices[] __initdata = {
&ffuart_device,
&btuart_device,
&stuart_device,
+ &i2c_device,
};
static int __init pxa_init(void)
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 5b670c9..007766a 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -409,3 +409,17 @@ config CPU_BPREDICT_DISABLE
depends on CPU_ARM1020
help
Say Y here to disable branch prediction. If unsure, say N.
+
+config HAS_TLS_REG
+ bool
+ depends on CPU_32v6 && !CPU_32v5 && !CPU_32v4 && !CPU_32v3
+ help
+ This selects support for the CP15 thread register.
+ It is defined to be available on ARMv6 or later. However
+ if the kernel is configured to support multiple CPUs including
+ a pre-ARMv6 processors, or if a given ARMv6 processor doesn't
+ implement the thread register for some reason, then access to
+ this register from user space must be trapped and emulated.
+ If user space is relying on the __kuser_get_tls code then
+ there should not be any impact.
+
diff --git a/arch/arm/mm/abort-ev6.S b/arch/arm/mm/abort-ev6.S
index 38b2cbb..8f76f3d 100644
--- a/arch/arm/mm/abort-ev6.S
+++ b/arch/arm/mm/abort-ev6.S
@@ -1,5 +1,6 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
+#include "abort-macro.S"
/*
* Function: v6_early_abort
*
@@ -13,11 +14,26 @@
* : sp = pointer to registers
*
* Purpose : obtain information about current aborted instruction.
+ * Note: we read user space. This means we might cause a data
+ * abort here if the I-TLB and D-TLB aren't seeing the same
+ * picture. Unfortunately, this does happen. We live with it.
*/
.align 5
ENTRY(v6_early_abort)
mrc p15, 0, r1, c5, c0, 0 @ get FSR
mrc p15, 0, r0, c6, c0, 0 @ get FAR
+/*
+ * Faulty SWP instruction on 1136 doesn't set bit 11 in DFSR.
+ * The test below covers all the write situations, including Java bytecodes
+ */
+ bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR
+ tst r3, #PSR_J_BIT @ Java?
+ movne pc, lr
+ do_thumb_abort
+ ldreq r3, [r2] @ read aborted ARM instruction
+ do_ldrd_abort
+ tst r3, #1 << 20 @ L = 0 -> write
+ orreq r1, r1, #1 << 11 @ yes.
mov pc, lr
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index f5a87db8..585dfb8 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -411,9 +411,10 @@ static void __init build_mem_type_table(void)
mem_types[MT_MEMORY].prot_sect &= ~PMD_BIT4;
mem_types[MT_ROM].prot_sect &= ~PMD_BIT4;
/*
- * Mark cache clean areas read only from SVC mode
- * and no access from userspace.
+ * Mark cache clean areas and XIP ROM read only
+ * from SVC mode and no access from userspace.
*/
+ mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
}
diff --git a/arch/arm26/kernel/ptrace.c b/arch/arm26/kernel/ptrace.c
index 2a13714..8a52124 100644
--- a/arch/arm26/kernel/ptrace.c
+++ b/arch/arm26/kernel/ptrace.c
@@ -18,6 +18,7 @@
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/security.h>
+#include <linux/signal.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
@@ -591,7 +592,7 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
case PTRACE_SYSCALL:
case PTRACE_CONT:
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
if (request == PTRACE_SYSCALL)
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -626,7 +627,7 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
*/
case PTRACE_SINGLESTEP:
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
child->ptrace |= PT_SINGLESTEP;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
diff --git a/arch/arm26/mm/small_page.c b/arch/arm26/mm/small_page.c
index 77be86c..3044710 100644
--- a/arch/arm26/mm/small_page.c
+++ b/arch/arm26/mm/small_page.c
@@ -92,8 +92,7 @@ static unsigned long __get_small_page(int priority, struct order *order)
page = list_entry(order->queue.next, struct page, lru);
again:
#ifdef PEDANTIC
- if (USED_MAP(page) & ~order->all_used)
- PAGE_BUG(page);
+ BUG_ON(USED_MAP(page) & ~order->all_used);
#endif
offset = ffz(USED_MAP(page));
SET_USED(page, offset);
@@ -141,8 +140,7 @@ static void __free_small_page(unsigned long spage, struct order *order)
goto non_small;
#ifdef PEDANTIC
- if (USED_MAP(page) & ~order->all_used)
- PAGE_BUG(page);
+ BUG_ON(USED_MAP(page) & ~order->all_used);
#endif
spage = spage >> order->shift;
diff --git a/arch/cris/arch-v10/kernel/ptrace.c b/arch/cris/arch-v10/kernel/ptrace.c
index da15db8..581ecab 100644
--- a/arch/cris/arch-v10/kernel/ptrace.c
+++ b/arch/cris/arch-v10/kernel/ptrace.c
@@ -10,6 +10,7 @@
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
+#include <linux/signal.h>
#include <asm/uaccess.h>
#include <asm/page.h>
@@ -184,7 +185,7 @@ sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_CONT:
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
if (request == PTRACE_SYSCALL) {
@@ -219,7 +220,7 @@ sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_SINGLESTEP:
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
diff --git a/arch/frv/kernel/ptrace.c b/arch/frv/kernel/ptrace.c
index 2a0efb7..cbe03cb 100644
--- a/arch/frv/kernel/ptrace.c
+++ b/arch/frv/kernel/ptrace.c
@@ -20,6 +20,7 @@
#include <linux/user.h>
#include <linux/config.h>
#include <linux/security.h>
+#include <linux/signal.h>
#include <asm/uaccess.h>
#include <asm/page.h>
@@ -239,7 +240,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: /* restart after signal. */
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
if (request == PTRACE_SYSCALL)
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -267,7 +268,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_SINGLESTEP: /* set the trap flag. */
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
ptrace_enable(child);
diff --git a/arch/h8300/kernel/ptrace.c b/arch/h8300/kernel/ptrace.c
index 5f19d77..05c15e8 100644
--- a/arch/h8300/kernel/ptrace.c
+++ b/arch/h8300/kernel/ptrace.c
@@ -24,6 +24,7 @@
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/config.h>
+#include <linux/signal.h>
#include <asm/uaccess.h>
#include <asm/page.h>
@@ -171,7 +172,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: { /* restart after signal. */
ret = -EIO;
- if ((unsigned long) data >= _NSIG)
+ if (!valid_signal(data))
break ;
if (request == PTRACE_SYSCALL)
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -202,7 +203,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_SINGLESTEP: { /* set the trap flag. */
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
child->exit_code = data;
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index 17a0cbc..99b4f29 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -653,6 +653,24 @@ config I8K
Say Y if you intend to run this kernel on a Dell Inspiron 8000.
Say N otherwise.
+config X86_REBOOTFIXUPS
+ bool "Enable X86 board specific fixups for reboot"
+ depends on X86
+ default n
+ ---help---
+ This enables chipset and/or board specific fixups to be done
+ in order to get reboot to work correctly. This is only needed on
+ some combinations of hardware and BIOS. The symptom, for which
+ this config is intended, is when reboot ends with a stalled/hung
+ system.
+
+ Currently, the only fixup is for the Geode GX1/CS5530A/TROM2.1.
+ combination.
+
+ Say Y if you want to enable the fixup. Currently, it's safe to
+ enable this option even if you don't need it.
+ Say N otherwise.
+
config MICROCODE
tristate "/dev/cpu/microcode - Intel IA32 CPU microcode support"
---help---
diff --git a/arch/i386/Makefile b/arch/i386/Makefile
index 314c714..04783ce 100644
--- a/arch/i386/Makefile
+++ b/arch/i386/Makefile
@@ -123,7 +123,7 @@ AFLAGS += $(mflags-y)
boot := arch/i386/boot
.PHONY: zImage bzImage compressed zlilo bzlilo \
- zdisk bzdisk fdimage fdimage144 fdimage288 install
+ zdisk bzdisk fdimage fdimage144 fdimage288 install kernel_install
all: bzImage
@@ -145,8 +145,9 @@ zdisk bzdisk: vmlinux
fdimage fdimage144 fdimage288: vmlinux
$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@
-install:
- $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@
+install: vmlinux
+install kernel_install:
+ $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install
prepare: include/asm-$(ARCH)/asm_offsets.h
CLEAN_FILES += include/asm-$(ARCH)/asm_offsets.h
diff --git a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c
index fa67045..cedc55c 100644
--- a/arch/i386/boot/compressed/misc.c
+++ b/arch/i386/boot/compressed/misc.c
@@ -12,7 +12,6 @@
#include <linux/linkage.h>
#include <linux/vmalloc.h>
#include <linux/tty.h>
-#include <video/edid.h>
#include <asm/io.h>
/*
diff --git a/arch/i386/boot/setup.S b/arch/i386/boot/setup.S
index a934ab3..caa1fde 100644
--- a/arch/i386/boot/setup.S
+++ b/arch/i386/boot/setup.S
@@ -164,7 +164,7 @@ ramdisk_max: .long (-__PAGE_OFFSET-(512 << 20)-1) & 0x7fffffff
trampoline: call start_of_setup
.align 16
# The offset at this point is 0x240
- .space (0x7ff-0x240+1) # E820 & EDD space (ending at 0x7ff)
+ .space (0xeff-0x240+1) # E820 & EDD space (ending at 0xeff)
# End of setup header #####################################################
start_of_setup:
@@ -333,9 +333,9 @@ jmpe820:
# sizeof(e820rec).
#
good820:
- movb (E820NR), %al # up to 32 entries
+ movb (E820NR), %al # up to 128 entries
cmpb $E820MAX, %al
- jnl bail820
+ jae bail820
incb (E820NR)
movw %di, %ax
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
index aacdae6..0fbcfe0 100644
--- a/arch/i386/kernel/Makefile
+++ b/arch/i386/kernel/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o
obj-$(CONFIG_X86_MPPARSE) += mpparse.o
obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o
obj-$(CONFIG_X86_IO_APIC) += io_apic.o
+obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups.o
obj-$(CONFIG_X86_NUMAQ) += numaq.o
obj-$(CONFIG_X86_SUMMIT_NUMA) += summit.o
obj-$(CONFIG_KPROBES) += kprobes.o
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index e3879f7..d509836 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -1265,8 +1265,6 @@ int __init APIC_init_uniprocessor (void)
setup_local_APIC();
- if (nmi_watchdog == NMI_LOCAL_APIC)
- check_nmi_watchdog();
#ifdef CONFIG_X86_IO_APIC
if (smp_found_config)
if (!skip_ioapic_setup && nr_ioapics)
diff --git a/arch/i386/kernel/cpu/mtrr/generic.c b/arch/i386/kernel/cpu/mtrr/generic.c
index 9f7a7ea..f468a97 100644
--- a/arch/i386/kernel/cpu/mtrr/generic.c
+++ b/arch/i386/kernel/cpu/mtrr/generic.c
@@ -124,8 +124,8 @@ int generic_get_free_region(unsigned long base, unsigned long size)
return -ENOSPC;
}
-void generic_get_mtrr(unsigned int reg, unsigned long *base,
- unsigned int *size, mtrr_type * type)
+static void generic_get_mtrr(unsigned int reg, unsigned long *base,
+ unsigned int *size, mtrr_type * type)
{
unsigned int mask_lo, mask_hi, base_lo, base_hi;
diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c
index 54999e4..e1c2042 100644
--- a/arch/i386/kernel/cpu/mtrr/main.c
+++ b/arch/i386/kernel/cpu/mtrr/main.c
@@ -72,17 +72,21 @@ void set_mtrr_ops(struct mtrr_ops * ops)
static int have_wrcomb(void)
{
struct pci_dev *dev;
+ u8 rev;
if ((dev = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, NULL)) != NULL) {
- /* ServerWorks LE chipsets have problems with write-combining
+ /* ServerWorks LE chipsets < rev 6 have problems with write-combining
Don't allow it and leave room for other chipsets to be tagged */
if (dev->vendor == PCI_VENDOR_ID_SERVERWORKS &&
dev->device == PCI_DEVICE_ID_SERVERWORKS_LE) {
- printk(KERN_INFO "mtrr: Serverworks LE detected. Write-combining disabled.\n");
- pci_dev_put(dev);
- return 0;
+ pci_read_config_byte(dev, PCI_CLASS_REVISION, &rev);
+ if (rev <= 5) {
+ printk(KERN_INFO "mtrr: Serverworks LE rev < 6 detected. Write-combining disabled.\n");
+ pci_dev_put(dev);
+ return 0;
+ }
}
- /* Intel 450NX errata # 23. Non ascending cachline evictions to
+ /* Intel 450NX errata # 23. Non ascending cacheline evictions to
write combining memory may resulting in data corruption */
if (dev->vendor == PCI_VENDOR_ID_INTEL &&
dev->device == PCI_DEVICE_ID_INTEL_82451NX) {
diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c
index 4f28eba..7323c19 100644
--- a/arch/i386/kernel/cpu/proc.c
+++ b/arch/i386/kernel/cpu/proc.c
@@ -25,7 +25,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
"fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe",
/* AMD-defined */
- "pni", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
NULL, NULL, NULL, "mp", "nx", NULL, "mmxext", NULL,
NULL, "fxsr_opt", NULL, NULL, NULL, "lm", "3dnowext", "3dnow",
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index 3c73dc8..a991d4e 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -260,11 +260,9 @@ restore_nocheck:
.section .fixup,"ax"
iret_exc:
sti
- movl $__USER_DS, %edx
- movl %edx, %ds
- movl %edx, %es
- movl $11,%eax
- call do_exit
+ pushl $0 # no error code
+ pushl $do_iret_error
+ jmp error_code
.previous
.section __ex_table,"a"
.align 4
@@ -516,8 +514,6 @@ debug_stack_correct:
xorl %edx,%edx # error code 0
movl %esp,%eax # pt_regs pointer
call do_debug
- testl %eax,%eax
- jnz restore_all
jmp ret_from_exception
/*
@@ -598,8 +594,6 @@ ENTRY(int3)
xorl %edx,%edx # zero error code
movl %esp,%eax # pt_regs pointer
call do_int3
- testl %eax,%eax
- jnz restore_all
jmp ret_from_exception
ENTRY(overflow)
@@ -658,296 +652,6 @@ ENTRY(spurious_interrupt_bug)
pushl $do_spurious_interrupt_bug
jmp error_code
-.data
-ENTRY(sys_call_table)
- .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
- .long sys_exit
- .long sys_fork
- .long sys_read
- .long sys_write
- .long sys_open /* 5 */
- .long sys_close
- .long sys_waitpid
- .long sys_creat
- .long sys_link
- .long sys_unlink /* 10 */
- .long sys_execve
- .long sys_chdir
- .long sys_time
- .long sys_mknod
- .long sys_chmod /* 15 */
- .long sys_lchown16
- .long sys_ni_syscall /* old break syscall holder */
- .long sys_stat
- .long sys_lseek
- .long sys_getpid /* 20 */
- .long sys_mount
- .long sys_oldumount
- .long sys_setuid16
- .long sys_getuid16
- .long sys_stime /* 25 */
- .long sys_ptrace
- .long sys_alarm
- .long sys_fstat
- .long sys_pause
- .long sys_utime /* 30 */
- .long sys_ni_syscall /* old stty syscall holder */
- .long sys_ni_syscall /* old gtty syscall holder */
- .long sys_access
- .long sys_nice
- .long sys_ni_syscall /* 35 - old ftime syscall holder */
- .long sys_sync
- .long sys_kill
- .long sys_rename
- .long sys_mkdir
- .long sys_rmdir /* 40 */
- .long sys_dup
- .long sys_pipe
- .long sys_times
- .long sys_ni_syscall /* old prof syscall holder */
- .long sys_brk /* 45 */
- .long sys_setgid16
- .long sys_getgid16
- .long sys_signal
- .long sys_geteuid16
- .long sys_getegid16 /* 50 */
- .long sys_acct
- .long sys_umount /* recycled never used phys() */
- .long sys_ni_syscall /* old lock syscall holder */
- .long sys_ioctl
- .long sys_fcntl /* 55 */
- .long sys_ni_syscall /* old mpx syscall holder */
- .long sys_setpgid
- .long sys_ni_syscall /* old ulimit syscall holder */
- .long sys_olduname
- .long sys_umask /* 60 */
- .long sys_chroot
- .long sys_ustat
- .long sys_dup2
- .long sys_getppid
- .long sys_getpgrp /* 65 */
- .long sys_setsid
- .long sys_sigaction
- .long sys_sgetmask
- .long sys_ssetmask
- .long sys_setreuid16 /* 70 */
- .long sys_setregid16
- .long sys_sigsuspend
- .long sys_sigpending
- .long sys_sethostname
- .long sys_setrlimit /* 75 */
- .long sys_old_getrlimit
- .long sys_getrusage
- .long sys_gettimeofday
- .long sys_settimeofday
- .long sys_getgroups16 /* 80 */
- .long sys_setgroups16
- .long old_select
- .long sys_symlink
- .long sys_lstat
- .long sys_readlink /* 85 */
- .long sys_uselib
- .long sys_swapon
- .long sys_reboot
- .long old_readdir
- .long old_mmap /* 90 */
- .long sys_munmap
- .long sys_truncate
- .long sys_ftruncate
- .long sys_fchmod
- .long sys_fchown16 /* 95 */
- .long sys_getpriority
- .long sys_setpriority
- .long sys_ni_syscall /* old profil syscall holder */
- .long sys_statfs
- .long sys_fstatfs /* 100 */
- .long sys_ioperm
- .long sys_socketcall
- .long sys_syslog
- .long sys_setitimer
- .long sys_getitimer /* 105 */
- .long sys_newstat
- .long sys_newlstat
- .long sys_newfstat
- .long sys_uname
- .long sys_iopl /* 110 */
- .long sys_vhangup
- .long sys_ni_syscall /* old "idle" system call */
- .long sys_vm86old
- .long sys_wait4
- .long sys_swapoff /* 115 */
- .long sys_sysinfo
- .long sys_ipc
- .long sys_fsync
- .long sys_sigreturn
- .long sys_clone /* 120 */
- .long sys_setdomainname
- .long sys_newuname
- .long sys_modify_ldt
- .long sys_adjtimex
- .long sys_mprotect /* 125 */
- .long sys_sigprocmask
- .long sys_ni_syscall /* old "create_module" */
- .long sys_init_module
- .long sys_delete_module
- .long sys_ni_syscall /* 130: old "get_kernel_syms" */
- .long sys_quotactl
- .long sys_getpgid
- .long sys_fchdir
- .long sys_bdflush
- .long sys_sysfs /* 135 */
- .long sys_personality
- .long sys_ni_syscall /* reserved for afs_syscall */
- .long sys_setfsuid16
- .long sys_setfsgid16
- .long sys_llseek /* 140 */
- .long sys_getdents
- .long sys_select
- .long sys_flock
- .long sys_msync
- .long sys_readv /* 145 */
- .long sys_writev
- .long sys_getsid
- .long sys_fdatasync
- .long sys_sysctl
- .long sys_mlock /* 150 */
- .long sys_munlock
- .long sys_mlockall
- .long sys_munlockall
- .long sys_sched_setparam
- .long sys_sched_getparam /* 155 */
- .long sys_sched_setscheduler
- .long sys_sched_getscheduler
- .long sys_sched_yield
- .long sys_sched_get_priority_max
- .long sys_sched_get_priority_min /* 160 */
- .long sys_sched_rr_get_interval
- .long sys_nanosleep
- .long sys_mremap
- .long sys_setresuid16
- .long sys_getresuid16 /* 165 */
- .long sys_vm86
- .long sys_ni_syscall /* Old sys_query_module */
- .long sys_poll
- .long sys_nfsservctl
- .long sys_setresgid16 /* 170 */
- .long sys_getresgid16
- .long sys_prctl
- .long sys_rt_sigreturn
- .long sys_rt_sigaction
- .long sys_rt_sigprocmask /* 175 */
- .long sys_rt_sigpending
- .long sys_rt_sigtimedwait
- .long sys_rt_sigqueueinfo
- .long sys_rt_sigsuspend
- .long sys_pread64 /* 180 */
- .long sys_pwrite64
- .long sys_chown16
- .long sys_getcwd
- .long sys_capget
- .long sys_capset /* 185 */
- .long sys_sigaltstack
- .long sys_sendfile
- .long sys_ni_syscall /* reserved for streams1 */
- .long sys_ni_syscall /* reserved for streams2 */
- .long sys_vfork /* 190 */
- .long sys_getrlimit
- .long sys_mmap2
- .long sys_truncate64
- .long sys_ftruncate64
- .long sys_stat64 /* 195 */
- .long sys_lstat64
- .long sys_fstat64
- .long sys_lchown
- .long sys_getuid
- .long sys_getgid /* 200 */
- .long sys_geteuid
- .long sys_getegid
- .long sys_setreuid
- .long sys_setregid
- .long sys_getgroups /* 205 */
- .long sys_setgroups
- .long sys_fchown
- .long sys_setresuid
- .long sys_getresuid
- .long sys_setresgid /* 210 */
- .long sys_getresgid
- .long sys_chown
- .long sys_setuid
- .long sys_setgid
- .long sys_setfsuid /* 215 */
- .long sys_setfsgid
- .long sys_pivot_root
- .long sys_mincore
- .long sys_madvise
- .long sys_getdents64 /* 220 */
- .long sys_fcntl64
- .long sys_ni_syscall /* reserved for TUX */
- .long sys_ni_syscall
- .long sys_gettid
- .long sys_readahead /* 225 */
- .long sys_setxattr
- .long sys_lsetxattr
- .long sys_fsetxattr
- .long sys_getxattr
- .long sys_lgetxattr /* 230 */
- .long sys_fgetxattr
- .long sys_listxattr
- .long sys_llistxattr
- .long sys_flistxattr
- .long sys_removexattr /* 235 */
- .long sys_lremovexattr
- .long sys_fremovexattr
- .long sys_tkill
- .long sys_sendfile64
- .long sys_futex /* 240 */
- .long sys_sched_setaffinity
- .long sys_sched_getaffinity
- .long sys_set_thread_area
- .long sys_get_thread_area
- .long sys_io_setup /* 245 */
- .long sys_io_destroy
- .long sys_io_getevents
- .long sys_io_submit
- .long sys_io_cancel
- .long sys_fadvise64 /* 250 */
- .long sys_ni_syscall
- .long sys_exit_group
- .long sys_lookup_dcookie
- .long sys_epoll_create
- .long sys_epoll_ctl /* 255 */
- .long sys_epoll_wait
- .long sys_remap_file_pages
- .long sys_set_tid_address
- .long sys_timer_create
- .long sys_timer_settime /* 260 */
- .long sys_timer_gettime
- .long sys_timer_getoverrun
- .long sys_timer_delete
- .long sys_clock_settime
- .long sys_clock_gettime /* 265 */
- .long sys_clock_getres
- .long sys_clock_nanosleep
- .long sys_statfs64
- .long sys_fstatfs64
- .long sys_tgkill /* 270 */
- .long sys_utimes
- .long sys_fadvise64_64
- .long sys_ni_syscall /* sys_vserver */
- .long sys_mbind
- .long sys_get_mempolicy
- .long sys_set_mempolicy
- .long sys_mq_open
- .long sys_mq_unlink
- .long sys_mq_timedsend
- .long sys_mq_timedreceive /* 280 */
- .long sys_mq_notify
- .long sys_mq_getsetattr
- .long sys_ni_syscall /* reserved for kexec */
- .long sys_waitid
- .long sys_ni_syscall /* 285 */ /* available */
- .long sys_add_key
- .long sys_request_key
- .long sys_keyctl
+#include "syscall_table.S"
syscall_table_size=(.-sys_call_table)
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S
index d273fd7..e966fc8 100644
--- a/arch/i386/kernel/head.S
+++ b/arch/i386/kernel/head.S
@@ -380,6 +380,7 @@ rp_sidt:
ALIGN
ignore_int:
cld
+#ifdef CONFIG_PRINTK
pushl %eax
pushl %ecx
pushl %edx
@@ -400,6 +401,7 @@ ignore_int:
popl %edx
popl %ecx
popl %eax
+#endif
iret
/*
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 5e0d55b..7a324e8 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -2175,7 +2175,6 @@ static inline void check_timer(void)
disable_8259A_irq(0);
setup_nmi();
enable_8259A_irq(0);
- check_nmi_watchdog();
}
return;
}
@@ -2198,7 +2197,6 @@ static inline void check_timer(void)
add_pin_to_irq(0, 0, pin2);
if (nmi_watchdog == NMI_IO_APIC) {
setup_nmi();
- check_nmi_watchdog();
}
return;
}
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
index 2f89d00..2c0ee9c 100644
--- a/arch/i386/kernel/nmi.c
+++ b/arch/i386/kernel/nmi.c
@@ -102,20 +102,21 @@ int nmi_active;
(P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT| \
P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE)
-int __init check_nmi_watchdog (void)
+static int __init check_nmi_watchdog(void)
{
unsigned int prev_nmi_count[NR_CPUS];
int cpu;
- printk(KERN_INFO "testing NMI watchdog ... ");
+ if (nmi_watchdog == NMI_NONE)
+ return 0;
+
+ printk(KERN_INFO "Testing NMI watchdog ... ");
for (cpu = 0; cpu < NR_CPUS; cpu++)
prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count;
local_irq_enable();
mdelay((10*1000)/nmi_hz); // wait 10 ticks
- /* FIXME: Only boot CPU is online at this stage. Check CPUs
- as they come up. */
for (cpu = 0; cpu < NR_CPUS; cpu++) {
#ifdef CONFIG_SMP
/* Check cpu_callin_map here because that is set
@@ -139,6 +140,8 @@ int __init check_nmi_watchdog (void)
return 0;
}
+/* This needs to happen later in boot so counters are working */
+late_initcall(check_nmi_watchdog);
static int __init setup_nmi_watchdog(char *str)
{
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index b2203e2..85bd56d 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -611,8 +611,8 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas
* Save away %fs and %gs. No need to save %es and %ds, as
* those are always kernel segments while inside the kernel.
*/
- asm volatile("movl %%fs,%0":"=m" (*(int *)&prev->fs));
- asm volatile("movl %%gs,%0":"=m" (*(int *)&prev->gs));
+ asm volatile("mov %%fs,%0":"=m" (prev->fs));
+ asm volatile("mov %%gs,%0":"=m" (prev->gs));
/*
* Restore %fs and %gs if needed.
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index 5606ec7..e34f651 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -16,6 +16,7 @@
#include <linux/security.h>
#include <linux/audit.h>
#include <linux/seccomp.h>
+#include <linux/signal.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
@@ -511,7 +512,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: /* restart after signal. */
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
if (request == PTRACE_SYSCALL) {
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -543,7 +544,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_SINGLESTEP: /* set the trap flag. */
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
set_singlestep(child);
diff --git a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c
index 3d7e994..6dc27eb 100644
--- a/arch/i386/kernel/reboot.c
+++ b/arch/i386/kernel/reboot.c
@@ -13,6 +13,7 @@
#include <asm/uaccess.h>
#include <asm/apic.h>
#include "mach_reboot.h"
+#include <linux/reboot_fixups.h>
/*
* Power off function, if any
@@ -348,6 +349,7 @@ void machine_restart(char * __unused)
/* rebooting needs to touch the page at absolute addr 0 */
*((unsigned short *)__va(0x472)) = reboot_mode;
for (;;) {
+ mach_reboot_fixups(); /* for board specific fixups */
mach_reboot();
/* That didn't work - force a triple fault.. */
__asm__ __volatile__("lidt %0": :"m" (no_idt));
diff --git a/arch/i386/kernel/reboot_fixups.c b/arch/i386/kernel/reboot_fixups.c
new file mode 100644
index 0000000..1b183b3
--- /dev/null
+++ b/arch/i386/kernel/reboot_fixups.c
@@ -0,0 +1,56 @@
+/*
+ * linux/arch/i386/kernel/reboot_fixups.c
+ *
+ * This is a good place to put board specific reboot fixups.
+ *
+ * List of supported fixups:
+ * geode-gx1/cs5530a - Jaya Kumar <jayalk@intworks.biz>
+ *
+ */
+
+#include <asm/delay.h>
+#include <linux/pci.h>
+
+static void cs5530a_warm_reset(struct pci_dev *dev)
+{
+ /* writing 1 to the reset control register, 0x44 causes the
+ cs5530a to perform a system warm reset */
+ pci_write_config_byte(dev, 0x44, 0x1);
+ udelay(50); /* shouldn't get here but be safe and spin-a-while */
+ return;
+}
+
+struct device_fixup {
+ unsigned int vendor;
+ unsigned int device;
+ void (*reboot_fixup)(struct pci_dev *);
+};
+
+static struct device_fixup fixups_table[] = {
+{ PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, cs5530a_warm_reset },
+};
+
+/*
+ * we see if any fixup is available for our current hardware. if there
+ * is a fixup, we call it and we expect to never return from it. if we
+ * do return, we keep looking and then eventually fall back to the
+ * standard mach_reboot on return.
+ */
+void mach_reboot_fixups(void)
+{
+ struct device_fixup *cur;
+ struct pci_dev *dev;
+ int i;
+
+ for (i=0; i < (sizeof(fixups_table)/sizeof(fixups_table[0])); i++) {
+ cur = &(fixups_table[i]);
+ dev = pci_get_device(cur->vendor, cur->device, 0);
+ if (!dev)
+ continue;
+
+ cur->reboot_fixup(dev);
+ }
+
+ printk(KERN_WARNING "No reboot fixup found for your hardware\n");
+}
+
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index fd36d2f..cbea7ac 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -1089,9 +1089,6 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
}
}
- if (nmi_watchdog == NMI_LOCAL_APIC)
- check_nmi_watchdog();
-
smpboot_setup_io_apic();
setup_boot_APIC_clock();
diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S
new file mode 100644
index 0000000..6cd1ed3
--- /dev/null
+++ b/arch/i386/kernel/syscall_table.S
@@ -0,0 +1,291 @@
+.data
+ENTRY(sys_call_table)
+ .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
+ .long sys_exit
+ .long sys_fork
+ .long sys_read
+ .long sys_write
+ .long sys_open /* 5 */
+ .long sys_close
+ .long sys_waitpid
+ .long sys_creat
+ .long sys_link
+ .long sys_unlink /* 10 */
+ .long sys_execve
+ .long sys_chdir
+ .long sys_time
+ .long sys_mknod
+ .long sys_chmod /* 15 */
+ .long sys_lchown16
+ .long sys_ni_syscall /* old break syscall holder */
+ .long sys_stat
+ .long sys_lseek
+ .long sys_getpid /* 20 */
+ .long sys_mount
+ .long sys_oldumount
+ .long sys_setuid16
+ .long sys_getuid16
+ .long sys_stime /* 25 */
+ .long sys_ptrace
+ .long sys_alarm
+ .long sys_fstat
+ .long sys_pause
+ .long sys_utime /* 30 */
+ .long sys_ni_syscall /* old stty syscall holder */
+ .long sys_ni_syscall /* old gtty syscall holder */
+ .long sys_access
+ .long sys_nice
+ .long sys_ni_syscall /* 35 - old ftime syscall holder */
+ .long sys_sync
+ .long sys_kill
+ .long sys_rename
+ .long sys_mkdir
+ .long sys_rmdir /* 40 */
+ .long sys_dup
+ .long sys_pipe
+ .long sys_times
+ .long sys_ni_syscall /* old prof syscall holder */
+ .long sys_brk /* 45 */
+ .long sys_setgid16
+ .long sys_getgid16
+ .long sys_signal
+ .long sys_geteuid16
+ .long sys_getegid16 /* 50 */
+ .long sys_acct
+ .long sys_umount /* recycled never used phys() */
+ .long sys_ni_syscall /* old lock syscall holder */
+ .long sys_ioctl
+ .long sys_fcntl /* 55 */
+ .long sys_ni_syscall /* old mpx syscall holder */
+ .long sys_setpgid
+ .long sys_ni_syscall /* old ulimit syscall holder */
+ .long sys_olduname
+ .long sys_umask /* 60 */
+ .long sys_chroot
+ .long sys_ustat
+ .long sys_dup2
+ .long sys_getppid
+ .long sys_getpgrp /* 65 */
+ .long sys_setsid
+ .long sys_sigaction
+ .long sys_sgetmask
+ .long sys_ssetmask
+ .long sys_setreuid16 /* 70 */
+ .long sys_setregid16
+ .long sys_sigsuspend
+ .long sys_sigpending
+ .long sys_sethostname
+ .long sys_setrlimit /* 75 */
+ .long sys_old_getrlimit
+ .long sys_getrusage
+ .long sys_gettimeofday
+ .long sys_settimeofday
+ .long sys_getgroups16 /* 80 */
+ .long sys_setgroups16
+ .long old_select
+ .long sys_symlink
+ .long sys_lstat
+ .long sys_readlink /* 85 */
+ .long sys_uselib
+ .long sys_swapon
+ .long sys_reboot
+ .long old_readdir
+ .long old_mmap /* 90 */
+ .long sys_munmap
+ .long sys_truncate
+ .long sys_ftruncate
+ .long sys_fchmod
+ .long sys_fchown16 /* 95 */
+ .long sys_getpriority
+ .long sys_setpriority
+ .long sys_ni_syscall /* old profil syscall holder */
+ .long sys_statfs
+ .long sys_fstatfs /* 100 */
+ .long sys_ioperm
+ .long sys_socketcall
+ .long sys_syslog
+ .long sys_setitimer
+ .long sys_getitimer /* 105 */
+ .long sys_newstat
+ .long sys_newlstat
+ .long sys_newfstat
+ .long sys_uname
+ .long sys_iopl /* 110 */
+ .long sys_vhangup
+ .long sys_ni_syscall /* old "idle" system call */
+ .long sys_vm86old
+ .long sys_wait4
+ .long sys_swapoff /* 115 */
+ .long sys_sysinfo
+ .long sys_ipc
+ .long sys_fsync
+ .long sys_sigreturn
+ .long sys_clone /* 120 */
+ .long sys_setdomainname
+ .long sys_newuname
+ .long sys_modify_ldt
+ .long sys_adjtimex
+ .long sys_mprotect /* 125 */
+ .long sys_sigprocmask
+ .long sys_ni_syscall /* old "create_module" */
+ .long sys_init_module
+ .long sys_delete_module
+ .long sys_ni_syscall /* 130: old "get_kernel_syms" */
+ .long sys_quotactl
+ .long sys_getpgid
+ .long sys_fchdir
+ .long sys_bdflush
+ .long sys_sysfs /* 135 */
+ .long sys_personality
+ .long sys_ni_syscall /* reserved for afs_syscall */
+ .long sys_setfsuid16
+ .long sys_setfsgid16
+ .long sys_llseek /* 140 */
+ .long sys_getdents
+ .long sys_select
+ .long sys_flock
+ .long sys_msync
+ .long sys_readv /* 145 */
+ .long sys_writev
+ .long sys_getsid
+ .long sys_fdatasync
+ .long sys_sysctl
+ .long sys_mlock /* 150 */
+ .long sys_munlock
+ .long sys_mlockall
+ .long sys_munlockall
+ .long sys_sched_setparam
+ .long sys_sched_getparam /* 155 */
+ .long sys_sched_setscheduler
+ .long sys_sched_getscheduler
+ .long sys_sched_yield
+ .long sys_sched_get_priority_max
+ .long sys_sched_get_priority_min /* 160 */
+ .long sys_sched_rr_get_interval
+ .long sys_nanosleep
+ .long sys_mremap
+ .long sys_setresuid16
+ .long sys_getresuid16 /* 165 */
+ .long sys_vm86
+ .long sys_ni_syscall /* Old sys_query_module */
+ .long sys_poll
+ .long sys_nfsservctl
+ .long sys_setresgid16 /* 170 */
+ .long sys_getresgid16
+ .long sys_prctl
+ .long sys_rt_sigreturn
+ .long sys_rt_sigaction
+ .long sys_rt_sigprocmask /* 175 */
+ .long sys_rt_sigpending
+ .long sys_rt_sigtimedwait
+ .long sys_rt_sigqueueinfo
+ .long sys_rt_sigsuspend
+ .long sys_pread64 /* 180 */
+ .long sys_pwrite64
+ .long sys_chown16
+ .long sys_getcwd
+ .long sys_capget
+ .long sys_capset /* 185 */
+ .long sys_sigaltstack
+ .long sys_sendfile
+ .long sys_ni_syscall /* reserved for streams1 */
+ .long sys_ni_syscall /* reserved for streams2 */
+ .long sys_vfork /* 190 */
+ .long sys_getrlimit
+ .long sys_mmap2
+ .long sys_truncate64
+ .long sys_ftruncate64
+ .long sys_stat64 /* 195 */
+ .long sys_lstat64
+ .long sys_fstat64
+ .long sys_lchown
+ .long sys_getuid
+ .long sys_getgid /* 200 */
+ .long sys_geteuid
+ .long sys_getegid
+ .long sys_setreuid
+ .long sys_setregid
+ .long sys_getgroups /* 205 */
+ .long sys_setgroups
+ .long sys_fchown
+ .long sys_setresuid
+ .long sys_getresuid
+ .long sys_setresgid /* 210 */
+ .long sys_getresgid
+ .long sys_chown
+ .long sys_setuid
+ .long sys_setgid
+ .long sys_setfsuid /* 215 */
+ .long sys_setfsgid
+ .long sys_pivot_root
+ .long sys_mincore
+ .long sys_madvise
+ .long sys_getdents64 /* 220 */
+ .long sys_fcntl64
+ .long sys_ni_syscall /* reserved for TUX */
+ .long sys_ni_syscall
+ .long sys_gettid
+ .long sys_readahead /* 225 */
+ .long sys_setxattr
+ .long sys_lsetxattr
+ .long sys_fsetxattr
+ .long sys_getxattr
+ .long sys_lgetxattr /* 230 */
+ .long sys_fgetxattr
+ .long sys_listxattr
+ .long sys_llistxattr
+ .long sys_flistxattr
+ .long sys_removexattr /* 235 */
+ .long sys_lremovexattr
+ .long sys_fremovexattr
+ .long sys_tkill
+ .long sys_sendfile64
+ .long sys_futex /* 240 */
+ .long sys_sched_setaffinity
+ .long sys_sched_getaffinity
+ .long sys_set_thread_area
+ .long sys_get_thread_area
+ .long sys_io_setup /* 245 */
+ .long sys_io_destroy
+ .long sys_io_getevents
+ .long sys_io_submit
+ .long sys_io_cancel
+ .long sys_fadvise64 /* 250 */
+ .long sys_ni_syscall
+ .long sys_exit_group
+ .long sys_lookup_dcookie
+ .long sys_epoll_create
+ .long sys_epoll_ctl /* 255 */
+ .long sys_epoll_wait
+ .long sys_remap_file_pages
+ .long sys_set_tid_address
+ .long sys_timer_create
+ .long sys_timer_settime /* 260 */
+ .long sys_timer_gettime
+ .long sys_timer_getoverrun
+ .long sys_timer_delete
+ .long sys_clock_settime
+ .long sys_clock_gettime /* 265 */
+ .long sys_clock_getres
+ .long sys_clock_nanosleep
+ .long sys_statfs64
+ .long sys_fstatfs64
+ .long sys_tgkill /* 270 */
+ .long sys_utimes
+ .long sys_fadvise64_64
+ .long sys_ni_syscall /* sys_vserver */
+ .long sys_mbind
+ .long sys_get_mempolicy
+ .long sys_set_mempolicy
+ .long sys_mq_open
+ .long sys_mq_unlink
+ .long sys_mq_timedsend
+ .long sys_mq_timedreceive /* 280 */
+ .long sys_mq_notify
+ .long sys_mq_getsetattr
+ .long sys_ni_syscall /* reserved for kexec */
+ .long sys_waitid
+ .long sys_ni_syscall /* 285 */ /* available */
+ .long sys_add_key
+ .long sys_request_key
+ .long sys_keyctl
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
index 4d75b37..a0dcb7c 100644
--- a/arch/i386/kernel/time.c
+++ b/arch/i386/kernel/time.c
@@ -441,7 +441,7 @@ static void __init hpet_time_init(void)
set_normalized_timespec(&wall_to_monotonic,
-xtime.tv_sec, -xtime.tv_nsec);
- if (hpet_enable() >= 0) {
+ if ((hpet_enable() >= 0) && hpet_use_timer) {
printk("Using HPET for base-timer\n");
}
diff --git a/arch/i386/kernel/time_hpet.c b/arch/i386/kernel/time_hpet.c
index 244a31b..10a0cbb 100644
--- a/arch/i386/kernel/time_hpet.c
+++ b/arch/i386/kernel/time_hpet.c
@@ -26,6 +26,7 @@
static unsigned long hpet_period; /* fsecs / HPET clock */
unsigned long hpet_tick; /* hpet clks count per tick */
unsigned long hpet_address; /* hpet memory map physical address */
+int hpet_use_timer;
static int use_hpet; /* can be used for runtime check of hpet */
static int boot_hpet_disable; /* boottime override for HPET timer */
@@ -73,27 +74,30 @@ static int hpet_timer_stop_set_go(unsigned long tick)
hpet_writel(0, HPET_COUNTER);
hpet_writel(0, HPET_COUNTER + 4);
- /*
- * Set up timer 0, as periodic with first interrupt to happen at
- * hpet_tick, and period also hpet_tick.
- */
- cfg = hpet_readl(HPET_T0_CFG);
- cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC |
- HPET_TN_SETVAL | HPET_TN_32BIT;
- hpet_writel(cfg, HPET_T0_CFG);
-
- /*
- * The first write after writing TN_SETVAL to the config register sets
- * the counter value, the second write sets the threshold.
- */
- hpet_writel(tick, HPET_T0_CMP);
- hpet_writel(tick, HPET_T0_CMP);
+ if (hpet_use_timer) {
+ /*
+ * Set up timer 0, as periodic with first interrupt to happen at
+ * hpet_tick, and period also hpet_tick.
+ */
+ cfg = hpet_readl(HPET_T0_CFG);
+ cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC |
+ HPET_TN_SETVAL | HPET_TN_32BIT;
+ hpet_writel(cfg, HPET_T0_CFG);
+ /*
+ * The first write after writing TN_SETVAL to the config register sets
+ * the counter value, the second write sets the threshold.
+ */
+ hpet_writel(tick, HPET_T0_CMP);
+ hpet_writel(tick, HPET_T0_CMP);
+ }
/*
* Go!
*/
cfg = hpet_readl(HPET_CFG);
- cfg |= HPET_CFG_ENABLE | HPET_CFG_LEGACY;
+ if (hpet_use_timer)
+ cfg |= HPET_CFG_LEGACY;
+ cfg |= HPET_CFG_ENABLE;
hpet_writel(cfg, HPET_CFG);
return 0;
@@ -128,12 +132,11 @@ int __init hpet_enable(void)
* However, we can do with one timer otherwise using the
* the single HPET timer for system time.
*/
- if (
#ifdef CONFIG_HPET_EMULATE_RTC
- !(id & HPET_ID_NUMBER) ||
-#endif
- !(id & HPET_ID_LEGSUP))
+ if (!(id & HPET_ID_NUMBER))
return -1;
+#endif
+
hpet_period = hpet_readl(HPET_PERIOD);
if ((hpet_period < HPET_MIN_PERIOD) || (hpet_period > HPET_MAX_PERIOD))
@@ -152,6 +155,8 @@ int __init hpet_enable(void)
if (hpet_tick_rem > (hpet_period >> 1))
hpet_tick++; /* rounding the result */
+ hpet_use_timer = id & HPET_ID_LEGSUP;
+
if (hpet_timer_stop_set_go(hpet_tick))
return -1;
@@ -202,7 +207,8 @@ int __init hpet_enable(void)
#endif
#ifdef CONFIG_X86_LOCAL_APIC
- wait_timer_tick = wait_hpet_tick;
+ if (hpet_use_timer)
+ wait_timer_tick = wait_hpet_tick;
#endif
return 0;
}
diff --git a/arch/i386/kernel/timers/timer_hpet.c b/arch/i386/kernel/timers/timer_hpet.c
index 713134e..f778f47 100644
--- a/arch/i386/kernel/timers/timer_hpet.c
+++ b/arch/i386/kernel/timers/timer_hpet.c
@@ -79,7 +79,7 @@ static unsigned long get_offset_hpet(void)
eax = hpet_readl(HPET_COUNTER);
eax -= hpet_last; /* hpet delta */
-
+ eax = min(hpet_tick, eax);
/*
* Time offset = (hpet delta) * ( usecs per HPET clock )
* = (hpet delta) * ( usecs per tick / HPET clocks per tick)
@@ -105,9 +105,12 @@ static void mark_offset_hpet(void)
last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
rdtsc(last_tsc_low, last_tsc_high);
- offset = hpet_readl(HPET_T0_CMP) - hpet_tick;
- if (unlikely(((offset - hpet_last) > hpet_tick) && (hpet_last != 0))) {
- int lost_ticks = (offset - hpet_last) / hpet_tick;
+ if (hpet_use_timer)
+ offset = hpet_readl(HPET_T0_CMP) - hpet_tick;
+ else
+ offset = hpet_readl(HPET_COUNTER);
+ if (unlikely(((offset - hpet_last) >= (2*hpet_tick)) && (hpet_last != 0))) {
+ int lost_ticks = ((offset - hpet_last) / hpet_tick) - 1;
jiffies_64 += lost_ticks;
}
hpet_last = offset;
diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c
index a685994..7926d96 100644
--- a/arch/i386/kernel/timers/timer_tsc.c
+++ b/arch/i386/kernel/timers/timer_tsc.c
@@ -477,7 +477,7 @@ static int __init init_tsc(char* override)
if (cpu_has_tsc) {
unsigned long tsc_quotient;
#ifdef CONFIG_HPET_TIMER
- if (is_hpet_enabled()){
+ if (is_hpet_enabled() && hpet_use_timer) {
unsigned long result, remain;
printk("Using TSC for gettimeofday\n");
tsc_quotient = calibrate_tsc_hpet(NULL);
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 6c0e383..00c6341 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -451,6 +451,7 @@ DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
DO_ERROR(11, SIGBUS, "segment not present", segment_not_present)
DO_ERROR(12, SIGBUS, "stack segment", stack_segment)
DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
+DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0)
fastcall void do_general_protection(struct pt_regs * regs, long error_code)
{
@@ -642,16 +643,15 @@ void unset_nmi_callback(void)
}
#ifdef CONFIG_KPROBES
-fastcall int do_int3(struct pt_regs *regs, long error_code)
+fastcall void do_int3(struct pt_regs *regs, long error_code)
{
if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP)
== NOTIFY_STOP)
- return 1;
+ return;
/* This is an interrupt gate, because kprobes wants interrupts
disabled. Normal trap handlers don't. */
restore_interrupts(regs);
do_trap(3, SIGTRAP, "int3", 1, regs, error_code, NULL);
- return 0;
}
#endif
diff --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c
index 2f3d52d..ec0f68c 100644
--- a/arch/i386/kernel/vm86.c
+++ b/arch/i386/kernel/vm86.c
@@ -222,7 +222,7 @@ asmlinkage int sys_vm86(struct pt_regs regs)
goto out;
case VM86_PLUS_INSTALL_CHECK:
/* NOTE: on old vm86 stuff this will return the error
- from verify_area(), because the subfunction is
+ from access_ok(), because the subfunction is
interpreted as (invalid) address to vm86_struct.
So the installation check works.
*/
@@ -294,8 +294,8 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk
*/
info->regs32->eax = 0;
tsk->thread.saved_esp0 = tsk->thread.esp0;
- asm volatile("movl %%fs,%0":"=m" (tsk->thread.saved_fs));
- asm volatile("movl %%gs,%0":"=m" (tsk->thread.saved_gs));
+ asm volatile("mov %%fs,%0":"=m" (tsk->thread.saved_fs));
+ asm volatile("mov %%gs,%0":"=m" (tsk->thread.saved_gs));
tss = &per_cpu(init_tss, get_cpu());
tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
@@ -717,12 +717,12 @@ static irqreturn_t irq_handler(int intno, void *dev_id, struct pt_regs * regs)
irqbits |= irq_bit;
if (vm86_irqs[intno].sig)
send_sig(vm86_irqs[intno].sig, vm86_irqs[intno].tsk, 1);
- spin_unlock_irqrestore(&irqbits_lock, flags);
/*
* IRQ will be re-enabled when user asks for the irq (whether
* polling or as a result of the signal)
*/
- disable_irq(intno);
+ disable_irq_nosync(intno);
+ spin_unlock_irqrestore(&irqbits_lock, flags);
return IRQ_HANDLED;
out:
@@ -754,17 +754,20 @@ static inline int get_and_reset_irq(int irqnumber)
{
int bit;
unsigned long flags;
+ int ret = 0;
if (invalid_vm86_irq(irqnumber)) return 0;
if (vm86_irqs[irqnumber].tsk != current) return 0;
spin_lock_irqsave(&irqbits_lock, flags);
bit = irqbits & (1 << irqnumber);
irqbits &= ~bit;
+ if (bit) {
+ enable_irq(irqnumber);
+ ret = 1;
+ }
+
spin_unlock_irqrestore(&irqbits_lock, flags);
- if (!bit)
- return 0;
- enable_irq(irqnumber);
- return 1;
+ return ret;
}
diff --git a/arch/i386/oprofile/nmi_timer_int.c b/arch/i386/oprofile/nmi_timer_int.c
index b2e462a..c58d0c1 100644
--- a/arch/i386/oprofile/nmi_timer_int.c
+++ b/arch/i386/oprofile/nmi_timer_int.c
@@ -36,7 +36,7 @@ static void timer_stop(void)
{
enable_timer_nmi_watchdog();
unset_nmi_callback();
- synchronize_kernel();
+ synchronize_sched(); /* Allow already-started NMIs to complete. */
}
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
index e07589d..d6598da 100644
--- a/arch/i386/pci/irq.c
+++ b/arch/i386/pci/irq.c
@@ -495,6 +495,8 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route
case PCI_DEVICE_ID_INTEL_ICH6_1:
case PCI_DEVICE_ID_INTEL_ICH7_0:
case PCI_DEVICE_ID_INTEL_ICH7_1:
+ case PCI_DEVICE_ID_INTEL_ICH7_30:
+ case PCI_DEVICE_ID_INTEL_ICH7_31:
case PCI_DEVICE_ID_INTEL_ESB2_0:
r->name = "PIIX/ICH";
r->get = pirq_piix_get;
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index bd86fea..d3f0938 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -1417,7 +1417,7 @@ sys_call_table:
data8 sys_msgrcv
data8 sys_msgctl
data8 sys_shmget
- data8 ia64_shmat
+ data8 sys_shmat
data8 sys_shmdt // 1115
data8 sys_shmctl
data8 sys_syslog
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index 8dde0b1..907464e 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -17,6 +17,7 @@
#include <linux/user.h>
#include <linux/security.h>
#include <linux/audit.h>
+#include <linux/signal.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
@@ -1481,7 +1482,7 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data)
case PTRACE_CONT:
/* restart after signal. */
ret = -EIO;
- if (data > _NSIG)
+ if (!valid_signal(data))
goto out_tsk;
if (request == PTRACE_SYSCALL)
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -1520,7 +1521,7 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data)
/* let child execute for one instruction */
case PTRACE_SINGLEBLOCK:
ret = -EIO;
- if (data > _NSIG)
+ if (!valid_signal(data))
goto out_tsk;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c
index 3ac216e..a8cf6d8 100644
--- a/arch/ia64/kernel/sys_ia64.c
+++ b/arch/ia64/kernel/sys_ia64.c
@@ -93,20 +93,6 @@ sys_getpagesize (void)
}
asmlinkage unsigned long
-ia64_shmat (int shmid, void __user *shmaddr, int shmflg)
-{
- unsigned long raddr;
- int retval;
-
- retval = do_shmat(shmid, shmaddr, shmflg, &raddr);
- if (retval < 0)
- return retval;
-
- force_successful_syscall_return();
- return raddr;
-}
-
-asmlinkage unsigned long
ia64_brk (unsigned long brk)
{
unsigned long rlim, retval, newbrk, oldbrk;
diff --git a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c
index 8b40f36..124f7c1 100644
--- a/arch/m32r/kernel/ptrace.c
+++ b/arch/m32r/kernel/ptrace.c
@@ -24,6 +24,7 @@
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/string.h>
+#include <linux/signal.h>
#include <asm/cacheflush.h>
#include <asm/io.h>
@@ -665,7 +666,7 @@ do_ptrace(long request, struct task_struct *child, long addr, long data)
case PTRACE_SYSCALL:
case PTRACE_CONT:
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
if (request == PTRACE_SYSCALL)
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -700,7 +701,7 @@ do_ptrace(long request, struct task_struct *child, long addr, long data)
unsigned long pc, insn;
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
if ((child->ptrace & PT_DTRACE) == 0) {
diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c
index 0beb533..f4e1e5e 100644
--- a/arch/m68k/kernel/ptrace.c
+++ b/arch/m68k/kernel/ptrace.c
@@ -19,6 +19,7 @@
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/config.h>
+#include <linux/signal.h>
#include <asm/uaccess.h>
#include <asm/page.h>
@@ -251,7 +252,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
long tmp;
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
if (request == PTRACE_SYSCALL) {
child->thread.work.syscall_trace = ~0;
@@ -292,7 +293,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
long tmp;
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
child->thread.work.syscall_trace = 0;
tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16);
diff --git a/arch/m68knommu/kernel/ptrace.c b/arch/m68knommu/kernel/ptrace.c
index 15cf790..9724e1c 100644
--- a/arch/m68knommu/kernel/ptrace.c
+++ b/arch/m68knommu/kernel/ptrace.c
@@ -19,6 +19,7 @@
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/config.h>
+#include <linux/signal.h>
#include <asm/uaccess.h>
#include <asm/page.h>
@@ -240,7 +241,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
long tmp;
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
if (request == PTRACE_SYSCALL)
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -278,7 +279,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
long tmp;
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16);
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 4abc2ee5..92e70ca 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -26,6 +26,7 @@
#include <linux/smp_lock.h>
#include <linux/user.h>
#include <linux/security.h>
+#include <linux/signal.h>
#include <asm/cpu.h>
#include <asm/fpu.h>
@@ -257,7 +258,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: { /* restart after signal. */
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
if (request == PTRACE_SYSCALL) {
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c
index 611dee9..eee2079 100644
--- a/arch/mips/kernel/ptrace32.c
+++ b/arch/mips/kernel/ptrace32.c
@@ -24,6 +24,7 @@
#include <linux/smp_lock.h>
#include <linux/user.h>
#include <linux/security.h>
+#include <linux/signal.h>
#include <asm/cpu.h>
#include <asm/fpu.h>
@@ -241,7 +242,7 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: { /* restart after signal. */
ret = -EIO;
- if ((unsigned int) data > _NSIG)
+ if (!valid_signal(data))
break;
if (request == PTRACE_SYSCALL) {
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 598bfe7..ae2a131 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -374,22 +374,6 @@ asmlinkage int sys_ipc (uint call, int first, int second,
}
/*
- * Native ABI that is O32 or N64 version
- */
-asmlinkage long sys_shmat(int shmid, char __user *shmaddr,
- int shmflg, unsigned long *addr)
-{
- unsigned long raddr;
- int err;
-
- err = do_shmat(shmid, shmaddr, shmflg, &raddr);
- if (err)
- return err;
-
- return put_user(raddr, addr);
-}
-
-/*
* No implemented yet ...
*/
asmlinkage int sys_cachectl(char *addr, int nbytes, int op)
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index 2937a92..c07db9d 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -17,6 +17,7 @@
#include <linux/personality.h>
#include <linux/security.h>
#include <linux/compat.h>
+#include <linux/signal.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
@@ -285,7 +286,7 @@ long sys_ptrace(long request, pid_t pid, long addr, long data)
ret = -EIO;
DBG("sys_ptrace(%s)\n",
request == PTRACE_SYSCALL ? "SYSCALL" : "CONT");
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
goto out_tsk;
child->ptrace &= ~(PT_SINGLESTEP|PT_BLOCKSTEP);
if (request == PTRACE_SYSCALL) {
@@ -311,7 +312,7 @@ long sys_ptrace(long request, pid_t pid, long addr, long data)
case PTRACE_SINGLEBLOCK:
DBG("sys_ptrace(SINGLEBLOCK)\n");
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
goto out_tsk;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
child->ptrace &= ~PT_SINGLESTEP;
@@ -328,7 +329,7 @@ long sys_ptrace(long request, pid_t pid, long addr, long data)
case PTRACE_SINGLESTEP:
DBG("sys_ptrace(SINGLESTEP)\n");
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
goto out_tsk;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
index 7958cd8..d15a1d5 100644
--- a/arch/parisc/kernel/sys_parisc.c
+++ b/arch/parisc/kernel/sys_parisc.c
@@ -161,17 +161,6 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
}
}
-long sys_shmat_wrapper(int shmid, char __user *shmaddr, int shmflag)
-{
- unsigned long raddr;
- int r;
-
- r = do_shmat(shmid, shmaddr, shmflag, &raddr);
- if (r < 0)
- return r;
- return raddr;
-}
-
/* Fucking broken ABI */
#ifdef CONFIG_64BIT
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
index 779b537..dcfa4d3 100644
--- a/arch/parisc/kernel/syscall_table.S
+++ b/arch/parisc/kernel/syscall_table.S
@@ -297,7 +297,7 @@
ENTRY_DIFF(msgrcv)
ENTRY_SAME(msgget) /* 190 */
ENTRY_SAME(msgctl)
- ENTRY_SAME(shmat_wrapper)
+ ENTRY_SAME(shmat)
ENTRY_SAME(shmdt)
ENTRY_SAME(shmget)
ENTRY_SAME(shmctl) /* 195 */
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 74aa1e9..c3d9413 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -53,6 +53,7 @@ choice
config 6xx
bool "6xx/7xx/74xx/52xx/82xx/83xx"
+ select PPC_FPU
help
There are four types of PowerPC chips supported. The more common
types (601, 603, 604, 740, 750, 7400), the Motorola embedded
@@ -86,6 +87,9 @@ config E500
endchoice
+config PPC_FPU
+ bool
+
config BOOKE
bool
depends on E500
diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile
index 73cbdda..0432a25 100644
--- a/arch/ppc/Makefile
+++ b/arch/ppc/Makefile
@@ -53,6 +53,7 @@ head-$(CONFIG_FSL_BOOKE) := arch/ppc/kernel/head_fsl_booke.o
head-$(CONFIG_6xx) += arch/ppc/kernel/idle_6xx.o
head-$(CONFIG_POWER4) += arch/ppc/kernel/idle_power4.o
+head-$(CONFIG_PPC_FPU) += arch/ppc/kernel/fpu.o
core-y += arch/ppc/kernel/ arch/ppc/platforms/ \
arch/ppc/mm/ arch/ppc/lib/ arch/ppc/syslib/
diff --git a/arch/ppc/boot/images/Makefile b/arch/ppc/boot/images/Makefile
index 774de8e..f850fb0 100644
--- a/arch/ppc/boot/images/Makefile
+++ b/arch/ppc/boot/images/Makefile
@@ -20,8 +20,9 @@ quiet_cmd_uimage = UIMAGE $@
targets += uImage
$(obj)/uImage: $(obj)/vmlinux.gz
+ $(Q)rm -f $@
$(call if_changed,uimage)
- @echo ' Image $@ is ready'
+ @echo ' Image: $@' $(if $(wildcard $@),'is ready','not made')
# Files generated that shall be removed upon make clean
clean-files := sImage vmapus vmlinux* miboot* zImage* uImage
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index 86bc878..b284451 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -9,6 +9,7 @@ extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o
extra-$(CONFIG_8xx) := head_8xx.o
extra-$(CONFIG_6xx) += idle_6xx.o
extra-$(CONFIG_POWER4) += idle_power4.o
+extra-$(CONFIG_PPC_FPU) += fpu.o
extra-y += vmlinux.lds
obj-y := entry.o traps.o irq.o idle.o time.o misc.o \
diff --git a/arch/ppc/kernel/align.c b/arch/ppc/kernel/align.c
index 79c9294..ff81da9 100644
--- a/arch/ppc/kernel/align.c
+++ b/arch/ppc/kernel/align.c
@@ -290,6 +290,10 @@ fix_alignment(struct pt_regs *regs)
/* lwm, stmw */
nb = (32 - reg) * 4;
}
+
+ if (!access_ok((flags & ST? VERIFY_WRITE: VERIFY_READ), addr, nb+nb0))
+ return -EFAULT; /* bad address */
+
rptr = (unsigned char *) &regs->gpr[reg];
if (flags & LD) {
for (i = 0; i < nb; ++i)
@@ -368,16 +372,24 @@ fix_alignment(struct pt_regs *regs)
/* Single-precision FP load and store require conversions... */
case LD+F+S:
+#ifdef CONFIG_PPC_FPU
preempt_disable();
enable_kernel_fp();
cvt_fd(&data.f, &data.d, &current->thread.fpscr);
preempt_enable();
+#else
+ return 0;
+#endif
break;
case ST+F+S:
+#ifdef CONFIG_PPC_FPU
preempt_disable();
enable_kernel_fp();
cvt_df(&data.d, &data.f, &current->thread.fpscr);
preempt_enable();
+#else
+ return 0;
+#endif
break;
}
diff --git a/arch/ppc/kernel/cpu_setup_6xx.S b/arch/ppc/kernel/cpu_setup_6xx.S
index 74f781b..468721d 100644
--- a/arch/ppc/kernel/cpu_setup_6xx.S
+++ b/arch/ppc/kernel/cpu_setup_6xx.S
@@ -30,12 +30,14 @@ _GLOBAL(__setup_cpu_604)
blr
_GLOBAL(__setup_cpu_750)
mflr r4
+ bl __init_fpu_registers
bl setup_common_caches
bl setup_750_7400_hid0
mtlr r4
blr
_GLOBAL(__setup_cpu_750cx)
mflr r4
+ bl __init_fpu_registers
bl setup_common_caches
bl setup_750_7400_hid0
bl setup_750cx
@@ -43,6 +45,7 @@ _GLOBAL(__setup_cpu_750cx)
blr
_GLOBAL(__setup_cpu_750fx)
mflr r4
+ bl __init_fpu_registers
bl setup_common_caches
bl setup_750_7400_hid0
bl setup_750fx
@@ -50,6 +53,7 @@ _GLOBAL(__setup_cpu_750fx)
blr
_GLOBAL(__setup_cpu_7400)
mflr r4
+ bl __init_fpu_registers
bl setup_7400_workarounds
bl setup_common_caches
bl setup_750_7400_hid0
@@ -57,6 +61,7 @@ _GLOBAL(__setup_cpu_7400)
blr
_GLOBAL(__setup_cpu_7410)
mflr r4
+ bl __init_fpu_registers
bl setup_7410_workarounds
bl setup_common_caches
bl setup_750_7400_hid0
@@ -80,7 +85,7 @@ setup_common_caches:
bne 1f /* don't invalidate the D-cache */
ori r8,r8,HID0_DCI /* unless it wasn't enabled */
1: sync
- mtspr SPRN_HID0,r8 /* enable and invalidate caches */
+ mtspr SPRN_HID0,r8 /* enable and invalidate caches */
sync
mtspr SPRN_HID0,r11 /* enable caches */
sync
@@ -152,9 +157,13 @@ setup_7410_workarounds:
setup_750_7400_hid0:
mfspr r11,SPRN_HID0
ori r11,r11,HID0_SGE | HID0_ABE | HID0_BHTE | HID0_BTIC
+ oris r11,r11,HID0_DPM@h
BEGIN_FTR_SECTION
- oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */
-END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM)
+ xori r11,r11,HID0_BTIC
+END_FTR_SECTION_IFSET(CPU_FTR_NO_BTIC)
+BEGIN_FTR_SECTION
+ xoris r11,r11,HID0_DPM@h /* disable dynamic power mgmt */
+END_FTR_SECTION_IFSET(CPU_FTR_NO_DPM)
li r3,HID0_SPD
andc r11,r11,r3 /* clear SPD: enable speculative */
li r3,0
@@ -218,13 +227,15 @@ setup_745x_specifics:
/* All of the bits we have to set.....
*/
- ori r11,r11,HID0_SGE | HID0_FOLD | HID0_BHTE | HID0_LRSTK | HID0_BTIC
+ ori r11,r11,HID0_SGE | HID0_FOLD | HID0_BHTE
+ ori r11,r11,HID0_LRSTK | HID0_BTIC
+ oris r11,r11,HID0_DPM@h
BEGIN_FTR_SECTION
xori r11,r11,HID0_BTIC
END_FTR_SECTION_IFSET(CPU_FTR_NO_BTIC)
BEGIN_FTR_SECTION
- oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */
-END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM)
+ xoris r11,r11,HID0_DPM@h /* disable dynamic power mgmt */
+END_FTR_SECTION_IFSET(CPU_FTR_NO_DPM)
/* All of the bits we have to clear....
*/
@@ -248,6 +259,25 @@ END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM)
isync
blr
+/*
+ * Initialize the FPU registers. This is needed to work around an errata
+ * in some 750 cpus where using a not yet initialized FPU register after
+ * power on reset may hang the CPU
+ */
+_GLOBAL(__init_fpu_registers)
+ mfmsr r10
+ ori r11,r10,MSR_FP
+ mtmsr r11
+ isync
+ addis r9,r3,empty_zero_page@ha
+ addi r9,r9,empty_zero_page@l
+ REST_32FPRS(0,r9)
+ sync
+ mtmsr r10
+ isync
+ blr
+
+
/* Definitions for the table use to save CPU states */
#define CS_HID0 0
#define CS_HID1 4
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
index 035217d..5f075db 100644
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -563,6 +563,65 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
addi r1,r1,INT_FRAME_SIZE
blr
+ .globl fast_exception_return
+fast_exception_return:
+#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
+ andi. r10,r9,MSR_RI /* check for recoverable interrupt */
+ beq 1f /* if not, we've got problems */
+#endif
+
+2: REST_4GPRS(3, r11)
+ lwz r10,_CCR(r11)
+ REST_GPR(1, r11)
+ mtcr r10
+ lwz r10,_LINK(r11)
+ mtlr r10
+ REST_GPR(10, r11)
+ mtspr SPRN_SRR1,r9
+ mtspr SPRN_SRR0,r12
+ REST_GPR(9, r11)
+ REST_GPR(12, r11)
+ lwz r11,GPR11(r11)
+ SYNC
+ RFI
+
+#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
+/* check if the exception happened in a restartable section */
+1: lis r3,exc_exit_restart_end@ha
+ addi r3,r3,exc_exit_restart_end@l
+ cmplw r12,r3
+ bge 3f
+ lis r4,exc_exit_restart@ha
+ addi r4,r4,exc_exit_restart@l
+ cmplw r12,r4
+ blt 3f
+ lis r3,fee_restarts@ha
+ tophys(r3,r3)
+ lwz r5,fee_restarts@l(r3)
+ addi r5,r5,1
+ stw r5,fee_restarts@l(r3)
+ mr r12,r4 /* restart at exc_exit_restart */
+ b 2b
+
+ .comm fee_restarts,4
+
+/* aargh, a nonrecoverable interrupt, panic */
+/* aargh, we don't know which trap this is */
+/* but the 601 doesn't implement the RI bit, so assume it's OK */
+3:
+BEGIN_FTR_SECTION
+ b 2b
+END_FTR_SECTION_IFSET(CPU_FTR_601)
+ li r10,-1
+ stw r10,TRAP(r11)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ lis r10,MSR_KERNEL@h
+ ori r10,r10,MSR_KERNEL@l
+ bl transfer_to_handler_full
+ .long nonrecoverable_exception
+ .long ret_from_except
+#endif
+
.globl sigreturn_exit
sigreturn_exit:
subi r1,r3,STACK_FRAME_OVERHEAD
diff --git a/arch/ppc/kernel/fpu.S b/arch/ppc/kernel/fpu.S
new file mode 100644
index 0000000..6189b26
--- /dev/null
+++ b/arch/ppc/kernel/fpu.S
@@ -0,0 +1,133 @@
+/*
+ * FPU support code, moved here from head.S so that it can be used
+ * by chips which use other head-whatever.S files.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/config.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/cputable.h>
+#include <asm/cache.h>
+#include <asm/thread_info.h>
+#include <asm/ppc_asm.h>
+#include <asm/offsets.h>
+
+/*
+ * This task wants to use the FPU now.
+ * On UP, disable FP for the task which had the FPU previously,
+ * and save its floating-point registers in its thread_struct.
+ * Load up this task's FP registers from its thread_struct,
+ * enable the FPU for the current task and return to the task.
+ */
+ .globl load_up_fpu
+load_up_fpu:
+ mfmsr r5
+ ori r5,r5,MSR_FP
+#ifdef CONFIG_PPC64BRIDGE
+ clrldi r5,r5,1 /* turn off 64-bit mode */
+#endif /* CONFIG_PPC64BRIDGE */
+ SYNC
+ MTMSRD(r5) /* enable use of fpu now */
+ isync
+/*
+ * For SMP, we don't do lazy FPU switching because it just gets too
+ * horrendously complex, especially when a task switches from one CPU
+ * to another. Instead we call giveup_fpu in switch_to.
+ */
+#ifndef CONFIG_SMP
+ tophys(r6,0) /* get __pa constant */
+ addis r3,r6,last_task_used_math@ha
+ lwz r4,last_task_used_math@l(r3)
+ cmpwi 0,r4,0
+ beq 1f
+ add r4,r4,r6
+ addi r4,r4,THREAD /* want last_task_used_math->thread */
+ SAVE_32FPRS(0, r4)
+ mffs fr0
+ stfd fr0,THREAD_FPSCR-4(r4)
+ lwz r5,PT_REGS(r4)
+ add r5,r5,r6
+ lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+ li r10,MSR_FP|MSR_FE0|MSR_FE1
+ andc r4,r4,r10 /* disable FP for previous task */
+ stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#endif /* CONFIG_SMP */
+ /* enable use of FP after return */
+ mfspr r5,SPRN_SPRG3 /* current task's THREAD (phys) */
+ lwz r4,THREAD_FPEXC_MODE(r5)
+ ori r9,r9,MSR_FP /* enable FP for current */
+ or r9,r9,r4
+ lfd fr0,THREAD_FPSCR-4(r5)
+ mtfsf 0xff,fr0
+ REST_32FPRS(0, r5)
+#ifndef CONFIG_SMP
+ subi r4,r5,THREAD
+ sub r4,r4,r6
+ stw r4,last_task_used_math@l(r3)
+#endif /* CONFIG_SMP */
+ /* restore registers and return */
+ /* we haven't used ctr or xer or lr */
+ b fast_exception_return
+
+/*
+ * FP unavailable trap from kernel - print a message, but let
+ * the task use FP in the kernel until it returns to user mode.
+ */
+ .globl KernelFP
+KernelFP:
+ lwz r3,_MSR(r1)
+ ori r3,r3,MSR_FP
+ stw r3,_MSR(r1) /* enable use of FP after return */
+ lis r3,86f@h
+ ori r3,r3,86f@l
+ mr r4,r2 /* current */
+ lwz r5,_NIP(r1)
+ bl printk
+ b ret_from_except
+86: .string "floating point used in kernel (task=%p, pc=%x)\n"
+ .align 4,0
+
+/*
+ * giveup_fpu(tsk)
+ * Disable FP for the task given as the argument,
+ * and save the floating-point registers in its thread_struct.
+ * Enables the FPU for use in the kernel on return.
+ */
+ .globl giveup_fpu
+giveup_fpu:
+ mfmsr r5
+ ori r5,r5,MSR_FP
+ SYNC_601
+ ISYNC_601
+ MTMSRD(r5) /* enable use of fpu now */
+ SYNC_601
+ isync
+ cmpwi 0,r3,0
+ beqlr- /* if no previous owner, done */
+ addi r3,r3,THREAD /* want THREAD of task */
+ lwz r5,PT_REGS(r3)
+ cmpwi 0,r5,0
+ SAVE_32FPRS(0, r3)
+ mffs fr0
+ stfd fr0,THREAD_FPSCR-4(r3)
+ beq 1f
+ lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+ li r3,MSR_FP|MSR_FE0|MSR_FE1
+ andc r4,r4,r3 /* disable FP for previous task */
+ stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#ifndef CONFIG_SMP
+ li r5,0
+ lis r4,last_task_used_math@ha
+ stw r5,last_task_used_math@l(r4)
+#endif /* CONFIG_SMP */
+ blr
diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S
index 1a89a71..a931d77 100644
--- a/arch/ppc/kernel/head.S
+++ b/arch/ppc/kernel/head.S
@@ -775,133 +775,6 @@ InstructionSegment:
EXC_XFER_STD(0x480, UnknownException)
#endif /* CONFIG_PPC64BRIDGE */
-/*
- * This task wants to use the FPU now.
- * On UP, disable FP for the task which had the FPU previously,
- * and save its floating-point registers in its thread_struct.
- * Load up this task's FP registers from its thread_struct,
- * enable the FPU for the current task and return to the task.
- */
-load_up_fpu:
- mfmsr r5
- ori r5,r5,MSR_FP
-#ifdef CONFIG_PPC64BRIDGE
- clrldi r5,r5,1 /* turn off 64-bit mode */
-#endif /* CONFIG_PPC64BRIDGE */
- SYNC
- MTMSRD(r5) /* enable use of fpu now */
- isync
-/*
- * For SMP, we don't do lazy FPU switching because it just gets too
- * horrendously complex, especially when a task switches from one CPU
- * to another. Instead we call giveup_fpu in switch_to.
- */
-#ifndef CONFIG_SMP
- tophys(r6,0) /* get __pa constant */
- addis r3,r6,last_task_used_math@ha
- lwz r4,last_task_used_math@l(r3)
- cmpwi 0,r4,0
- beq 1f
- add r4,r4,r6
- addi r4,r4,THREAD /* want last_task_used_math->thread */
- SAVE_32FPRS(0, r4)
- mffs fr0
- stfd fr0,THREAD_FPSCR-4(r4)
- lwz r5,PT_REGS(r4)
- add r5,r5,r6
- lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
- li r10,MSR_FP|MSR_FE0|MSR_FE1
- andc r4,r4,r10 /* disable FP for previous task */
- stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#endif /* CONFIG_SMP */
- /* enable use of FP after return */
- mfspr r5,SPRN_SPRG3 /* current task's THREAD (phys) */
- lwz r4,THREAD_FPEXC_MODE(r5)
- ori r9,r9,MSR_FP /* enable FP for current */
- or r9,r9,r4
- lfd fr0,THREAD_FPSCR-4(r5)
- mtfsf 0xff,fr0
- REST_32FPRS(0, r5)
-#ifndef CONFIG_SMP
- subi r4,r5,THREAD
- sub r4,r4,r6
- stw r4,last_task_used_math@l(r3)
-#endif /* CONFIG_SMP */
- /* restore registers and return */
- /* we haven't used ctr or xer or lr */
- /* fall through to fast_exception_return */
-
- .globl fast_exception_return
-fast_exception_return:
- andi. r10,r9,MSR_RI /* check for recoverable interrupt */
- beq 1f /* if not, we've got problems */
-2: REST_4GPRS(3, r11)
- lwz r10,_CCR(r11)
- REST_GPR(1, r11)
- mtcr r10
- lwz r10,_LINK(r11)
- mtlr r10
- REST_GPR(10, r11)
- mtspr SPRN_SRR1,r9
- mtspr SPRN_SRR0,r12
- REST_GPR(9, r11)
- REST_GPR(12, r11)
- lwz r11,GPR11(r11)
- SYNC
- RFI
-
-/* check if the exception happened in a restartable section */
-1: lis r3,exc_exit_restart_end@ha
- addi r3,r3,exc_exit_restart_end@l
- cmplw r12,r3
- bge 3f
- lis r4,exc_exit_restart@ha
- addi r4,r4,exc_exit_restart@l
- cmplw r12,r4
- blt 3f
- lis r3,fee_restarts@ha
- tophys(r3,r3)
- lwz r5,fee_restarts@l(r3)
- addi r5,r5,1
- stw r5,fee_restarts@l(r3)
- mr r12,r4 /* restart at exc_exit_restart */
- b 2b
-
- .comm fee_restarts,4
-
-/* aargh, a nonrecoverable interrupt, panic */
-/* aargh, we don't know which trap this is */
-/* but the 601 doesn't implement the RI bit, so assume it's OK */
-3:
-BEGIN_FTR_SECTION
- b 2b
-END_FTR_SECTION_IFSET(CPU_FTR_601)
- li r10,-1
- stw r10,TRAP(r11)
- addi r3,r1,STACK_FRAME_OVERHEAD
- li r10,MSR_KERNEL
- bl transfer_to_handler_full
- .long nonrecoverable_exception
- .long ret_from_except
-
-/*
- * FP unavailable trap from kernel - print a message, but let
- * the task use FP in the kernel until it returns to user mode.
- */
-KernelFP:
- lwz r3,_MSR(r1)
- ori r3,r3,MSR_FP
- stw r3,_MSR(r1) /* enable use of FP after return */
- lis r3,86f@h
- ori r3,r3,86f@l
- mr r4,r2 /* current */
- lwz r5,_NIP(r1)
- bl printk
- b ret_from_except
-86: .string "floating point used in kernel (task=%p, pc=%x)\n"
- .align 4,0
-
#ifdef CONFIG_ALTIVEC
/* Note that the AltiVec support is closely modeled after the FP
* support. Changes to one are likely to be applicable to the
@@ -1016,42 +889,6 @@ giveup_altivec:
#endif /* CONFIG_ALTIVEC */
/*
- * giveup_fpu(tsk)
- * Disable FP for the task given as the argument,
- * and save the floating-point registers in its thread_struct.
- * Enables the FPU for use in the kernel on return.
- */
- .globl giveup_fpu
-giveup_fpu:
- mfmsr r5
- ori r5,r5,MSR_FP
- SYNC_601
- ISYNC_601
- MTMSRD(r5) /* enable use of fpu now */
- SYNC_601
- isync
- cmpwi 0,r3,0
- beqlr- /* if no previous owner, done */
- addi r3,r3,THREAD /* want THREAD of task */
- lwz r5,PT_REGS(r3)
- cmpwi 0,r5,0
- SAVE_32FPRS(0, r3)
- mffs fr0
- stfd fr0,THREAD_FPSCR-4(r3)
- beq 1f
- lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
- li r3,MSR_FP|MSR_FE0|MSR_FE1
- andc r4,r4,r3 /* disable FP for previous task */
- stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#ifndef CONFIG_SMP
- li r5,0
- lis r4,last_task_used_math@ha
- stw r5,last_task_used_math@l(r4)
-#endif /* CONFIG_SMP */
- blr
-
-/*
* This code is jumped to from the startup code to copy
* the kernel image to physical address 0.
*/
diff --git a/arch/ppc/kernel/head_44x.S b/arch/ppc/kernel/head_44x.S
index 9ed8165..9b6a8e5 100644
--- a/arch/ppc/kernel/head_44x.S
+++ b/arch/ppc/kernel/head_44x.S
@@ -426,7 +426,11 @@ interrupt_base:
PROGRAM_EXCEPTION
/* Floating Point Unavailable Interrupt */
+#ifdef CONFIG_PPC_FPU
+ FP_UNAVAILABLE_EXCEPTION
+#else
EXCEPTION(0x2010, FloatingPointUnavailable, UnknownException, EXC_XFER_EE)
+#endif
/* System Call Interrupt */
START_EXCEPTION(SystemCall)
@@ -686,8 +690,10 @@ _GLOBAL(giveup_altivec)
*
* The 44x core does not have an FPU.
*/
+#ifndef CONFIG_PPC_FPU
_GLOBAL(giveup_fpu)
blr
+#endif
/*
* extern void abort(void)
diff --git a/arch/ppc/kernel/head_booke.h b/arch/ppc/kernel/head_booke.h
index 884dac9..f213d12 100644
--- a/arch/ppc/kernel/head_booke.h
+++ b/arch/ppc/kernel/head_booke.h
@@ -337,4 +337,11 @@ label:
addi r3,r1,STACK_FRAME_OVERHEAD; \
EXC_XFER_LITE(0x0900, timer_interrupt)
+#define FP_UNAVAILABLE_EXCEPTION \
+ START_EXCEPTION(FloatingPointUnavailable) \
+ NORMAL_EXCEPTION_PROLOG; \
+ bne load_up_fpu; /* if from user, just load it up */ \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ EXC_XFER_EE_LITE(0x800, KernelFP)
+
#endif /* __HEAD_BOOKE_H__ */
diff --git a/arch/ppc/kernel/head_fsl_booke.S b/arch/ppc/kernel/head_fsl_booke.S
index d64bf61..f22ddce 100644
--- a/arch/ppc/kernel/head_fsl_booke.S
+++ b/arch/ppc/kernel/head_fsl_booke.S
@@ -504,7 +504,11 @@ interrupt_base:
PROGRAM_EXCEPTION
/* Floating Point Unavailable Interrupt */
+#ifdef CONFIG_PPC_FPU
+ FP_UNAVAILABLE_EXCEPTION
+#else
EXCEPTION(0x0800, FloatingPointUnavailable, UnknownException, EXC_XFER_EE)
+#endif
/* System Call Interrupt */
START_EXCEPTION(SystemCall)
@@ -916,10 +920,12 @@ _GLOBAL(giveup_spe)
/*
* extern void giveup_fpu(struct task_struct *prev)
*
- * The e500 core does not have an FPU.
+ * Not all FSL Book-E cores have an FPU
*/
+#ifndef CONFIG_PPC_FPU
_GLOBAL(giveup_fpu)
blr
+#endif
/*
* extern void abort(void)
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index 73f7c23..e4f1615 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -1096,17 +1096,7 @@ _GLOBAL(_get_SP)
* and exceptions as if the cpu had performed the load or store.
*/
-#if defined(CONFIG_4xx) || defined(CONFIG_E500)
-_GLOBAL(cvt_fd)
- lfs 0,0(r3)
- stfd 0,0(r4)
- blr
-
-_GLOBAL(cvt_df)
- lfd 0,0(r3)
- stfs 0,0(r4)
- blr
-#else
+#ifdef CONFIG_PPC_FPU
_GLOBAL(cvt_fd)
lfd 0,-4(r5) /* load up fpscr value */
mtfsf 0xff,0
diff --git a/arch/ppc/kernel/ptrace.c b/arch/ppc/kernel/ptrace.c
index 426b6f7..59d59a8 100644
--- a/arch/ppc/kernel/ptrace.c
+++ b/arch/ppc/kernel/ptrace.c
@@ -26,6 +26,7 @@
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/security.h>
+#include <linux/signal.h>
#include <asm/uaccess.h>
#include <asm/page.h>
@@ -356,7 +357,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: { /* restart after signal. */
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
if (request == PTRACE_SYSCALL) {
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -389,7 +390,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_SINGLESTEP: { /* set the trap flag. */
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
set_single_step(child);
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index 361865c..f8e7e32 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -176,7 +176,7 @@ static inline int check_io_access(struct pt_regs *regs)
#else
#define get_mc_reason(regs) (mfspr(SPRN_MCSR))
#endif
-#define REASON_FP 0
+#define REASON_FP ESR_FP
#define REASON_ILLEGAL ESR_PIL
#define REASON_PRIVILEGED ESR_PPR
#define REASON_TRAP ESR_PTR
diff --git a/arch/ppc/platforms/pmac_cache.S b/arch/ppc/platforms/pmac_cache.S
index da34a9b..fb977de 100644
--- a/arch/ppc/platforms/pmac_cache.S
+++ b/arch/ppc/platforms/pmac_cache.S
@@ -64,27 +64,39 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
mtspr SPRN_HID0,r4 /* Disable DPM */
sync
- /* disp-flush L1 */
- li r4,0x4000
- mtctr r4
+ /* Disp-flush L1. We have a weird problem here that I never
+ * totally figured out. On 750FX, using the ROM for the flush
+ * results in a non-working flush. We use that workaround for
+ * now until I finally understand what's going on. --BenH
+ */
+
+ /* ROM base by default */
lis r4,0xfff0
-1: lwzx r0,r0,r4
+ mfpvr r3
+ srwi r3,r3,16
+ cmplwi cr0,r3,0x7000
+ bne+ 1f
+ /* RAM base on 750FX */
+ li r4,0
+1: li r4,0x4000
+ mtctr r4
+1: lwz r0,0(r4)
addi r4,r4,32
bdnz 1b
sync
isync
- /* disable / invalidate / enable L1 data */
+ /* Disable / invalidate / enable L1 data */
mfspr r3,SPRN_HID0
- rlwinm r0,r0,0,~HID0_DCE
+ rlwinm r3,r3,0,~(HID0_DCE | HID0_ICE)
mtspr SPRN_HID0,r3
sync
isync
- ori r3,r3,HID0_DCE|HID0_DCI
+ ori r3,r3,(HID0_DCE|HID0_DCI|HID0_ICE|HID0_ICFI)
sync
isync
mtspr SPRN_HID0,r3
- xori r3,r3,HID0_DCI
+ xori r3,r3,(HID0_DCI|HID0_ICFI)
mtspr SPRN_HID0,r3
sync
@@ -110,11 +122,20 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
lis r4,2
mtctr r4
lis r4,0xfff0
-1: lwzx r0,r0,r4
+1: lwz r0,0(r4)
+ addi r4,r4,32
+ bdnz 1b
+ sync
+ isync
+ lis r4,2
+ mtctr r4
+ lis r4,0xfff0
+1: dcbf 0,r4
addi r4,r4,32
bdnz 1b
sync
isync
+
/* now disable L2 */
rlwinm r5,r5,0,~L2CR_L2E
b 2f
@@ -135,6 +156,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
mtspr SPRN_L2CR,r4
sync
isync
+
+ /* Wait for the invalidation to complete */
+1: mfspr r3,SPRN_L2CR
+ rlwinm. r0,r3,0,31,31
+ bne 1b
+
+ /* Clear L2I */
xoris r4,r4,L2CR_L2I@h
sync
mtspr SPRN_L2CR,r4
@@ -142,14 +170,16 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
/* now disable the L1 data cache */
mfspr r0,SPRN_HID0
- rlwinm r0,r0,0,~HID0_DCE
+ rlwinm r0,r0,0,~(HID0_DCE|HID0_ICE)
mtspr SPRN_HID0,r0
sync
isync
/* Restore HID0[DPM] to whatever it was before */
sync
- mtspr SPRN_HID0,r8
+ mfspr r0,SPRN_HID0
+ rlwimi r0,r8,0,11,11 /* Turn back HID0[DPM] */
+ mtspr SPRN_HID0,r0
sync
/* restore DR and EE */
@@ -201,7 +231,7 @@ flush_disable_745x:
mtctr r4
li r4,0
1:
- lwzx r0,r0,r4
+ lwz r0,0(r4)
addi r4,r4,32 /* Go to start of next cache line */
bdnz 1b
isync
diff --git a/arch/ppc/platforms/pmac_feature.c b/arch/ppc/platforms/pmac_feature.c
index 46cbf36..867336a 100644
--- a/arch/ppc/platforms/pmac_feature.c
+++ b/arch/ppc/platforms/pmac_feature.c
@@ -1590,6 +1590,114 @@ intrepid_shutdown(struct macio_chip* macio, int sleep_mode)
mdelay(10);
}
+
+void __pmac pmac_tweak_clock_spreading(int enable)
+{
+ struct macio_chip* macio = &macio_chips[0];
+
+ /* Hack for doing clock spreading on some machines PowerBooks and
+ * iBooks. This implements the "platform-do-clockspreading" OF
+ * property as decoded manually on various models. For safety, we also
+ * check the product ID in the device-tree in cases we'll whack the i2c
+ * chip to make reasonably sure we won't set wrong values in there
+ *
+ * Of course, ultimately, we have to implement a real parser for
+ * the platform-do-* stuff...
+ */
+
+ if (macio->type == macio_intrepid) {
+ if (enable)
+ UN_OUT(UNI_N_CLOCK_SPREADING, 2);
+ else
+ UN_OUT(UNI_N_CLOCK_SPREADING, 0);
+ mdelay(40);
+ }
+
+ while (machine_is_compatible("PowerBook5,2") ||
+ machine_is_compatible("PowerBook5,3") ||
+ machine_is_compatible("PowerBook6,2") ||
+ machine_is_compatible("PowerBook6,3")) {
+ struct device_node *ui2c = of_find_node_by_type(NULL, "i2c");
+ struct device_node *dt = of_find_node_by_name(NULL, "device-tree");
+ u8 buffer[9];
+ u32 *productID;
+ int i, rc, changed = 0;
+
+ if (dt == NULL)
+ break;
+ productID = (u32 *)get_property(dt, "pid#", NULL);
+ if (productID == NULL)
+ break;
+ while(ui2c) {
+ struct device_node *p = of_get_parent(ui2c);
+ if (p && !strcmp(p->name, "uni-n"))
+ break;
+ ui2c = of_find_node_by_type(ui2c, "i2c");
+ }
+ if (ui2c == NULL)
+ break;
+ DBG("Trying to bump clock speed for PID: %08x...\n", *productID);
+ rc = pmac_low_i2c_open(ui2c, 1);
+ if (rc != 0)
+ break;
+ pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined);
+ rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9);
+ DBG("read result: %d,", rc);
+ if (rc != 0) {
+ pmac_low_i2c_close(ui2c);
+ break;
+ }
+ for (i=0; i<9; i++)
+ DBG(" %02x", buffer[i]);
+ DBG("\n");
+
+ switch(*productID) {
+ case 0x1182: /* AlBook 12" rev 2 */
+ case 0x1183: /* iBook G4 12" */
+ buffer[0] = (buffer[0] & 0x8f) | 0x70;
+ buffer[2] = (buffer[2] & 0x7f) | 0x00;
+ buffer[5] = (buffer[5] & 0x80) | 0x31;
+ buffer[6] = (buffer[6] & 0x40) | 0xb0;
+ buffer[7] = (buffer[7] & 0x00) | (enable ? 0xc0 : 0xba);
+ buffer[8] = (buffer[8] & 0x00) | 0x30;
+ changed = 1;
+ break;
+ case 0x3142: /* AlBook 15" (ATI M10) */
+ case 0x3143: /* AlBook 17" (ATI M10) */
+ buffer[0] = (buffer[0] & 0xaf) | 0x50;
+ buffer[2] = (buffer[2] & 0x7f) | 0x00;
+ buffer[5] = (buffer[5] & 0x80) | 0x31;
+ buffer[6] = (buffer[6] & 0x40) | 0xb0;
+ buffer[7] = (buffer[7] & 0x00) | (enable ? 0xd0 : 0xc0);
+ buffer[8] = (buffer[8] & 0x00) | 0x30;
+ changed = 1;
+ break;
+ default:
+ DBG("i2c-hwclock: Machine model not handled\n");
+ break;
+ }
+ if (!changed) {
+ pmac_low_i2c_close(ui2c);
+ break;
+ }
+ pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_stdsub);
+ rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_write, 0x80, buffer, 9);
+ DBG("write result: %d,", rc);
+ pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined);
+ rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9);
+ DBG("read result: %d,", rc);
+ if (rc != 0) {
+ pmac_low_i2c_close(ui2c);
+ break;
+ }
+ for (i=0; i<9; i++)
+ DBG(" %02x", buffer[i]);
+ pmac_low_i2c_close(ui2c);
+ break;
+ }
+}
+
+
static int __pmac
core99_sleep(void)
{
@@ -1601,12 +1709,6 @@ core99_sleep(void)
macio->type != macio_intrepid)
return -ENODEV;
- /* The device-tree contains that in the hwclock node */
- if (macio->type == macio_intrepid) {
- UN_OUT(UNI_N_CLOCK_SPREADING, 0);
- mdelay(40);
- }
-
/* We power off the wireless slot in case it was not done
* by the driver. We don't power it on automatically however
*/
@@ -1749,12 +1851,6 @@ core99_wake_up(void)
UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl);
udelay(100);
- /* Restore clock spreading */
- if (macio->type == macio_intrepid) {
- UN_OUT(UNI_N_CLOCK_SPREADING, 2);
- mdelay(40);
- }
-
return 0;
}
@@ -2149,7 +2245,7 @@ static struct pmac_mb_def pmac_mb_defs[] __pmacdata = {
},
{ "PowerBook1,1", "PowerBook 101 (Lombard)",
PMAC_TYPE_101_PBOOK, paddington_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_MOBILE
+ PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
},
{ "PowerBook2,1", "iBook (first generation)",
PMAC_TYPE_ORIG_IBOOK, core99_features,
@@ -2718,97 +2814,11 @@ set_initial_features(void)
MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N);
}
- /* Hack for bumping clock speed on the new PowerBooks and the
- * iBook G4. This implements the "platform-do-clockspreading" OF
- * property. For safety, we also check the product ID in the
- * device-tree to make reasonably sure we won't set wrong values
- * in the clock chip.
- *
- * Of course, ultimately, we have to implement a real parser for
- * the platform-do-* stuff...
+ /* Some machine models need the clock chip to be properly setup for
+ * clock spreading now. This should be a platform function but we
+ * don't do these at the moment
*/
- while (machine_is_compatible("PowerBook5,2") ||
- machine_is_compatible("PowerBook5,3") ||
- machine_is_compatible("PowerBook6,2") ||
- machine_is_compatible("PowerBook6,3")) {
- struct device_node *ui2c = of_find_node_by_type(NULL, "i2c");
- struct device_node *dt = of_find_node_by_name(NULL, "device-tree");
- u8 buffer[9];
- u32 *productID;
- int i, rc, changed = 0;
-
- if (dt == NULL)
- break;
- productID = (u32 *)get_property(dt, "pid#", NULL);
- if (productID == NULL)
- break;
- while(ui2c) {
- struct device_node *p = of_get_parent(ui2c);
- if (p && !strcmp(p->name, "uni-n"))
- break;
- ui2c = of_find_node_by_type(ui2c, "i2c");
- }
- if (ui2c == NULL)
- break;
- DBG("Trying to bump clock speed for PID: %08x...\n", *productID);
- rc = pmac_low_i2c_open(ui2c, 1);
- if (rc != 0)
- break;
- pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined);
- rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9);
- DBG("read result: %d,", rc);
- if (rc != 0) {
- pmac_low_i2c_close(ui2c);
- break;
- }
- for (i=0; i<9; i++)
- DBG(" %02x", buffer[i]);
- DBG("\n");
-
- switch(*productID) {
- case 0x1182: /* AlBook 12" rev 2 */
- case 0x1183: /* iBook G4 12" */
- buffer[0] = (buffer[0] & 0x8f) | 0x70;
- buffer[2] = (buffer[2] & 0x7f) | 0x00;
- buffer[5] = (buffer[5] & 0x80) | 0x31;
- buffer[6] = (buffer[6] & 0x40) | 0xb0;
- buffer[7] = (buffer[7] & 0x00) | 0xc0;
- buffer[8] = (buffer[8] & 0x00) | 0x30;
- changed = 1;
- break;
- case 0x3142: /* AlBook 15" (ATI M10) */
- case 0x3143: /* AlBook 17" (ATI M10) */
- buffer[0] = (buffer[0] & 0xaf) | 0x50;
- buffer[2] = (buffer[2] & 0x7f) | 0x00;
- buffer[5] = (buffer[5] & 0x80) | 0x31;
- buffer[6] = (buffer[6] & 0x40) | 0xb0;
- buffer[7] = (buffer[7] & 0x00) | 0xd0;
- buffer[8] = (buffer[8] & 0x00) | 0x30;
- changed = 1;
- break;
- default:
- DBG("i2c-hwclock: Machine model not handled\n");
- break;
- }
- if (!changed) {
- pmac_low_i2c_close(ui2c);
- break;
- }
- pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_stdsub);
- rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_write, 0x80, buffer, 9);
- DBG("write result: %d,", rc);
- pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined);
- rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9);
- DBG("read result: %d,", rc);
- if (rc != 0) {
- pmac_low_i2c_close(ui2c);
- break;
- }
- for (i=0; i<9; i++)
- DBG(" %02x", buffer[i]);
- pmac_low_i2c_close(ui2c);
- break;
- }
+ pmac_tweak_clock_spreading(1);
#endif /* CONFIG_POWER4 */
diff --git a/arch/ppc/platforms/pmac_sleep.S b/arch/ppc/platforms/pmac_sleep.S
index 3139b67..f459ade 100644
--- a/arch/ppc/platforms/pmac_sleep.S
+++ b/arch/ppc/platforms/pmac_sleep.S
@@ -267,6 +267,10 @@ grackle_wake_up:
/* Restore various CPU config stuffs */
bl __restore_cpu_setup
+ /* Make sure all FPRs have been initialized */
+ bl reloc_offset
+ bl __init_fpu_registers
+
/* Invalidate & enable L1 cache, we don't care about
* whatever the ROM may have tried to write to memory
*/
diff --git a/arch/ppc/platforms/radstone_ppc7d.c b/arch/ppc/platforms/radstone_ppc7d.c
index 2a99b43..c30607a 100644
--- a/arch/ppc/platforms/radstone_ppc7d.c
+++ b/arch/ppc/platforms/radstone_ppc7d.c
@@ -68,6 +68,7 @@
#define PPC7D_RST_PIN 17 /* GPP17 */
extern u32 mv64360_irq_base;
+extern spinlock_t rtc_lock;
static struct mv64x60_handle bh;
static int ppc7d_has_alma;
@@ -75,6 +76,11 @@ static int ppc7d_has_alma;
extern void gen550_progress(char *, unsigned short);
extern void gen550_init(int, struct uart_port *);
+/* FIXME - move to h file */
+extern int ds1337_do_command(int id, int cmd, void *arg);
+#define DS1337_GET_DATE 0
+#define DS1337_SET_DATE 1
+
/* residual data */
unsigned char __res[sizeof(bd_t)];
@@ -253,6 +259,8 @@ static int ppc7d_show_cpuinfo(struct seq_file *m)
u8 val1, val2;
static int flash_sizes[4] = { 64, 32, 0, 16 };
static int flash_banks[4] = { 4, 3, 2, 1 };
+ static int sdram_bank_sizes[4] = { 128, 256, 512, 1 };
+ int sdram_num_banks = 2;
static char *pci_modes[] = { "PCI33", "PCI66",
"Unknown", "Unknown",
"PCIX33", "PCIX66",
@@ -279,13 +287,17 @@ static int ppc7d_show_cpuinfo(struct seq_file *m)
(val1 == PPC7D_CPLD_MB_TYPE_PLL_100) ? 100 :
(val1 == PPC7D_CPLD_MB_TYPE_PLL_64) ? 64 : 0);
+ val = inb(PPC7D_CPLD_MEM_CONFIG);
+ if (val & PPC7D_CPLD_SDRAM_BANK_NUM_MASK) sdram_num_banks--;
+
val = inb(PPC7D_CPLD_MEM_CONFIG_EXTEND);
- val1 = val & PPC7D_CPLD_SDRAM_BANK_SIZE_MASK;
- seq_printf(m, "SDRAM\t\t: %d%c",
- (val1 == PPC7D_CPLD_SDRAM_BANK_SIZE_128M) ? 128 :
- (val1 == PPC7D_CPLD_SDRAM_BANK_SIZE_256M) ? 256 :
- (val1 == PPC7D_CPLD_SDRAM_BANK_SIZE_512M) ? 512 : 1,
- (val1 == PPC7D_CPLD_SDRAM_BANK_SIZE_1G) ? 'G' : 'M');
+ val1 = (val & PPC7D_CPLD_SDRAM_BANK_SIZE_MASK) >> 6;
+ seq_printf(m, "SDRAM\t\t: %d banks of %d%c, total %d%c",
+ sdram_num_banks,
+ sdram_bank_sizes[val1],
+ (sdram_bank_sizes[val1] < 128) ? 'G' : 'M',
+ sdram_num_banks * sdram_bank_sizes[val1],
+ (sdram_bank_sizes[val1] < 128) ? 'G' : 'M');
if (val2 & PPC7D_CPLD_MB_TYPE_ECC_FITTED_MASK) {
seq_printf(m, " [ECC %sabled]",
(val2 & PPC7D_CPLD_MB_TYPE_ECC_ENABLE_MASK) ? "en" :
@@ -1236,6 +1248,38 @@ static void __init ppc7d_setup_arch(void)
printk(KERN_INFO "Radstone Technology PPC7D\n");
if (ppc_md.progress)
ppc_md.progress("ppc7d_setup_arch: exit", 0);
+
+}
+
+/* Real Time Clock support.
+ * PPC7D has a DS1337 accessed by I2C.
+ */
+static ulong ppc7d_get_rtc_time(void)
+{
+ struct rtc_time tm;
+ int result;
+
+ spin_lock(&rtc_lock);
+ result = ds1337_do_command(0, DS1337_GET_DATE, &tm);
+ spin_unlock(&rtc_lock);
+
+ if (result == 0)
+ result = mktime(tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
+
+ return result;
+}
+
+static int ppc7d_set_rtc_time(unsigned long nowtime)
+{
+ struct rtc_time tm;
+ int result;
+
+ spin_lock(&rtc_lock);
+ to_tm(nowtime, &tm);
+ result = ds1337_do_command(0, DS1337_SET_DATE, &tm);
+ spin_unlock(&rtc_lock);
+
+ return result;
}
/* This kernel command line parameter can be used to have the target
@@ -1293,6 +1337,10 @@ static void ppc7d_init2(void)
data8 |= 0x07;
outb(data8, PPC7D_CPLD_LEDS);
+ /* Hook up RTC. We couldn't do this earlier because we need the I2C subsystem */
+ ppc_md.set_rtc_time = ppc7d_set_rtc_time;
+ ppc_md.get_rtc_time = ppc7d_get_rtc_time;
+
pr_debug("%s: exit\n", __FUNCTION__);
}
diff --git a/arch/ppc/platforms/radstone_ppc7d.h b/arch/ppc/platforms/radstone_ppc7d.h
index 4546fff2..9383755 100644
--- a/arch/ppc/platforms/radstone_ppc7d.h
+++ b/arch/ppc/platforms/radstone_ppc7d.h
@@ -240,6 +240,7 @@
#define PPC7D_CPLD_FLASH_CNTL 0x086E
/* MEMORY_CONFIG_EXTEND */
+#define PPC7D_CPLD_SDRAM_BANK_NUM_MASK 0x02
#define PPC7D_CPLD_SDRAM_BANK_SIZE_MASK 0xc0
#define PPC7D_CPLD_SDRAM_BANK_SIZE_128M 0
#define PPC7D_CPLD_SDRAM_BANK_SIZE_256M 0x40
diff --git a/arch/ppc/syslib/cpm2_pic.c b/arch/ppc/syslib/cpm2_pic.c
index 954b07f..c867be6 100644
--- a/arch/ppc/syslib/cpm2_pic.c
+++ b/arch/ppc/syslib/cpm2_pic.c
@@ -107,6 +107,11 @@ static void cpm2_end_irq(unsigned int irq_nr)
simr = &(cpm2_immr->im_intctl.ic_simrh);
ppc_cached_irq_mask[word] |= 1 << bit;
simr[word] = ppc_cached_irq_mask[word];
+ /*
+ * Work around large numbers of spurious IRQs on PowerPC 82xx
+ * systems.
+ */
+ mb();
}
}
diff --git a/arch/ppc64/boot/addnote.c b/arch/ppc64/boot/addnote.c
index 66ff810..719663a 100644
--- a/arch/ppc64/boot/addnote.c
+++ b/arch/ppc64/boot/addnote.c
@@ -19,6 +19,7 @@
#include <unistd.h>
#include <string.h>
+/* CHRP note section */
char arch[] = "PowerPC";
#define N_DESCR 6
@@ -31,6 +32,29 @@ unsigned int descr[N_DESCR] = {
0x4000, /* load-base */
};
+/* RPA note section */
+char rpaname[] = "IBM,RPA-Client-Config";
+
+/*
+ * Note: setting ignore_my_client_config *should* mean that OF ignores
+ * all the other fields, but there is a firmware bug which means that
+ * it looks at the splpar field at least. So these values need to be
+ * reasonable.
+ */
+#define N_RPA_DESCR 8
+unsigned int rpanote[N_RPA_DESCR] = {
+ 0, /* lparaffinity */
+ 64, /* min_rmo_size */
+ 0, /* min_rmo_percent */
+ 40, /* max_pft_size */
+ 1, /* splpar */
+ -1, /* min_load */
+ 0, /* new_mem_def */
+ 1, /* ignore_my_client_config */
+};
+
+#define ROUNDUP(len) (((len) + 3) & ~3)
+
unsigned char buf[512];
#define GET_16BE(off) ((buf[off] << 8) + (buf[(off)+1]))
@@ -69,7 +93,7 @@ main(int ac, char **av)
{
int fd, n, i;
int ph, ps, np;
- int nnote, ns;
+ int nnote, nnote2, ns;
if (ac != 2) {
fprintf(stderr, "Usage: %s elf-file\n", av[0]);
@@ -81,7 +105,8 @@ main(int ac, char **av)
exit(1);
}
- nnote = strlen(arch) + 1 + (N_DESCR + 3) * 4;
+ nnote = 12 + ROUNDUP(strlen(arch) + 1) + sizeof(descr);
+ nnote2 = 12 + ROUNDUP(strlen(rpaname) + 1) + sizeof(rpanote);
n = read(fd, buf, sizeof(buf));
if (n < 0) {
@@ -104,7 +129,7 @@ main(int ac, char **av)
np = GET_16BE(E_PHNUM);
if (ph < E_HSIZE || ps < PH_HSIZE || np < 1)
goto notelf;
- if (ph + (np + 1) * ps + nnote > n)
+ if (ph + (np + 2) * ps + nnote + nnote2 > n)
goto nospace;
for (i = 0; i < np; ++i) {
@@ -117,12 +142,12 @@ main(int ac, char **av)
}
/* XXX check that the area we want to use is all zeroes */
- for (i = 0; i < ps + nnote; ++i)
+ for (i = 0; i < 2 * ps + nnote + nnote2; ++i)
if (buf[ph + i] != 0)
goto nospace;
/* fill in the program header entry */
- ns = ph + ps;
+ ns = ph + 2 * ps;
PUT_32BE(ph + PH_TYPE, PT_NOTE);
PUT_32BE(ph + PH_OFFSET, ns);
PUT_32BE(ph + PH_FILESZ, nnote);
@@ -134,11 +159,26 @@ main(int ac, char **av)
PUT_32BE(ns + 8, 0x1275);
strcpy(&buf[ns + 12], arch);
ns += 12 + strlen(arch) + 1;
- for (i = 0; i < N_DESCR; ++i)
- PUT_32BE(ns + i * 4, descr[i]);
+ for (i = 0; i < N_DESCR; ++i, ns += 4)
+ PUT_32BE(ns, descr[i]);
+
+ /* fill in the second program header entry and the RPA note area */
+ ph += ps;
+ PUT_32BE(ph + PH_TYPE, PT_NOTE);
+ PUT_32BE(ph + PH_OFFSET, ns);
+ PUT_32BE(ph + PH_FILESZ, nnote2);
+
+ /* fill in the note area we point to */
+ PUT_32BE(ns, strlen(rpaname) + 1);
+ PUT_32BE(ns + 4, sizeof(rpanote));
+ PUT_32BE(ns + 8, 0x12759999);
+ strcpy(&buf[ns + 12], rpaname);
+ ns += 12 + ROUNDUP(strlen(rpaname) + 1);
+ for (i = 0; i < N_RPA_DESCR; ++i, ns += 4)
+ PUT_32BE(ns, rpanote[i]);
/* Update the number of program headers */
- PUT_16BE(E_PHNUM, np + 1);
+ PUT_16BE(E_PHNUM, np + 2);
/* write back */
lseek(fd, (long) 0, SEEK_SET);
@@ -155,11 +195,11 @@ main(int ac, char **av)
exit(0);
notelf:
- fprintf(stderr, "%s does not appear to be an ELF file\n", av[0]);
+ fprintf(stderr, "%s does not appear to be an ELF file\n", av[1]);
exit(1);
nospace:
fprintf(stderr, "sorry, I can't find space in %s to put the note\n",
- av[0]);
+ av[1]);
exit(1);
}
diff --git a/arch/ppc64/kernel/HvLpEvent.c b/arch/ppc64/kernel/HvLpEvent.c
index 9802bee..f8f1963 100644
--- a/arch/ppc64/kernel/HvLpEvent.c
+++ b/arch/ppc64/kernel/HvLpEvent.c
@@ -45,7 +45,7 @@ int HvLpEvent_unregisterHandler( HvLpEvent_Type eventType )
/* We now sleep until all other CPUs have scheduled. This ensures that
* the deletion is seen by all other CPUs, and that the deleted handler
* isn't still running on another CPU when we return. */
- synchronize_kernel();
+ synchronize_rcu();
}
}
return rc;
diff --git a/arch/ppc64/kernel/nvram.c b/arch/ppc64/kernel/nvram.c
index b9069c2..4e71781 100644
--- a/arch/ppc64/kernel/nvram.c
+++ b/arch/ppc64/kernel/nvram.c
@@ -339,9 +339,9 @@ static int nvram_remove_os_partition(void)
static int nvram_create_os_partition(void)
{
struct list_head * p;
- struct nvram_partition * part;
- struct nvram_partition * new_part = NULL;
- struct nvram_partition * free_part = NULL;
+ struct nvram_partition *part = NULL;
+ struct nvram_partition *new_part = NULL;
+ struct nvram_partition *free_part = NULL;
int seq_init[2] = { 0, 0 };
loff_t tmp_index;
long size = 0;
@@ -364,13 +364,11 @@ static int nvram_create_os_partition(void)
free_part = part;
}
}
- if (!size) {
+ if (!size)
return -ENOSPC;
- }
/* Create our OS partition */
- new_part = (struct nvram_partition *)
- kmalloc(sizeof(struct nvram_partition), GFP_KERNEL);
+ new_part = kmalloc(sizeof(*new_part), GFP_KERNEL);
if (!new_part) {
printk(KERN_ERR "nvram_create_os_partition: kmalloc failed\n");
return -ENOMEM;
@@ -379,7 +377,7 @@ static int nvram_create_os_partition(void)
new_part->index = free_part->index;
new_part->header.signature = NVRAM_SIG_OS;
new_part->header.length = size;
- sprintf(new_part->header.name, "ppc64,linux");
+ strcpy(new_part->header.name, "ppc64,linux");
new_part->header.checksum = nvram_checksum(&new_part->header);
rc = nvram_write_header(new_part);
@@ -394,7 +392,8 @@ static int nvram_create_os_partition(void)
tmp_index = new_part->index + NVRAM_HEADER_LEN;
rc = ppc_md.nvram_write((char *)&seq_init, sizeof(seq_init), &tmp_index);
if (rc <= 0) {
- printk(KERN_ERR "nvram_create_os_partition: nvram_write failed (%d)\n", rc);
+ printk(KERN_ERR "nvram_create_os_partition: nvram_write "
+ "failed (%d)\n", rc);
return rc;
}
diff --git a/arch/ppc64/kernel/pSeries_hvCall.S b/arch/ppc64/kernel/pSeries_hvCall.S
index 0715d30..176e8da 100644
--- a/arch/ppc64/kernel/pSeries_hvCall.S
+++ b/arch/ppc64/kernel/pSeries_hvCall.S
@@ -28,6 +28,8 @@
unsigned long *out3); R10
*/
_GLOBAL(plpar_hcall)
+ HMT_MEDIUM
+
mfcr r0
std r8,STK_PARM(r8)(r1) /* Save out ptrs */
@@ -53,6 +55,8 @@ _GLOBAL(plpar_hcall)
/* Simple interface with no output values (other than status) */
_GLOBAL(plpar_hcall_norets)
+ HMT_MEDIUM
+
mfcr r0
stw r0,8(r1)
@@ -75,6 +79,8 @@ _GLOBAL(plpar_hcall_norets)
unsigned long *out1); 120(R1)
*/
_GLOBAL(plpar_hcall_8arg_2ret)
+ HMT_MEDIUM
+
mfcr r0
ld r11,STK_PARM(r11)(r1) /* put arg8 in R11 */
stw r0,8(r1)
@@ -99,6 +105,8 @@ _GLOBAL(plpar_hcall_8arg_2ret)
unsigned long *out4); 112(R1)
*/
_GLOBAL(plpar_hcall_4out)
+ HMT_MEDIUM
+
mfcr r0
stw r0,8(r1)
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c
index 45a4ad0..fe2946c 100644
--- a/arch/ppc64/kernel/prom.c
+++ b/arch/ppc64/kernel/prom.c
@@ -321,6 +321,10 @@ static int __devinit finish_node_interrupts(struct device_node *np,
char *name = get_property(ic->parent, "name", NULL);
if (name && !strcmp(name, "u3"))
np->intrs[intrcount].line += 128;
+ else if (!(name && !strcmp(name, "mac-io")))
+ /* ignore other cascaded controllers, such as
+ the k2-sata-root */
+ break;
}
np->intrs[intrcount].sense = 1;
if (n > 1)
diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c
index 8dffa9a..35ec42d 100644
--- a/arch/ppc64/kernel/prom_init.c
+++ b/arch/ppc64/kernel/prom_init.c
@@ -493,6 +493,113 @@ static void __init early_cmdline_parse(void)
}
/*
+ * To tell the firmware what our capabilities are, we have to pass
+ * it a fake 32-bit ELF header containing a couple of PT_NOTE sections
+ * that contain structures that contain the actual values.
+ */
+static struct fake_elf {
+ Elf32_Ehdr elfhdr;
+ Elf32_Phdr phdr[2];
+ struct chrpnote {
+ u32 namesz;
+ u32 descsz;
+ u32 type;
+ char name[8]; /* "PowerPC" */
+ struct chrpdesc {
+ u32 real_mode;
+ u32 real_base;
+ u32 real_size;
+ u32 virt_base;
+ u32 virt_size;
+ u32 load_base;
+ } chrpdesc;
+ } chrpnote;
+ struct rpanote {
+ u32 namesz;
+ u32 descsz;
+ u32 type;
+ char name[24]; /* "IBM,RPA-Client-Config" */
+ struct rpadesc {
+ u32 lpar_affinity;
+ u32 min_rmo_size;
+ u32 min_rmo_percent;
+ u32 max_pft_size;
+ u32 splpar;
+ u32 min_load;
+ u32 new_mem_def;
+ u32 ignore_me;
+ } rpadesc;
+ } rpanote;
+} fake_elf = {
+ .elfhdr = {
+ .e_ident = { 0x7f, 'E', 'L', 'F',
+ ELFCLASS32, ELFDATA2MSB, EV_CURRENT },
+ .e_type = ET_EXEC, /* yeah right */
+ .e_machine = EM_PPC,
+ .e_version = EV_CURRENT,
+ .e_phoff = offsetof(struct fake_elf, phdr),
+ .e_phentsize = sizeof(Elf32_Phdr),
+ .e_phnum = 2
+ },
+ .phdr = {
+ [0] = {
+ .p_type = PT_NOTE,
+ .p_offset = offsetof(struct fake_elf, chrpnote),
+ .p_filesz = sizeof(struct chrpnote)
+ }, [1] = {
+ .p_type = PT_NOTE,
+ .p_offset = offsetof(struct fake_elf, rpanote),
+ .p_filesz = sizeof(struct rpanote)
+ }
+ },
+ .chrpnote = {
+ .namesz = sizeof("PowerPC"),
+ .descsz = sizeof(struct chrpdesc),
+ .type = 0x1275,
+ .name = "PowerPC",
+ .chrpdesc = {
+ .real_mode = ~0U, /* ~0 means "don't care" */
+ .real_base = ~0U,
+ .real_size = ~0U,
+ .virt_base = ~0U,
+ .virt_size = ~0U,
+ .load_base = ~0U
+ },
+ },
+ .rpanote = {
+ .namesz = sizeof("IBM,RPA-Client-Config"),
+ .descsz = sizeof(struct rpadesc),
+ .type = 0x12759999,
+ .name = "IBM,RPA-Client-Config",
+ .rpadesc = {
+ .lpar_affinity = 0,
+ .min_rmo_size = 64, /* in megabytes */
+ .min_rmo_percent = 0,
+ .max_pft_size = 48, /* 2^48 bytes max PFT size */
+ .splpar = 1,
+ .min_load = ~0U,
+ .new_mem_def = 0
+ }
+ }
+};
+
+static void __init prom_send_capabilities(void)
+{
+ unsigned long offset = reloc_offset();
+ ihandle elfloader;
+ int ret;
+
+ elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader"));
+ if (elfloader == 0) {
+ prom_printf("couldn't open /packages/elf-loader\n");
+ return;
+ }
+ ret = call_prom("call-method", 3, 1, ADDR("process-elf-header"),
+ elfloader, ADDR(&fake_elf));
+ call_prom("close", 1, 0, elfloader);
+}
+
+/*
* Memory allocation strategy... our layout is normally:
*
* at 14Mb or more we vmlinux, then a gap and initrd. In some rare cases, initrd
@@ -1448,6 +1555,12 @@ static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start,
}
}
+/*
+ * The Open Firmware 1275 specification states properties must be 31 bytes or
+ * less, however not all firmwares obey this. Make it 64 bytes to be safe.
+ */
+#define MAX_PROPERTY_NAME 64
+
static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
unsigned long *mem_end)
{
@@ -1457,7 +1570,7 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
unsigned long soff;
unsigned char *valp;
unsigned long offset = reloc_offset();
- char pname[32];
+ char pname[MAX_PROPERTY_NAME];
char *path;
path = RELOC(prom_scratch);
diff --git a/arch/ppc64/kernel/ptrace.c b/arch/ppc64/kernel/ptrace.c
index 3c76333..9f8c608 100644
--- a/arch/ppc64/kernel/ptrace.c
+++ b/arch/ppc64/kernel/ptrace.c
@@ -28,6 +28,7 @@
#include <linux/security.h>
#include <linux/audit.h>
#include <linux/seccomp.h>
+#include <linux/signal.h>
#include <asm/uaccess.h>
#include <asm/page.h>
@@ -162,7 +163,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: { /* restart after signal. */
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
if (request == PTRACE_SYSCALL)
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -194,7 +195,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_SINGLESTEP: { /* set the trap flag. */
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
set_single_step(child);
diff --git a/arch/ppc64/kernel/ptrace32.c b/arch/ppc64/kernel/ptrace32.c
index ee81b1b..1643642 100644
--- a/arch/ppc64/kernel/ptrace32.c
+++ b/arch/ppc64/kernel/ptrace32.c
@@ -26,6 +26,7 @@
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/security.h>
+#include <linux/signal.h>
#include <asm/uaccess.h>
#include <asm/page.h>
@@ -293,7 +294,7 @@ int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data)
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: { /* restart after signal. */
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
if (request == PTRACE_SYSCALL)
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -325,7 +326,7 @@ int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data)
case PTRACE_SINGLESTEP: { /* set the trap flag. */
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
set_single_step(child);
diff --git a/arch/ppc64/kernel/signal32.c b/arch/ppc64/kernel/signal32.c
index b0e167d..3c2fa5c 100644
--- a/arch/ppc64/kernel/signal32.c
+++ b/arch/ppc64/kernel/signal32.c
@@ -657,7 +657,7 @@ static int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
/* Save user registers on the stack */
frame = &rt_sf->uc.uc_mcontext;
- if (put_user(regs->gpr[1], (unsigned long __user *)newsp))
+ if (put_user(regs->gpr[1], (u32 __user *)newsp))
goto badframe;
if (vdso32_rt_sigtramp && current->thread.vdso_base) {
@@ -842,7 +842,7 @@ static int handle_signal32(unsigned long sig, struct k_sigaction *ka,
regs->link = (unsigned long) frame->mctx.tramp;
}
- if (put_user(regs->gpr[1], (unsigned long __user *)newsp))
+ if (put_user(regs->gpr[1], (u32 __user *)newsp))
goto badframe;
regs->gpr[1] = (unsigned long) newsp;
regs->gpr[3] = sig;
diff --git a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c
index 1c92da3..3b906cd 100644
--- a/arch/ppc64/kernel/smp.c
+++ b/arch/ppc64/kernel/smp.c
@@ -125,7 +125,7 @@ void __devinit smp_generic_kick_cpu(int nr)
* the processor will continue on to secondary_start
*/
paca[nr].cpu_start = 1;
- mb();
+ smp_mb();
}
#endif /* CONFIG_PPC_MULTIPLATFORM */
@@ -256,7 +256,7 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
}
call_data = &data;
- wmb();
+ smp_wmb();
/* Send a message to all other CPUs and wait for them to respond */
smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_CALL_FUNCTION);
@@ -431,7 +431,7 @@ int generic_cpu_enable(unsigned int cpu)
/* get the target out of it's holding state */
per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
- wmb();
+ smp_wmb();
while (!cpu_online(cpu))
cpu_relax();
@@ -447,7 +447,7 @@ void generic_cpu_die(unsigned int cpu)
int i;
for (i = 0; i < 100; i++) {
- rmb();
+ smp_rmb();
if (per_cpu(cpu_state, cpu) == CPU_DEAD)
return;
msleep(100);
@@ -463,7 +463,7 @@ void generic_mach_cpu_die(void)
cpu = smp_processor_id();
printk(KERN_DEBUG "CPU%d offline\n", cpu);
__get_cpu_var(cpu_state) = CPU_DEAD;
- wmb();
+ smp_wmb();
while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE)
cpu_relax();
@@ -515,7 +515,7 @@ int __devinit __cpu_up(unsigned int cpu)
* be written out to main store before we release
* the processor.
*/
- mb();
+ smp_mb();
/* wake up cpus */
DBG("smp: kicking cpu %d\n", cpu);
diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c
index 77ded5a..772a465 100644
--- a/arch/ppc64/kernel/time.c
+++ b/arch/ppc64/kernel/time.c
@@ -221,15 +221,15 @@ static __inline__ void timer_recalc_offset(unsigned long cur_tb)
temp_varp->tb_to_xs = do_gtod.varp->tb_to_xs;
temp_varp->tb_orig_stamp = new_tb_orig_stamp;
temp_varp->stamp_xsec = new_stamp_xsec;
- mb();
+ smp_mb();
do_gtod.varp = temp_varp;
do_gtod.var_idx = temp_idx;
++(systemcfg->tb_update_count);
- wmb();
+ smp_wmb();
systemcfg->tb_orig_stamp = new_tb_orig_stamp;
systemcfg->stamp_xsec = new_stamp_xsec;
- wmb();
+ smp_wmb();
++(systemcfg->tb_update_count);
}
@@ -648,7 +648,7 @@ void ppc_adjtimex(void)
temp_varp->tb_to_xs = new_tb_to_xs;
temp_varp->stamp_xsec = new_stamp_xsec;
temp_varp->tb_orig_stamp = do_gtod.varp->tb_orig_stamp;
- mb();
+ smp_mb();
do_gtod.varp = temp_varp;
do_gtod.var_idx = temp_idx;
@@ -662,10 +662,10 @@ void ppc_adjtimex(void)
* loops back and reads them again until this criteria is met.
*/
++(systemcfg->tb_update_count);
- wmb();
+ smp_wmb();
systemcfg->tb_to_xs = new_tb_to_xs;
systemcfg->stamp_xsec = new_stamp_xsec;
- wmb();
+ smp_wmb();
++(systemcfg->tb_update_count);
write_sequnlock_irqrestore( &xtime_lock, flags );
diff --git a/arch/ppc64/kernel/vdso32/Makefile b/arch/ppc64/kernel/vdso32/Makefile
index ede2f7e..0b1b0df 100644
--- a/arch/ppc64/kernel/vdso32/Makefile
+++ b/arch/ppc64/kernel/vdso32/Makefile
@@ -1,7 +1,7 @@
# List of files in the vdso, has to be asm only for now
-obj-vdso32 = sigtramp.o gettimeofday.o datapage.o cacheflush.o
+obj-vdso32 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o
# Build rules
diff --git a/arch/ppc64/kernel/vdso32/note.S b/arch/ppc64/kernel/vdso32/note.S
new file mode 100644
index 0000000..d4b5be4
--- /dev/null
+++ b/arch/ppc64/kernel/vdso32/note.S
@@ -0,0 +1,25 @@
+/*
+ * This supplies .note.* sections to go into the PT_NOTE inside the vDSO text.
+ * Here we can supply some information useful to userland.
+ */
+
+#include <linux/uts.h>
+#include <linux/version.h>
+
+#define ASM_ELF_NOTE_BEGIN(name, flags, vendor, type) \
+ .section name, flags; \
+ .balign 4; \
+ .long 1f - 0f; /* name length */ \
+ .long 3f - 2f; /* data length */ \
+ .long type; /* note type */ \
+0: .asciz vendor; /* vendor name */ \
+1: .balign 4; \
+2:
+
+#define ASM_ELF_NOTE_END \
+3: .balign 4; /* pad out section */ \
+ .previous
+
+ ASM_ELF_NOTE_BEGIN(".note.kernel-version", "a", UTS_SYSNAME, 0)
+ .long LINUX_VERSION_CODE
+ ASM_ELF_NOTE_END
diff --git a/arch/ppc64/kernel/vdso32/vdso32.lds.S b/arch/ppc64/kernel/vdso32/vdso32.lds.S
index cca27bd..11290c9 100644
--- a/arch/ppc64/kernel/vdso32/vdso32.lds.S
+++ b/arch/ppc64/kernel/vdso32/vdso32.lds.S
@@ -20,6 +20,8 @@ SECTIONS
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
+ .note : { *(.note.*) } :text :note
+
. = ALIGN (16);
.text :
{
@@ -87,6 +89,7 @@ SECTIONS
PHDRS
{
text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */
+ note PT_NOTE FLAGS(4); /* PF_R */
dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */
}
diff --git a/arch/ppc64/kernel/vdso64/Makefile b/arch/ppc64/kernel/vdso64/Makefile
index bd3f70b..ab39988 100644
--- a/arch/ppc64/kernel/vdso64/Makefile
+++ b/arch/ppc64/kernel/vdso64/Makefile
@@ -1,6 +1,6 @@
# List of files in the vdso, has to be asm only for now
-obj-vdso64 = sigtramp.o gettimeofday.o datapage.o cacheflush.o
+obj-vdso64 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o
# Build rules
diff --git a/arch/ppc64/kernel/vdso64/note.S b/arch/ppc64/kernel/vdso64/note.S
new file mode 100644
index 0000000..dc2a509
--- /dev/null
+++ b/arch/ppc64/kernel/vdso64/note.S
@@ -0,0 +1 @@
+#include "../vdso32/note.S"
diff --git a/arch/ppc64/kernel/vdso64/vdso64.lds.S b/arch/ppc64/kernel/vdso64/vdso64.lds.S
index 942c815..9cb2818 100644
--- a/arch/ppc64/kernel/vdso64/vdso64.lds.S
+++ b/arch/ppc64/kernel/vdso64/vdso64.lds.S
@@ -18,12 +18,14 @@ SECTIONS
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
+ .note : { *(.note.*) } :text :note
+
. = ALIGN (16);
.text :
{
*(.text .stub .text.* .gnu.linkonce.t.*)
*(.sfpr .glink)
- }
+ } :text
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
@@ -88,6 +90,7 @@ SECTIONS
PHDRS
{
text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */
+ note PT_NOTE FLAGS(4); /* PF_R */
dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */
}
diff --git a/arch/ppc64/mm/hash_low.S b/arch/ppc64/mm/hash_low.S
index 8c0156a..c23d469 100644
--- a/arch/ppc64/mm/hash_low.S
+++ b/arch/ppc64/mm/hash_low.S
@@ -85,7 +85,10 @@ _GLOBAL(__hash_page)
bne- htab_wrong_access
/* Check if PTE is busy */
andi. r0,r31,_PAGE_BUSY
- bne- 1b
+ /* If so, just bail out and refault if needed. Someone else
+ * is changing this PTE anyway and might hash it.
+ */
+ bne- bail_ok
/* Prepare new PTE value (turn access RW into DIRTY, then
* add BUSY,HASHPTE and ACCESSED)
*/
@@ -215,6 +218,10 @@ _GLOBAL(htab_call_hpte_remove)
/* Try all again */
b htab_insert_pte
+bail_ok:
+ li r3,0
+ b bail
+
htab_pte_insert_ok:
/* Insert slot number & secondary bit in PTE */
rldimi r30,r3,12,63-15
diff --git a/arch/ppc64/mm/hugetlbpage.c b/arch/ppc64/mm/hugetlbpage.c
index 390296e..d3bf86a 100644
--- a/arch/ppc64/mm/hugetlbpage.c
+++ b/arch/ppc64/mm/hugetlbpage.c
@@ -42,7 +42,7 @@ static inline int hugepgd_index(unsigned long addr)
return (addr & ~REGION_MASK) >> HUGEPGDIR_SHIFT;
}
-static pgd_t *hugepgd_offset(struct mm_struct *mm, unsigned long addr)
+static pud_t *hugepgd_offset(struct mm_struct *mm, unsigned long addr)
{
int index;
@@ -52,21 +52,21 @@ static pgd_t *hugepgd_offset(struct mm_struct *mm, unsigned long addr)
index = hugepgd_index(addr);
BUG_ON(index >= PTRS_PER_HUGEPGD);
- return mm->context.huge_pgdir + index;
+ return (pud_t *)(mm->context.huge_pgdir + index);
}
-static inline pte_t *hugepte_offset(pgd_t *dir, unsigned long addr)
+static inline pte_t *hugepte_offset(pud_t *dir, unsigned long addr)
{
int index;
- if (pgd_none(*dir))
+ if (pud_none(*dir))
return NULL;
index = (addr >> HPAGE_SHIFT) % PTRS_PER_HUGEPTE;
- return (pte_t *)pgd_page(*dir) + index;
+ return (pte_t *)pud_page(*dir) + index;
}
-static pgd_t *hugepgd_alloc(struct mm_struct *mm, unsigned long addr)
+static pud_t *hugepgd_alloc(struct mm_struct *mm, unsigned long addr)
{
BUG_ON(! in_hugepage_area(mm->context, addr));
@@ -90,10 +90,9 @@ static pgd_t *hugepgd_alloc(struct mm_struct *mm, unsigned long addr)
return hugepgd_offset(mm, addr);
}
-static pte_t *hugepte_alloc(struct mm_struct *mm, pgd_t *dir,
- unsigned long addr)
+static pte_t *hugepte_alloc(struct mm_struct *mm, pud_t *dir, unsigned long addr)
{
- if (! pgd_present(*dir)) {
+ if (! pud_present(*dir)) {
pte_t *new;
spin_unlock(&mm->page_table_lock);
@@ -104,7 +103,7 @@ static pte_t *hugepte_alloc(struct mm_struct *mm, pgd_t *dir,
* Because we dropped the lock, we should re-check the
* entry, as somebody else could have populated it..
*/
- if (pgd_present(*dir)) {
+ if (pud_present(*dir)) {
if (new)
kmem_cache_free(zero_cache, new);
} else {
@@ -115,7 +114,7 @@ static pte_t *hugepte_alloc(struct mm_struct *mm, pgd_t *dir,
ptepage = virt_to_page(new);
ptepage->mapping = (void *) mm;
ptepage->index = addr & HUGEPGDIR_MASK;
- pgd_populate(mm, dir, new);
+ pud_populate(mm, dir, new);
}
}
@@ -124,28 +123,28 @@ static pte_t *hugepte_alloc(struct mm_struct *mm, pgd_t *dir,
static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
{
- pgd_t *pgd;
+ pud_t *pud;
BUG_ON(! in_hugepage_area(mm->context, addr));
- pgd = hugepgd_offset(mm, addr);
- if (! pgd)
+ pud = hugepgd_offset(mm, addr);
+ if (! pud)
return NULL;
- return hugepte_offset(pgd, addr);
+ return hugepte_offset(pud, addr);
}
static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
{
- pgd_t *pgd;
+ pud_t *pud;
BUG_ON(! in_hugepage_area(mm->context, addr));
- pgd = hugepgd_alloc(mm, addr);
- if (! pgd)
+ pud = hugepgd_alloc(mm, addr);
+ if (! pud)
return NULL;
- return hugepte_alloc(mm, pgd, addr);
+ return hugepte_alloc(mm, pud, addr);
}
static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma,
@@ -709,10 +708,10 @@ void hugetlb_mm_free_pgd(struct mm_struct *mm)
/* cleanup any hugepte pages leftover */
for (i = 0; i < PTRS_PER_HUGEPGD; i++) {
- pgd_t *pgd = pgdir + i;
+ pud_t *pud = (pud_t *)(pgdir + i);
- if (! pgd_none(*pgd)) {
- pte_t *pte = (pte_t *)pgd_page(*pgd);
+ if (! pud_none(*pud)) {
+ pte_t *pte = (pte_t *)pud_page(*pud);
struct page *ptepage = virt_to_page(pte);
ptepage->mapping = NULL;
@@ -720,7 +719,7 @@ void hugetlb_mm_free_pgd(struct mm_struct *mm)
BUG_ON(memcmp(pte, empty_zero_page, PAGE_SIZE));
kmem_cache_free(zero_cache, pte);
}
- pgd_clear(pgd);
+ pud_clear(pud);
}
BUG_ON(memcmp(pgdir, empty_zero_page, PAGE_SIZE));
diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c
index a7149b9..cf33d7e 100644
--- a/arch/ppc64/mm/init.c
+++ b/arch/ppc64/mm/init.c
@@ -136,14 +136,78 @@ void iounmap(volatile void __iomem *addr)
#else
+static void unmap_im_area_pte(pmd_t *pmd, unsigned long addr,
+ unsigned long end)
+{
+ pte_t *pte;
+
+ pte = pte_offset_kernel(pmd, addr);
+ do {
+ pte_t ptent = ptep_get_and_clear(&ioremap_mm, addr, pte);
+ WARN_ON(!pte_none(ptent) && !pte_present(ptent));
+ } while (pte++, addr += PAGE_SIZE, addr != end);
+}
+
+static inline void unmap_im_area_pmd(pud_t *pud, unsigned long addr,
+ unsigned long end)
+{
+ pmd_t *pmd;
+ unsigned long next;
+
+ pmd = pmd_offset(pud, addr);
+ do {
+ next = pmd_addr_end(addr, end);
+ if (pmd_none_or_clear_bad(pmd))
+ continue;
+ unmap_im_area_pte(pmd, addr, next);
+ } while (pmd++, addr = next, addr != end);
+}
+
+static inline void unmap_im_area_pud(pgd_t *pgd, unsigned long addr,
+ unsigned long end)
+{
+ pud_t *pud;
+ unsigned long next;
+
+ pud = pud_offset(pgd, addr);
+ do {
+ next = pud_addr_end(addr, end);
+ if (pud_none_or_clear_bad(pud))
+ continue;
+ unmap_im_area_pmd(pud, addr, next);
+ } while (pud++, addr = next, addr != end);
+}
+
+static void unmap_im_area(unsigned long addr, unsigned long end)
+{
+ struct mm_struct *mm = &ioremap_mm;
+ unsigned long next;
+ pgd_t *pgd;
+
+ spin_lock(&mm->page_table_lock);
+
+ pgd = pgd_offset_i(addr);
+ flush_cache_vunmap(addr, end);
+ do {
+ next = pgd_addr_end(addr, end);
+ if (pgd_none_or_clear_bad(pgd))
+ continue;
+ unmap_im_area_pud(pgd, addr, next);
+ } while (pgd++, addr = next, addr != end);
+ flush_tlb_kernel_range(start, end);
+
+ spin_unlock(&mm->page_table_lock);
+}
+
/*
* map_io_page currently only called by __ioremap
* map_io_page adds an entry to the ioremap page table
* and adds an entry to the HPT, possibly bolting it
*/
-static void map_io_page(unsigned long ea, unsigned long pa, int flags)
+static int map_io_page(unsigned long ea, unsigned long pa, int flags)
{
pgd_t *pgdp;
+ pud_t *pudp;
pmd_t *pmdp;
pte_t *ptep;
unsigned long vsid;
@@ -151,9 +215,15 @@ static void map_io_page(unsigned long ea, unsigned long pa, int flags)
if (mem_init_done) {
spin_lock(&ioremap_mm.page_table_lock);
pgdp = pgd_offset_i(ea);
- pmdp = pmd_alloc(&ioremap_mm, pgdp, ea);
+ pudp = pud_alloc(&ioremap_mm, pgdp, ea);
+ if (!pudp)
+ return -ENOMEM;
+ pmdp = pmd_alloc(&ioremap_mm, pudp, ea);
+ if (!pmdp)
+ return -ENOMEM;
ptep = pte_alloc_kernel(&ioremap_mm, pmdp, ea);
-
+ if (!ptep)
+ return -ENOMEM;
pa = abs_to_phys(pa);
set_pte_at(&ioremap_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT,
__pgprot(flags)));
@@ -181,6 +251,7 @@ static void map_io_page(unsigned long ea, unsigned long pa, int flags)
panic("map_io_page: could not insert mapping");
}
}
+ return 0;
}
@@ -194,9 +265,14 @@ static void __iomem * __ioremap_com(unsigned long addr, unsigned long pa,
flags |= pgprot_val(PAGE_KERNEL);
for (i = 0; i < size; i += PAGE_SIZE)
- map_io_page(ea+i, pa+i, flags);
+ if (map_io_page(ea+i, pa+i, flags))
+ goto failure;
return (void __iomem *) (ea + (addr & ~PAGE_MASK));
+ failure:
+ if (mem_init_done)
+ unmap_im_area(ea, ea + size);
+ return NULL;
}
@@ -206,10 +282,11 @@ ioremap(unsigned long addr, unsigned long size)
return __ioremap(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED);
}
-void __iomem *
-__ioremap(unsigned long addr, unsigned long size, unsigned long flags)
+void __iomem * __ioremap(unsigned long addr, unsigned long size,
+ unsigned long flags)
{
unsigned long pa, ea;
+ void __iomem *ret;
/*
* Choose an address to map it to.
@@ -232,12 +309,16 @@ __ioremap(unsigned long addr, unsigned long size, unsigned long flags)
if (area == NULL)
return NULL;
ea = (unsigned long)(area->addr);
+ ret = __ioremap_com(addr, pa, ea, size, flags);
+ if (!ret)
+ im_free(area->addr);
} else {
ea = ioremap_bot;
- ioremap_bot += size;
+ ret = __ioremap_com(addr, pa, ea, size, flags);
+ if (ret)
+ ioremap_bot += size;
}
-
- return __ioremap_com(addr, pa, ea, size, flags);
+ return ret;
}
#define IS_PAGE_ALIGNED(_val) ((_val) == ((_val) & PAGE_MASK))
@@ -246,6 +327,7 @@ int __ioremap_explicit(unsigned long pa, unsigned long ea,
unsigned long size, unsigned long flags)
{
struct vm_struct *area;
+ void __iomem *ret;
/* For now, require page-aligned values for pa, ea, and size */
if (!IS_PAGE_ALIGNED(pa) || !IS_PAGE_ALIGNED(ea) ||
@@ -276,7 +358,12 @@ int __ioremap_explicit(unsigned long pa, unsigned long ea,
}
}
- if (__ioremap_com(pa, pa, ea, size, flags) != (void *) ea) {
+ ret = __ioremap_com(pa, pa, ea, size, flags);
+ if (ret == NULL) {
+ printk(KERN_ERR "ioremap_explicit() allocation failure !\n");
+ return 1;
+ }
+ if (ret != (void *) ea) {
printk(KERN_ERR "__ioremap_com() returned unexpected addr\n");
return 1;
}
@@ -284,69 +371,6 @@ int __ioremap_explicit(unsigned long pa, unsigned long ea,
return 0;
}
-static void unmap_im_area_pte(pmd_t *pmd, unsigned long address,
- unsigned long size)
-{
- unsigned long base, end;
- pte_t *pte;
-
- if (pmd_none(*pmd))
- return;
- if (pmd_bad(*pmd)) {
- pmd_ERROR(*pmd);
- pmd_clear(pmd);
- return;
- }
-
- pte = pte_offset_kernel(pmd, address);
- base = address & PMD_MASK;
- address &= ~PMD_MASK;
- end = address + size;
- if (end > PMD_SIZE)
- end = PMD_SIZE;
-
- do {
- pte_t page;
- page = ptep_get_and_clear(&ioremap_mm, base + address, pte);
- address += PAGE_SIZE;
- pte++;
- if (pte_none(page))
- continue;
- if (pte_present(page))
- continue;
- printk(KERN_CRIT "Whee.. Swapped out page in kernel page"
- " table\n");
- } while (address < end);
-}
-
-static void unmap_im_area_pmd(pgd_t *dir, unsigned long address,
- unsigned long size)
-{
- unsigned long base, end;
- pmd_t *pmd;
-
- if (pgd_none(*dir))
- return;
- if (pgd_bad(*dir)) {
- pgd_ERROR(*dir);
- pgd_clear(dir);
- return;
- }
-
- pmd = pmd_offset(dir, address);
- base = address & PGDIR_MASK;
- address &= ~PGDIR_MASK;
- end = address + size;
- if (end > PGDIR_SIZE)
- end = PGDIR_SIZE;
-
- do {
- unmap_im_area_pte(pmd, base + address, end - address);
- address = (address + PMD_SIZE) & PMD_MASK;
- pmd++;
- } while (address < end);
-}
-
/*
* Unmap an IO region and remove it from imalloc'd list.
* Access to IO memory should be serialized by driver.
@@ -356,39 +380,19 @@ static void unmap_im_area_pmd(pgd_t *dir, unsigned long address,
*/
void iounmap(volatile void __iomem *token)
{
- unsigned long address, start, end, size;
- struct mm_struct *mm;
- pgd_t *dir;
+ unsigned long address, size;
void *addr;
- if (!mem_init_done) {
+ if (!mem_init_done)
return;
- }
addr = (void *) ((unsigned long __force) token & PAGE_MASK);
- if ((size = im_free(addr)) == 0) {
+ if ((size = im_free(addr)) == 0)
return;
- }
address = (unsigned long)addr;
- start = address;
- end = address + size;
-
- mm = &ioremap_mm;
- spin_lock(&mm->page_table_lock);
-
- dir = pgd_offset_i(address);
- flush_cache_vunmap(address, end);
- do {
- unmap_im_area_pmd(dir, address, end - address);
- address = (address + PGDIR_SIZE) & PGDIR_MASK;
- dir++;
- } while (address && (address < end));
- flush_tlb_kernel_range(start, end);
-
- spin_unlock(&mm->page_table_lock);
- return;
+ unmap_im_area(address, address + size);
}
static int iounmap_subset_regions(unsigned long addr, unsigned long size)
diff --git a/arch/ppc64/mm/slb.c b/arch/ppc64/mm/slb.c
index 6a20773..244150a 100644
--- a/arch/ppc64/mm/slb.c
+++ b/arch/ppc64/mm/slb.c
@@ -33,8 +33,8 @@ static inline unsigned long mk_vsid_data(unsigned long ea, unsigned long flags)
return (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | flags;
}
-static inline void create_slbe(unsigned long ea, unsigned long vsid,
- unsigned long flags, unsigned long entry)
+static inline void create_slbe(unsigned long ea, unsigned long flags,
+ unsigned long entry)
{
asm volatile("slbmte %0,%1" :
: "r" (mk_vsid_data(ea, flags)),
@@ -145,9 +145,8 @@ void slb_initialize(void)
asm volatile("isync":::"memory");
asm volatile("slbmte %0,%0"::"r" (0) : "memory");
asm volatile("isync; slbia; isync":::"memory");
- create_slbe(KERNELBASE, get_kernel_vsid(KERNELBASE), flags, 0);
- create_slbe(VMALLOCBASE, get_kernel_vsid(KERNELBASE),
- SLB_VSID_KERNEL, 1);
+ create_slbe(KERNELBASE, flags, 0);
+ create_slbe(VMALLOCBASE, SLB_VSID_KERNEL, 1);
/* We don't bolt the stack for the time being - we're in boot,
* so the stack is in the bolted segment. By the time it goes
* elsewhere, we'll call _switch() which will bolt in the new
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index 1358b42..07fd041 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.11
-# Wed Mar 2 16:57:55 2005
+# Linux kernel version: 2.6.12-rc3
+# Fri Apr 22 15:30:58 2005
#
CONFIG_MMU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
@@ -15,6 +15,7 @@ CONFIG_UID16=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
@@ -26,24 +27,25 @@ CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=17
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+# CONFIG_CPUSETS is not set
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SHMEM=y
CONFIG_CC_ALIGN_FUNCTIONS=0
CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -261,7 +263,6 @@ CONFIG_NET=y
#
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
CONFIG_UNIX=y
CONFIG_NET_KEY=y
CONFIG_INET=y
@@ -329,6 +330,7 @@ CONFIG_NET_SCH_DSMARK=m
CONFIG_NET_QOS=y
CONFIG_NET_ESTIMATOR=y
CONFIG_NET_CLS=y
+# CONFIG_NET_CLS_BASIC is not set
CONFIG_NET_CLS_TCINDEX=m
CONFIG_NET_CLS_ROUTE4=m
CONFIG_NET_CLS_ROUTE=y
@@ -338,6 +340,7 @@ CONFIG_NET_CLS_U32=m
# CONFIG_NET_CLS_IND is not set
CONFIG_NET_CLS_RSVP=m
CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_EMATCH is not set
# CONFIG_NET_CLS_ACT is not set
CONFIG_NET_CLS_POLICE=y
@@ -393,6 +396,8 @@ CONFIG_CTC=m
CONFIG_IUCV=m
# CONFIG_NETIUCV is not set
# CONFIG_SMSGIUCV is not set
+# CONFIG_CLAW is not set
+# CONFIG_MPC is not set
CONFIG_QETH=y
#
@@ -532,10 +537,13 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=17
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_INFO is not set
@@ -560,6 +568,7 @@ CONFIG_CRYPTO=y
# CONFIG_CRYPTO_SHA256 is not set
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
# CONFIG_CRYPTO_DES is not set
# CONFIG_CRYPTO_DES_Z990 is not set
# CONFIG_CRYPTO_BLOWFISH is not set
diff --git a/arch/s390/kernel/compat_ioctl.c b/arch/s390/kernel/compat_ioctl.c
index 96571ff..03d03c6 100644
--- a/arch/s390/kernel/compat_ioctl.c
+++ b/arch/s390/kernel/compat_ioctl.c
@@ -16,6 +16,7 @@
#define CODE
#include "../../../fs/compat_ioctl.c"
#include <asm/dasd.h>
+#include <asm/cmb.h>
#include <asm/tape390.h>
static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd,
@@ -58,7 +59,11 @@ COMPATIBLE_IOCTL(BIODASDPRRD)
COMPATIBLE_IOCTL(BIODASDPSRD)
COMPATIBLE_IOCTL(BIODASDGATTR)
COMPATIBLE_IOCTL(BIODASDSATTR)
-
+#if defined(CONFIG_DASD_CMB) || defined(CONFIG_DASD_CMB_MODULE)
+COMPATIBLE_IOCTL(BIODASDCMFENABLE)
+COMPATIBLE_IOCTL(BIODASDCMFDISABLE)
+COMPATIBLE_IOCTL(BIODASDREADALLCMB)
+#endif
#endif
#if defined(CONFIG_S390_TAPE) || defined(CONFIG_S390_TAPE_MODULE)
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 2d546c6..2688936 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -32,6 +32,7 @@
#include <linux/user.h>
#include <linux/security.h>
#include <linux/audit.h>
+#include <linux/signal.h>
#include <asm/segment.h>
#include <asm/page.h>
@@ -609,7 +610,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data)
/* continue and stop at next (return from) syscall */
case PTRACE_CONT:
/* restart after signal. */
- if ((unsigned long) data >= _NSIG)
+ if (!valid_signal(data))
return -EIO;
if (request == PTRACE_SYSCALL)
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -637,7 +638,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data)
case PTRACE_SINGLESTEP:
/* set the trap flag. */
- if ((unsigned long) data >= _NSIG)
+ if (!valid_signal(data))
return -EIO;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
child->exit_code = data;
diff --git a/arch/s390/kernel/s390_ksyms.c b/arch/s390/kernel/s390_ksyms.c
index 11fd6d5..bee654a 100644
--- a/arch/s390/kernel/s390_ksyms.c
+++ b/arch/s390/kernel/s390_ksyms.c
@@ -34,7 +34,6 @@ EXPORT_SYMBOL(__clear_user_asm);
EXPORT_SYMBOL(__strncpy_from_user_asm);
EXPORT_SYMBOL(__strnlen_user_asm);
EXPORT_SYMBOL(diag10);
-EXPORT_SYMBOL(default_storage_key);
/*
* semaphore ops
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index c879c40..df83215 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -44,6 +44,8 @@
#include <asm/cpcmd.h>
#include <asm/lowcore.h>
#include <asm/irq.h>
+#include <asm/page.h>
+#include <asm/ptrace.h>
/*
* Machine setup..
@@ -53,13 +55,14 @@ unsigned int console_devno = -1;
unsigned int console_irq = -1;
unsigned long memory_size = 0;
unsigned long machine_flags = 0;
-unsigned int default_storage_key = 0;
struct {
unsigned long addr, size, type;
} memory_chunk[MEMORY_CHUNKS] = { { 0 } };
#define CHUNK_READ_WRITE 0
#define CHUNK_READ_ONLY 1
volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */
+unsigned long __initdata zholes_size[MAX_NR_ZONES];
+static unsigned long __initdata memory_end;
/*
* Setup options
@@ -78,11 +81,15 @@ static char command_line[COMMAND_LINE_SIZE] = { 0, };
static struct resource code_resource = {
.name = "Kernel code",
+ .start = (unsigned long) &_text,
+ .end = (unsigned long) &_etext - 1,
.flags = IORESOURCE_BUSY | IORESOURCE_MEM,
};
static struct resource data_resource = {
.name = "Kernel data",
+ .start = (unsigned long) &_etext,
+ .end = (unsigned long) &_edata - 1,
.flags = IORESOURCE_BUSY | IORESOURCE_MEM,
};
@@ -310,90 +317,50 @@ void machine_power_off(void)
EXPORT_SYMBOL(machine_power_off);
-/*
- * Setup function called from init/main.c just after the banner
- * was printed.
- */
-extern char _pstart, _pend, _stext;
+static void __init
+add_memory_hole(unsigned long start, unsigned long end)
+{
+ unsigned long dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT;
+
+ if (end <= dma_pfn)
+ zholes_size[ZONE_DMA] += end - start + 1;
+ else if (start > dma_pfn)
+ zholes_size[ZONE_NORMAL] += end - start + 1;
+ else {
+ zholes_size[ZONE_DMA] += dma_pfn - start + 1;
+ zholes_size[ZONE_NORMAL] += end - dma_pfn;
+ }
+}
-void __init setup_arch(char **cmdline_p)
+static void __init
+parse_cmdline_early(char **cmdline_p)
{
- unsigned long bootmap_size;
- unsigned long memory_start, memory_end;
- char c = ' ', cn, *to = command_line, *from = COMMAND_LINE;
- unsigned long start_pfn, end_pfn;
- static unsigned int smptrap=0;
- unsigned long delay = 0;
- struct _lowcore *lc;
- int i;
+ char c = ' ', cn, *to = command_line, *from = COMMAND_LINE;
+ unsigned long delay = 0;
- if (smptrap)
- return;
- smptrap=1;
+ /* Save unparsed command line copy for /proc/cmdline */
+ memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
+ saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
- /*
- * print what head.S has found out about the machine
- */
-#ifndef CONFIG_ARCH_S390X
- printk((MACHINE_IS_VM) ?
- "We are running under VM (31 bit mode)\n" :
- "We are running native (31 bit mode)\n");
- printk((MACHINE_HAS_IEEE) ?
- "This machine has an IEEE fpu\n" :
- "This machine has no IEEE fpu\n");
-#else /* CONFIG_ARCH_S390X */
- printk((MACHINE_IS_VM) ?
- "We are running under VM (64 bit mode)\n" :
- "We are running native (64 bit mode)\n");
-#endif /* CONFIG_ARCH_S390X */
-
- ROOT_DEV = Root_RAM0;
- memory_start = (unsigned long) &_end; /* fixit if use $CODELO etc*/
-#ifndef CONFIG_ARCH_S390X
- memory_end = memory_size & ~0x400000UL; /* align memory end to 4MB */
- /*
- * We need some free virtual space to be able to do vmalloc.
- * On a machine with 2GB memory we make sure that we have at
- * least 128 MB free space for vmalloc.
- */
- if (memory_end > 1920*1024*1024)
- memory_end = 1920*1024*1024;
-#else /* CONFIG_ARCH_S390X */
- memory_end = memory_size & ~0x200000UL; /* detected in head.s */
-#endif /* CONFIG_ARCH_S390X */
- init_mm.start_code = PAGE_OFFSET;
- init_mm.end_code = (unsigned long) &_etext;
- init_mm.end_data = (unsigned long) &_edata;
- init_mm.brk = (unsigned long) &_end;
-
- code_resource.start = (unsigned long) &_text;
- code_resource.end = (unsigned long) &_etext - 1;
- data_resource.start = (unsigned long) &_etext;
- data_resource.end = (unsigned long) &_edata - 1;
-
- /* Save unparsed command line copy for /proc/cmdline */
- memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
- saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
-
- for (;;) {
- /*
- * "mem=XXX[kKmM]" sets memsize
- */
- if (c == ' ' && strncmp(from, "mem=", 4) == 0) {
- memory_end = simple_strtoul(from+4, &from, 0);
- if ( *from == 'K' || *from == 'k' ) {
- memory_end = memory_end << 10;
- from++;
- } else if ( *from == 'M' || *from == 'm' ) {
- memory_end = memory_end << 20;
- from++;
- }
- }
- /*
- * "ipldelay=XXX[sm]" sets ipl delay in seconds or minutes
- */
- if (c == ' ' && strncmp(from, "ipldelay=", 9) == 0) {
- delay = simple_strtoul(from+9, &from, 0);
+ for (;;) {
+ /*
+ * "mem=XXX[kKmM]" sets memsize
+ */
+ if (c == ' ' && strncmp(from, "mem=", 4) == 0) {
+ memory_end = simple_strtoul(from+4, &from, 0);
+ if ( *from == 'K' || *from == 'k' ) {
+ memory_end = memory_end << 10;
+ from++;
+ } else if ( *from == 'M' || *from == 'm' ) {
+ memory_end = memory_end << 20;
+ from++;
+ }
+ }
+ /*
+ * "ipldelay=XXX[sm]" sets ipl delay in seconds or minutes
+ */
+ if (c == ' ' && strncmp(from, "ipldelay=", 9) == 0) {
+ delay = simple_strtoul(from+9, &from, 0);
if (*from == 's' || *from == 'S') {
delay = delay*1000000;
from++;
@@ -403,24 +370,110 @@ void __init setup_arch(char **cmdline_p)
}
/* now wait for the requested amount of time */
udelay(delay);
- }
- cn = *(from++);
- if (!cn)
- break;
- if (cn == '\n')
- cn = ' '; /* replace newlines with space */
+ }
+ cn = *(from++);
+ if (!cn)
+ break;
+ if (cn == '\n')
+ cn = ' '; /* replace newlines with space */
if (cn == 0x0d)
cn = ' '; /* replace 0x0d with space */
- if (cn == ' ' && c == ' ')
- continue; /* remove additional spaces */
- c = cn;
- if (to - command_line >= COMMAND_LINE_SIZE)
- break;
- *(to++) = c;
- }
- if (c == ' ' && to > command_line) to--;
- *to = '\0';
- *cmdline_p = command_line;
+ if (cn == ' ' && c == ' ')
+ continue; /* remove additional spaces */
+ c = cn;
+ if (to - command_line >= COMMAND_LINE_SIZE)
+ break;
+ *(to++) = c;
+ }
+ if (c == ' ' && to > command_line) to--;
+ *to = '\0';
+ *cmdline_p = command_line;
+}
+
+static void __init
+setup_lowcore(void)
+{
+ struct _lowcore *lc;
+ int lc_pages;
+
+ /*
+ * Setup lowcore for boot cpu
+ */
+ lc_pages = sizeof(void *) == 8 ? 2 : 1;
+ lc = (struct _lowcore *)
+ __alloc_bootmem(lc_pages * PAGE_SIZE, lc_pages * PAGE_SIZE, 0);
+ memset(lc, 0, lc_pages * PAGE_SIZE);
+ lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
+ lc->restart_psw.addr =
+ PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
+ lc->external_new_psw.mask = PSW_KERNEL_BITS;
+ lc->external_new_psw.addr =
+ PSW_ADDR_AMODE | (unsigned long) ext_int_handler;
+ lc->svc_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_IO | PSW_MASK_EXT;
+ lc->svc_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) system_call;
+ lc->program_new_psw.mask = PSW_KERNEL_BITS;
+ lc->program_new_psw.addr =
+ PSW_ADDR_AMODE | (unsigned long)pgm_check_handler;
+ lc->mcck_new_psw.mask = PSW_KERNEL_BITS;
+ lc->mcck_new_psw.addr =
+ PSW_ADDR_AMODE | (unsigned long) mcck_int_handler;
+ lc->io_new_psw.mask = PSW_KERNEL_BITS;
+ lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler;
+ lc->ipl_device = S390_lowcore.ipl_device;
+ lc->jiffy_timer = -1LL;
+ lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE;
+ lc->async_stack = (unsigned long)
+ __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) + ASYNC_SIZE;
+#ifdef CONFIG_CHECK_STACK
+ lc->panic_stack = (unsigned long)
+ __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0) + PAGE_SIZE;
+#endif
+ lc->current_task = (unsigned long) init_thread_union.thread_info.task;
+ lc->thread_info = (unsigned long) &init_thread_union;
+#ifdef CONFIG_ARCH_S390X
+ if (MACHINE_HAS_DIAG44)
+ lc->diag44_opcode = 0x83000044;
+ else
+ lc->diag44_opcode = 0x07000700;
+#endif /* CONFIG_ARCH_S390X */
+ set_prefix((u32)(unsigned long) lc);
+}
+
+static void __init
+setup_resources(void)
+{
+ struct resource *res;
+ int i;
+
+ for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) {
+ res = alloc_bootmem_low(sizeof(struct resource));
+ res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
+ switch (memory_chunk[i].type) {
+ case CHUNK_READ_WRITE:
+ res->name = "System RAM";
+ break;
+ case CHUNK_READ_ONLY:
+ res->name = "System ROM";
+ res->flags |= IORESOURCE_READONLY;
+ break;
+ default:
+ res->name = "reserved";
+ }
+ res->start = memory_chunk[i].addr;
+ res->end = memory_chunk[i].addr + memory_chunk[i].size - 1;
+ request_resource(&iomem_resource, res);
+ request_resource(res, &code_resource);
+ request_resource(res, &data_resource);
+ }
+}
+
+static void __init
+setup_memory(void)
+{
+ unsigned long bootmap_size;
+ unsigned long start_pfn, end_pfn, init_pfn;
+ unsigned long last_rw_end;
+ int i;
/*
* partially used pages are not usable - thus
@@ -429,6 +482,10 @@ void __init setup_arch(char **cmdline_p)
start_pfn = (__pa(&_end) + PAGE_SIZE - 1) >> PAGE_SHIFT;
end_pfn = max_pfn = memory_end >> PAGE_SHIFT;
+ /* Initialize storage key for kernel pages */
+ for (init_pfn = 0 ; init_pfn < start_pfn; init_pfn++)
+ page_set_storage_key(init_pfn << PAGE_SHIFT, PAGE_DEFAULT_KEY);
+
/*
* Initialize the boot-time allocator (with low memory only):
*/
@@ -437,7 +494,9 @@ void __init setup_arch(char **cmdline_p)
/*
* Register RAM areas with the bootmem allocator.
*/
- for (i = 0; i < 16 && memory_chunk[i].size > 0; i++) {
+ last_rw_end = start_pfn;
+
+ for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) {
unsigned long start_chunk, end_chunk;
if (memory_chunk[i].type != CHUNK_READ_WRITE)
@@ -450,102 +509,98 @@ void __init setup_arch(char **cmdline_p)
start_chunk = start_pfn;
if (end_chunk > end_pfn)
end_chunk = end_pfn;
- if (start_chunk < end_chunk)
+ if (start_chunk < end_chunk) {
+ /* Initialize storage key for RAM pages */
+ for (init_pfn = start_chunk ; init_pfn < end_chunk;
+ init_pfn++)
+ page_set_storage_key(init_pfn << PAGE_SHIFT,
+ PAGE_DEFAULT_KEY);
free_bootmem(start_chunk << PAGE_SHIFT,
(end_chunk - start_chunk) << PAGE_SHIFT);
+ if (last_rw_end < start_chunk)
+ add_memory_hole(last_rw_end, start_chunk - 1);
+ last_rw_end = end_chunk;
+ }
}
- /*
- * Reserve the bootmem bitmap itself as well. We do this in two
- * steps (first step was init_bootmem()) because this catches
- * the (very unlikely) case of us accidentally initializing the
- * bootmem allocator with an invalid RAM area.
- */
- reserve_bootmem(start_pfn << PAGE_SHIFT, bootmap_size);
+ psw_set_key(PAGE_DEFAULT_KEY);
+
+ if (last_rw_end < end_pfn - 1)
+ add_memory_hole(last_rw_end, end_pfn - 1);
+
+ /*
+ * Reserve the bootmem bitmap itself as well. We do this in two
+ * steps (first step was init_bootmem()) because this catches
+ * the (very unlikely) case of us accidentally initializing the
+ * bootmem allocator with an invalid RAM area.
+ */
+ reserve_bootmem(start_pfn << PAGE_SHIFT, bootmap_size);
#ifdef CONFIG_BLK_DEV_INITRD
- if (INITRD_START) {
+ if (INITRD_START) {
if (INITRD_START + INITRD_SIZE <= memory_end) {
reserve_bootmem(INITRD_START, INITRD_SIZE);
initrd_start = INITRD_START;
initrd_end = initrd_start + INITRD_SIZE;
} else {
- printk("initrd extends beyond end of memory "
- "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
- initrd_start + INITRD_SIZE, memory_end);
- initrd_start = initrd_end = 0;
+ printk("initrd extends beyond end of memory "
+ "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
+ initrd_start + INITRD_SIZE, memory_end);
+ initrd_start = initrd_end = 0;
}
- }
+ }
#endif
+}
- for (i = 0; i < 16 && memory_chunk[i].size > 0; i++) {
- struct resource *res;
-
- res = alloc_bootmem_low(sizeof(struct resource));
- res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
-
- switch (memory_chunk[i].type) {
- case CHUNK_READ_WRITE:
- res->name = "System RAM";
- break;
- case CHUNK_READ_ONLY:
- res->name = "System ROM";
- res->flags |= IORESOURCE_READONLY;
- break;
- default:
- res->name = "reserved";
- }
- res->start = memory_chunk[i].addr;
- res->end = memory_chunk[i].addr + memory_chunk[i].size - 1;
- request_resource(&iomem_resource, res);
- request_resource(res, &code_resource);
- request_resource(res, &data_resource);
- }
+/*
+ * Setup function called from init/main.c just after the banner
+ * was printed.
+ */
+void __init
+setup_arch(char **cmdline_p)
+{
/*
- * Setup lowcore for boot cpu
+ * print what head.S has found out about the machine
*/
#ifndef CONFIG_ARCH_S390X
- lc = (struct _lowcore *) __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0);
- memset(lc, 0, PAGE_SIZE);
+ printk((MACHINE_IS_VM) ?
+ "We are running under VM (31 bit mode)\n" :
+ "We are running native (31 bit mode)\n");
+ printk((MACHINE_HAS_IEEE) ?
+ "This machine has an IEEE fpu\n" :
+ "This machine has no IEEE fpu\n");
#else /* CONFIG_ARCH_S390X */
- lc = (struct _lowcore *) __alloc_bootmem(2*PAGE_SIZE, 2*PAGE_SIZE, 0);
- memset(lc, 0, 2*PAGE_SIZE);
+ printk((MACHINE_IS_VM) ?
+ "We are running under VM (64 bit mode)\n" :
+ "We are running native (64 bit mode)\n");
#endif /* CONFIG_ARCH_S390X */
- lc->restart_psw.mask = PSW_BASE_BITS;
- lc->restart_psw.addr =
- PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
- lc->external_new_psw.mask = PSW_KERNEL_BITS;
- lc->external_new_psw.addr =
- PSW_ADDR_AMODE | (unsigned long) ext_int_handler;
- lc->svc_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_IO | PSW_MASK_EXT;
- lc->svc_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) system_call;
- lc->program_new_psw.mask = PSW_KERNEL_BITS;
- lc->program_new_psw.addr =
- PSW_ADDR_AMODE | (unsigned long)pgm_check_handler;
- lc->mcck_new_psw.mask = PSW_KERNEL_BITS;
- lc->mcck_new_psw.addr =
- PSW_ADDR_AMODE | (unsigned long) mcck_int_handler;
- lc->io_new_psw.mask = PSW_KERNEL_BITS;
- lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler;
- lc->ipl_device = S390_lowcore.ipl_device;
- lc->jiffy_timer = -1LL;
- lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE;
- lc->async_stack = (unsigned long)
- __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) + ASYNC_SIZE;
-#ifdef CONFIG_CHECK_STACK
- lc->panic_stack = (unsigned long)
- __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0) + PAGE_SIZE;
-#endif
- lc->current_task = (unsigned long) init_thread_union.thread_info.task;
- lc->thread_info = (unsigned long) &init_thread_union;
-#ifdef CONFIG_ARCH_S390X
- if (MACHINE_HAS_DIAG44)
- lc->diag44_opcode = 0x83000044;
- else
- lc->diag44_opcode = 0x07000700;
+
+ ROOT_DEV = Root_RAM0;
+#ifndef CONFIG_ARCH_S390X
+ memory_end = memory_size & ~0x400000UL; /* align memory end to 4MB */
+ /*
+ * We need some free virtual space to be able to do vmalloc.
+ * On a machine with 2GB memory we make sure that we have at
+ * least 128 MB free space for vmalloc.
+ */
+ if (memory_end > 1920*1024*1024)
+ memory_end = 1920*1024*1024;
+#else /* CONFIG_ARCH_S390X */
+ memory_end = memory_size & ~0x200000UL; /* detected in head.s */
#endif /* CONFIG_ARCH_S390X */
- set_prefix((u32)(unsigned long) lc);
+
+ init_mm.start_code = PAGE_OFFSET;
+ init_mm.end_code = (unsigned long) &_etext;
+ init_mm.end_data = (unsigned long) &_edata;
+ init_mm.brk = (unsigned long) &_end;
+
+ parse_cmdline_early(cmdline_p);
+
+ setup_memory();
+ setup_resources();
+ setup_lowcore();
+
cpu_init();
__cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr;
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 061e811..8ca4856 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -244,7 +244,7 @@ int sysctl_hz_timer = 1;
*/
static inline void stop_hz_timer(void)
{
- __u64 timer;
+ __u64 timer, todval;
if (sysctl_hz_timer != 0)
return;
@@ -265,8 +265,14 @@ static inline void stop_hz_timer(void)
* for the next event.
*/
timer = (__u64) (next_timer_interrupt() - jiffies) + jiffies_64;
- timer = jiffies_timer_cc + timer * CLK_TICKS_PER_JIFFY;
- asm volatile ("SCKC %0" : : "m" (timer));
+ todval = -1ULL;
+ /* Be careful about overflows. */
+ if (timer < (-1ULL / CLK_TICKS_PER_JIFFY)) {
+ timer = jiffies_timer_cc + timer * CLK_TICKS_PER_JIFFY;
+ if (timer >= jiffies_timer_cc)
+ todval = timer;
+ }
+ asm volatile ("SCKC %0" : : "m" (todval));
}
/*
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index bb6cf02..fa07265 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -122,12 +122,17 @@ static void start_cpu_timer(void)
struct vtimer_queue *vt_list;
vt_list = &per_cpu(virt_cpu_timer, smp_processor_id());
- set_vtimer(vt_list->idle);
+
+ /* CPU timer interrupt is pending, don't reprogramm it */
+ if (vt_list->idle & 1LL<<63)
+ return;
+
+ if (!list_empty(&vt_list->list))
+ set_vtimer(vt_list->idle);
}
static void stop_cpu_timer(void)
{
- __u64 done;
struct vtimer_queue *vt_list;
vt_list = &per_cpu(virt_cpu_timer, smp_processor_id());
@@ -138,21 +143,17 @@ static void stop_cpu_timer(void)
goto fire;
}
- /* store progress */
- asm volatile ("STPT %0" : "=m" (done));
+ /* store the actual expire value */
+ asm volatile ("STPT %0" : "=m" (vt_list->idle));
/*
- * If done is negative we do not stop the CPU timer
- * because we will get instantly an interrupt that
- * will start the CPU timer again.
+ * If the CPU timer is negative we don't reprogramm
+ * it because we will get instantly an interrupt.
*/
- if (done & 1LL<<63)
+ if (vt_list->idle & 1LL<<63)
return;
- else
- vt_list->offset += vt_list->to_expire - done;
- /* save the actual expire value */
- vt_list->idle = done;
+ vt_list->offset += vt_list->to_expire - vt_list->idle;
/*
* We cannot halt the CPU timer, we just write a value that
diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c
index d30cdb4..f5a5bc0 100644
--- a/arch/s390/mm/cmm.c
+++ b/arch/s390/mm/cmm.c
@@ -20,6 +20,11 @@
#include <asm/pgalloc.h>
#include <asm/uaccess.h>
+static char *sender = "VMRMSVM";
+module_param(sender, charp, 0);
+MODULE_PARM_DESC(sender,
+ "Guest name that may send SMSG messages (default VMRMSVM)");
+
#include "../../../drivers/s390/net/smsgiucv.h"
#define CMM_NR_PAGES ((PAGE_SIZE / sizeof(unsigned long)) - 2)
@@ -367,10 +372,12 @@ static struct ctl_table cmm_dir_table[] = {
#ifdef CONFIG_CMM_IUCV
#define SMSG_PREFIX "CMM"
static void
-cmm_smsg_target(char *msg)
+cmm_smsg_target(char *from, char *msg)
{
long pages, seconds;
+ if (strlen(sender) > 0 && strcmp(from, sender) != 0)
+ return;
if (!cmm_skip_blanks(msg + strlen(SMSG_PREFIX), &msg))
return;
if (strncmp(msg, "SHRINK", 6) == 0) {
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index 8e723bc..6ec5cd9 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -101,6 +101,7 @@ extern unsigned long _end;
extern unsigned long __init_begin;
extern unsigned long __init_end;
+extern unsigned long __initdata zholes_size[];
/*
* paging_init() sets up the page tables
*/
@@ -163,10 +164,13 @@ void __init paging_init(void)
local_flush_tlb();
{
- unsigned long zones_size[MAX_NR_ZONES] = { 0, 0, 0};
+ unsigned long zones_size[MAX_NR_ZONES];
+ memset(zones_size, 0, sizeof(zones_size));
zones_size[ZONE_DMA] = max_low_pfn;
- free_area_init(zones_size);
+ free_area_init_node(0, &contig_page_data, zones_size,
+ __pa(PAGE_OFFSET) >> PAGE_SHIFT,
+ zholes_size);
}
return;
}
@@ -184,9 +188,10 @@ void __init paging_init(void)
_KERN_REGION_TABLE;
static const int ssm_mask = 0x04000000L;
- unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+ unsigned long zones_size[MAX_NR_ZONES];
unsigned long dma_pfn, high_pfn;
+ memset(zones_size, 0, sizeof(zones_size));
dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT;
high_pfn = max_low_pfn;
@@ -198,8 +203,8 @@ void __init paging_init(void)
}
/* Initialize mem_map[]. */
- free_area_init(zones_size);
-
+ free_area_init_node(0, &contig_page_data, zones_size,
+ __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size);
/*
* map whole physical memory to virtual memory (identity mapping)
diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c
index 1b0dfb4..b28919b 100644
--- a/arch/sh/kernel/ptrace.c
+++ b/arch/sh/kernel/ptrace.c
@@ -20,6 +20,7 @@
#include <linux/user.h>
#include <linux/slab.h>
#include <linux/security.h>
+#include <linux/signal.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -197,7 +198,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: { /* restart after signal. */
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
if (request == PTRACE_SYSCALL)
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -228,7 +229,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
struct pt_regs *dummy = NULL;
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
if ((child->ptrace & PT_DTRACE) == 0) {
diff --git a/arch/sh64/kernel/ptrace.c b/arch/sh64/kernel/ptrace.c
index 800288c..fd20009 100644
--- a/arch/sh64/kernel/ptrace.c
+++ b/arch/sh64/kernel/ptrace.c
@@ -27,6 +27,7 @@
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
+#include <linux/signal.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -255,7 +256,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: { /* restart after signal. */
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
if (request == PTRACE_SYSCALL)
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -285,7 +286,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
struct pt_regs *regs;
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
if ((child->ptrace & PT_DTRACE) == 0) {
diff --git a/arch/sh64/kernel/sys_sh64.c b/arch/sh64/kernel/sys_sh64.c
index 4546845b..58ff7d5 100644
--- a/arch/sh64/kernel/sys_sh64.c
+++ b/arch/sh64/kernel/sys_sh64.c
@@ -283,18 +283,3 @@ asmlinkage int sys_uname(struct old_utsname * name)
up_read(&uts_sem);
return err?-EFAULT:0;
}
-
-/* Copy from mips version */
-asmlinkage long sys_shmatcall(int shmid, char __user *shmaddr,
- int shmflg)
-{
- unsigned long raddr;
- int err;
-
- err = do_shmat(shmid, shmaddr, shmflg, &raddr);
- if (err)
- return err;
-
- err = raddr;
- return err;
-}
diff --git a/arch/sh64/kernel/syscalls.S b/arch/sh64/kernel/syscalls.S
index 8ed417d..6aabc63 100644
--- a/arch/sh64/kernel/syscalls.S
+++ b/arch/sh64/kernel/syscalls.S
@@ -268,7 +268,7 @@ sys_call_table:
.long sys_msgrcv
.long sys_msgget
.long sys_msgctl
- .long sys_shmatcall
+ .long sys_shmat
.long sys_shmdt /* 245 */
.long sys_shmget
.long sys_shmctl
diff --git a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c
index c4f93bd2..475c4c1 100644
--- a/arch/sparc/kernel/ptrace.c
+++ b/arch/sparc/kernel/ptrace.c
@@ -18,6 +18,7 @@
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/security.h>
+#include <linux/signal.h>
#include <asm/pgtable.h>
#include <asm/system.h>
@@ -526,7 +527,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
addr = 1;
case PTRACE_CONT: { /* restart after signal. */
- if (data > _NSIG) {
+ if (!valid_signal(data)) {
pt_error_return(regs, EIO);
goto out_tsk;
}
diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c
index 5f080cf..80a76e2 100644
--- a/arch/sparc64/kernel/ptrace.c
+++ b/arch/sparc64/kernel/ptrace.c
@@ -19,6 +19,7 @@
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/security.h>
+#include <linux/signal.h>
#include <asm/asi.h>
#include <asm/pgtable.h>
@@ -559,7 +560,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
addr = 1;
case PTRACE_CONT: { /* restart after signal. */
- if (data > _NSIG) {
+ if (!valid_signal(data)) {
pt_error_return(regs, EIO);
goto out_tsk;
}
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index 9a23df1..c529218 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -244,6 +244,7 @@ config KERNEL_HALF_GIGS
config HIGHMEM
bool "Highmem support"
+ depends on !64BIT
config KERNEL_STACK_ORDER
int "Kernel stack size order"
diff --git a/arch/um/Kconfig_i386 b/arch/um/Kconfig_i386
index 203c242..e41f374 100644
--- a/arch/um/Kconfig_i386
+++ b/arch/um/Kconfig_i386
@@ -1,4 +1,8 @@
-config 64_BIT
+config UML_X86
+ bool
+ default y
+
+config 64BIT
bool
default n
diff --git a/arch/um/Kconfig_x86_64 b/arch/um/Kconfig_x86_64
index 768dc66..fd8d7e8 100644
--- a/arch/um/Kconfig_x86_64
+++ b/arch/um/Kconfig_x86_64
@@ -1,4 +1,8 @@
-config 64_BIT
+config UML_X86
+ bool
+ default y
+
+config 64BIT
bool
default y
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
index 97b223b..f9e3c0f 100644
--- a/arch/um/Makefile-i386
+++ b/arch/um/Makefile-i386
@@ -1,4 +1,4 @@
-SUBARCH_CORE := arch/um/sys-i386/
+SUBARCH_CORE := arch/um/sys-i386/ arch/i386/crypto/
TOP_ADDR := $(CONFIG_TOP_ADDR)
diff --git a/arch/um/defconfig b/arch/um/defconfig
index fc3075c..4067c3a 100644
--- a/arch/um/defconfig
+++ b/arch/um/defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk1
-# Sun Mar 20 16:53:00 2005
+# Linux kernel version: 2.6.12-rc3-skas3-v9-pre2
+# Sun Apr 24 19:46:10 2005
#
CONFIG_GENERIC_HARDIRQS=y
CONFIG_UML=y
@@ -15,7 +15,8 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
#
CONFIG_MODE_TT=y
CONFIG_MODE_SKAS=y
-# CONFIG_64_BIT is not set
+CONFIG_UML_X86=y
+# CONFIG_64BIT is not set
CONFIG_TOP_ADDR=0xc0000000
# CONFIG_3_LEVEL_PGTABLES is not set
CONFIG_ARCH_HAS_SC_SIGNALS=y
@@ -41,6 +42,7 @@ CONFIG_UML_REAL_TIME_CLOCK=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
@@ -158,7 +160,6 @@ CONFIG_UML_NET_SLIRP=y
#
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
@@ -412,6 +413,5 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_FS is not set
CONFIG_FRAME_POINTER=y
CONFIG_PT_PROXY=y
-# CONFIG_GPROF is not set
# CONFIG_GCOV is not set
# CONFIG_SYSCALL_DEBUG is not set
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 1f77deb..0150038 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -22,7 +22,7 @@
#ifdef CONFIG_NOCONFIG_CHAN
static void *not_configged_init(char *str, int device, struct chan_opts *opts)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ printf(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return(NULL);
}
@@ -30,27 +30,27 @@ static void *not_configged_init(char *str, int device, struct chan_opts *opts)
static int not_configged_open(int input, int output, int primary, void *data,
char **dev_out)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ printf(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return(-ENODEV);
}
static void not_configged_close(int fd, void *data)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ printf(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
}
static int not_configged_read(int fd, char *c_out, void *data)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ printf(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return(-EIO);
}
static int not_configged_write(int fd, const char *buf, int len, void *data)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ printf(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return(-EIO);
}
@@ -58,7 +58,7 @@ static int not_configged_write(int fd, const char *buf, int len, void *data)
static int not_configged_console_write(int fd, const char *buf, int len,
void *data)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ printf(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return(-EIO);
}
@@ -66,14 +66,14 @@ static int not_configged_console_write(int fd, const char *buf, int len,
static int not_configged_window_size(int fd, void *data, unsigned short *rows,
unsigned short *cols)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ printf(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
return(-ENODEV);
}
static void not_configged_free(void *data)
{
- printk(KERN_ERR "Using a channel type which is configured out of "
+ printf(KERN_ERR "Using a channel type which is configured out of "
"UML\n");
}
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 6924f27..d0f9712 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -39,19 +39,69 @@ static void line_timer_cb(void *arg)
line_interrupt(line->driver->read_irq, arg, NULL);
}
-static int write_room(struct line *dev)
+/* Returns the free space inside the ring buffer of this line.
+ *
+ * Should be called while holding line->lock (this does not modify datas).
+ */
+static int write_room(struct line *line)
{
int n;
- if (dev->buffer == NULL)
- return (LINE_BUFSIZE - 1);
+ if (line->buffer == NULL)
+ return LINE_BUFSIZE - 1;
+
+ /* This is for the case where the buffer is wrapped! */
+ n = line->head - line->tail;
- n = dev->head - dev->tail;
if (n <= 0)
- n = LINE_BUFSIZE + n;
- return (n - 1);
+ n = LINE_BUFSIZE + n; /* The other case */
+ return n - 1;
+}
+
+int line_write_room(struct tty_struct *tty)
+{
+ struct line *line = tty->driver_data;
+ unsigned long flags;
+ int room;
+
+ if (tty->stopped)
+ return 0;
+
+ spin_lock_irqsave(&line->lock, flags);
+ room = write_room(line);
+ spin_unlock_irqrestore(&line->lock, flags);
+
+ /*XXX: Warning to remove */
+ if (0 == room)
+ printk(KERN_DEBUG "%s: %s: no room left in buffer\n",
+ __FUNCTION__,tty->name);
+ return room;
}
+int line_chars_in_buffer(struct tty_struct *tty)
+{
+ struct line *line = tty->driver_data;
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&line->lock, flags);
+
+ /*write_room subtracts 1 for the needed NULL, so we readd it.*/
+ ret = LINE_BUFSIZE - (write_room(line) + 1);
+ spin_unlock_irqrestore(&line->lock, flags);
+
+ return ret;
+}
+
+/*
+ * This copies the content of buf into the circular buffer associated with
+ * this line.
+ * The return value is the number of characters actually copied, i.e. the ones
+ * for which there was space: this function is not supposed to ever flush out
+ * the circular buffer.
+ *
+ * Must be called while holding line->lock!
+ */
static int buffer_data(struct line *line, const char *buf, int len)
{
int end, room;
@@ -70,48 +120,95 @@ static int buffer_data(struct line *line, const char *buf, int len)
len = (len > room) ? room : len;
end = line->buffer + LINE_BUFSIZE - line->tail;
- if(len < end){
+
+ if (len < end){
memcpy(line->tail, buf, len);
line->tail += len;
- }
- else {
+ } else {
+ /* The circular buffer is wrapping */
memcpy(line->tail, buf, end);
buf += end;
memcpy(line->buffer, buf, len - end);
line->tail = line->buffer + len - end;
}
- return(len);
+ return len;
}
+/*
+ * Flushes the ring buffer to the output channels. That is, write_chan is
+ * called, passing it line->head as buffer, and an appropriate count.
+ *
+ * On exit, returns 1 when the buffer is empty,
+ * 0 when the buffer is not empty on exit,
+ * and -errno when an error occurred.
+ *
+ * Must be called while holding line->lock!*/
static int flush_buffer(struct line *line)
{
int n, count;
if ((line->buffer == NULL) || (line->head == line->tail))
- return(1);
+ return 1;
if (line->tail < line->head) {
+ /* line->buffer + LINE_BUFSIZE is the end of the buffer! */
count = line->buffer + LINE_BUFSIZE - line->head;
+
n = write_chan(&line->chan_list, line->head, count,
line->driver->write_irq);
if (n < 0)
- return(n);
- if (n == count)
+ return n;
+ if (n == count) {
+ /* We have flushed from ->head to buffer end, now we
+ * must flush only from the beginning to ->tail.*/
line->head = line->buffer;
- else {
+ } else {
line->head += n;
- return(0);
+ return 0;
}
}
count = line->tail - line->head;
n = write_chan(&line->chan_list, line->head, count,
line->driver->write_irq);
- if(n < 0) return(n);
+
+ if(n < 0)
+ return n;
line->head += n;
- return(line->head == line->tail);
+ return line->head == line->tail;
+}
+
+void line_flush_buffer(struct tty_struct *tty)
+{
+ struct line *line = tty->driver_data;
+ unsigned long flags;
+ int err;
+
+ /*XXX: copied from line_write, verify if it is correct!*/
+ if(tty->stopped)
+ return;
+ //return 0;
+
+ spin_lock_irqsave(&line->lock, flags);
+ err = flush_buffer(line);
+ /*if (err == 1)
+ err = 0;*/
+ spin_unlock_irqrestore(&line->lock, flags);
+ //return err;
+}
+
+/* We map both ->flush_chars and ->put_char (which go in pair) onto ->flush_buffer
+ * and ->write. Hope it's not that bad.*/
+void line_flush_chars(struct tty_struct *tty)
+{
+ line_flush_buffer(tty);
+}
+
+void line_put_char(struct tty_struct *tty, unsigned char ch)
+{
+ line_write(tty, &ch, sizeof(ch));
}
int line_write(struct tty_struct *tty, const unsigned char *buf, int len)
@@ -120,38 +217,31 @@ int line_write(struct tty_struct *tty, const unsigned char *buf, int len)
unsigned long flags;
int n, err, ret = 0;
- if(tty->stopped) return 0;
+ if(tty->stopped)
+ return 0;
- down(&line->sem);
- if(line->head != line->tail){
- local_irq_save(flags);
+ spin_lock_irqsave(&line->lock, flags);
+ if (line->head != line->tail) {
ret = buffer_data(line, buf, len);
err = flush_buffer(line);
- local_irq_restore(flags);
- if(err <= 0 && (err != -EAGAIN || !ret))
+ if (err <= 0 && (err != -EAGAIN || !ret))
ret = err;
- }
- else {
+ } else {
n = write_chan(&line->chan_list, buf, len,
line->driver->write_irq);
- if(n < 0){
+ if (n < 0) {
ret = n;
goto out_up;
}
len -= n;
ret += n;
- if(len > 0)
+ if (len > 0)
ret += buffer_data(line, buf + n, len);
}
- out_up:
- up(&line->sem);
- return(ret);
-}
-
-void line_put_char(struct tty_struct *tty, unsigned char ch)
-{
- line_write(tty, &ch, sizeof(ch));
+out_up:
+ spin_unlock_irqrestore(&line->lock, flags);
+ return ret;
}
void line_set_termios(struct tty_struct *tty, struct termios * old)
@@ -159,11 +249,6 @@ void line_set_termios(struct tty_struct *tty, struct termios * old)
/* nothing */
}
-int line_chars_in_buffer(struct tty_struct *tty)
-{
- return 0;
-}
-
static struct {
int cmd;
char *level;
@@ -250,7 +335,7 @@ int line_ioctl(struct tty_struct *tty, struct file * file,
ret = -ENOIOCTLCMD;
break;
}
- return(ret);
+ return ret;
}
static irqreturn_t line_write_interrupt(int irq, void *data,
@@ -260,18 +345,23 @@ static irqreturn_t line_write_interrupt(int irq, void *data,
struct line *line = tty->driver_data;
int err;
+ /* Interrupts are enabled here because we registered the interrupt with
+ * SA_INTERRUPT (see line_setup_irq).*/
+
+ spin_lock_irq(&line->lock);
err = flush_buffer(line);
- if(err == 0)
- return(IRQ_NONE);
- else if(err < 0){
+ if (err == 0) {
+ return IRQ_NONE;
+ } else if(err < 0) {
line->head = line->buffer;
line->tail = line->buffer;
}
+ spin_unlock_irq(&line->lock);
if(tty == NULL)
- return(IRQ_NONE);
+ return IRQ_NONE;
- if(test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
+ if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
(tty->ldisc.write_wakeup != NULL))
(tty->ldisc.write_wakeup)(tty);
@@ -281,9 +371,9 @@ static irqreturn_t line_write_interrupt(int irq, void *data,
* writes.
*/
- if(waitqueue_active(&tty->write_wait))
+ if (waitqueue_active(&tty->write_wait))
wake_up_interruptible(&tty->write_wait);
- return(IRQ_HANDLED);
+ return IRQ_HANDLED;
}
int line_setup_irq(int fd, int input, int output, struct tty_struct *tty)
@@ -292,15 +382,18 @@ int line_setup_irq(int fd, int input, int output, struct tty_struct *tty)
struct line_driver *driver = line->driver;
int err = 0, flags = SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM;
- if(input) err = um_request_irq(driver->read_irq, fd, IRQ_READ,
+ if (input)
+ err = um_request_irq(driver->read_irq, fd, IRQ_READ,
line_interrupt, flags,
driver->read_irq_name, tty);
- if(err) return(err);
- if(output) err = um_request_irq(driver->write_irq, fd, IRQ_WRITE,
+ if (err)
+ return err;
+ if (output)
+ err = um_request_irq(driver->write_irq, fd, IRQ_WRITE,
line_write_interrupt, flags,
driver->write_irq_name, tty);
line->have_irq = 1;
- return(err);
+ return err;
}
void line_disable(struct tty_struct *tty, int current_irq)
@@ -336,7 +429,9 @@ int line_open(struct line *lines, struct tty_struct *tty,
line = &lines[tty->index];
tty->driver_data = line;
- down(&line->sem);
+ /* The IRQ which takes this lock is not yet enabled and won't be run
+ * before the end, so we don't need to use spin_lock_irq.*/
+ spin_lock(&line->lock);
if (tty->count == 1) {
if (!line->valid) {
err = -ENODEV;
@@ -349,6 +444,7 @@ int line_open(struct line *lines, struct tty_struct *tty,
err = open_chan(&line->chan_list);
if(err) goto out;
}
+ /* Here the interrupt is registered.*/
enable_chan(&line->chan_list, tty);
INIT_WORK(&line->task, line_timer_cb, tty);
}
@@ -362,21 +458,27 @@ int line_open(struct line *lines, struct tty_struct *tty,
line->count++;
out:
- up(&line->sem);
- return(err);
+ spin_unlock(&line->lock);
+ return err;
}
void line_close(struct tty_struct *tty, struct file * filp)
{
struct line *line = tty->driver_data;
- down(&line->sem);
+ /* XXX: I assume this should be called in process context, not with interrupt
+ * disabled!*/
+ spin_lock_irq(&line->lock);
+
+ /* We ignore the error anyway! */
+ flush_buffer(line);
+
line->count--;
if (tty->count == 1) {
line_disable(tty, -1);
tty->driver_data = NULL;
}
- up(&line->sem);
+ spin_unlock_irq(&line->lock);
}
void close_lines(struct line *lines, int nlines)
@@ -387,31 +489,41 @@ void close_lines(struct line *lines, int nlines)
close_chan(&lines[i].chan_list);
}
-int line_setup(struct line *lines, int num, char *init, int all_allowed)
+/* Common setup code for both startup command line and mconsole initialization.
+ * @lines contains the the array (of size @num) to modify;
+ * @init is the setup string;
+ * @all_allowed is a boolean saying if we can setup the whole @lines
+ * at once. For instance, it will be usually true for startup init. (where we
+ * can use con=xterm) and false for mconsole.*/
+
+int line_setup(struct line *lines, unsigned int num, char *init, int all_allowed)
{
int i, n;
char *end;
- if(*init == '=') n = -1;
- else {
+ if(*init == '=') {
+ /* We said con=/ssl= instead of con#=, so we are configuring all
+ * consoles at once.*/
+ n = -1;
+ } else {
n = simple_strtoul(init, &end, 0);
if(*end != '='){
printk(KERN_ERR "line_setup failed to parse \"%s\"\n",
init);
- return(0);
+ return 0;
}
init = end;
}
init++;
- if((n >= 0) && (n >= num)){
+
+ if (n >= (signed int) num) {
printk("line_setup - %d out of range ((0 ... %d) allowed)\n",
n, num - 1);
- return(0);
- }
- else if (n >= 0){
+ return 0;
+ } else if (n >= 0){
if (lines[n].count > 0) {
printk("line_setup - device %d is open\n", n);
- return(0);
+ return 0;
}
if (lines[n].init_pri <= INIT_ONE){
lines[n].init_pri = INIT_ONE;
@@ -422,13 +534,11 @@ int line_setup(struct line *lines, int num, char *init, int all_allowed)
lines[n].valid = 1;
}
}
- }
- else if(!all_allowed){
+ } else if(!all_allowed){
printk("line_setup - can't configure all devices from "
"mconsole\n");
- return(0);
- }
- else {
+ return 0;
+ } else {
for(i = 0; i < num; i++){
if(lines[i].init_pri <= INIT_ALL){
lines[i].init_pri = INIT_ALL;
@@ -440,21 +550,21 @@ int line_setup(struct line *lines, int num, char *init, int all_allowed)
}
}
}
- return(1);
+ return 1;
}
-int line_config(struct line *lines, int num, char *str)
+int line_config(struct line *lines, unsigned int num, char *str)
{
char *new = uml_strdup(str);
if(new == NULL){
printk("line_config - uml_strdup failed\n");
- return(-ENOMEM);
+ return -ENOMEM;
}
- return(!line_setup(lines, num, new, 0));
+ return !line_setup(lines, num, new, 0);
}
-int line_get_config(char *name, struct line *lines, int num, char *str,
+int line_get_config(char *name, struct line *lines, unsigned int num, char *str,
int size, char **error_out)
{
struct line *line;
@@ -464,47 +574,33 @@ int line_get_config(char *name, struct line *lines, int num, char *str,
dev = simple_strtoul(name, &end, 0);
if((*end != '\0') || (end == name)){
*error_out = "line_get_config failed to parse device number";
- return(0);
+ return 0;
}
if((dev < 0) || (dev >= num)){
- *error_out = "device number of of range";
- return(0);
+ *error_out = "device number out of range";
+ return 0;
}
line = &lines[dev];
- down(&line->sem);
+ spin_lock(&line->lock);
if(!line->valid)
CONFIG_CHUNK(str, size, n, "none", 1);
else if(line->count == 0)
CONFIG_CHUNK(str, size, n, line->init_str, 1);
else n = chan_config_string(&line->chan_list, str, size, error_out);
- up(&line->sem);
+ spin_unlock(&line->lock);
- return(n);
+ return n;
}
-int line_remove(struct line *lines, int num, char *str)
+int line_remove(struct line *lines, unsigned int num, char *str)
{
char config[sizeof("conxxxx=none\0")];
sprintf(config, "%s=none", str);
- return(!line_setup(lines, num, config, 0));
-}
-
-int line_write_room(struct tty_struct *tty)
-{
- struct line *dev = tty->driver_data;
- int room;
-
- if (tty->stopped)
- return 0;
- room = write_room(dev);
- if (0 == room)
- printk(KERN_DEBUG "%s: %s: no room left in buffer\n",
- __FUNCTION__,tty->name);
- return room;
+ return !line_setup(lines, num, config, 0);
}
struct tty_driver *line_register_devfs(struct lines *set,
@@ -553,7 +649,7 @@ void lines_init(struct line *lines, int nlines)
for(i = 0; i < nlines; i++){
line = &lines[i];
INIT_LIST_HEAD(&line->chan_list);
- sema_init(&line->sem, 1);
+ spin_lock_init(&line->lock);
if(line->init_str != NULL){
line->init_str = uml_strdup(line->init_str);
if(line->init_str == NULL)
@@ -587,7 +683,7 @@ irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused)
"errno = %d\n", -err);
printk("fd %d is losing SIGWINCH support\n",
winch->tty_fd);
- return(IRQ_HANDLED);
+ return IRQ_HANDLED;
}
goto out;
}
@@ -603,7 +699,7 @@ irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused)
out:
if(winch->fd != -1)
reactivate_fd(winch->fd, WINCH_IRQ);
- return(IRQ_HANDLED);
+ return IRQ_HANDLED;
}
DECLARE_MUTEX(winch_handler_sem);
@@ -625,7 +721,7 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty)
.pid = pid,
.tty = tty });
list_add(&winch->list, &winch_handlers);
- if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
+ if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
"winch", winch) < 0)
printk("register_winch_irq - failed to register IRQ\n");
@@ -656,26 +752,16 @@ char *add_xterm_umid(char *base)
int len;
umid = get_umid(1);
- if(umid == NULL) return(base);
+ if(umid == NULL)
+ return base;
len = strlen(base) + strlen(" ()") + strlen(umid) + 1;
title = kmalloc(len, GFP_KERNEL);
if(title == NULL){
printk("Failed to allocate buffer for xterm title\n");
- return(base);
+ return base;
}
snprintf(title, len, "%s (%s)", base, umid);
- return(title);
+ return title;
}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
index c5839c3..a2bac42 100644
--- a/arch/um/drivers/ssl.c
+++ b/arch/um/drivers/ssl.c
@@ -107,11 +107,6 @@ int ssl_open(struct tty_struct *tty, struct file *filp)
}
#if 0
-static int ssl_chars_in_buffer(struct tty_struct *tty)
-{
- return(0);
-}
-
static void ssl_flush_buffer(struct tty_struct *tty)
{
return;
@@ -149,11 +144,11 @@ static struct tty_operations ssl_ops = {
.put_char = line_put_char,
.write_room = line_write_room,
.chars_in_buffer = line_chars_in_buffer,
+ .flush_buffer = line_flush_buffer,
+ .flush_chars = line_flush_chars,
.set_termios = line_set_termios,
.ioctl = line_ioctl,
#if 0
- .flush_chars = ssl_flush_chars,
- .flush_buffer = ssl_flush_buffer,
.throttle = ssl_throttle,
.unthrottle = ssl_unthrottle,
.stop = ssl_stop,
@@ -171,10 +166,11 @@ static void ssl_console_write(struct console *c, const char *string,
unsigned len)
{
struct line *line = &serial_lines[c->index];
+ unsigned long flags;
- down(&line->sem);
+ spin_lock_irqsave(&line->lock, flags);
console_write_chan(&line->chan_list, string, len);
- up(&line->sem);
+ spin_unlock_irqrestore(&line->lock, flags);
}
static struct tty_driver *ssl_console_device(struct console *c, int *index)
@@ -238,14 +234,3 @@ static int ssl_chan_setup(char *str)
__setup("ssl", ssl_chan_setup);
__channel_help(ssl_chan_setup, "ssl");
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index e604d7c..361d0be 100644
--- a/arch/um/drivers/stdio_console.c
+++ b/arch/um/drivers/stdio_console.c
@@ -116,8 +116,11 @@ static struct tty_operations console_ops = {
.open = con_open,
.close = line_close,
.write = line_write,
+ .put_char = line_put_char,
.write_room = line_write_room,
.chars_in_buffer = line_chars_in_buffer,
+ .flush_buffer = line_flush_buffer,
+ .flush_chars = line_flush_chars,
.set_termios = line_set_termios,
.ioctl = line_ioctl,
};
@@ -126,10 +129,11 @@ static void uml_console_write(struct console *console, const char *string,
unsigned len)
{
struct line *line = &vts[console->index];
+ unsigned long flags;
- down(&line->sem);
+ spin_lock_irqsave(&line->lock, flags);
console_write_chan(&line->chan_list, string, len);
- up(&line->sem);
+ spin_unlock_irqrestore(&line->lock, flags);
}
static struct tty_driver *uml_console_device(struct console *c, int *index)
@@ -192,14 +196,3 @@ static int console_chan_setup(char *str)
}
__setup("con", console_chan_setup);
__channel_help(console_chan_setup, "con");
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 4d8b165..9a56ff9 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -156,6 +156,7 @@ static struct gendisk *fake_gendisk[MAX_DEV];
static struct openflags global_openflags = OPEN_FLAGS;
struct cow {
+ /* This is the backing file, actually */
char *file;
int fd;
unsigned long *bitmap;
@@ -927,10 +928,14 @@ static int ubd_open(struct inode *inode, struct file *filp)
}
}
dev->count++;
- if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){
+ set_disk_ro(disk, !dev->openflags.w);
+
+ /* This should no more be needed. And it didn't work anyway to exclude
+ * read-write remounting of filesystems.*/
+ /*if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){
if(--dev->count == 0) ubd_close(dev);
err = -EROFS;
- }
+ }*/
out:
return(err);
}
@@ -1096,6 +1101,7 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
if(req->rq_status == RQ_INACTIVE) return(1);
+ /* This should be impossible now */
if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
printk("Write attempted on readonly ubd device %s\n",
disk->disk_name);
@@ -1243,6 +1249,7 @@ static int ubd_check_remapped(int fd, unsigned long address, int is_write,
/* It's a write to a ubd device */
+ /* This should be impossible now */
if(!dev->openflags.w){
/* It's a write access on a read-only device - probably
* shouldn't happen. If the kernel is trying to change
@@ -1605,8 +1612,7 @@ void do_io(struct io_thread_req *req)
}
} while((n < len) && (n != 0));
if (n < len) memset(&buf[n], 0, len - n);
- }
- else {
+ } else {
n = os_write_file(req->fds[bit], buf, len);
if(n != len){
printk("do_io - write failed err = %d "
diff --git a/arch/um/include/line.h b/arch/um/include/line.h
index 6d81ecc..4c5e92c 100644
--- a/arch/um/include/line.h
+++ b/arch/um/include/line.h
@@ -10,7 +10,7 @@
#include "linux/workqueue.h"
#include "linux/tty.h"
#include "linux/interrupt.h"
-#include "asm/semaphore.h"
+#include "linux/spinlock.h"
#include "chan_user.h"
#include "mconsole_kern.h"
@@ -37,10 +37,18 @@ struct line {
struct list_head chan_list;
int valid;
int count;
- struct semaphore sem;
+ /*This lock is actually, mostly, local to*/
+ spinlock_t lock;
+
+ /* Yes, this is a real circular buffer.
+ * XXX: And this should become a struct kfifo!
+ *
+ * buffer points to a buffer allocated on demand, of length
+ * LINE_BUFSIZE, head to the start of the ring, tail to the end.*/
char *buffer;
char *head;
char *tail;
+
int sigio;
struct work_struct task;
struct line_driver *driver;
@@ -52,7 +60,6 @@ struct line {
init_pri : INIT_STATIC, \
chan_list : { }, \
valid : 1, \
- sem : { }, \
buffer : NULL, \
head : NULL, \
tail : NULL, \
@@ -69,15 +76,18 @@ struct lines {
extern void line_close(struct tty_struct *tty, struct file * filp);
extern int line_open(struct line *lines, struct tty_struct *tty,
struct chan_opts *opts);
-extern int line_setup(struct line *lines, int num, char *init,
+extern int line_setup(struct line *lines, unsigned int sizeof_lines, char *init,
int all_allowed);
extern int line_write(struct tty_struct *tty, const unsigned char *buf, int len);
extern void line_put_char(struct tty_struct *tty, unsigned char ch);
extern void line_set_termios(struct tty_struct *tty, struct termios * old);
extern int line_chars_in_buffer(struct tty_struct *tty);
+extern void line_flush_buffer(struct tty_struct *tty);
+extern void line_flush_chars(struct tty_struct *tty);
extern int line_write_room(struct tty_struct *tty);
extern int line_ioctl(struct tty_struct *tty, struct file * file,
unsigned int cmd, unsigned long arg);
+
extern char *add_xterm_umid(char *base);
extern int line_setup_irq(int fd, int input, int output, struct tty_struct *tty);
extern void line_close_chan(struct line *line);
@@ -89,20 +99,10 @@ extern struct tty_driver * line_register_devfs(struct lines *set,
int nlines);
extern void lines_init(struct line *lines, int nlines);
extern void close_lines(struct line *lines, int nlines);
-extern int line_config(struct line *lines, int num, char *str);
-extern int line_remove(struct line *lines, int num, char *str);
-extern int line_get_config(char *dev, struct line *lines, int num, char *str,
+
+extern int line_config(struct line *lines, unsigned int sizeof_lines, char *str);
+extern int line_remove(struct line *lines, unsigned int sizeof_lines, char *str);
+extern int line_get_config(char *dev, struct line *lines, unsigned int sizeof_lines, char *str,
int size, char **error_out);
#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/sysdep-i386/syscalls.h b/arch/um/include/sysdep-i386/syscalls.h
index 5db81ec..be0a3e3 100644
--- a/arch/um/include/sysdep-i386/syscalls.h
+++ b/arch/um/include/sysdep-i386/syscalls.h
@@ -22,102 +22,3 @@ extern syscall_handler_t old_mmap_i386;
extern long sys_mmap2(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff);
-
-/* On i386 they choose a meaningless naming.*/
-#define __NR_kexec_load __NR_sys_kexec_load
-
-#define ARCH_SYSCALLS \
- [ __NR_waitpid ] = (syscall_handler_t *) sys_waitpid, \
- [ __NR_break ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_oldstat ] = (syscall_handler_t *) sys_stat, \
- [ __NR_umount ] = (syscall_handler_t *) sys_oldumount, \
- [ __NR_stime ] = um_stime, \
- [ __NR_oldfstat ] = (syscall_handler_t *) sys_fstat, \
- [ __NR_stty ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_gtty ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_nice ] = (syscall_handler_t *) sys_nice, \
- [ __NR_ftime ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_prof ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_signal ] = (syscall_handler_t *) sys_signal, \
- [ __NR_lock ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_mpx ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_ulimit ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_oldolduname ] = (syscall_handler_t *) sys_olduname, \
- [ __NR_sigaction ] = (syscall_handler_t *) sys_sigaction, \
- [ __NR_sgetmask ] = (syscall_handler_t *) sys_sgetmask, \
- [ __NR_ssetmask ] = (syscall_handler_t *) sys_ssetmask, \
- [ __NR_sigsuspend ] = (syscall_handler_t *) sys_sigsuspend, \
- [ __NR_sigpending ] = (syscall_handler_t *) sys_sigpending, \
- [ __NR_oldlstat ] = (syscall_handler_t *) sys_lstat, \
- [ __NR_readdir ] = old_readdir, \
- [ __NR_profil ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_socketcall ] = (syscall_handler_t *) sys_socketcall, \
- [ __NR_olduname ] = (syscall_handler_t *) sys_uname, \
- [ __NR_iopl ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_idle ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_ipc ] = (syscall_handler_t *) sys_ipc, \
- [ __NR_sigreturn ] = (syscall_handler_t *) sys_sigreturn, \
- [ __NR_sigprocmask ] = (syscall_handler_t *) sys_sigprocmask, \
- [ __NR_bdflush ] = (syscall_handler_t *) sys_bdflush, \
- [ __NR__llseek ] = (syscall_handler_t *) sys_llseek, \
- [ __NR__newselect ] = (syscall_handler_t *) sys_select, \
- [ __NR_vm86 ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_mmap ] = (syscall_handler_t *) old_mmap_i386, \
- [ __NR_ugetrlimit ] = (syscall_handler_t *) sys_getrlimit, \
- [ __NR_mmap2 ] = (syscall_handler_t *) sys_mmap2, \
- [ __NR_truncate64 ] = (syscall_handler_t *) sys_truncate64, \
- [ __NR_ftruncate64 ] = (syscall_handler_t *) sys_ftruncate64, \
- [ __NR_stat64 ] = (syscall_handler_t *) sys_stat64, \
- [ __NR_lstat64 ] = (syscall_handler_t *) sys_lstat64, \
- [ __NR_fstat64 ] = (syscall_handler_t *) sys_fstat64, \
- [ __NR_fcntl64 ] = (syscall_handler_t *) sys_fcntl64, \
- [ __NR_sendfile64 ] = (syscall_handler_t *) sys_sendfile64, \
- [ __NR_statfs64 ] = (syscall_handler_t *) sys_statfs64, \
- [ __NR_fstatfs64 ] = (syscall_handler_t *) sys_fstatfs64, \
- [ __NR_fadvise64_64 ] = (syscall_handler_t *) sys_fadvise64_64, \
- [ __NR_select ] = (syscall_handler_t *) old_select, \
- [ __NR_vm86old ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_modify_ldt ] = (syscall_handler_t *) sys_modify_ldt, \
- [ __NR_lchown32 ] = (syscall_handler_t *) sys_lchown, \
- [ __NR_getuid32 ] = (syscall_handler_t *) sys_getuid, \
- [ __NR_getgid32 ] = (syscall_handler_t *) sys_getgid, \
- [ __NR_geteuid32 ] = (syscall_handler_t *) sys_geteuid, \
- [ __NR_getegid32 ] = (syscall_handler_t *) sys_getegid, \
- [ __NR_setreuid32 ] = (syscall_handler_t *) sys_setreuid, \
- [ __NR_setregid32 ] = (syscall_handler_t *) sys_setregid, \
- [ __NR_getgroups32 ] = (syscall_handler_t *) sys_getgroups, \
- [ __NR_setgroups32 ] = (syscall_handler_t *) sys_setgroups, \
- [ __NR_fchown32 ] = (syscall_handler_t *) sys_fchown, \
- [ __NR_setresuid32 ] = (syscall_handler_t *) sys_setresuid, \
- [ __NR_getresuid32 ] = (syscall_handler_t *) sys_getresuid, \
- [ __NR_setresgid32 ] = (syscall_handler_t *) sys_setresgid, \
- [ __NR_getresgid32 ] = (syscall_handler_t *) sys_getresgid, \
- [ __NR_chown32 ] = (syscall_handler_t *) sys_chown, \
- [ __NR_setuid32 ] = (syscall_handler_t *) sys_setuid, \
- [ __NR_setgid32 ] = (syscall_handler_t *) sys_setgid, \
- [ __NR_setfsuid32 ] = (syscall_handler_t *) sys_setfsuid, \
- [ __NR_setfsgid32 ] = (syscall_handler_t *) sys_setfsgid, \
- [ __NR_pivot_root ] = (syscall_handler_t *) sys_pivot_root, \
- [ __NR_mincore ] = (syscall_handler_t *) sys_mincore, \
- [ __NR_madvise ] = (syscall_handler_t *) sys_madvise, \
- [ 222 ] = (syscall_handler_t *) sys_ni_syscall, \
- [ 223 ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_set_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_get_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
- [ 251 ] = (syscall_handler_t *) sys_ni_syscall, \
- [ 285 ] = (syscall_handler_t *) sys_ni_syscall,
-
-/* 222 doesn't yet have a name in include/asm-i386/unistd.h */
-
-#define LAST_ARCH_SYSCALL 285
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/sysdep-x86_64/syscalls.h b/arch/um/include/sysdep-x86_64/syscalls.h
index b187a41..67923cc 100644
--- a/arch/um/include/sysdep-x86_64/syscalls.h
+++ b/arch/um/include/sysdep-x86_64/syscalls.h
@@ -26,66 +26,9 @@ extern syscall_handler_t *ia32_sys_call_table[];
extern long old_mmap(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff);
-extern syscall_handler_t wrap_sys_shmat;
extern syscall_handler_t sys_modify_ldt;
extern syscall_handler_t sys_arch_prctl;
-#define ARCH_SYSCALLS \
- [ __NR_mmap ] = (syscall_handler_t *) old_mmap, \
- [ __NR_select ] = (syscall_handler_t *) sys_select, \
- [ __NR_mincore ] = (syscall_handler_t *) sys_mincore, \
- [ __NR_madvise ] = (syscall_handler_t *) sys_madvise, \
- [ __NR_shmget ] = (syscall_handler_t *) sys_shmget, \
- [ __NR_shmat ] = (syscall_handler_t *) wrap_sys_shmat, \
- [ __NR_shmctl ] = (syscall_handler_t *) sys_shmctl, \
- [ __NR_semop ] = (syscall_handler_t *) sys_semop, \
- [ __NR_semget ] = (syscall_handler_t *) sys_semget, \
- [ __NR_semctl ] = (syscall_handler_t *) sys_semctl, \
- [ __NR_shmdt ] = (syscall_handler_t *) sys_shmdt, \
- [ __NR_msgget ] = (syscall_handler_t *) sys_msgget, \
- [ __NR_msgsnd ] = (syscall_handler_t *) sys_msgsnd, \
- [ __NR_msgrcv ] = (syscall_handler_t *) sys_msgrcv, \
- [ __NR_msgctl ] = (syscall_handler_t *) sys_msgctl, \
- [ __NR_pivot_root ] = (syscall_handler_t *) sys_pivot_root, \
- [ __NR_tuxcall ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_security ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_epoll_ctl_old ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_epoll_wait_old ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_modify_ldt ] = (syscall_handler_t *) sys_modify_ldt, \
- [ __NR_arch_prctl ] = (syscall_handler_t *) sys_arch_prctl, \
- [ __NR_socket ] = (syscall_handler_t *) sys_socket, \
- [ __NR_connect ] = (syscall_handler_t *) sys_connect, \
- [ __NR_accept ] = (syscall_handler_t *) sys_accept, \
- [ __NR_recvfrom ] = (syscall_handler_t *) sys_recvfrom, \
- [ __NR_recvmsg ] = (syscall_handler_t *) sys_recvmsg, \
- [ __NR_sendmsg ] = (syscall_handler_t *) sys_sendmsg, \
- [ __NR_bind ] = (syscall_handler_t *) sys_bind, \
- [ __NR_listen ] = (syscall_handler_t *) sys_listen, \
- [ __NR_getsockname ] = (syscall_handler_t *) sys_getsockname, \
- [ __NR_getpeername ] = (syscall_handler_t *) sys_getpeername, \
- [ __NR_socketpair ] = (syscall_handler_t *) sys_socketpair, \
- [ __NR_sendto ] = (syscall_handler_t *) sys_sendto, \
- [ __NR_shutdown ] = (syscall_handler_t *) sys_shutdown, \
- [ __NR_setsockopt ] = (syscall_handler_t *) sys_setsockopt, \
- [ __NR_getsockopt ] = (syscall_handler_t *) sys_getsockopt, \
- [ __NR_iopl ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_set_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_get_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
- [ __NR_semtimedop ] = (syscall_handler_t *) sys_semtimedop, \
- [ 251 ] = (syscall_handler_t *) sys_ni_syscall,
-
-#define LAST_ARCH_SYSCALL 251
-#define NR_syscalls 1024
+#define NR_syscalls (__NR_syscall_max + 1)
#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index dc796c1..246f0e7 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -10,7 +10,7 @@ obj-y = checksum.o config.o exec_kern.o exitcode.o \
helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o mem_user.o \
physmem.o process.o process_kern.o ptrace.o reboot.o resource.o \
sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \
- syscall_kern.o sysrq.o sys_call_table.o tempfile.o time.o time_kern.o \
+ syscall_kern.o sysrq.o tempfile.o time.o time_kern.o \
tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o umid.o \
user_util.o
@@ -53,6 +53,7 @@ quiet_cmd_quote2 = QUOTE $@
cmd_quote2 = sed -e '/CONFIG/{' \
-e 's/"CONFIG"\;/""/' \
-e 'r $(obj)/config.tmp' \
- -e 'a""\;' \
+ -e 'a \' \
+ -e '""\;' \
-e '}' \
$< > $@
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
index 1d719d5..7a94369 100644
--- a/arch/um/kernel/process_kern.c
+++ b/arch/um/kernel/process_kern.c
@@ -161,10 +161,6 @@ void *get_current(void)
return(current);
}
-void prepare_to_copy(struct task_struct *tsk)
-{
-}
-
int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
unsigned long stack_top, struct task_struct * p,
struct pt_regs *regs)
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index 7b259a2..959b2d2 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -143,7 +143,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: { /* restart after signal. */
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
child->ptrace &= ~PT_DTRACE;
@@ -179,7 +179,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_SINGLESTEP: { /* set the trap flag. */
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
child->ptrace |= PT_DTRACE;
diff --git a/arch/um/kernel/skas/include/uaccess-skas.h b/arch/um/kernel/skas/include/uaccess-skas.h
index 11986c9..c356203 100644
--- a/arch/um/kernel/skas/include/uaccess-skas.h
+++ b/arch/um/kernel/skas/include/uaccess-skas.h
@@ -18,7 +18,7 @@
((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \
((unsigned long) (addr) + (size) >= (unsigned long)(addr))))
-static inline int verify_area_skas(int type, const void * addr,
+static inline int __deprecated verify_area_skas(int type, const void * addr,
unsigned long size)
{
return(access_ok_skas(type, addr, size) ? 0 : -EFAULT);
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
index 7575ec4..f7da9d0 100644
--- a/arch/um/kernel/skas/uaccess.c
+++ b/arch/um/kernel/skas/uaccess.c
@@ -3,6 +3,7 @@
* Licensed under the GPL
*/
+#include "linux/compiler.h"
#include "linux/stddef.h"
#include "linux/kernel.h"
#include "linux/string.h"
@@ -61,8 +62,7 @@ static void do_buffer_op(void *jmpbuf, void *arg_ptr)
void *arg;
int *res;
- /* Some old gccs recognize __va_copy, but not va_copy */
- __va_copy(args, *(va_list *)arg_ptr);
+ va_copy(args, *(va_list *)arg_ptr);
addr = va_arg(args, unsigned long);
len = va_arg(args, int);
is_write = va_arg(args, int);
diff --git a/arch/um/kernel/sys_call_table.c b/arch/um/kernel/sys_call_table.c
deleted file mode 100644
index 7fc06c8..0000000
--- a/arch/um/kernel/sys_call_table.c
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
- * Copyright 2003 PathScale, Inc.
- * Licensed under the GPL
- */
-
-#include "linux/config.h"
-#include "linux/unistd.h"
-#include "linux/sys.h"
-#include "linux/swap.h"
-#include "linux/syscalls.h"
-#include "linux/sysctl.h"
-#include "asm/signal.h"
-#include "sysdep/syscalls.h"
-#include "kern_util.h"
-
-#ifdef CONFIG_NFSD
-#define NFSSERVCTL sys_nfsservctl
-#else
-#define NFSSERVCTL sys_ni_syscall
-#endif
-
-#define LAST_GENERIC_SYSCALL __NR_keyctl
-
-#if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL
-#define LAST_SYSCALL LAST_GENERIC_SYSCALL
-#else
-#define LAST_SYSCALL LAST_ARCH_SYSCALL
-#endif
-
-extern syscall_handler_t sys_fork;
-extern syscall_handler_t sys_execve;
-extern syscall_handler_t um_time;
-extern syscall_handler_t um_stime;
-extern syscall_handler_t sys_pipe;
-extern syscall_handler_t sys_olduname;
-extern syscall_handler_t sys_sigaction;
-extern syscall_handler_t sys_sigsuspend;
-extern syscall_handler_t old_readdir;
-extern syscall_handler_t sys_uname;
-extern syscall_handler_t sys_ipc;
-extern syscall_handler_t sys_sigreturn;
-extern syscall_handler_t sys_clone;
-extern syscall_handler_t sys_rt_sigreturn;
-extern syscall_handler_t sys_sigaltstack;
-extern syscall_handler_t sys_vfork;
-extern syscall_handler_t old_select;
-extern syscall_handler_t sys_modify_ldt;
-extern syscall_handler_t sys_rt_sigsuspend;
-extern syscall_handler_t sys_mbind;
-extern syscall_handler_t sys_get_mempolicy;
-extern syscall_handler_t sys_set_mempolicy;
-extern syscall_handler_t sys_sys_setaltroot;
-
-syscall_handler_t *sys_call_table[] = {
- [ __NR_restart_syscall ] = (syscall_handler_t *) sys_restart_syscall,
- [ __NR_exit ] = (syscall_handler_t *) sys_exit,
- [ __NR_fork ] = (syscall_handler_t *) sys_fork,
- [ __NR_read ] = (syscall_handler_t *) sys_read,
- [ __NR_write ] = (syscall_handler_t *) sys_write,
-
- /* These three are declared differently in asm/unistd.h */
- [ __NR_open ] = (syscall_handler_t *) sys_open,
- [ __NR_close ] = (syscall_handler_t *) sys_close,
- [ __NR_creat ] = (syscall_handler_t *) sys_creat,
- [ __NR_link ] = (syscall_handler_t *) sys_link,
- [ __NR_unlink ] = (syscall_handler_t *) sys_unlink,
- [ __NR_execve ] = (syscall_handler_t *) sys_execve,
-
- /* declared differently in kern_util.h */
- [ __NR_chdir ] = (syscall_handler_t *) sys_chdir,
- [ __NR_time ] = um_time,
- [ __NR_mknod ] = (syscall_handler_t *) sys_mknod,
- [ __NR_chmod ] = (syscall_handler_t *) sys_chmod,
- [ __NR_lchown ] = (syscall_handler_t *) sys_lchown16,
- [ __NR_lseek ] = (syscall_handler_t *) sys_lseek,
- [ __NR_getpid ] = (syscall_handler_t *) sys_getpid,
- [ __NR_mount ] = (syscall_handler_t *) sys_mount,
- [ __NR_setuid ] = (syscall_handler_t *) sys_setuid16,
- [ __NR_getuid ] = (syscall_handler_t *) sys_getuid16,
- [ __NR_ptrace ] = (syscall_handler_t *) sys_ptrace,
- [ __NR_alarm ] = (syscall_handler_t *) sys_alarm,
- [ __NR_pause ] = (syscall_handler_t *) sys_pause,
- [ __NR_utime ] = (syscall_handler_t *) sys_utime,
- [ __NR_access ] = (syscall_handler_t *) sys_access,
- [ __NR_sync ] = (syscall_handler_t *) sys_sync,
- [ __NR_kill ] = (syscall_handler_t *) sys_kill,
- [ __NR_rename ] = (syscall_handler_t *) sys_rename,
- [ __NR_mkdir ] = (syscall_handler_t *) sys_mkdir,
- [ __NR_rmdir ] = (syscall_handler_t *) sys_rmdir,
-
- /* Declared differently in asm/unistd.h */
- [ __NR_dup ] = (syscall_handler_t *) sys_dup,
- [ __NR_pipe ] = (syscall_handler_t *) sys_pipe,
- [ __NR_times ] = (syscall_handler_t *) sys_times,
- [ __NR_brk ] = (syscall_handler_t *) sys_brk,
- [ __NR_setgid ] = (syscall_handler_t *) sys_setgid16,
- [ __NR_getgid ] = (syscall_handler_t *) sys_getgid16,
- [ __NR_geteuid ] = (syscall_handler_t *) sys_geteuid16,
- [ __NR_getegid ] = (syscall_handler_t *) sys_getegid16,
- [ __NR_acct ] = (syscall_handler_t *) sys_acct,
- [ __NR_umount2 ] = (syscall_handler_t *) sys_umount,
- [ __NR_ioctl ] = (syscall_handler_t *) sys_ioctl,
- [ __NR_fcntl ] = (syscall_handler_t *) sys_fcntl,
- [ __NR_setpgid ] = (syscall_handler_t *) sys_setpgid,
- [ __NR_umask ] = (syscall_handler_t *) sys_umask,
- [ __NR_chroot ] = (syscall_handler_t *) sys_chroot,
- [ __NR_ustat ] = (syscall_handler_t *) sys_ustat,
- [ __NR_dup2 ] = (syscall_handler_t *) sys_dup2,
- [ __NR_getppid ] = (syscall_handler_t *) sys_getppid,
- [ __NR_getpgrp ] = (syscall_handler_t *) sys_getpgrp,
- [ __NR_setsid ] = (syscall_handler_t *) sys_setsid,
- [ __NR_setreuid ] = (syscall_handler_t *) sys_setreuid16,
- [ __NR_setregid ] = (syscall_handler_t *) sys_setregid16,
- [ __NR_sethostname ] = (syscall_handler_t *) sys_sethostname,
- [ __NR_setrlimit ] = (syscall_handler_t *) sys_setrlimit,
- [ __NR_getrlimit ] = (syscall_handler_t *) sys_old_getrlimit,
- [ __NR_getrusage ] = (syscall_handler_t *) sys_getrusage,
- [ __NR_gettimeofday ] = (syscall_handler_t *) sys_gettimeofday,
- [ __NR_settimeofday ] = (syscall_handler_t *) sys_settimeofday,
- [ __NR_getgroups ] = (syscall_handler_t *) sys_getgroups16,
- [ __NR_setgroups ] = (syscall_handler_t *) sys_setgroups16,
- [ __NR_symlink ] = (syscall_handler_t *) sys_symlink,
- [ __NR_readlink ] = (syscall_handler_t *) sys_readlink,
- [ __NR_uselib ] = (syscall_handler_t *) sys_uselib,
- [ __NR_swapon ] = (syscall_handler_t *) sys_swapon,
- [ __NR_reboot ] = (syscall_handler_t *) sys_reboot,
- [ __NR_munmap ] = (syscall_handler_t *) sys_munmap,
- [ __NR_truncate ] = (syscall_handler_t *) sys_truncate,
- [ __NR_ftruncate ] = (syscall_handler_t *) sys_ftruncate,
- [ __NR_fchmod ] = (syscall_handler_t *) sys_fchmod,
- [ __NR_fchown ] = (syscall_handler_t *) sys_fchown16,
- [ __NR_getpriority ] = (syscall_handler_t *) sys_getpriority,
- [ __NR_setpriority ] = (syscall_handler_t *) sys_setpriority,
- [ __NR_statfs ] = (syscall_handler_t *) sys_statfs,
- [ __NR_fstatfs ] = (syscall_handler_t *) sys_fstatfs,
- [ __NR_ioperm ] = (syscall_handler_t *) sys_ni_syscall,
- [ __NR_syslog ] = (syscall_handler_t *) sys_syslog,
- [ __NR_setitimer ] = (syscall_handler_t *) sys_setitimer,
- [ __NR_getitimer ] = (syscall_handler_t *) sys_getitimer,
- [ __NR_stat ] = (syscall_handler_t *) sys_newstat,
- [ __NR_lstat ] = (syscall_handler_t *) sys_newlstat,
- [ __NR_fstat ] = (syscall_handler_t *) sys_newfstat,
- [ __NR_vhangup ] = (syscall_handler_t *) sys_vhangup,
- [ __NR_wait4 ] = (syscall_handler_t *) sys_wait4,
- [ __NR_swapoff ] = (syscall_handler_t *) sys_swapoff,
- [ __NR_sysinfo ] = (syscall_handler_t *) sys_sysinfo,
- [ __NR_fsync ] = (syscall_handler_t *) sys_fsync,
- [ __NR_clone ] = (syscall_handler_t *) sys_clone,
- [ __NR_setdomainname ] = (syscall_handler_t *) sys_setdomainname,
- [ __NR_uname ] = (syscall_handler_t *) sys_newuname,
- [ __NR_adjtimex ] = (syscall_handler_t *) sys_adjtimex,
- [ __NR_mprotect ] = (syscall_handler_t *) sys_mprotect,
- [ __NR_create_module ] = (syscall_handler_t *) sys_ni_syscall,
- [ __NR_init_module ] = (syscall_handler_t *) sys_init_module,
- [ __NR_delete_module ] = (syscall_handler_t *) sys_delete_module,
- [ __NR_get_kernel_syms ] = (syscall_handler_t *) sys_ni_syscall,
- [ __NR_quotactl ] = (syscall_handler_t *) sys_quotactl,
- [ __NR_getpgid ] = (syscall_handler_t *) sys_getpgid,
- [ __NR_fchdir ] = (syscall_handler_t *) sys_fchdir,
- [ __NR_sysfs ] = (syscall_handler_t *) sys_sysfs,
- [ __NR_personality ] = (syscall_handler_t *) sys_personality,
- [ __NR_afs_syscall ] = (syscall_handler_t *) sys_ni_syscall,
- [ __NR_setfsuid ] = (syscall_handler_t *) sys_setfsuid16,
- [ __NR_setfsgid ] = (syscall_handler_t *) sys_setfsgid16,
- [ __NR_getdents ] = (syscall_handler_t *) sys_getdents,
- [ __NR_flock ] = (syscall_handler_t *) sys_flock,
- [ __NR_msync ] = (syscall_handler_t *) sys_msync,
- [ __NR_readv ] = (syscall_handler_t *) sys_readv,
- [ __NR_writev ] = (syscall_handler_t *) sys_writev,
- [ __NR_getsid ] = (syscall_handler_t *) sys_getsid,
- [ __NR_fdatasync ] = (syscall_handler_t *) sys_fdatasync,
- [ __NR__sysctl ] = (syscall_handler_t *) sys_sysctl,
- [ __NR_mlock ] = (syscall_handler_t *) sys_mlock,
- [ __NR_munlock ] = (syscall_handler_t *) sys_munlock,
- [ __NR_mlockall ] = (syscall_handler_t *) sys_mlockall,
- [ __NR_munlockall ] = (syscall_handler_t *) sys_munlockall,
- [ __NR_sched_setparam ] = (syscall_handler_t *) sys_sched_setparam,
- [ __NR_sched_getparam ] = (syscall_handler_t *) sys_sched_getparam,
- [ __NR_sched_setscheduler ] = (syscall_handler_t *) sys_sched_setscheduler,
- [ __NR_sched_getscheduler ] = (syscall_handler_t *) sys_sched_getscheduler,
- [ __NR_sched_yield ] = (syscall_handler_t *) yield,
- [ __NR_sched_get_priority_max ] = (syscall_handler_t *) sys_sched_get_priority_max,
- [ __NR_sched_get_priority_min ] = (syscall_handler_t *) sys_sched_get_priority_min,
- [ __NR_sched_rr_get_interval ] = (syscall_handler_t *) sys_sched_rr_get_interval,
- [ __NR_nanosleep ] = (syscall_handler_t *) sys_nanosleep,
- [ __NR_mremap ] = (syscall_handler_t *) sys_mremap,
- [ __NR_setresuid ] = (syscall_handler_t *) sys_setresuid16,
- [ __NR_getresuid ] = (syscall_handler_t *) sys_getresuid16,
- [ __NR_query_module ] = (syscall_handler_t *) sys_ni_syscall,
- [ __NR_poll ] = (syscall_handler_t *) sys_poll,
- [ __NR_nfsservctl ] = (syscall_handler_t *) NFSSERVCTL,
- [ __NR_setresgid ] = (syscall_handler_t *) sys_setresgid16,
- [ __NR_getresgid ] = (syscall_handler_t *) sys_getresgid16,
- [ __NR_prctl ] = (syscall_handler_t *) sys_prctl,
- [ __NR_rt_sigreturn ] = (syscall_handler_t *) sys_rt_sigreturn,
- [ __NR_rt_sigaction ] = (syscall_handler_t *) sys_rt_sigaction,
- [ __NR_rt_sigprocmask ] = (syscall_handler_t *) sys_rt_sigprocmask,
- [ __NR_rt_sigpending ] = (syscall_handler_t *) sys_rt_sigpending,
- [ __NR_rt_sigtimedwait ] = (syscall_handler_t *) sys_rt_sigtimedwait,
- [ __NR_rt_sigqueueinfo ] = (syscall_handler_t *) sys_rt_sigqueueinfo,
- [ __NR_rt_sigsuspend ] = (syscall_handler_t *) sys_rt_sigsuspend,
- [ __NR_pread64 ] = (syscall_handler_t *) sys_pread64,
- [ __NR_pwrite64 ] = (syscall_handler_t *) sys_pwrite64,
- [ __NR_chown ] = (syscall_handler_t *) sys_chown16,
- [ __NR_getcwd ] = (syscall_handler_t *) sys_getcwd,
- [ __NR_capget ] = (syscall_handler_t *) sys_capget,
- [ __NR_capset ] = (syscall_handler_t *) sys_capset,
- [ __NR_sigaltstack ] = (syscall_handler_t *) sys_sigaltstack,
- [ __NR_sendfile ] = (syscall_handler_t *) sys_sendfile,
- [ __NR_getpmsg ] = (syscall_handler_t *) sys_ni_syscall,
- [ __NR_putpmsg ] = (syscall_handler_t *) sys_ni_syscall,
- [ __NR_vfork ] = (syscall_handler_t *) sys_vfork,
- [ __NR_getdents64 ] = (syscall_handler_t *) sys_getdents64,
- [ __NR_gettid ] = (syscall_handler_t *) sys_gettid,
- [ __NR_readahead ] = (syscall_handler_t *) sys_readahead,
- [ __NR_setxattr ] = (syscall_handler_t *) sys_setxattr,
- [ __NR_lsetxattr ] = (syscall_handler_t *) sys_lsetxattr,
- [ __NR_fsetxattr ] = (syscall_handler_t *) sys_fsetxattr,
- [ __NR_getxattr ] = (syscall_handler_t *) sys_getxattr,
- [ __NR_lgetxattr ] = (syscall_handler_t *) sys_lgetxattr,
- [ __NR_fgetxattr ] = (syscall_handler_t *) sys_fgetxattr,
- [ __NR_listxattr ] = (syscall_handler_t *) sys_listxattr,
- [ __NR_llistxattr ] = (syscall_handler_t *) sys_llistxattr,
- [ __NR_flistxattr ] = (syscall_handler_t *) sys_flistxattr,
- [ __NR_removexattr ] = (syscall_handler_t *) sys_removexattr,
- [ __NR_lremovexattr ] = (syscall_handler_t *) sys_lremovexattr,
- [ __NR_fremovexattr ] = (syscall_handler_t *) sys_fremovexattr,
- [ __NR_tkill ] = (syscall_handler_t *) sys_tkill,
- [ __NR_futex ] = (syscall_handler_t *) sys_futex,
- [ __NR_sched_setaffinity ] = (syscall_handler_t *) sys_sched_setaffinity,
- [ __NR_sched_getaffinity ] = (syscall_handler_t *) sys_sched_getaffinity,
- [ __NR_io_setup ] = (syscall_handler_t *) sys_io_setup,
- [ __NR_io_destroy ] = (syscall_handler_t *) sys_io_destroy,
- [ __NR_io_getevents ] = (syscall_handler_t *) sys_io_getevents,
- [ __NR_io_submit ] = (syscall_handler_t *) sys_io_submit,
- [ __NR_io_cancel ] = (syscall_handler_t *) sys_io_cancel,
- [ __NR_exit_group ] = (syscall_handler_t *) sys_exit_group,
- [ __NR_lookup_dcookie ] = (syscall_handler_t *) sys_lookup_dcookie,
- [ __NR_epoll_create ] = (syscall_handler_t *) sys_epoll_create,
- [ __NR_epoll_ctl ] = (syscall_handler_t *) sys_epoll_ctl,
- [ __NR_epoll_wait ] = (syscall_handler_t *) sys_epoll_wait,
- [ __NR_remap_file_pages ] = (syscall_handler_t *) sys_remap_file_pages,
- [ __NR_set_tid_address ] = (syscall_handler_t *) sys_set_tid_address,
- [ __NR_timer_create ] = (syscall_handler_t *) sys_timer_create,
- [ __NR_timer_settime ] = (syscall_handler_t *) sys_timer_settime,
- [ __NR_timer_gettime ] = (syscall_handler_t *) sys_timer_gettime,
- [ __NR_timer_getoverrun ] = (syscall_handler_t *) sys_timer_getoverrun,
- [ __NR_timer_delete ] = (syscall_handler_t *) sys_timer_delete,
- [ __NR_clock_settime ] = (syscall_handler_t *) sys_clock_settime,
- [ __NR_clock_gettime ] = (syscall_handler_t *) sys_clock_gettime,
- [ __NR_clock_getres ] = (syscall_handler_t *) sys_clock_getres,
- [ __NR_clock_nanosleep ] = (syscall_handler_t *) sys_clock_nanosleep,
- [ __NR_tgkill ] = (syscall_handler_t *) sys_tgkill,
- [ __NR_utimes ] = (syscall_handler_t *) sys_utimes,
- [ __NR_fadvise64 ] = (syscall_handler_t *) sys_fadvise64,
- [ __NR_vserver ] = (syscall_handler_t *) sys_ni_syscall,
- [ __NR_mbind ] = (syscall_handler_t *) sys_mbind,
- [ __NR_get_mempolicy ] = (syscall_handler_t *) sys_get_mempolicy,
- [ __NR_set_mempolicy ] = (syscall_handler_t *) sys_set_mempolicy,
- [ __NR_mq_open ] = (syscall_handler_t *) sys_mq_open,
- [ __NR_mq_unlink ] = (syscall_handler_t *) sys_mq_unlink,
- [ __NR_mq_timedsend ] = (syscall_handler_t *) sys_mq_timedsend,
- [ __NR_mq_timedreceive ] = (syscall_handler_t *) sys_mq_timedreceive,
- [ __NR_mq_notify ] = (syscall_handler_t *) sys_mq_notify,
- [ __NR_mq_getsetattr ] = (syscall_handler_t *) sys_mq_getsetattr,
- [ __NR_kexec_load ] = (syscall_handler_t *) sys_ni_syscall,
- [ __NR_waitid ] = (syscall_handler_t *) sys_waitid,
- [ __NR_add_key ] = (syscall_handler_t *) sys_add_key,
- [ __NR_request_key ] = (syscall_handler_t *) sys_request_key,
- [ __NR_keyctl ] = (syscall_handler_t *) sys_keyctl,
-
- ARCH_SYSCALLS
- [ LAST_SYSCALL + 1 ... NR_syscalls ] =
- (syscall_handler_t *) sys_ni_syscall
-};
diff --git a/arch/um/kernel/tt/include/uaccess-tt.h b/arch/um/kernel/tt/include/uaccess-tt.h
index f0bad01..bb69d6b 100644
--- a/arch/um/kernel/tt/include/uaccess-tt.h
+++ b/arch/um/kernel/tt/include/uaccess-tt.h
@@ -33,7 +33,7 @@ extern unsigned long uml_physmem;
(((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \
(under_task_size(addr, size) || is_stack(addr, size))))
-static inline int verify_area_tt(int type, const void * addr,
+static inline int __deprecated verify_area_tt(int type, const void * addr,
unsigned long size)
{
return(access_ok_tt(type, addr, size) ? 0 : -EFAULT);
diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c
index 148645b..9a0ad09 100644
--- a/arch/um/os-Linux/sys-i386/registers.c
+++ b/arch/um/os-Linux/sys-i386/registers.c
@@ -105,14 +105,15 @@ void init_registers(int pid)
panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
err);
+ errno = 0;
err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs);
if(!err)
return;
+ if(errno != EIO)
+ panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d",
+ errno);
have_fpx_regs = 0;
- if(err != EIO)
- panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d",
- err);
err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs);
if(err)
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
index 71b47e6..950781e 100644
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -1,5 +1,6 @@
obj-y = bitops.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \
- ptrace_user.o semaphore.o signal.o sigcontext.o syscalls.o sysrq.o
+ ptrace_user.o semaphore.o signal.o sigcontext.o syscalls.o sysrq.o \
+ sys_call_table.o
obj-$(CONFIG_HIGHMEM) += highmem.o
obj-$(CONFIG_MODULES) += module.o
diff --git a/arch/um/sys-i386/sys_call_table.S b/arch/um/sys-i386/sys_call_table.S
new file mode 100644
index 0000000..ad75c27
--- /dev/null
+++ b/arch/um/sys-i386/sys_call_table.S
@@ -0,0 +1,16 @@
+#include <linux/linkage.h>
+/* Steal i386 syscall table for our purposes, but with some slight changes.*/
+
+#define sys_iopl sys_ni_syscall
+#define sys_ioperm sys_ni_syscall
+
+#define sys_vm86old sys_ni_syscall
+#define sys_vm86 sys_ni_syscall
+#define sys_set_thread_area sys_ni_syscall
+#define sys_get_thread_area sys_ni_syscall
+
+#define sys_stime um_stime
+#define sys_time um_time
+#define old_mmap old_mmap_i386
+
+#include "../../i386/kernel/syscall_table.S"
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile
index 2129e31..d7ed2f7 100644
--- a/arch/um/sys-x86_64/Makefile
+++ b/arch/um/sys-x86_64/Makefile
@@ -6,7 +6,7 @@
lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \
ptrace.o ptrace_user.o semaphore.o sigcontext.o signal.o \
- syscalls.o sysrq.o thunk.o
+ syscalls.o sysrq.o thunk.o syscall_table.o
USER_OBJS := ptrace_user.o sigcontext.o
diff --git a/arch/um/sys-x86_64/syscall_table.c b/arch/um/sys-x86_64/syscall_table.c
new file mode 100644
index 0000000..34b2e84
--- /dev/null
+++ b/arch/um/sys-x86_64/syscall_table.c
@@ -0,0 +1,59 @@
+/* System call table for UML/x86-64, copied from arch/x86_64/kernel/syscall.c
+ * with some changes for UML. */
+
+#include <linux/linkage.h>
+#include <linux/sys.h>
+#include <linux/cache.h>
+#include <linux/config.h>
+
+#define __NO_STUBS
+
+/* Below you can see, in terms of #define's, the differences between the x86-64
+ * and the UML syscall table. */
+
+/* Not going to be implemented by UML, since we have no hardware. */
+#define stub_iopl sys_ni_syscall
+#define sys_ioperm sys_ni_syscall
+
+/* The UML TLS problem. Note that x86_64 does not implement this, so the below
+ * is needed only for the ia32 compatibility. */
+/*#define sys_set_thread_area sys_ni_syscall
+#define sys_get_thread_area sys_ni_syscall*/
+
+/* For __NR_time. The x86-64 name hopefully will change from sys_time64 to
+ * sys_time (since the current situation is bogus). I've sent a patch to cleanup
+ * this. Remove below the obsoleted line. */
+#define sys_time64 um_time
+#define sys_time um_time
+
+/* On UML we call it this way ("old" means it's not mmap2) */
+#define sys_mmap old_mmap
+/* On x86-64 sys_uname is actually sys_newuname plus a compatibility trick.
+ * See arch/x86_64/kernel/sys_x86_64.c */
+#define sys_uname sys_uname64
+
+#define stub_clone sys_clone
+#define stub_fork sys_fork
+#define stub_vfork sys_vfork
+#define stub_execve sys_execve
+#define stub_rt_sigsuspend sys_rt_sigsuspend
+#define stub_sigaltstack sys_sigaltstack
+#define stub_rt_sigreturn sys_rt_sigreturn
+
+#define __SYSCALL(nr, sym) extern asmlinkage void sym(void) ;
+#undef _ASM_X86_64_UNISTD_H_
+#include <asm-x86_64/unistd.h>
+
+#undef __SYSCALL
+#define __SYSCALL(nr, sym) [ nr ] = sym,
+#undef _ASM_X86_64_UNISTD_H_
+
+typedef void (*sys_call_ptr_t)(void);
+
+extern void sys_ni_syscall(void);
+
+sys_call_ptr_t sys_call_table[__NR_syscall_max+1] __cacheline_aligned = {
+ /* Smells like a like a compiler bug -- it doesn't work when the & below is removed. */
+ [0 ... __NR_syscall_max] = &sys_ni_syscall,
+#include <asm-x86_64/unistd.h>
+};
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c
index 68205a0..ab4b0ab 100644
--- a/arch/um/sys-x86_64/syscalls.c
+++ b/arch/um/sys-x86_64/syscalls.c
@@ -14,11 +14,15 @@
#include "asm/prctl.h" /* XXX This should get the constants from libc */
#include "choose-mode.h"
-asmlinkage long wrap_sys_shmat(int shmid, char __user *shmaddr, int shmflg)
+asmlinkage long sys_uname64(struct new_utsname __user * name)
{
- unsigned long raddr;
-
- return do_shmat(shmid, shmaddr, shmflg, &raddr) ?: (long) raddr;
+ int err;
+ down_read(&uts_sem);
+ err = copy_to_user(name, &system_utsname, sizeof (*name));
+ up_read(&uts_sem);
+ if (personality(current->personality) == PER_LINUX32)
+ err |= copy_to_user(&name->machine, "i686", 5);
+ return err ? -EFAULT : 0;
}
#ifdef CONFIG_MODE_TT
diff --git a/arch/v850/kernel/ptrace.c b/arch/v850/kernel/ptrace.c
index 8fa7807..4726b87 100644
--- a/arch/v850/kernel/ptrace.c
+++ b/arch/v850/kernel/ptrace.c
@@ -23,6 +23,7 @@
#include <linux/sched.h>
#include <linux/smp_lock.h>
#include <linux/ptrace.h>
+#include <linux/signal.h>
#include <asm/errno.h>
#include <asm/ptrace.h>
@@ -208,7 +209,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
/* Execute a single instruction. */
case PTRACE_SINGLESTEP:
rval = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
/* Turn CHILD's single-step flag on or off. */
diff --git a/arch/x86_64/boot/setup.S b/arch/x86_64/boot/setup.S
index 3e838be..75d4d2a 100644
--- a/arch/x86_64/boot/setup.S
+++ b/arch/x86_64/boot/setup.S
@@ -160,7 +160,7 @@ ramdisk_max: .long 0xffffffff
trampoline: call start_of_setup
.align 16
# The offset at this point is 0x240
- .space (0x7ff-0x240+1) # E820 & EDD space (ending at 0x7ff)
+ .space (0xeff-0x240+1) # E820 & EDD space (ending at 0xeff)
# End of setup header #####################################################
start_of_setup:
@@ -412,9 +412,9 @@ jmpe820:
# sizeof(e820rec).
#
good820:
- movb (E820NR), %al # up to 32 entries
+ movb (E820NR), %al # up to 128 entries
cmpb $E820MAX, %al
- jnl bail820
+ jae bail820
incb (E820NR)
movw %di, %ax
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c
index 56516ac..7c154df 100644
--- a/arch/x86_64/kernel/e820.c
+++ b/arch/x86_64/kernel/e820.c
@@ -2,6 +2,12 @@
* Handle the memory map.
* The functions here do the job until bootmem takes over.
* $Id: e820.c,v 1.4 2002/09/19 19:25:32 ak Exp $
+ *
+ * Getting sanitize_e820_map() in sync with i386 version by applying change:
+ * - Provisions for empty E820 memory regions (reported by certain BIOSes).
+ * Alex Achenbach <xela@slit.de>, December 2002.
+ * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ *
*/
#include <linux/config.h>
#include <linux/kernel.h>
@@ -277,7 +283,7 @@ static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
int chgidx, still_changing;
int overlap_entries;
int new_bios_entry;
- int old_nr, new_nr;
+ int old_nr, new_nr, chg_nr;
int i;
/*
@@ -331,20 +337,24 @@ static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
for (i=0; i < 2*old_nr; i++)
change_point[i] = &change_point_list[i];
- /* record all known change-points (starting and ending addresses) */
+ /* record all known change-points (starting and ending addresses),
+ omitting those that are for empty memory regions */
chgidx = 0;
for (i=0; i < old_nr; i++) {
- change_point[chgidx]->addr = biosmap[i].addr;
- change_point[chgidx++]->pbios = &biosmap[i];
- change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size;
- change_point[chgidx++]->pbios = &biosmap[i];
+ if (biosmap[i].size != 0) {
+ change_point[chgidx]->addr = biosmap[i].addr;
+ change_point[chgidx++]->pbios = &biosmap[i];
+ change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size;
+ change_point[chgidx++]->pbios = &biosmap[i];
+ }
}
+ chg_nr = chgidx;
/* sort change-point list by memory addresses (low -> high) */
still_changing = 1;
while (still_changing) {
still_changing = 0;
- for (i=1; i < 2*old_nr; i++) {
+ for (i=1; i < chg_nr; i++) {
/* if <current_addr> > <last_addr>, swap */
/* or, if current=<start_addr> & last=<end_addr>, swap */
if ((change_point[i]->addr < change_point[i-1]->addr) ||
@@ -367,7 +377,7 @@ static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
last_type = 0; /* start with undefined memory type */
last_addr = 0; /* start with 0 as last starting address */
/* loop through change-points, determining affect on the new bios map */
- for (chgidx=0; chgidx < 2*old_nr; chgidx++)
+ for (chgidx=0; chgidx < chg_nr; chgidx++)
{
/* keep track of all overlapping bios entries */
if (change_point[chgidx]->addr == change_point[chgidx]->pbios->addr)
diff --git a/arch/x86_64/kernel/early_printk.c b/arch/x86_64/kernel/early_printk.c
index 750bcd0..e3a19e8 100644
--- a/arch/x86_64/kernel/early_printk.c
+++ b/arch/x86_64/kernel/early_printk.c
@@ -60,7 +60,7 @@ static struct console early_vga_console = {
/* Serial functions loosely based on a similar package from Klaus P. Gerlicher */
-int early_serial_base = 0x3f8; /* ttyS0 */
+static int early_serial_base = 0x3f8; /* ttyS0 */
#define XMTRDY 0x20
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S
index 3233a15..1086b5f 100644
--- a/arch/x86_64/kernel/entry.S
+++ b/arch/x86_64/kernel/entry.S
@@ -296,6 +296,7 @@ int_very_careful:
call syscall_trace_leave
popq %rdi
andl $~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edi
+ cli
jmp int_restore_rest
int_signal:
@@ -307,6 +308,7 @@ int_signal:
1: movl $_TIF_NEED_RESCHED,%edi
int_restore_rest:
RESTORE_REST
+ cli
jmp int_with_check
CFI_ENDPROC
@@ -490,7 +492,8 @@ retint_signal:
call do_notify_resume
RESTORE_REST
cli
- GET_THREAD_INFO(%rcx)
+ GET_THREAD_INFO(%rcx)
+ movl $_TIF_WORK_MASK,%edi
jmp retint_check
#ifdef CONFIG_PREEMPT
diff --git a/arch/x86_64/kernel/head64.c b/arch/x86_64/kernel/head64.c
index 6cad46c..0f8c78d 100644
--- a/arch/x86_64/kernel/head64.c
+++ b/arch/x86_64/kernel/head64.c
@@ -29,8 +29,6 @@ static void __init clear_bss(void)
(unsigned long) __bss_end - (unsigned long) __bss_start);
}
-extern char x86_boot_params[2048];
-
#define NEW_CL_POINTER 0x228 /* Relative to real mode data */
#define OLD_CL_MAGIC_ADDR 0x90020
#define OLD_CL_MAGIC 0xA33F
@@ -44,7 +42,7 @@ static void __init copy_bootdata(char *real_mode_data)
int new_data;
char * command_line;
- memcpy(x86_boot_params, real_mode_data, 2048);
+ memcpy(x86_boot_params, real_mode_data, BOOT_PARAM_SIZE);
new_data = *(int *) (x86_boot_params + NEW_CL_POINTER);
if (!new_data) {
if (OLD_CL_MAGIC != * (u16 *) OLD_CL_MAGIC_ADDR) {
@@ -93,9 +91,6 @@ void __init x86_64_start_kernel(char * real_mode_data)
#ifdef CONFIG_SMP
cpu_set(0, cpu_online_map);
#endif
- /* default console: */
- if (!strstr(saved_command_line, "console="))
- strcat(saved_command_line, " console=tty0");
s = strstr(saved_command_line, "earlyprintk=");
if (s != NULL)
setup_early_printk(s);
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index 29a2572..60be586 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -1607,7 +1607,6 @@ static inline void check_timer(void)
disable_8259A_irq(0);
setup_nmi();
enable_8259A_irq(0);
- check_nmi_watchdog();
}
return;
}
@@ -1627,7 +1626,6 @@ static inline void check_timer(void)
nmi_watchdog_default();
if (nmi_watchdog == NMI_IO_APIC) {
setup_nmi();
- check_nmi_watchdog();
}
return;
}
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
index e00d4ad..61de0b3 100644
--- a/arch/x86_64/kernel/nmi.c
+++ b/arch/x86_64/kernel/nmi.c
@@ -112,17 +112,20 @@ static __init int cpu_has_lapic(void)
}
}
-int __init check_nmi_watchdog (void)
+static int __init check_nmi_watchdog (void)
{
int counts[NR_CPUS];
int cpu;
+ if (nmi_watchdog == NMI_NONE)
+ return 0;
+
if (nmi_watchdog == NMI_LOCAL_APIC && !cpu_has_lapic()) {
nmi_watchdog = NMI_NONE;
return -1;
}
- printk(KERN_INFO "testing NMI watchdog ... ");
+ printk(KERN_INFO "Testing NMI watchdog ... ");
for (cpu = 0; cpu < NR_CPUS; cpu++)
counts[cpu] = cpu_pda[cpu].__nmi_count;
@@ -148,6 +151,8 @@ int __init check_nmi_watchdog (void)
return 0;
}
+/* Have this called later during boot so counters are updating */
+late_initcall(check_nmi_watchdog);
int __init setup_nmi_watchdog(char *str)
{
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 9922d2b..761b6d3 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -402,10 +402,10 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp,
p->thread.fs = me->thread.fs;
p->thread.gs = me->thread.gs;
- asm("movl %%gs,%0" : "=m" (p->thread.gsindex));
- asm("movl %%fs,%0" : "=m" (p->thread.fsindex));
- asm("movl %%es,%0" : "=m" (p->thread.es));
- asm("movl %%ds,%0" : "=m" (p->thread.ds));
+ asm("mov %%gs,%0" : "=m" (p->thread.gsindex));
+ asm("mov %%fs,%0" : "=m" (p->thread.fsindex));
+ asm("mov %%es,%0" : "=m" (p->thread.es));
+ asm("mov %%ds,%0" : "=m" (p->thread.ds));
if (unlikely(me->thread.io_bitmap_ptr != NULL)) {
p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
@@ -468,11 +468,11 @@ struct task_struct *__switch_to(struct task_struct *prev_p, struct task_struct *
* Switch DS and ES.
* This won't pick up thread selector changes, but I guess that is ok.
*/
- asm volatile("movl %%es,%0" : "=m" (prev->es));
+ asm volatile("mov %%es,%0" : "=m" (prev->es));
if (unlikely(next->es | prev->es))
loadsegment(es, next->es);
- asm volatile ("movl %%ds,%0" : "=m" (prev->ds));
+ asm volatile ("mov %%ds,%0" : "=m" (prev->ds));
if (unlikely(next->ds | prev->ds))
loadsegment(ds, next->ds);
diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c
index ecbccbb..19eba9a 100644
--- a/arch/x86_64/kernel/ptrace.c
+++ b/arch/x86_64/kernel/ptrace.c
@@ -18,6 +18,7 @@
#include <linux/security.h>
#include <linux/audit.h>
#include <linux/seccomp.h>
+#include <linux/signal.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
@@ -467,7 +468,7 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data
case PTRACE_CONT: /* restart after signal. */
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
if (request == PTRACE_SYSCALL)
set_tsk_thread_flag(child,TIF_SYSCALL_TRACE);
@@ -529,7 +530,7 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data
case PTRACE_SINGLESTEP: /* set the trap flag. */
ret = -EIO;
- if ((unsigned long) data > _NSIG)
+ if (!valid_signal(data))
break;
clear_tsk_thread_flag(child,TIF_SYSCALL_TRACE);
set_singlestep(child);
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index b18c114..2129cf9 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -977,7 +977,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
if ((xlvl & 0xffff0000) == 0x80000000) {
if (xlvl >= 0x80000001) {
c->x86_capability[1] = cpuid_edx(0x80000001);
- c->x86_capability[5] = cpuid_ecx(0x80000001);
+ c->x86_capability[6] = cpuid_ecx(0x80000001);
}
if (xlvl >= 0x80000004)
get_model_name(c); /* Default name */
@@ -1076,7 +1076,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
"fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", NULL,
/* AMD-defined */
- "pni", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, "nx", NULL, "mmxext", NULL,
NULL, "fxsr_opt", NULL, NULL, NULL, "lm", "3dnowext", "3dnow",
@@ -1100,11 +1100,17 @@ static int show_cpuinfo(struct seq_file *m, void *v)
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ /* VIA/Cyrix/Centaur-defined */
+ NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en",
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
/* AMD-defined (#2) */
"lahf_lm", "cmp_legacy", NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
};
static char *x86_power_flags[] = {
"ts", /* temperature sensor */
diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c
index b5305b0..678b7ac 100644
--- a/arch/x86_64/kernel/setup64.c
+++ b/arch/x86_64/kernel/setup64.c
@@ -12,6 +12,7 @@
#include <linux/string.h>
#include <linux/bootmem.h>
#include <linux/bitops.h>
+#include <asm/bootsetup.h>
#include <asm/pda.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
@@ -26,7 +27,7 @@
#include <asm/mman.h>
#include <asm/numa.h>
-char x86_boot_params[2048] __initdata = {0,};
+char x86_boot_params[BOOT_PARAM_SIZE] __initdata = {0,};
cpumask_t cpu_initialized __initdata = CPU_MASK_NONE;
diff --git a/arch/x86_64/kernel/sys_x86_64.c b/arch/x86_64/kernel/sys_x86_64.c
index 477d8be..dbebd5c 100644
--- a/arch/x86_64/kernel/sys_x86_64.c
+++ b/arch/x86_64/kernel/sys_x86_64.c
@@ -152,12 +152,6 @@ asmlinkage long sys_uname(struct new_utsname __user * name)
return err ? -EFAULT : 0;
}
-asmlinkage long wrap_sys_shmat(int shmid, char __user *shmaddr, int shmflg)
-{
- unsigned long raddr;
- return do_shmat(shmid,shmaddr,shmflg,&raddr) ?: (long)raddr;
-}
-
asmlinkage long sys_time64(long __user * tloc)
{
struct timeval now;