aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@shinybook.infradead.org>2005-05-03 03:14:09 -0400
committerDavid Woodhouse <dwmw2@shinybook.infradead.org>2005-05-03 03:14:09 -0400
commit27b030d58c8e72fc7a95187a791bd9406e350f02 (patch)
treeab3bab7f39a5ce5bab65578a7e08fa4dfdeb198c /arch
parent79d20b14a0d651f15b0ef9a22b6cf12d284a6d38 (diff)
parent6628465e33ca694bd8fd5c3cf4eb7ff9177bc694 (diff)
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 b5d0fd2bb10a..64e450dddb49 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)
457 return 0; 457 return 0;
458} 458}
459 459
460asmlinkage long
461osf_shmat(int shmid, void __user *shmaddr, int shmflg)
462{
463 unsigned long raddr;
464 long err;
465
466 err = do_shmat(shmid, shmaddr, shmflg, &raddr);
467
468 /*
469 * This works because all user-level addresses are
470 * non-negative longs!
471 */
472 return err ? err : (long)raddr;
473}
474
475
476/* 460/*
477 * The following stuff should move into a header file should it ever 461 * The following stuff should move into a header file should it ever
478 * be labeled "officially supported." Right now, there is just enough 462 * 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 d00583161574..bbd37536d14e 100644
--- a/arch/alpha/kernel/ptrace.c
+++ b/arch/alpha/kernel/ptrace.c
@@ -14,6 +14,7 @@
14#include <linux/user.h> 14#include <linux/user.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/security.h> 16#include <linux/security.h>
17#include <linux/signal.h>
17 18
18#include <asm/uaccess.h> 19#include <asm/uaccess.h>
19#include <asm/pgtable.h> 20#include <asm/pgtable.h>
@@ -335,7 +336,7 @@ do_sys_ptrace(long request, long pid, long addr, long data,
335 /* continue and stop at next (return from) syscall */ 336 /* continue and stop at next (return from) syscall */
336 case PTRACE_CONT: /* restart after signal. */ 337 case PTRACE_CONT: /* restart after signal. */
337 ret = -EIO; 338 ret = -EIO;
338 if ((unsigned long) data > _NSIG) 339 if (!valid_signal(data))
339 break; 340 break;
340 if (request == PTRACE_SYSCALL) 341 if (request == PTRACE_SYSCALL)
341 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 342 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -365,7 +366,7 @@ do_sys_ptrace(long request, long pid, long addr, long data,
365 366
366 case PTRACE_SINGLESTEP: /* execute single instruction. */ 367 case PTRACE_SINGLESTEP: /* execute single instruction. */
367 ret = -EIO; 368 ret = -EIO;
368 if ((unsigned long) data > _NSIG) 369 if (!valid_signal(data))
369 break; 370 break;
370 /* Mark single stepping. */ 371 /* Mark single stepping. */
371 child->thread_info->bpt_nsaved = -1; 372 child->thread_info->bpt_nsaved = -1;
diff --git a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S
index 3864b33562ee..052120882876 100644
--- a/arch/alpha/kernel/systbls.S
+++ b/arch/alpha/kernel/systbls.S
@@ -227,7 +227,7 @@ sys_call_table:
227 .quad sys_semop 227 .quad sys_semop
228 .quad osf_utsname 228 .quad osf_utsname
229 .quad sys_lchown 229 .quad sys_lchown
230 .quad osf_shmat 230 .quad sys_shmat
231 .quad sys_shmctl /* 210 */ 231 .quad sys_shmctl /* 210 */
232 .quad sys_shmdt 232 .quad sys_shmdt
233 .quad sys_shmget 233 .quad sys_shmget
diff --git a/arch/arm/common/rtctime.c b/arch/arm/common/rtctime.c
index c397e71f938d..72b03f201eb9 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
141 next->tm_sec = alrm->tm_sec; 141 next->tm_sec = alrm->tm_sec;
142} 142}
143 143
144static inline void rtc_read_time(struct rtc_ops *ops, struct rtc_time *tm) 144static inline int rtc_read_time(struct rtc_ops *ops, struct rtc_time *tm)
145{ 145{
146 memset(tm, 0, sizeof(struct rtc_time)); 146 memset(tm, 0, sizeof(struct rtc_time));
147 ops->read_time(tm); 147 return ops->read_time(tm);
148} 148}
149 149
150static inline int rtc_set_time(struct rtc_ops *ops, struct rtc_time *tm) 150static 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)
163 int ret = -EINVAL; 163 int ret = -EINVAL;
164 if (ops->read_alarm) { 164 if (ops->read_alarm) {
165 memset(alrm, 0, sizeof(struct rtc_wkalrm)); 165 memset(alrm, 0, sizeof(struct rtc_wkalrm));
166 ops->read_alarm(alrm); 166 ret = ops->read_alarm(alrm);
167 ret = 0;
168 } 167 }
169 return ret; 168 return ret;
170} 169}
@@ -283,7 +282,9 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
283 break; 282 break;
284 283
285 case RTC_RD_TIME: 284 case RTC_RD_TIME:
286 rtc_read_time(ops, &tm); 285 ret = rtc_read_time(ops, &tm);
286 if (ret)
287 break;
287 ret = copy_to_user(uarg, &tm, sizeof(tm)); 288 ret = copy_to_user(uarg, &tm, sizeof(tm));
288 if (ret) 289 if (ret)
289 ret = -EFAULT; 290 ret = -EFAULT;
@@ -424,15 +425,15 @@ static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eo
424 struct rtc_time tm; 425 struct rtc_time tm;
425 char *p = page; 426 char *p = page;
426 427
427 rtc_read_time(ops, &tm); 428 if (rtc_read_time(ops, &tm) == 0) {
428 429 p += sprintf(p,
429 p += sprintf(p, 430 "rtc_time\t: %02d:%02d:%02d\n"
430 "rtc_time\t: %02d:%02d:%02d\n" 431 "rtc_date\t: %04d-%02d-%02d\n"
431 "rtc_date\t: %04d-%02d-%02d\n" 432 "rtc_epoch\t: %04lu\n",
432 "rtc_epoch\t: %04lu\n", 433 tm.tm_hour, tm.tm_min, tm.tm_sec,
433 tm.tm_hour, tm.tm_min, tm.tm_sec, 434 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
434 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 435 rtc_epoch);
435 rtc_epoch); 436 }
436 437
437 if (rtc_read_alarm(ops, &alrm) == 0) { 438 if (rtc_read_alarm(ops, &alrm) == 0) {
438 p += sprintf(p, "alrm_time\t: "); 439 p += sprintf(p, "alrm_time\t: ");
diff --git a/arch/arm/configs/ixdp2800_defconfig b/arch/arm/configs/ixdp2800_defconfig
index d36f99192962..7be3521f91fc 100644
--- a/arch/arm/configs/ixdp2800_defconfig
+++ b/arch/arm/configs/ixdp2800_defconfig
@@ -133,7 +133,7 @@ CONFIG_ALIGNMENT_TRAP=y
133# 133#
134CONFIG_ZBOOT_ROM_TEXT=0x0 134CONFIG_ZBOOT_ROM_TEXT=0x0
135CONFIG_ZBOOT_ROM_BSS=0x0 135CONFIG_ZBOOT_ROM_BSS=0x0
136CONFIG_CMDLINE="console=ttyS0,9600 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware" 136CONFIG_CMDLINE="console=ttyS0,9600 root=/dev/nfs ip=bootp mem=64M@0x0"
137# CONFIG_XIP_KERNEL is not set 137# CONFIG_XIP_KERNEL is not set
138 138
139# 139#
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 2a5c3fe09a95..080df907f242 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -269,6 +269,12 @@ __pabt_svc:
269 add r5, sp, #S_PC 269 add r5, sp, #S_PC
270 ldmia r7, {r2 - r4} @ Get USR pc, cpsr 270 ldmia r7, {r2 - r4} @ Get USR pc, cpsr
271 271
272#if __LINUX_ARM_ARCH__ < 6
273 @ make sure our user space atomic helper is aborted
274 cmp r2, #VIRT_OFFSET
275 bichs r3, r3, #PSR_Z_BIT
276#endif
277
272 @ 278 @
273 @ We are now ready to fill in the remaining blanks on the stack: 279 @ We are now ready to fill in the remaining blanks on the stack:
274 @ 280 @
@@ -499,8 +505,12 @@ ENTRY(__switch_to)
499 mra r4, r5, acc0 505 mra r4, r5, acc0
500 stmia ip, {r4, r5} 506 stmia ip, {r4, r5}
501#endif 507#endif
508#ifdef CONFIG_HAS_TLS_REG
509 mcr p15, 0, r3, c13, c0, 3 @ set TLS register
510#else
502 mov r4, #0xffff0fff 511 mov r4, #0xffff0fff
503 str r3, [r4, #-3] @ Set TLS ptr 512 str r3, [r4, #-15] @ TLS val at 0xffff0ff0
513#endif
504 mcr p15, 0, r6, c3, c0, 0 @ Set domain register 514 mcr p15, 0, r6, c3, c0, 0 @ Set domain register
505#ifdef CONFIG_VFP 515#ifdef CONFIG_VFP
506 @ Always disable VFP so we can lazily save/restore the old 516 @ Always disable VFP so we can lazily save/restore the old
@@ -519,6 +529,207 @@ ENTRY(__switch_to)
519 ldmib r2, {r4 - sl, fp, sp, pc} @ Load all regs saved previously 529 ldmib r2, {r4 - sl, fp, sp, pc} @ Load all regs saved previously
520 530
521 __INIT 531 __INIT
532
533/*
534 * User helpers.
535 *
536 * These are segment of kernel provided user code reachable from user space
537 * at a fixed address in kernel memory. This is used to provide user space
538 * with some operations which require kernel help because of unimplemented
539 * native feature and/or instructions in many ARM CPUs. The idea is for
540 * this code to be executed directly in user mode for best efficiency but
541 * which is too intimate with the kernel counter part to be left to user
542 * libraries. In fact this code might even differ from one CPU to another
543 * depending on the available instruction set and restrictions like on
544 * SMP systems. In other words, the kernel reserves the right to change
545 * this code as needed without warning. Only the entry points and their
546 * results are guaranteed to be stable.
547 *
548 * Each segment is 32-byte aligned and will be moved to the top of the high
549 * vector page. New segments (if ever needed) must be added in front of
550 * existing ones. This mechanism should be used only for things that are
551 * really small and justified, and not be abused freely.
552 *
553 * User space is expected to implement those things inline when optimizing
554 * for a processor that has the necessary native support, but only if such
555 * resulting binaries are already to be incompatible with earlier ARM
556 * processors due to the use of unsupported instructions other than what
557 * is provided here. In other words don't make binaries unable to run on
558 * earlier processors just for the sake of not using these kernel helpers
559 * if your compiled code is not going to use the new instructions for other
560 * purpose.
561 */
562
563 .align 5
564 .globl __kuser_helper_start
565__kuser_helper_start:
566
567/*
568 * Reference prototype:
569 *
570 * int __kernel_cmpxchg(int oldval, int newval, int *ptr)
571 *
572 * Input:
573 *
574 * r0 = oldval
575 * r1 = newval
576 * r2 = ptr
577 * lr = return address
578 *
579 * Output:
580 *
581 * r0 = returned value (zero or non-zero)
582 * C flag = set if r0 == 0, clear if r0 != 0
583 *
584 * Clobbered:
585 *
586 * r3, ip, flags
587 *
588 * Definition and user space usage example:
589 *
590 * typedef int (__kernel_cmpxchg_t)(int oldval, int newval, int *ptr);
591 * #define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0)
592 *
593 * Atomically store newval in *ptr if *ptr is equal to oldval for user space.
594 * Return zero if *ptr was changed or non-zero if no exchange happened.
595 * The C flag is also set if *ptr was changed to allow for assembly
596 * optimization in the calling code.
597 *
598 * For example, a user space atomic_add implementation could look like this:
599 *
600 * #define atomic_add(ptr, val) \
601 * ({ register unsigned int *__ptr asm("r2") = (ptr); \
602 * register unsigned int __result asm("r1"); \
603 * asm volatile ( \
604 * "1: @ atomic_add\n\t" \
605 * "ldr r0, [r2]\n\t" \
606 * "mov r3, #0xffff0fff\n\t" \
607 * "add lr, pc, #4\n\t" \
608 * "add r1, r0, %2\n\t" \
609 * "add pc, r3, #(0xffff0fc0 - 0xffff0fff)\n\t" \
610 * "bcc 1b" \
611 * : "=&r" (__result) \
612 * : "r" (__ptr), "rIL" (val) \
613 * : "r0","r3","ip","lr","cc","memory" ); \
614 * __result; })
615 */
616
617__kuser_cmpxchg: @ 0xffff0fc0
618
619#if __LINUX_ARM_ARCH__ < 6
620
621#ifdef CONFIG_SMP /* sanity check */
622#error "CONFIG_SMP on a machine supporting pre-ARMv6 processors?"
623#endif
624
625 /*
626 * Theory of operation:
627 *
628 * We set the Z flag before loading oldval. If ever an exception
629 * occurs we can not be sure the loaded value will still be the same
630 * when the exception returns, therefore the user exception handler
631 * will clear the Z flag whenever the interrupted user code was
632 * actually from the kernel address space (see the usr_entry macro).
633 *
634 * The post-increment on the str is used to prevent a race with an
635 * exception happening just after the str instruction which would
636 * clear the Z flag although the exchange was done.
637 */
638 teq ip, ip @ set Z flag
639 ldr ip, [r2] @ load current val
640 add r3, r2, #1 @ prepare store ptr
641 teqeq ip, r0 @ compare with oldval if still allowed
642 streq r1, [r3, #-1]! @ store newval if still allowed
643 subs r0, r2, r3 @ if r2 == r3 the str occured
644 mov pc, lr
645
646#else
647
648 ldrex r3, [r2]
649 subs r3, r3, r0
650 strexeq r3, r1, [r2]
651 rsbs r0, r3, #0
652 mov pc, lr
653
654#endif
655
656 .align 5
657
658/*
659 * Reference prototype:
660 *
661 * int __kernel_get_tls(void)
662 *
663 * Input:
664 *
665 * lr = return address
666 *
667 * Output:
668 *
669 * r0 = TLS value
670 *
671 * Clobbered:
672 *
673 * the Z flag might be lost
674 *
675 * Definition and user space usage example:
676 *
677 * typedef int (__kernel_get_tls_t)(void);
678 * #define __kernel_get_tls (*(__kernel_get_tls_t *)0xffff0fe0)
679 *
680 * Get the TLS value as previously set via the __ARM_NR_set_tls syscall.
681 *
682 * This could be used as follows:
683 *
684 * #define __kernel_get_tls() \
685 * ({ register unsigned int __val asm("r0"); \
686 * asm( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #31" \
687 * : "=r" (__val) : : "lr","cc" ); \
688 * __val; })
689 */
690
691__kuser_get_tls: @ 0xffff0fe0
692
693#ifndef CONFIG_HAS_TLS_REG
694
695#ifdef CONFIG_SMP /* sanity check */
696#error "CONFIG_SMP without CONFIG_HAS_TLS_REG is wrong"
697#endif
698
699 ldr r0, [pc, #(16 - 8)] @ TLS stored at 0xffff0ff0
700 mov pc, lr
701
702#else
703
704 mrc p15, 0, r0, c13, c0, 3 @ read TLS register
705 mov pc, lr
706
707#endif
708
709 .rep 5
710 .word 0 @ pad up to __kuser_helper_version
711 .endr
712
713/*
714 * Reference declaration:
715 *
716 * extern unsigned int __kernel_helper_version;
717 *
718 * Definition and user space usage example:
719 *
720 * #define __kernel_helper_version (*(unsigned int *)0xffff0ffc)
721 *
722 * User space may read this to determine the curent number of helpers
723 * available.
724 */
725
726__kuser_helper_version: @ 0xffff0ffc
727 .word ((__kuser_helper_end - __kuser_helper_start) >> 5)
728
729 .globl __kuser_helper_end
730__kuser_helper_end:
731
732
522/* 733/*
523 * Vector stubs. 734 * Vector stubs.
524 * 735 *
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index efd7a341614b..cd99b83f14c2 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -19,6 +19,7 @@
19#include <linux/user.h> 19#include <linux/user.h>
20#include <linux/security.h> 20#include <linux/security.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/signal.h>
22 23
23#include <asm/uaccess.h> 24#include <asm/uaccess.h>
24#include <asm/pgtable.h> 25#include <asm/pgtable.h>
@@ -693,7 +694,7 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
693 case PTRACE_SYSCALL: 694 case PTRACE_SYSCALL:
694 case PTRACE_CONT: 695 case PTRACE_CONT:
695 ret = -EIO; 696 ret = -EIO;
696 if ((unsigned long) data > _NSIG) 697 if (!valid_signal(data))
697 break; 698 break;
698 if (request == PTRACE_SYSCALL) 699 if (request == PTRACE_SYSCALL)
699 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 700 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
728 */ 729 */
729 case PTRACE_SINGLESTEP: 730 case PTRACE_SINGLESTEP:
730 ret = -EIO; 731 ret = -EIO;
731 if ((unsigned long) data > _NSIG) 732 if (!valid_signal(data))
732 break; 733 break;
733 child->ptrace |= PT_SINGLESTEP; 734 child->ptrace |= PT_SINGLESTEP;
734 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 735 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 7ba6342cf93d..ef32577da304 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,
227 } 227 }
228} 228}
229 229
230asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg,
231 unsigned long __user *addr)
232{
233 unsigned long ret;
234 long err;
235
236 err = do_shmat(shmid, shmaddr, shmflg, &ret);
237 if (err == 0)
238 err = put_user(ret, addr);
239 return err;
240}
241
242/* Fork a new task - this creates a new program thread. 230/* Fork a new task - this creates a new program thread.
243 * This is called indirectly via a small wrapper 231 * This is called indirectly via a small wrapper
244 */ 232 */
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 0078aeb85737..3a001fe5540b 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)
450 450
451 case NR(set_tls): 451 case NR(set_tls):
452 thread->tp_value = regs->ARM_r0; 452 thread->tp_value = regs->ARM_r0;
453#ifdef CONFIG_HAS_TLS_REG
454 asm ("mcr p15, 0, %0, c13, c0, 3" : : "r" (regs->ARM_r0) );
455#else
453 /* 456 /*
454 * Our user accessible TLS ptr is located at 0xffff0ffc. 457 * User space must never try to access this directly.
455 * On SMP read access to this address must raise a fault 458 * Expect your app to break eventually if you do so.
456 * and be emulated from the data abort handler. 459 * The user helper at 0xffff0fe0 must be used instead.
457 * m 460 * (see entry-armv.S for details)
458 */ 461 */
459 *((unsigned long *)0xffff0ffc) = thread->tp_value; 462 *((unsigned int *)0xffff0ff0) = regs->ARM_r0;
463#endif
460 return 0; 464 return 0;
461 465
462 default: 466 default:
@@ -493,6 +497,41 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
493 return 0; 497 return 0;
494} 498}
495 499
500#if defined(CONFIG_CPU_32v6) && !defined(CONFIG_HAS_TLS_REG)
501
502/*
503 * We might be running on an ARMv6+ processor which should have the TLS
504 * register, but for some reason we can't use it and have to emulate it.
505 */
506
507static int get_tp_trap(struct pt_regs *regs, unsigned int instr)
508{
509 int reg = (instr >> 12) & 15;
510 if (reg == 15)
511 return 1;
512 regs->uregs[reg] = current_thread_info()->tp_value;
513 regs->ARM_pc += 4;
514 return 0;
515}
516
517static struct undef_hook arm_mrc_hook = {
518 .instr_mask = 0x0fff0fff,
519 .instr_val = 0x0e1d0f70,
520 .cpsr_mask = PSR_T_BIT,
521 .cpsr_val = 0,
522 .fn = get_tp_trap,
523};
524
525static int __init arm_mrc_hook_init(void)
526{
527 register_undef_hook(&arm_mrc_hook);
528 return 0;
529}
530
531late_initcall(arm_mrc_hook_init);
532
533#endif
534
496void __bad_xchg(volatile void *ptr, int size) 535void __bad_xchg(volatile void *ptr, int size)
497{ 536{
498 printk("xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n", 537 printk("xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n",
@@ -580,14 +619,17 @@ void __init trap_init(void)
580{ 619{
581 extern char __stubs_start[], __stubs_end[]; 620 extern char __stubs_start[], __stubs_end[];
582 extern char __vectors_start[], __vectors_end[]; 621 extern char __vectors_start[], __vectors_end[];
622 extern char __kuser_helper_start[], __kuser_helper_end[];
623 int kuser_sz = __kuser_helper_end - __kuser_helper_start;
583 624
584 /* 625 /*
585 * Copy the vectors and stubs (in entry-armv.S) into the 626 * Copy the vectors, stubs and kuser helpers (in entry-armv.S)
586 * vector page, mapped at 0xffff0000, and ensure these are 627 * into the vector page, mapped at 0xffff0000, and ensure these
587 * visible to the instruction stream. 628 * are visible to the instruction stream.
588 */ 629 */
589 memcpy((void *)0xffff0000, __vectors_start, __vectors_end - __vectors_start); 630 memcpy((void *)0xffff0000, __vectors_start, __vectors_end - __vectors_start);
590 memcpy((void *)0xffff0200, __stubs_start, __stubs_end - __stubs_start); 631 memcpy((void *)0xffff0200, __stubs_start, __stubs_end - __stubs_start);
632 memcpy((void *)0xffff1000 - kuser_sz, __kuser_helper_start, kuser_sz);
591 flush_icache_range(0xffff0000, 0xffff0000 + PAGE_SIZE); 633 flush_icache_range(0xffff0000, 0xffff0000 + PAGE_SIZE);
592 modify_domain(DOMAIN_USER, DOMAIN_CLIENT); 634 modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
593} 635}
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 68e15c36e336..3b948e8c2751 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 = {
420 */ 420 */
421static void cp_clcd_enable(struct clcd_fb *fb) 421static void cp_clcd_enable(struct clcd_fb *fb)
422{ 422{
423 cm_control(CM_CTRL_LCDMUXSEL_MASK, CM_CTRL_LCDMUXSEL_VGA); 423 u32 val;
424
425 if (fb->fb.var.bits_per_pixel <= 8)
426 val = CM_CTRL_LCDMUXSEL_VGA_8421BPP;
427 else if (fb->fb.var.bits_per_pixel <= 16)
428 val = CM_CTRL_LCDMUXSEL_VGA_16BPP;
429 else
430 val = 0; /* no idea for this, don't trust the docs */
431
432 cm_control(CM_CTRL_LCDMUXSEL_MASK|
433 CM_CTRL_LCDEN0|
434 CM_CTRL_LCDEN1|
435 CM_CTRL_STATIC1|
436 CM_CTRL_STATIC2|
437 CM_CTRL_STATIC|
438 CM_CTRL_n24BITEN, val);
424} 439}
425 440
426static unsigned long framesize = SZ_1M; 441static unsigned long framesize = SZ_1M;
diff --git a/arch/arm/mach-integrator/time.c b/arch/arm/mach-integrator/time.c
index 20729de2af28..1a844ca139e0 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)
40 return 1; 40 return 1;
41} 41}
42 42
43static void rtc_read_alarm(struct rtc_wkalrm *alrm) 43static int rtc_read_alarm(struct rtc_wkalrm *alrm)
44{ 44{
45 rtc_time_to_tm(readl(rtc_base + RTC_MR), &alrm->time); 45 rtc_time_to_tm(readl(rtc_base + RTC_MR), &alrm->time);
46 return 0;
46} 47}
47 48
48static int rtc_set_alarm(struct rtc_wkalrm *alrm) 49static inline int rtc_set_alarm(struct rtc_wkalrm *alrm)
49{ 50{
50 unsigned long time; 51 unsigned long time;
51 int ret; 52 int ret;
52 53
53 ret = rtc_tm_to_time(&alrm->time, &time); 54 /*
55 * At the moment, we can only deal with non-wildcarded alarm times.
56 */
57 ret = rtc_valid_tm(&alrm->time);
58 if (ret == 0)
59 ret = rtc_tm_to_time(&alrm->time, &time);
54 if (ret == 0) 60 if (ret == 0)
55 writel(time, rtc_base + RTC_MR); 61 writel(time, rtc_base + RTC_MR);
56 return ret; 62 return ret;
57} 63}
58 64
59static void rtc_read_time(struct rtc_time *tm) 65static int rtc_read_time(struct rtc_time *tm)
60{ 66{
61 rtc_time_to_tm(readl(rtc_base + RTC_DR), tm); 67 rtc_time_to_tm(readl(rtc_base + RTC_DR), tm);
68 return 0;
62} 69}
63 70
64/* 71/*
@@ -69,7 +76,7 @@ static void rtc_read_time(struct rtc_time *tm)
69 * edge of the 1Hz clock, we must write the time one second 76 * edge of the 1Hz clock, we must write the time one second
70 * in advance. 77 * in advance.
71 */ 78 */
72static int rtc_set_time(struct rtc_time *tm) 79static inline int rtc_set_time(struct rtc_time *tm)
73{ 80{
74 unsigned long time; 81 unsigned long time;
75 int ret; 82 int ret;
diff --git a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c
index c4683aaff84a..aec13c7108a9 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 = {
65/************************************************************************* 65/*************************************************************************
66 * IXDP2800 PCI 66 * IXDP2800 PCI
67 *************************************************************************/ 67 *************************************************************************/
68static void __init ixdp2800_slave_disable_pci_master(void)
69{
70 *IXP2000_PCI_CMDSTAT &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
71}
72
73static void __init ixdp2800_master_wait_for_slave(void)
74{
75 volatile u32 *addr;
76
77 printk(KERN_INFO "IXDP2800: waiting for slave NPU to configure "
78 "its BAR sizes\n");
79
80 addr = ixp2000_pci_config_addr(0, IXDP2X00_SLAVE_NPU_DEVFN,
81 PCI_BASE_ADDRESS_1);
82 do {
83 *addr = 0xffffffff;
84 cpu_relax();
85 } while (*addr != 0xfe000008);
86
87 addr = ixp2000_pci_config_addr(0, IXDP2X00_SLAVE_NPU_DEVFN,
88 PCI_BASE_ADDRESS_2);
89 do {
90 *addr = 0xffffffff;
91 cpu_relax();
92 } while (*addr != 0xc0000008);
93
94 /*
95 * Configure the slave's SDRAM BAR by hand.
96 */
97 *addr = 0x40000008;
98}
99
100static void __init ixdp2800_slave_wait_for_master_enable(void)
101{
102 printk(KERN_INFO "IXDP2800: waiting for master NPU to enable us\n");
103
104 while ((*IXP2000_PCI_CMDSTAT & PCI_COMMAND_MASTER) == 0)
105 cpu_relax();
106}
107
68void __init ixdp2800_pci_preinit(void) 108void __init ixdp2800_pci_preinit(void)
69{ 109{
70 printk("ixdp2x00_pci_preinit called\n"); 110 printk("ixdp2x00_pci_preinit called\n");
71 111
72 *IXP2000_PCI_ADDR_EXT = 0x0000e000; 112 *IXP2000_PCI_ADDR_EXT = 0x0001e000;
113
114 if (!ixdp2x00_master_npu())
115 ixdp2800_slave_disable_pci_master();
73 116
74 *IXP2000_PCI_DRAM_BASE_ADDR_MASK = (0x40000000 - 1) & ~0xfffff;
75 *IXP2000_PCI_SRAM_BASE_ADDR_MASK = (0x2000000 - 1) & ~0x3ffff; 117 *IXP2000_PCI_SRAM_BASE_ADDR_MASK = (0x2000000 - 1) & ~0x3ffff;
118 *IXP2000_PCI_DRAM_BASE_ADDR_MASK = (0x40000000 - 1) & ~0xfffff;
76 119
77 ixp2000_pci_preinit(); 120 ixp2000_pci_preinit();
121
122 if (ixdp2x00_master_npu()) {
123 /*
124 * Wait until the slave set its SRAM/SDRAM BAR sizes
125 * correctly before we proceed to scan and enumerate
126 * the bus.
127 */
128 ixdp2800_master_wait_for_slave();
129
130 /*
131 * We configure the SDRAM BARs by hand because they
132 * are 1G and fall outside of the regular allocated
133 * PCI address space.
134 */
135 *IXP2000_PCI_SDRAM_BAR = 0x00000008;
136 } else {
137 /*
138 * Wait for the master to complete scanning the bus
139 * and assigning resources before we proceed to scan
140 * the bus ourselves. Set pci=firmware to honor the
141 * master's resource assignment.
142 */
143 ixdp2800_slave_wait_for_master_enable();
144 pcibios_setup("firmware");
145 }
78} 146}
79 147
80int ixdp2800_pci_setup(int nr, struct pci_sys_data *sys) 148/*
149 * We assign the SDRAM BARs for the two IXP2800 CPUs by hand, outside
150 * of the regular PCI window, because there's only 512M of outbound PCI
151 * memory window on each IXP, while we need 1G for each of the BARs.
152 */
153static void __devinit ixp2800_pci_fixup(struct pci_dev *dev)
154{
155 if (machine_is_ixdp2800()) {
156 dev->resource[2].start = 0;
157 dev->resource[2].end = 0;
158 dev->resource[2].flags = 0;
159 }
160}
161DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IXP2800, ixp2800_pci_fixup);
162
163static int __init ixdp2800_pci_setup(int nr, struct pci_sys_data *sys)
81{ 164{
82 sys->mem_offset = 0x00000000; 165 sys->mem_offset = 0x00000000;
83 166
@@ -129,22 +212,47 @@ static int __init ixdp2800_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
129 } else return IRQ_IXP2000_PCIB; /* Slave NIC interrupt */ 212 } else return IRQ_IXP2000_PCIB; /* Slave NIC interrupt */
130} 213}
131 214
132static void ixdp2800_pci_postinit(void) 215static void __init ixdp2800_master_enable_slave(void)
133{ 216{
134 struct pci_dev *dev; 217 volatile u32 *addr;
135 218
136 if (ixdp2x00_master_npu()) { 219 printk(KERN_INFO "IXDP2800: enabling slave NPU\n");
137 dev = pci_find_slot(1, IXDP2800_SLAVE_ENET_DEVFN); 220
138 pci_remove_bus_device(dev); 221 addr = (volatile u32 *)ixp2000_pci_config_addr(0,
139 } else { 222 IXDP2X00_SLAVE_NPU_DEVFN,
140 dev = pci_find_slot(1, IXDP2800_MASTER_ENET_DEVFN); 223 PCI_COMMAND);
141 pci_remove_bus_device(dev); 224
225 *addr |= PCI_COMMAND_MASTER;
226}
142 227
228static void __init ixdp2800_master_wait_for_slave_bus_scan(void)
229{
230 volatile u32 *addr;
231
232 printk(KERN_INFO "IXDP2800: waiting for slave to finish bus scan\n");
233
234 addr = (volatile u32 *)ixp2000_pci_config_addr(0,
235 IXDP2X00_SLAVE_NPU_DEVFN,
236 PCI_COMMAND);
237 while ((*addr & PCI_COMMAND_MEMORY) == 0)
238 cpu_relax();
239}
240
241static void __init ixdp2800_slave_signal_bus_scan_completion(void)
242{
243 printk(KERN_INFO "IXDP2800: bus scan done, signaling master\n");
244 *IXP2000_PCI_CMDSTAT |= PCI_COMMAND_MEMORY;
245}
246
247static void __init ixdp2800_pci_postinit(void)
248{
249 if (!ixdp2x00_master_npu()) {
143 ixdp2x00_slave_pci_postinit(); 250 ixdp2x00_slave_pci_postinit();
251 ixdp2800_slave_signal_bus_scan_completion();
144 } 252 }
145} 253}
146 254
147struct hw_pci ixdp2800_pci __initdata = { 255struct __initdata hw_pci ixdp2800_pci __initdata = {
148 .nr_controllers = 1, 256 .nr_controllers = 1,
149 .setup = ixdp2800_pci_setup, 257 .setup = ixdp2800_pci_setup,
150 .preinit = ixdp2800_pci_preinit, 258 .preinit = ixdp2800_pci_preinit,
@@ -155,8 +263,21 @@ struct hw_pci ixdp2800_pci __initdata = {
155 263
156int __init ixdp2800_pci_init(void) 264int __init ixdp2800_pci_init(void)
157{ 265{
158 if (machine_is_ixdp2800()) 266 if (machine_is_ixdp2800()) {
267 struct pci_dev *dev;
268
159 pci_common_init(&ixdp2800_pci); 269 pci_common_init(&ixdp2800_pci);
270 if (ixdp2x00_master_npu()) {
271 dev = pci_find_slot(1, IXDP2800_SLAVE_ENET_DEVFN);
272 pci_remove_bus_device(dev);
273
274 ixdp2800_master_enable_slave();
275 ixdp2800_master_wait_for_slave_bus_scan();
276 } else {
277 dev = pci_find_slot(1, IXDP2800_MASTER_ENET_DEVFN);
278 pci_remove_bus_device(dev);
279 }
280 }
160 281
161 return 0; 282 return 0;
162} 283}
diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c
index 831f8ffb6b61..5ff2f2718c58 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;
37 37
38static int clear_master_aborts(void); 38static int clear_master_aborts(void);
39 39
40static u32 * 40u32 *
41ixp2000_pci_config_addr(unsigned int bus_nr, unsigned int devfn, int where) 41ixp2000_pci_config_addr(unsigned int bus_nr, unsigned int devfn, int where)
42{ 42{
43 u32 *paddress; 43 u32 *paddress;
@@ -208,15 +208,15 @@ ixp2000_pci_preinit(void)
208 * use our own resource space. 208 * use our own resource space.
209 */ 209 */
210static struct resource ixp2000_pci_mem_space = { 210static struct resource ixp2000_pci_mem_space = {
211 .start = 0x00000000, 211 .start = 0xe0000000,
212 .end = 0xffffffff, 212 .end = 0xffffffff,
213 .flags = IORESOURCE_MEM, 213 .flags = IORESOURCE_MEM,
214 .name = "PCI Mem Space" 214 .name = "PCI Mem Space"
215}; 215};
216 216
217static struct resource ixp2000_pci_io_space = { 217static struct resource ixp2000_pci_io_space = {
218 .start = 0x00000000, 218 .start = 0x00010000,
219 .end = 0xffffffff, 219 .end = 0x0001ffff,
220 .flags = IORESOURCE_IO, 220 .flags = IORESOURCE_IO,
221 .name = "PCI I/O Space" 221 .name = "PCI I/O Space"
222}; 222};
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index b1575b8dc1cd..a45aaa115a76 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 = {
220 .id = 2, 220 .id = 2,
221}; 221};
222 222
223static struct resource i2c_resources[] = {
224 {
225 .start = 0x40301680,
226 .end = 0x403016a3,
227 .flags = IORESOURCE_MEM,
228 }, {
229 .start = IRQ_I2C,
230 .end = IRQ_I2C,
231 .flags = IORESOURCE_IRQ,
232 },
233};
234
235static struct platform_device i2c_device = {
236 .name = "pxa2xx-i2c",
237 .id = 0,
238 .resource = i2c_resources,
239 .num_resources = ARRAY_SIZE(i2c_resources),
240};
241
242void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info)
243{
244 i2c_device.dev.platform_data = info;
245}
246
223static struct platform_device *devices[] __initdata = { 247static struct platform_device *devices[] __initdata = {
224 &pxamci_device, 248 &pxamci_device,
225 &udc_device, 249 &udc_device,
@@ -227,6 +251,7 @@ static struct platform_device *devices[] __initdata = {
227 &ffuart_device, 251 &ffuart_device,
228 &btuart_device, 252 &btuart_device,
229 &stuart_device, 253 &stuart_device,
254 &i2c_device,
230}; 255};
231 256
232static int __init pxa_init(void) 257static int __init pxa_init(void)
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 5b670c9ac5ef..007766a0644c 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -409,3 +409,17 @@ config CPU_BPREDICT_DISABLE
409 depends on CPU_ARM1020 409 depends on CPU_ARM1020
410 help 410 help
411 Say Y here to disable branch prediction. If unsure, say N. 411 Say Y here to disable branch prediction. If unsure, say N.
412
413config HAS_TLS_REG
414 bool
415 depends on CPU_32v6 && !CPU_32v5 && !CPU_32v4 && !CPU_32v3
416 help
417 This selects support for the CP15 thread register.
418 It is defined to be available on ARMv6 or later. However
419 if the kernel is configured to support multiple CPUs including
420 a pre-ARMv6 processors, or if a given ARMv6 processor doesn't
421 implement the thread register for some reason, then access to
422 this register from user space must be trapped and emulated.
423 If user space is relying on the __kuser_get_tls code then
424 there should not be any impact.
425
diff --git a/arch/arm/mm/abort-ev6.S b/arch/arm/mm/abort-ev6.S
index 38b2cbb89beb..8f76f3df7b4c 100644
--- a/arch/arm/mm/abort-ev6.S
+++ b/arch/arm/mm/abort-ev6.S
@@ -1,5 +1,6 @@
1#include <linux/linkage.h> 1#include <linux/linkage.h>
2#include <asm/assembler.h> 2#include <asm/assembler.h>
3#include "abort-macro.S"
3/* 4/*
4 * Function: v6_early_abort 5 * Function: v6_early_abort
5 * 6 *
@@ -13,11 +14,26 @@
13 * : sp = pointer to registers 14 * : sp = pointer to registers
14 * 15 *
15 * Purpose : obtain information about current aborted instruction. 16 * Purpose : obtain information about current aborted instruction.
17 * Note: we read user space. This means we might cause a data
18 * abort here if the I-TLB and D-TLB aren't seeing the same
19 * picture. Unfortunately, this does happen. We live with it.
16 */ 20 */
17 .align 5 21 .align 5
18ENTRY(v6_early_abort) 22ENTRY(v6_early_abort)
19 mrc p15, 0, r1, c5, c0, 0 @ get FSR 23 mrc p15, 0, r1, c5, c0, 0 @ get FSR
20 mrc p15, 0, r0, c6, c0, 0 @ get FAR 24 mrc p15, 0, r0, c6, c0, 0 @ get FAR
25/*
26 * Faulty SWP instruction on 1136 doesn't set bit 11 in DFSR.
27 * The test below covers all the write situations, including Java bytecodes
28 */
29 bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR
30 tst r3, #PSR_J_BIT @ Java?
31 movne pc, lr
32 do_thumb_abort
33 ldreq r3, [r2] @ read aborted ARM instruction
34 do_ldrd_abort
35 tst r3, #1 << 20 @ L = 0 -> write
36 orreq r1, r1, #1 << 11 @ yes.
21 mov pc, lr 37 mov pc, lr
22 38
23 39
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index f5a87db8b498..585dfb8e20b9 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)
411 mem_types[MT_MEMORY].prot_sect &= ~PMD_BIT4; 411 mem_types[MT_MEMORY].prot_sect &= ~PMD_BIT4;
412 mem_types[MT_ROM].prot_sect &= ~PMD_BIT4; 412 mem_types[MT_ROM].prot_sect &= ~PMD_BIT4;
413 /* 413 /*
414 * Mark cache clean areas read only from SVC mode 414 * Mark cache clean areas and XIP ROM read only
415 * and no access from userspace. 415 * from SVC mode and no access from userspace.
416 */ 416 */
417 mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
417 mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; 418 mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
418 mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; 419 mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
419 } 420 }
diff --git a/arch/arm26/kernel/ptrace.c b/arch/arm26/kernel/ptrace.c
index 2a137146a77c..8a52124de0e1 100644
--- a/arch/arm26/kernel/ptrace.c
+++ b/arch/arm26/kernel/ptrace.c
@@ -18,6 +18,7 @@
18#include <linux/ptrace.h> 18#include <linux/ptrace.h>
19#include <linux/user.h> 19#include <linux/user.h>
20#include <linux/security.h> 20#include <linux/security.h>
21#include <linux/signal.h>
21 22
22#include <asm/uaccess.h> 23#include <asm/uaccess.h>
23#include <asm/pgtable.h> 24#include <asm/pgtable.h>
@@ -591,7 +592,7 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
591 case PTRACE_SYSCALL: 592 case PTRACE_SYSCALL:
592 case PTRACE_CONT: 593 case PTRACE_CONT:
593 ret = -EIO; 594 ret = -EIO;
594 if ((unsigned long) data > _NSIG) 595 if (!valid_signal(data))
595 break; 596 break;
596 if (request == PTRACE_SYSCALL) 597 if (request == PTRACE_SYSCALL)
597 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 598 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
626 */ 627 */
627 case PTRACE_SINGLESTEP: 628 case PTRACE_SINGLESTEP:
628 ret = -EIO; 629 ret = -EIO;
629 if ((unsigned long) data > _NSIG) 630 if (!valid_signal(data))
630 break; 631 break;
631 child->ptrace |= PT_SINGLESTEP; 632 child->ptrace |= PT_SINGLESTEP;
632 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 633 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 77be86cca789..30447106c25f 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)
92 page = list_entry(order->queue.next, struct page, lru); 92 page = list_entry(order->queue.next, struct page, lru);
93again: 93again:
94#ifdef PEDANTIC 94#ifdef PEDANTIC
95 if (USED_MAP(page) & ~order->all_used) 95 BUG_ON(USED_MAP(page) & ~order->all_used);
96 PAGE_BUG(page);
97#endif 96#endif
98 offset = ffz(USED_MAP(page)); 97 offset = ffz(USED_MAP(page));
99 SET_USED(page, offset); 98 SET_USED(page, offset);
@@ -141,8 +140,7 @@ static void __free_small_page(unsigned long spage, struct order *order)
141 goto non_small; 140 goto non_small;
142 141
143#ifdef PEDANTIC 142#ifdef PEDANTIC
144 if (USED_MAP(page) & ~order->all_used) 143 BUG_ON(USED_MAP(page) & ~order->all_used);
145 PAGE_BUG(page);
146#endif 144#endif
147 145
148 spage = spage >> order->shift; 146 spage = spage >> order->shift;
diff --git a/arch/cris/arch-v10/kernel/ptrace.c b/arch/cris/arch-v10/kernel/ptrace.c
index da15db8ae482..581ecabaae53 100644
--- a/arch/cris/arch-v10/kernel/ptrace.c
+++ b/arch/cris/arch-v10/kernel/ptrace.c
@@ -10,6 +10,7 @@
10#include <linux/errno.h> 10#include <linux/errno.h>
11#include <linux/ptrace.h> 11#include <linux/ptrace.h>
12#include <linux/user.h> 12#include <linux/user.h>
13#include <linux/signal.h>
13 14
14#include <asm/uaccess.h> 15#include <asm/uaccess.h>
15#include <asm/page.h> 16#include <asm/page.h>
@@ -184,7 +185,7 @@ sys_ptrace(long request, long pid, long addr, long data)
184 case PTRACE_CONT: 185 case PTRACE_CONT:
185 ret = -EIO; 186 ret = -EIO;
186 187
187 if ((unsigned long) data > _NSIG) 188 if (!valid_signal(data))
188 break; 189 break;
189 190
190 if (request == PTRACE_SYSCALL) { 191 if (request == PTRACE_SYSCALL) {
@@ -219,7 +220,7 @@ sys_ptrace(long request, long pid, long addr, long data)
219 case PTRACE_SINGLESTEP: 220 case PTRACE_SINGLESTEP:
220 ret = -EIO; 221 ret = -EIO;
221 222
222 if ((unsigned long) data > _NSIG) 223 if (!valid_signal(data))
223 break; 224 break;
224 225
225 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 226 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
diff --git a/arch/frv/kernel/ptrace.c b/arch/frv/kernel/ptrace.c
index 2a0efb739adc..cbe03cba9f02 100644
--- a/arch/frv/kernel/ptrace.c
+++ b/arch/frv/kernel/ptrace.c
@@ -20,6 +20,7 @@
20#include <linux/user.h> 20#include <linux/user.h>
21#include <linux/config.h> 21#include <linux/config.h>
22#include <linux/security.h> 22#include <linux/security.h>
23#include <linux/signal.h>
23 24
24#include <asm/uaccess.h> 25#include <asm/uaccess.h>
25#include <asm/page.h> 26#include <asm/page.h>
@@ -239,7 +240,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
239 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ 240 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
240 case PTRACE_CONT: /* restart after signal. */ 241 case PTRACE_CONT: /* restart after signal. */
241 ret = -EIO; 242 ret = -EIO;
242 if ((unsigned long) data > _NSIG) 243 if (!valid_signal(data))
243 break; 244 break;
244 if (request == PTRACE_SYSCALL) 245 if (request == PTRACE_SYSCALL)
245 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 246 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -267,7 +268,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
267 268
268 case PTRACE_SINGLESTEP: /* set the trap flag. */ 269 case PTRACE_SINGLESTEP: /* set the trap flag. */
269 ret = -EIO; 270 ret = -EIO;
270 if ((unsigned long) data > _NSIG) 271 if (!valid_signal(data))
271 break; 272 break;
272 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 273 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
273 ptrace_enable(child); 274 ptrace_enable(child);
diff --git a/arch/h8300/kernel/ptrace.c b/arch/h8300/kernel/ptrace.c
index 5f19d774a288..05c15e869777 100644
--- a/arch/h8300/kernel/ptrace.c
+++ b/arch/h8300/kernel/ptrace.c
@@ -24,6 +24,7 @@
24#include <linux/ptrace.h> 24#include <linux/ptrace.h>
25#include <linux/user.h> 25#include <linux/user.h>
26#include <linux/config.h> 26#include <linux/config.h>
27#include <linux/signal.h>
27 28
28#include <asm/uaccess.h> 29#include <asm/uaccess.h>
29#include <asm/page.h> 30#include <asm/page.h>
@@ -171,7 +172,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
171 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ 172 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
172 case PTRACE_CONT: { /* restart after signal. */ 173 case PTRACE_CONT: { /* restart after signal. */
173 ret = -EIO; 174 ret = -EIO;
174 if ((unsigned long) data >= _NSIG) 175 if (!valid_signal(data))
175 break ; 176 break ;
176 if (request == PTRACE_SYSCALL) 177 if (request == PTRACE_SYSCALL)
177 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 178 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -202,7 +203,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
202 203
203 case PTRACE_SINGLESTEP: { /* set the trap flag. */ 204 case PTRACE_SINGLESTEP: { /* set the trap flag. */
204 ret = -EIO; 205 ret = -EIO;
205 if ((unsigned long) data > _NSIG) 206 if (!valid_signal(data))
206 break; 207 break;
207 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 208 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
208 child->exit_code = data; 209 child->exit_code = data;
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index 17a0cbce6f30..99b4f294a52d 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -653,6 +653,24 @@ config I8K
653 Say Y if you intend to run this kernel on a Dell Inspiron 8000. 653 Say Y if you intend to run this kernel on a Dell Inspiron 8000.
654 Say N otherwise. 654 Say N otherwise.
655 655
656config X86_REBOOTFIXUPS
657 bool "Enable X86 board specific fixups for reboot"
658 depends on X86
659 default n
660 ---help---
661 This enables chipset and/or board specific fixups to be done
662 in order to get reboot to work correctly. This is only needed on
663 some combinations of hardware and BIOS. The symptom, for which
664 this config is intended, is when reboot ends with a stalled/hung
665 system.
666
667 Currently, the only fixup is for the Geode GX1/CS5530A/TROM2.1.
668 combination.
669
670 Say Y if you want to enable the fixup. Currently, it's safe to
671 enable this option even if you don't need it.
672 Say N otherwise.
673
656config MICROCODE 674config MICROCODE
657 tristate "/dev/cpu/microcode - Intel IA32 CPU microcode support" 675 tristate "/dev/cpu/microcode - Intel IA32 CPU microcode support"
658 ---help--- 676 ---help---
diff --git a/arch/i386/Makefile b/arch/i386/Makefile
index 314c7146e9bf..04783ceb050c 100644
--- a/arch/i386/Makefile
+++ b/arch/i386/Makefile
@@ -123,7 +123,7 @@ AFLAGS += $(mflags-y)
123boot := arch/i386/boot 123boot := arch/i386/boot
124 124
125.PHONY: zImage bzImage compressed zlilo bzlilo \ 125.PHONY: zImage bzImage compressed zlilo bzlilo \
126 zdisk bzdisk fdimage fdimage144 fdimage288 install 126 zdisk bzdisk fdimage fdimage144 fdimage288 install kernel_install
127 127
128all: bzImage 128all: bzImage
129 129
@@ -145,8 +145,9 @@ zdisk bzdisk: vmlinux
145fdimage fdimage144 fdimage288: vmlinux 145fdimage fdimage144 fdimage288: vmlinux
146 $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@ 146 $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@
147 147
148install: 148install: vmlinux
149 $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@ 149install kernel_install:
150 $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install
150 151
151prepare: include/asm-$(ARCH)/asm_offsets.h 152prepare: include/asm-$(ARCH)/asm_offsets.h
152CLEAN_FILES += include/asm-$(ARCH)/asm_offsets.h 153CLEAN_FILES += include/asm-$(ARCH)/asm_offsets.h
diff --git a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c
index fa67045234a3..cedc55cc47de 100644
--- a/arch/i386/boot/compressed/misc.c
+++ b/arch/i386/boot/compressed/misc.c
@@ -12,7 +12,6 @@
12#include <linux/linkage.h> 12#include <linux/linkage.h>
13#include <linux/vmalloc.h> 13#include <linux/vmalloc.h>
14#include <linux/tty.h> 14#include <linux/tty.h>
15#include <video/edid.h>
16#include <asm/io.h> 15#include <asm/io.h>
17 16
18/* 17/*
diff --git a/arch/i386/boot/setup.S b/arch/i386/boot/setup.S
index a934ab32bf8e..caa1fde6904e 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
164trampoline: call start_of_setup 164trampoline: call start_of_setup
165 .align 16 165 .align 16
166 # The offset at this point is 0x240 166 # The offset at this point is 0x240
167 .space (0x7ff-0x240+1) # E820 & EDD space (ending at 0x7ff) 167 .space (0xeff-0x240+1) # E820 & EDD space (ending at 0xeff)
168# End of setup header ##################################################### 168# End of setup header #####################################################
169 169
170start_of_setup: 170start_of_setup:
@@ -333,9 +333,9 @@ jmpe820:
333 # sizeof(e820rec). 333 # sizeof(e820rec).
334 # 334 #
335good820: 335good820:
336 movb (E820NR), %al # up to 32 entries 336 movb (E820NR), %al # up to 128 entries
337 cmpb $E820MAX, %al 337 cmpb $E820MAX, %al
338 jnl bail820 338 jae bail820
339 339
340 incb (E820NR) 340 incb (E820NR)
341 movw %di, %ax 341 movw %di, %ax
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
index aacdae6f372d..0fbcfe00dd8d 100644
--- a/arch/i386/kernel/Makefile
+++ b/arch/i386/kernel/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o
23obj-$(CONFIG_X86_MPPARSE) += mpparse.o 23obj-$(CONFIG_X86_MPPARSE) += mpparse.o
24obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o 24obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o
25obj-$(CONFIG_X86_IO_APIC) += io_apic.o 25obj-$(CONFIG_X86_IO_APIC) += io_apic.o
26obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups.o
26obj-$(CONFIG_X86_NUMAQ) += numaq.o 27obj-$(CONFIG_X86_NUMAQ) += numaq.o
27obj-$(CONFIG_X86_SUMMIT_NUMA) += summit.o 28obj-$(CONFIG_X86_SUMMIT_NUMA) += summit.o
28obj-$(CONFIG_KPROBES) += kprobes.o 29obj-$(CONFIG_KPROBES) += kprobes.o
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index e3879f7625c2..d509836b70c3 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -1265,8 +1265,6 @@ int __init APIC_init_uniprocessor (void)
1265 1265
1266 setup_local_APIC(); 1266 setup_local_APIC();
1267 1267
1268 if (nmi_watchdog == NMI_LOCAL_APIC)
1269 check_nmi_watchdog();
1270#ifdef CONFIG_X86_IO_APIC 1268#ifdef CONFIG_X86_IO_APIC
1271 if (smp_found_config) 1269 if (smp_found_config)
1272 if (!skip_ioapic_setup && nr_ioapics) 1270 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 9f7a7ea6388d..f468a979e9aa 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)
124 return -ENOSPC; 124 return -ENOSPC;
125} 125}
126 126
127void generic_get_mtrr(unsigned int reg, unsigned long *base, 127static void generic_get_mtrr(unsigned int reg, unsigned long *base,
128 unsigned int *size, mtrr_type * type) 128 unsigned int *size, mtrr_type * type)
129{ 129{
130 unsigned int mask_lo, mask_hi, base_lo, base_hi; 130 unsigned int mask_lo, mask_hi, base_lo, base_hi;
131 131
diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c
index 54999e4c55fd..e1c2042b9b7e 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)
72static int have_wrcomb(void) 72static int have_wrcomb(void)
73{ 73{
74 struct pci_dev *dev; 74 struct pci_dev *dev;
75 u8 rev;
75 76
76 if ((dev = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, NULL)) != NULL) { 77 if ((dev = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, NULL)) != NULL) {
77 /* ServerWorks LE chipsets have problems with write-combining 78 /* ServerWorks LE chipsets < rev 6 have problems with write-combining
78 Don't allow it and leave room for other chipsets to be tagged */ 79 Don't allow it and leave room for other chipsets to be tagged */
79 if (dev->vendor == PCI_VENDOR_ID_SERVERWORKS && 80 if (dev->vendor == PCI_VENDOR_ID_SERVERWORKS &&
80 dev->device == PCI_DEVICE_ID_SERVERWORKS_LE) { 81 dev->device == PCI_DEVICE_ID_SERVERWORKS_LE) {
81 printk(KERN_INFO "mtrr: Serverworks LE detected. Write-combining disabled.\n"); 82 pci_read_config_byte(dev, PCI_CLASS_REVISION, &rev);
82 pci_dev_put(dev); 83 if (rev <= 5) {
83 return 0; 84 printk(KERN_INFO "mtrr: Serverworks LE rev < 6 detected. Write-combining disabled.\n");
85 pci_dev_put(dev);
86 return 0;
87 }
84 } 88 }
85 /* Intel 450NX errata # 23. Non ascending cachline evictions to 89 /* Intel 450NX errata # 23. Non ascending cacheline evictions to
86 write combining memory may resulting in data corruption */ 90 write combining memory may resulting in data corruption */
87 if (dev->vendor == PCI_VENDOR_ID_INTEL && 91 if (dev->vendor == PCI_VENDOR_ID_INTEL &&
88 dev->device == PCI_DEVICE_ID_INTEL_82451NX) { 92 dev->device == PCI_DEVICE_ID_INTEL_82451NX) {
diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c
index 4f28eba7fb8a..7323c19f354e 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)
25 "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe", 25 "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe",
26 26
27 /* AMD-defined */ 27 /* AMD-defined */
28 "pni", NULL, NULL, NULL, NULL, NULL, NULL, NULL, 28 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
29 NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL, 29 NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
30 NULL, NULL, NULL, "mp", "nx", NULL, "mmxext", NULL, 30 NULL, NULL, NULL, "mp", "nx", NULL, "mmxext", NULL,
31 NULL, "fxsr_opt", NULL, NULL, NULL, "lm", "3dnowext", "3dnow", 31 NULL, "fxsr_opt", NULL, NULL, NULL, "lm", "3dnowext", "3dnow",
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index 3c73dc865ead..a991d4e5edd2 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -260,11 +260,9 @@ restore_nocheck:
260.section .fixup,"ax" 260.section .fixup,"ax"
261iret_exc: 261iret_exc:
262 sti 262 sti
263 movl $__USER_DS, %edx 263 pushl $0 # no error code
264 movl %edx, %ds 264 pushl $do_iret_error
265 movl %edx, %es 265 jmp error_code
266 movl $11,%eax
267 call do_exit
268.previous 266.previous
269.section __ex_table,"a" 267.section __ex_table,"a"
270 .align 4 268 .align 4
@@ -516,8 +514,6 @@ debug_stack_correct:
516 xorl %edx,%edx # error code 0 514 xorl %edx,%edx # error code 0
517 movl %esp,%eax # pt_regs pointer 515 movl %esp,%eax # pt_regs pointer
518 call do_debug 516 call do_debug
519 testl %eax,%eax
520 jnz restore_all
521 jmp ret_from_exception 517 jmp ret_from_exception
522 518
523/* 519/*
@@ -598,8 +594,6 @@ ENTRY(int3)
598 xorl %edx,%edx # zero error code 594 xorl %edx,%edx # zero error code
599 movl %esp,%eax # pt_regs pointer 595 movl %esp,%eax # pt_regs pointer
600 call do_int3 596 call do_int3
601 testl %eax,%eax
602 jnz restore_all
603 jmp ret_from_exception 597 jmp ret_from_exception
604 598
605ENTRY(overflow) 599ENTRY(overflow)
@@ -658,296 +652,6 @@ ENTRY(spurious_interrupt_bug)
658 pushl $do_spurious_interrupt_bug 652 pushl $do_spurious_interrupt_bug
659 jmp error_code 653 jmp error_code
660 654
661.data 655#include "syscall_table.S"
662ENTRY(sys_call_table)
663 .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
664 .long sys_exit
665 .long sys_fork
666 .long sys_read
667 .long sys_write
668 .long sys_open /* 5 */
669 .long sys_close
670 .long sys_waitpid
671 .long sys_creat
672 .long sys_link
673 .long sys_unlink /* 10 */
674 .long sys_execve
675 .long sys_chdir
676 .long sys_time
677 .long sys_mknod
678 .long sys_chmod /* 15 */
679 .long sys_lchown16
680 .long sys_ni_syscall /* old break syscall holder */
681 .long sys_stat
682 .long sys_lseek
683 .long sys_getpid /* 20 */
684 .long sys_mount
685 .long sys_oldumount
686 .long sys_setuid16
687 .long sys_getuid16
688 .long sys_stime /* 25 */
689 .long sys_ptrace
690 .long sys_alarm
691 .long sys_fstat
692 .long sys_pause
693 .long sys_utime /* 30 */
694 .long sys_ni_syscall /* old stty syscall holder */
695 .long sys_ni_syscall /* old gtty syscall holder */
696 .long sys_access
697 .long sys_nice
698 .long sys_ni_syscall /* 35 - old ftime syscall holder */
699 .long sys_sync
700 .long sys_kill
701 .long sys_rename
702 .long sys_mkdir
703 .long sys_rmdir /* 40 */
704 .long sys_dup
705 .long sys_pipe
706 .long sys_times
707 .long sys_ni_syscall /* old prof syscall holder */
708 .long sys_brk /* 45 */
709 .long sys_setgid16
710 .long sys_getgid16
711 .long sys_signal
712 .long sys_geteuid16
713 .long sys_getegid16 /* 50 */
714 .long sys_acct
715 .long sys_umount /* recycled never used phys() */
716 .long sys_ni_syscall /* old lock syscall holder */
717 .long sys_ioctl
718 .long sys_fcntl /* 55 */
719 .long sys_ni_syscall /* old mpx syscall holder */
720 .long sys_setpgid
721 .long sys_ni_syscall /* old ulimit syscall holder */
722 .long sys_olduname
723 .long sys_umask /* 60 */
724 .long sys_chroot
725 .long sys_ustat
726 .long sys_dup2
727 .long sys_getppid
728 .long sys_getpgrp /* 65 */
729 .long sys_setsid
730 .long sys_sigaction
731 .long sys_sgetmask
732 .long sys_ssetmask
733 .long sys_setreuid16 /* 70 */
734 .long sys_setregid16
735 .long sys_sigsuspend
736 .long sys_sigpending
737 .long sys_sethostname
738 .long sys_setrlimit /* 75 */
739 .long sys_old_getrlimit
740 .long sys_getrusage
741 .long sys_gettimeofday
742 .long sys_settimeofday
743 .long sys_getgroups16 /* 80 */
744 .long sys_setgroups16
745 .long old_select
746 .long sys_symlink
747 .long sys_lstat
748 .long sys_readlink /* 85 */
749 .long sys_uselib
750 .long sys_swapon
751 .long sys_reboot
752 .long old_readdir
753 .long old_mmap /* 90 */
754 .long sys_munmap
755 .long sys_truncate
756 .long sys_ftruncate
757 .long sys_fchmod
758 .long sys_fchown16 /* 95 */
759 .long sys_getpriority
760 .long sys_setpriority
761 .long sys_ni_syscall /* old profil syscall holder */
762 .long sys_statfs
763 .long sys_fstatfs /* 100 */
764 .long sys_ioperm
765 .long sys_socketcall
766 .long sys_syslog
767 .long sys_setitimer
768 .long sys_getitimer /* 105 */
769 .long sys_newstat
770 .long sys_newlstat
771 .long sys_newfstat
772 .long sys_uname
773 .long sys_iopl /* 110 */
774 .long sys_vhangup
775 .long sys_ni_syscall /* old "idle" system call */
776 .long sys_vm86old
777 .long sys_wait4
778 .long sys_swapoff /* 115 */
779 .long sys_sysinfo
780 .long sys_ipc
781 .long sys_fsync
782 .long sys_sigreturn
783 .long sys_clone /* 120 */
784 .long sys_setdomainname
785 .long sys_newuname
786 .long sys_modify_ldt
787 .long sys_adjtimex
788 .long sys_mprotect /* 125 */
789 .long sys_sigprocmask
790 .long sys_ni_syscall /* old "create_module" */
791 .long sys_init_module
792 .long sys_delete_module
793 .long sys_ni_syscall /* 130: old "get_kernel_syms" */
794 .long sys_quotactl
795 .long sys_getpgid
796 .long sys_fchdir
797 .long sys_bdflush
798 .long sys_sysfs /* 135 */
799 .long sys_personality
800 .long sys_ni_syscall /* reserved for afs_syscall */
801 .long sys_setfsuid16
802 .long sys_setfsgid16
803 .long sys_llseek /* 140 */
804 .long sys_getdents
805 .long sys_select
806 .long sys_flock
807 .long sys_msync
808 .long sys_readv /* 145 */
809 .long sys_writev
810 .long sys_getsid
811 .long sys_fdatasync
812 .long sys_sysctl
813 .long sys_mlock /* 150 */
814 .long sys_munlock
815 .long sys_mlockall
816 .long sys_munlockall
817 .long sys_sched_setparam
818 .long sys_sched_getparam /* 155 */
819 .long sys_sched_setscheduler
820 .long sys_sched_getscheduler
821 .long sys_sched_yield
822 .long sys_sched_get_priority_max
823 .long sys_sched_get_priority_min /* 160 */
824 .long sys_sched_rr_get_interval
825 .long sys_nanosleep
826 .long sys_mremap
827 .long sys_setresuid16
828 .long sys_getresuid16 /* 165 */
829 .long sys_vm86
830 .long sys_ni_syscall /* Old sys_query_module */
831 .long sys_poll
832 .long sys_nfsservctl
833 .long sys_setresgid16 /* 170 */
834 .long sys_getresgid16
835 .long sys_prctl
836 .long sys_rt_sigreturn
837 .long sys_rt_sigaction
838 .long sys_rt_sigprocmask /* 175 */
839 .long sys_rt_sigpending
840 .long sys_rt_sigtimedwait
841 .long sys_rt_sigqueueinfo
842 .long sys_rt_sigsuspend
843 .long sys_pread64 /* 180 */
844 .long sys_pwrite64
845 .long sys_chown16
846 .long sys_getcwd
847 .long sys_capget
848 .long sys_capset /* 185 */
849 .long sys_sigaltstack
850 .long sys_sendfile
851 .long sys_ni_syscall /* reserved for streams1 */
852 .long sys_ni_syscall /* reserved for streams2 */
853 .long sys_vfork /* 190 */
854 .long sys_getrlimit
855 .long sys_mmap2
856 .long sys_truncate64
857 .long sys_ftruncate64
858 .long sys_stat64 /* 195 */
859 .long sys_lstat64
860 .long sys_fstat64
861 .long sys_lchown
862 .long sys_getuid
863 .long sys_getgid /* 200 */
864 .long sys_geteuid
865 .long sys_getegid
866 .long sys_setreuid
867 .long sys_setregid
868 .long sys_getgroups /* 205 */
869 .long sys_setgroups
870 .long sys_fchown
871 .long sys_setresuid
872 .long sys_getresuid
873 .long sys_setresgid /* 210 */
874 .long sys_getresgid
875 .long sys_chown
876 .long sys_setuid
877 .long sys_setgid
878 .long sys_setfsuid /* 215 */
879 .long sys_setfsgid
880 .long sys_pivot_root
881 .long sys_mincore
882 .long sys_madvise
883 .long sys_getdents64 /* 220 */
884 .long sys_fcntl64
885 .long sys_ni_syscall /* reserved for TUX */
886 .long sys_ni_syscall
887 .long sys_gettid
888 .long sys_readahead /* 225 */
889 .long sys_setxattr
890 .long sys_lsetxattr
891 .long sys_fsetxattr
892 .long sys_getxattr
893 .long sys_lgetxattr /* 230 */
894 .long sys_fgetxattr
895 .long sys_listxattr
896 .long sys_llistxattr
897 .long sys_flistxattr
898 .long sys_removexattr /* 235 */
899 .long sys_lremovexattr
900 .long sys_fremovexattr
901 .long sys_tkill
902 .long sys_sendfile64
903 .long sys_futex /* 240 */
904 .long sys_sched_setaffinity
905 .long sys_sched_getaffinity
906 .long sys_set_thread_area
907 .long sys_get_thread_area
908 .long sys_io_setup /* 245 */
909 .long sys_io_destroy
910 .long sys_io_getevents
911 .long sys_io_submit
912 .long sys_io_cancel
913 .long sys_fadvise64 /* 250 */
914 .long sys_ni_syscall
915 .long sys_exit_group
916 .long sys_lookup_dcookie
917 .long sys_epoll_create
918 .long sys_epoll_ctl /* 255 */
919 .long sys_epoll_wait
920 .long sys_remap_file_pages
921 .long sys_set_tid_address
922 .long sys_timer_create
923 .long sys_timer_settime /* 260 */
924 .long sys_timer_gettime
925 .long sys_timer_getoverrun
926 .long sys_timer_delete
927 .long sys_clock_settime
928 .long sys_clock_gettime /* 265 */
929 .long sys_clock_getres
930 .long sys_clock_nanosleep
931 .long sys_statfs64
932 .long sys_fstatfs64
933 .long sys_tgkill /* 270 */
934 .long sys_utimes
935 .long sys_fadvise64_64
936 .long sys_ni_syscall /* sys_vserver */
937 .long sys_mbind
938 .long sys_get_mempolicy
939 .long sys_set_mempolicy
940 .long sys_mq_open
941 .long sys_mq_unlink
942 .long sys_mq_timedsend
943 .long sys_mq_timedreceive /* 280 */
944 .long sys_mq_notify
945 .long sys_mq_getsetattr
946 .long sys_ni_syscall /* reserved for kexec */
947 .long sys_waitid
948 .long sys_ni_syscall /* 285 */ /* available */
949 .long sys_add_key
950 .long sys_request_key
951 .long sys_keyctl
952 656
953syscall_table_size=(.-sys_call_table) 657syscall_table_size=(.-sys_call_table)
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S
index d273fd746192..e966fc8c44c4 100644
--- a/arch/i386/kernel/head.S
+++ b/arch/i386/kernel/head.S
@@ -380,6 +380,7 @@ rp_sidt:
380 ALIGN 380 ALIGN
381ignore_int: 381ignore_int:
382 cld 382 cld
383#ifdef CONFIG_PRINTK
383 pushl %eax 384 pushl %eax
384 pushl %ecx 385 pushl %ecx
385 pushl %edx 386 pushl %edx
@@ -400,6 +401,7 @@ ignore_int:
400 popl %edx 401 popl %edx
401 popl %ecx 402 popl %ecx
402 popl %eax 403 popl %eax
404#endif
403 iret 405 iret
404 406
405/* 407/*
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 5e0d55be5435..7a324e8b86f9 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)
2175 disable_8259A_irq(0); 2175 disable_8259A_irq(0);
2176 setup_nmi(); 2176 setup_nmi();
2177 enable_8259A_irq(0); 2177 enable_8259A_irq(0);
2178 check_nmi_watchdog();
2179 } 2178 }
2180 return; 2179 return;
2181 } 2180 }
@@ -2198,7 +2197,6 @@ static inline void check_timer(void)
2198 add_pin_to_irq(0, 0, pin2); 2197 add_pin_to_irq(0, 0, pin2);
2199 if (nmi_watchdog == NMI_IO_APIC) { 2198 if (nmi_watchdog == NMI_IO_APIC) {
2200 setup_nmi(); 2199 setup_nmi();
2201 check_nmi_watchdog();
2202 } 2200 }
2203 return; 2201 return;
2204 } 2202 }
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
index 2f89d000f954..2c0ee9c2d020 100644
--- a/arch/i386/kernel/nmi.c
+++ b/arch/i386/kernel/nmi.c
@@ -102,20 +102,21 @@ int nmi_active;
102 (P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT| \ 102 (P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT| \
103 P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE) 103 P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE)
104 104
105int __init check_nmi_watchdog (void) 105static int __init check_nmi_watchdog(void)
106{ 106{
107 unsigned int prev_nmi_count[NR_CPUS]; 107 unsigned int prev_nmi_count[NR_CPUS];
108 int cpu; 108 int cpu;
109 109
110 printk(KERN_INFO "testing NMI watchdog ... "); 110 if (nmi_watchdog == NMI_NONE)
111 return 0;
112
113 printk(KERN_INFO "Testing NMI watchdog ... ");
111 114
112 for (cpu = 0; cpu < NR_CPUS; cpu++) 115 for (cpu = 0; cpu < NR_CPUS; cpu++)
113 prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count; 116 prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count;
114 local_irq_enable(); 117 local_irq_enable();
115 mdelay((10*1000)/nmi_hz); // wait 10 ticks 118 mdelay((10*1000)/nmi_hz); // wait 10 ticks
116 119
117 /* FIXME: Only boot CPU is online at this stage. Check CPUs
118 as they come up. */
119 for (cpu = 0; cpu < NR_CPUS; cpu++) { 120 for (cpu = 0; cpu < NR_CPUS; cpu++) {
120#ifdef CONFIG_SMP 121#ifdef CONFIG_SMP
121 /* Check cpu_callin_map here because that is set 122 /* Check cpu_callin_map here because that is set
@@ -139,6 +140,8 @@ int __init check_nmi_watchdog (void)
139 140
140 return 0; 141 return 0;
141} 142}
143/* This needs to happen later in boot so counters are working */
144late_initcall(check_nmi_watchdog);
142 145
143static int __init setup_nmi_watchdog(char *str) 146static int __init setup_nmi_watchdog(char *str)
144{ 147{
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index b2203e21acb3..85bd56d44314 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
611 * Save away %fs and %gs. No need to save %es and %ds, as 611 * Save away %fs and %gs. No need to save %es and %ds, as
612 * those are always kernel segments while inside the kernel. 612 * those are always kernel segments while inside the kernel.
613 */ 613 */
614 asm volatile("movl %%fs,%0":"=m" (*(int *)&prev->fs)); 614 asm volatile("mov %%fs,%0":"=m" (prev->fs));
615 asm volatile("movl %%gs,%0":"=m" (*(int *)&prev->gs)); 615 asm volatile("mov %%gs,%0":"=m" (prev->gs));
616 616
617 /* 617 /*
618 * Restore %fs and %gs if needed. 618 * Restore %fs and %gs if needed.
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index 5606ec7a5c2b..e34f651fa13c 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -16,6 +16,7 @@
16#include <linux/security.h> 16#include <linux/security.h>
17#include <linux/audit.h> 17#include <linux/audit.h>
18#include <linux/seccomp.h> 18#include <linux/seccomp.h>
19#include <linux/signal.h>
19 20
20#include <asm/uaccess.h> 21#include <asm/uaccess.h>
21#include <asm/pgtable.h> 22#include <asm/pgtable.h>
@@ -511,7 +512,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
511 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ 512 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
512 case PTRACE_CONT: /* restart after signal. */ 513 case PTRACE_CONT: /* restart after signal. */
513 ret = -EIO; 514 ret = -EIO;
514 if ((unsigned long) data > _NSIG) 515 if (!valid_signal(data))
515 break; 516 break;
516 if (request == PTRACE_SYSCALL) { 517 if (request == PTRACE_SYSCALL) {
517 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 518 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -543,7 +544,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
543 544
544 case PTRACE_SINGLESTEP: /* set the trap flag. */ 545 case PTRACE_SINGLESTEP: /* set the trap flag. */
545 ret = -EIO; 546 ret = -EIO;
546 if ((unsigned long) data > _NSIG) 547 if (!valid_signal(data))
547 break; 548 break;
548 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 549 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
549 set_singlestep(child); 550 set_singlestep(child);
diff --git a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c
index 3d7e994563df..6dc27eb70ee7 100644
--- a/arch/i386/kernel/reboot.c
+++ b/arch/i386/kernel/reboot.c
@@ -13,6 +13,7 @@
13#include <asm/uaccess.h> 13#include <asm/uaccess.h>
14#include <asm/apic.h> 14#include <asm/apic.h>
15#include "mach_reboot.h" 15#include "mach_reboot.h"
16#include <linux/reboot_fixups.h>
16 17
17/* 18/*
18 * Power off function, if any 19 * Power off function, if any
@@ -348,6 +349,7 @@ void machine_restart(char * __unused)
348 /* rebooting needs to touch the page at absolute addr 0 */ 349 /* rebooting needs to touch the page at absolute addr 0 */
349 *((unsigned short *)__va(0x472)) = reboot_mode; 350 *((unsigned short *)__va(0x472)) = reboot_mode;
350 for (;;) { 351 for (;;) {
352 mach_reboot_fixups(); /* for board specific fixups */
351 mach_reboot(); 353 mach_reboot();
352 /* That didn't work - force a triple fault.. */ 354 /* That didn't work - force a triple fault.. */
353 __asm__ __volatile__("lidt %0": :"m" (no_idt)); 355 __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 000000000000..1b183b378c2c
--- /dev/null
+++ b/arch/i386/kernel/reboot_fixups.c
@@ -0,0 +1,56 @@
1/*
2 * linux/arch/i386/kernel/reboot_fixups.c
3 *
4 * This is a good place to put board specific reboot fixups.
5 *
6 * List of supported fixups:
7 * geode-gx1/cs5530a - Jaya Kumar <jayalk@intworks.biz>
8 *
9 */
10
11#include <asm/delay.h>
12#include <linux/pci.h>
13
14static void cs5530a_warm_reset(struct pci_dev *dev)
15{
16 /* writing 1 to the reset control register, 0x44 causes the
17 cs5530a to perform a system warm reset */
18 pci_write_config_byte(dev, 0x44, 0x1);
19 udelay(50); /* shouldn't get here but be safe and spin-a-while */
20 return;
21}
22
23struct device_fixup {
24 unsigned int vendor;
25 unsigned int device;
26 void (*reboot_fixup)(struct pci_dev *);
27};
28
29static struct device_fixup fixups_table[] = {
30{ PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, cs5530a_warm_reset },
31};
32
33/*
34 * we see if any fixup is available for our current hardware. if there
35 * is a fixup, we call it and we expect to never return from it. if we
36 * do return, we keep looking and then eventually fall back to the
37 * standard mach_reboot on return.
38 */
39void mach_reboot_fixups(void)
40{
41 struct device_fixup *cur;
42 struct pci_dev *dev;
43 int i;
44
45 for (i=0; i < (sizeof(fixups_table)/sizeof(fixups_table[0])); i++) {
46 cur = &(fixups_table[i]);
47 dev = pci_get_device(cur->vendor, cur->device, 0);
48 if (!dev)
49 continue;
50
51 cur->reboot_fixup(dev);
52 }
53
54 printk(KERN_WARNING "No reboot fixup found for your hardware\n");
55}
56
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index fd36d2f65f88..cbea7ac582e5 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)
1089 } 1089 }
1090 } 1090 }
1091 1091
1092 if (nmi_watchdog == NMI_LOCAL_APIC)
1093 check_nmi_watchdog();
1094
1095 smpboot_setup_io_apic(); 1092 smpboot_setup_io_apic();
1096 1093
1097 setup_boot_APIC_clock(); 1094 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 000000000000..6cd1ed311f02
--- /dev/null
+++ b/arch/i386/kernel/syscall_table.S
@@ -0,0 +1,291 @@
1.data
2ENTRY(sys_call_table)
3 .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
4 .long sys_exit
5 .long sys_fork
6 .long sys_read
7 .long sys_write
8 .long sys_open /* 5 */
9 .long sys_close
10 .long sys_waitpid
11 .long sys_creat
12 .long sys_link
13 .long sys_unlink /* 10 */
14 .long sys_execve
15 .long sys_chdir
16 .long sys_time
17 .long sys_mknod
18 .long sys_chmod /* 15 */
19 .long sys_lchown16
20 .long sys_ni_syscall /* old break syscall holder */
21 .long sys_stat
22 .long sys_lseek
23 .long sys_getpid /* 20 */
24 .long sys_mount
25 .long sys_oldumount
26 .long sys_setuid16
27 .long sys_getuid16
28 .long sys_stime /* 25 */
29 .long sys_ptrace
30 .long sys_alarm
31 .long sys_fstat
32 .long sys_pause
33 .long sys_utime /* 30 */
34 .long sys_ni_syscall /* old stty syscall holder */
35 .long sys_ni_syscall /* old gtty syscall holder */
36 .long sys_access
37 .long sys_nice
38 .long sys_ni_syscall /* 35 - old ftime syscall holder */
39 .long sys_sync
40 .long sys_kill
41 .long sys_rename
42 .long sys_mkdir
43 .long sys_rmdir /* 40 */
44 .long sys_dup
45 .long sys_pipe
46 .long sys_times
47 .long sys_ni_syscall /* old prof syscall holder */
48 .long sys_brk /* 45 */
49 .long sys_setgid16
50 .long sys_getgid16
51 .long sys_signal
52 .long sys_geteuid16
53 .long sys_getegid16 /* 50 */
54 .long sys_acct
55 .long sys_umount /* recycled never used phys() */
56 .long sys_ni_syscall /* old lock syscall holder */
57 .long sys_ioctl
58 .long sys_fcntl /* 55 */
59 .long sys_ni_syscall /* old mpx syscall holder */
60 .long sys_setpgid
61 .long sys_ni_syscall /* old ulimit syscall holder */
62 .long sys_olduname
63 .long sys_umask /* 60 */
64 .long sys_chroot
65 .long sys_ustat
66 .long sys_dup2
67 .long sys_getppid
68 .long sys_getpgrp /* 65 */
69 .long sys_setsid
70 .long sys_sigaction
71 .long sys_sgetmask
72 .long sys_ssetmask
73 .long sys_setreuid16 /* 70 */
74 .long sys_setregid16
75 .long sys_sigsuspend
76 .long sys_sigpending
77 .long sys_sethostname
78 .long sys_setrlimit /* 75 */
79 .long sys_old_getrlimit
80 .long sys_getrusage
81 .long sys_gettimeofday
82 .long sys_settimeofday
83 .long sys_getgroups16 /* 80 */
84 .long sys_setgroups16
85 .long old_select
86 .long sys_symlink
87 .long sys_lstat
88 .long sys_readlink /* 85 */
89 .long sys_uselib
90 .long sys_swapon
91 .long sys_reboot
92 .long old_readdir
93 .long old_mmap /* 90 */
94 .long sys_munmap
95 .long sys_truncate
96 .long sys_ftruncate
97 .long sys_fchmod
98 .long sys_fchown16 /* 95 */
99 .long sys_getpriority
100 .long sys_setpriority
101 .long sys_ni_syscall /* old profil syscall holder */
102 .long sys_statfs
103 .long sys_fstatfs /* 100 */
104 .long sys_ioperm
105 .long sys_socketcall
106 .long sys_syslog
107 .long sys_setitimer
108 .long sys_getitimer /* 105 */
109 .long sys_newstat
110 .long sys_newlstat
111 .long sys_newfstat
112 .long sys_uname
113 .long sys_iopl /* 110 */
114 .long sys_vhangup
115 .long sys_ni_syscall /* old "idle" system call */
116 .long sys_vm86old
117 .long sys_wait4
118 .long sys_swapoff /* 115 */
119 .long sys_sysinfo
120 .long sys_ipc
121 .long sys_fsync
122 .long sys_sigreturn
123 .long sys_clone /* 120 */
124 .long sys_setdomainname
125 .long sys_newuname
126 .long sys_modify_ldt
127 .long sys_adjtimex
128 .long sys_mprotect /* 125 */
129 .long sys_sigprocmask
130 .long sys_ni_syscall /* old "create_module" */
131 .long sys_init_module
132 .long sys_delete_module
133 .long sys_ni_syscall /* 130: old "get_kernel_syms" */
134 .long sys_quotactl
135 .long sys_getpgid
136 .long sys_fchdir
137 .long sys_bdflush
138 .long sys_sysfs /* 135 */
139 .long sys_personality
140 .long sys_ni_syscall /* reserved for afs_syscall */
141 .long sys_setfsuid16
142 .long sys_setfsgid16
143 .long sys_llseek /* 140 */
144 .long sys_getdents
145 .long sys_select
146 .long sys_flock
147 .long sys_msync
148 .long sys_readv /* 145 */
149 .long sys_writev
150 .long sys_getsid
151 .long sys_fdatasync
152 .long sys_sysctl
153 .long sys_mlock /* 150 */
154 .long sys_munlock
155 .long sys_mlockall
156 .long sys_munlockall
157 .long sys_sched_setparam
158 .long sys_sched_getparam /* 155 */
159 .long sys_sched_setscheduler
160 .long sys_sched_getscheduler
161 .long sys_sched_yield
162 .long sys_sched_get_priority_max
163 .long sys_sched_get_priority_min /* 160 */
164 .long sys_sched_rr_get_interval
165 .long sys_nanosleep
166 .long sys_mremap
167 .long sys_setresuid16
168 .long sys_getresuid16 /* 165 */
169 .long sys_vm86
170 .long sys_ni_syscall /* Old sys_query_module */
171 .long sys_poll
172 .long sys_nfsservctl
173 .long sys_setresgid16 /* 170 */
174 .long sys_getresgid16
175 .long sys_prctl
176 .long sys_rt_sigreturn
177 .long sys_rt_sigaction
178 .long sys_rt_sigprocmask /* 175 */
179 .long sys_rt_sigpending
180 .long sys_rt_sigtimedwait
181 .long sys_rt_sigqueueinfo
182 .long sys_rt_sigsuspend
183 .long sys_pread64 /* 180 */
184 .long sys_pwrite64
185 .long sys_chown16
186 .long sys_getcwd
187 .long sys_capget
188 .long sys_capset /* 185 */
189 .long sys_sigaltstack
190 .long sys_sendfile
191 .long sys_ni_syscall /* reserved for streams1 */
192 .long sys_ni_syscall /* reserved for streams2 */
193 .long sys_vfork /* 190 */
194 .long sys_getrlimit
195 .long sys_mmap2
196 .long sys_truncate64
197 .long sys_ftruncate64
198 .long sys_stat64 /* 195 */
199 .long sys_lstat64
200 .long sys_fstat64
201 .long sys_lchown
202 .long sys_getuid
203 .long sys_getgid /* 200 */
204 .long sys_geteuid
205 .long sys_getegid
206 .long sys_setreuid
207 .long sys_setregid
208 .long sys_getgroups /* 205 */
209 .long sys_setgroups
210 .long sys_fchown
211 .long sys_setresuid
212 .long sys_getresuid
213 .long sys_setresgid /* 210 */
214 .long sys_getresgid
215 .long sys_chown
216 .long sys_setuid
217 .long sys_setgid
218 .long sys_setfsuid /* 215 */
219 .long sys_setfsgid
220 .long sys_pivot_root
221 .long sys_mincore
222 .long sys_madvise
223 .long sys_getdents64 /* 220 */
224 .long sys_fcntl64
225 .long sys_ni_syscall /* reserved for TUX */
226 .long sys_ni_syscall
227 .long sys_gettid
228 .long sys_readahead /* 225 */
229 .long sys_setxattr
230 .long sys_lsetxattr
231 .long sys_fsetxattr
232 .long sys_getxattr
233 .long sys_lgetxattr /* 230 */
234 .long sys_fgetxattr
235 .long sys_listxattr
236 .long sys_llistxattr
237 .long sys_flistxattr
238 .long sys_removexattr /* 235 */
239 .long sys_lremovexattr
240 .long sys_fremovexattr
241 .long sys_tkill
242 .long sys_sendfile64
243 .long sys_futex /* 240 */
244 .long sys_sched_setaffinity
245 .long sys_sched_getaffinity
246 .long sys_set_thread_area
247 .long sys_get_thread_area
248 .long sys_io_setup /* 245 */
249 .long sys_io_destroy
250 .long sys_io_getevents
251 .long sys_io_submit
252 .long sys_io_cancel
253 .long sys_fadvise64 /* 250 */
254 .long sys_ni_syscall
255 .long sys_exit_group
256 .long sys_lookup_dcookie
257 .long sys_epoll_create
258 .long sys_epoll_ctl /* 255 */
259 .long sys_epoll_wait
260 .long sys_remap_file_pages
261 .long sys_set_tid_address
262 .long sys_timer_create
263 .long sys_timer_settime /* 260 */
264 .long sys_timer_gettime
265 .long sys_timer_getoverrun
266 .long sys_timer_delete
267 .long sys_clock_settime
268 .long sys_clock_gettime /* 265 */
269 .long sys_clock_getres
270 .long sys_clock_nanosleep
271 .long sys_statfs64
272 .long sys_fstatfs64
273 .long sys_tgkill /* 270 */
274 .long sys_utimes
275 .long sys_fadvise64_64
276 .long sys_ni_syscall /* sys_vserver */
277 .long sys_mbind
278 .long sys_get_mempolicy
279 .long sys_set_mempolicy
280 .long sys_mq_open
281 .long sys_mq_unlink
282 .long sys_mq_timedsend
283 .long sys_mq_timedreceive /* 280 */
284 .long sys_mq_notify
285 .long sys_mq_getsetattr
286 .long sys_ni_syscall /* reserved for kexec */
287 .long sys_waitid
288 .long sys_ni_syscall /* 285 */ /* available */
289 .long sys_add_key
290 .long sys_request_key
291 .long sys_keyctl
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
index 4d75b373f90e..a0dcb7c87c30 100644
--- a/arch/i386/kernel/time.c
+++ b/arch/i386/kernel/time.c
@@ -441,7 +441,7 @@ static void __init hpet_time_init(void)
441 set_normalized_timespec(&wall_to_monotonic, 441 set_normalized_timespec(&wall_to_monotonic,
442 -xtime.tv_sec, -xtime.tv_nsec); 442 -xtime.tv_sec, -xtime.tv_nsec);
443 443
444 if (hpet_enable() >= 0) { 444 if ((hpet_enable() >= 0) && hpet_use_timer) {
445 printk("Using HPET for base-timer\n"); 445 printk("Using HPET for base-timer\n");
446 } 446 }
447 447
diff --git a/arch/i386/kernel/time_hpet.c b/arch/i386/kernel/time_hpet.c
index 244a31b04be7..10a0cbb88e75 100644
--- a/arch/i386/kernel/time_hpet.c
+++ b/arch/i386/kernel/time_hpet.c
@@ -26,6 +26,7 @@
26static unsigned long hpet_period; /* fsecs / HPET clock */ 26static unsigned long hpet_period; /* fsecs / HPET clock */
27unsigned long hpet_tick; /* hpet clks count per tick */ 27unsigned long hpet_tick; /* hpet clks count per tick */
28unsigned long hpet_address; /* hpet memory map physical address */ 28unsigned long hpet_address; /* hpet memory map physical address */
29int hpet_use_timer;
29 30
30static int use_hpet; /* can be used for runtime check of hpet */ 31static int use_hpet; /* can be used for runtime check of hpet */
31static int boot_hpet_disable; /* boottime override for HPET timer */ 32static int boot_hpet_disable; /* boottime override for HPET timer */
@@ -73,27 +74,30 @@ static int hpet_timer_stop_set_go(unsigned long tick)
73 hpet_writel(0, HPET_COUNTER); 74 hpet_writel(0, HPET_COUNTER);
74 hpet_writel(0, HPET_COUNTER + 4); 75 hpet_writel(0, HPET_COUNTER + 4);
75 76
76 /* 77 if (hpet_use_timer) {
77 * Set up timer 0, as periodic with first interrupt to happen at 78 /*
78 * hpet_tick, and period also hpet_tick. 79 * Set up timer 0, as periodic with first interrupt to happen at
79 */ 80 * hpet_tick, and period also hpet_tick.
80 cfg = hpet_readl(HPET_T0_CFG); 81 */
81 cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | 82 cfg = hpet_readl(HPET_T0_CFG);
82 HPET_TN_SETVAL | HPET_TN_32BIT; 83 cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC |
83 hpet_writel(cfg, HPET_T0_CFG); 84 HPET_TN_SETVAL | HPET_TN_32BIT;
84 85 hpet_writel(cfg, HPET_T0_CFG);
85 /*
86 * The first write after writing TN_SETVAL to the config register sets
87 * the counter value, the second write sets the threshold.
88 */
89 hpet_writel(tick, HPET_T0_CMP);
90 hpet_writel(tick, HPET_T0_CMP);
91 86
87 /*
88 * The first write after writing TN_SETVAL to the config register sets
89 * the counter value, the second write sets the threshold.
90 */
91 hpet_writel(tick, HPET_T0_CMP);
92 hpet_writel(tick, HPET_T0_CMP);
93 }
92 /* 94 /*
93 * Go! 95 * Go!
94 */ 96 */
95 cfg = hpet_readl(HPET_CFG); 97 cfg = hpet_readl(HPET_CFG);
96 cfg |= HPET_CFG_ENABLE | HPET_CFG_LEGACY; 98 if (hpet_use_timer)
99 cfg |= HPET_CFG_LEGACY;
100 cfg |= HPET_CFG_ENABLE;
97 hpet_writel(cfg, HPET_CFG); 101 hpet_writel(cfg, HPET_CFG);
98 102
99 return 0; 103 return 0;
@@ -128,12 +132,11 @@ int __init hpet_enable(void)
128 * However, we can do with one timer otherwise using the 132 * However, we can do with one timer otherwise using the
129 * the single HPET timer for system time. 133 * the single HPET timer for system time.
130 */ 134 */
131 if (
132#ifdef CONFIG_HPET_EMULATE_RTC 135#ifdef CONFIG_HPET_EMULATE_RTC
133 !(id & HPET_ID_NUMBER) || 136 if (!(id & HPET_ID_NUMBER))
134#endif
135 !(id & HPET_ID_LEGSUP))
136 return -1; 137 return -1;
138#endif
139
137 140
138 hpet_period = hpet_readl(HPET_PERIOD); 141 hpet_period = hpet_readl(HPET_PERIOD);
139 if ((hpet_period < HPET_MIN_PERIOD) || (hpet_period > HPET_MAX_PERIOD)) 142 if ((hpet_period < HPET_MIN_PERIOD) || (hpet_period > HPET_MAX_PERIOD))
@@ -152,6 +155,8 @@ int __init hpet_enable(void)
152 if (hpet_tick_rem > (hpet_period >> 1)) 155 if (hpet_tick_rem > (hpet_period >> 1))
153 hpet_tick++; /* rounding the result */ 156 hpet_tick++; /* rounding the result */
154 157
158 hpet_use_timer = id & HPET_ID_LEGSUP;
159
155 if (hpet_timer_stop_set_go(hpet_tick)) 160 if (hpet_timer_stop_set_go(hpet_tick))
156 return -1; 161 return -1;
157 162
@@ -202,7 +207,8 @@ int __init hpet_enable(void)
202#endif 207#endif
203 208
204#ifdef CONFIG_X86_LOCAL_APIC 209#ifdef CONFIG_X86_LOCAL_APIC
205 wait_timer_tick = wait_hpet_tick; 210 if (hpet_use_timer)
211 wait_timer_tick = wait_hpet_tick;
206#endif 212#endif
207 return 0; 213 return 0;
208} 214}
diff --git a/arch/i386/kernel/timers/timer_hpet.c b/arch/i386/kernel/timers/timer_hpet.c
index 713134e71844..f778f471a09a 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)
79 79
80 eax = hpet_readl(HPET_COUNTER); 80 eax = hpet_readl(HPET_COUNTER);
81 eax -= hpet_last; /* hpet delta */ 81 eax -= hpet_last; /* hpet delta */
82 82 eax = min(hpet_tick, eax);
83 /* 83 /*
84 * Time offset = (hpet delta) * ( usecs per HPET clock ) 84 * Time offset = (hpet delta) * ( usecs per HPET clock )
85 * = (hpet delta) * ( usecs per tick / HPET clocks per tick) 85 * = (hpet delta) * ( usecs per tick / HPET clocks per tick)
@@ -105,9 +105,12 @@ static void mark_offset_hpet(void)
105 last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low; 105 last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
106 rdtsc(last_tsc_low, last_tsc_high); 106 rdtsc(last_tsc_low, last_tsc_high);
107 107
108 offset = hpet_readl(HPET_T0_CMP) - hpet_tick; 108 if (hpet_use_timer)
109 if (unlikely(((offset - hpet_last) > hpet_tick) && (hpet_last != 0))) { 109 offset = hpet_readl(HPET_T0_CMP) - hpet_tick;
110 int lost_ticks = (offset - hpet_last) / hpet_tick; 110 else
111 offset = hpet_readl(HPET_COUNTER);
112 if (unlikely(((offset - hpet_last) >= (2*hpet_tick)) && (hpet_last != 0))) {
113 int lost_ticks = ((offset - hpet_last) / hpet_tick) - 1;
111 jiffies_64 += lost_ticks; 114 jiffies_64 += lost_ticks;
112 } 115 }
113 hpet_last = offset; 116 hpet_last = offset;
diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c
index a685994e5c8e..7926d967be00 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)
477 if (cpu_has_tsc) { 477 if (cpu_has_tsc) {
478 unsigned long tsc_quotient; 478 unsigned long tsc_quotient;
479#ifdef CONFIG_HPET_TIMER 479#ifdef CONFIG_HPET_TIMER
480 if (is_hpet_enabled()){ 480 if (is_hpet_enabled() && hpet_use_timer) {
481 unsigned long result, remain; 481 unsigned long result, remain;
482 printk("Using TSC for gettimeofday\n"); 482 printk("Using TSC for gettimeofday\n");
483 tsc_quotient = calibrate_tsc_hpet(NULL); 483 tsc_quotient = calibrate_tsc_hpet(NULL);
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 6c0e383915b6..00c63419c06f 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)
451DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) 451DO_ERROR(11, SIGBUS, "segment not present", segment_not_present)
452DO_ERROR(12, SIGBUS, "stack segment", stack_segment) 452DO_ERROR(12, SIGBUS, "stack segment", stack_segment)
453DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0) 453DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
454DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0)
454 455
455fastcall void do_general_protection(struct pt_regs * regs, long error_code) 456fastcall void do_general_protection(struct pt_regs * regs, long error_code)
456{ 457{
@@ -642,16 +643,15 @@ void unset_nmi_callback(void)
642} 643}
643 644
644#ifdef CONFIG_KPROBES 645#ifdef CONFIG_KPROBES
645fastcall int do_int3(struct pt_regs *regs, long error_code) 646fastcall void do_int3(struct pt_regs *regs, long error_code)
646{ 647{
647 if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) 648 if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP)
648 == NOTIFY_STOP) 649 == NOTIFY_STOP)
649 return 1; 650 return;
650 /* This is an interrupt gate, because kprobes wants interrupts 651 /* This is an interrupt gate, because kprobes wants interrupts
651 disabled. Normal trap handlers don't. */ 652 disabled. Normal trap handlers don't. */
652 restore_interrupts(regs); 653 restore_interrupts(regs);
653 do_trap(3, SIGTRAP, "int3", 1, regs, error_code, NULL); 654 do_trap(3, SIGTRAP, "int3", 1, regs, error_code, NULL);
654 return 0;
655} 655}
656#endif 656#endif
657 657
diff --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c
index 2f3d52dacff7..ec0f68ce6886 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)
222 goto out; 222 goto out;
223 case VM86_PLUS_INSTALL_CHECK: 223 case VM86_PLUS_INSTALL_CHECK:
224 /* NOTE: on old vm86 stuff this will return the error 224 /* NOTE: on old vm86 stuff this will return the error
225 from verify_area(), because the subfunction is 225 from access_ok(), because the subfunction is
226 interpreted as (invalid) address to vm86_struct. 226 interpreted as (invalid) address to vm86_struct.
227 So the installation check works. 227 So the installation check works.
228 */ 228 */
@@ -294,8 +294,8 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk
294 */ 294 */
295 info->regs32->eax = 0; 295 info->regs32->eax = 0;
296 tsk->thread.saved_esp0 = tsk->thread.esp0; 296 tsk->thread.saved_esp0 = tsk->thread.esp0;
297 asm volatile("movl %%fs,%0":"=m" (tsk->thread.saved_fs)); 297 asm volatile("mov %%fs,%0":"=m" (tsk->thread.saved_fs));
298 asm volatile("movl %%gs,%0":"=m" (tsk->thread.saved_gs)); 298 asm volatile("mov %%gs,%0":"=m" (tsk->thread.saved_gs));
299 299
300 tss = &per_cpu(init_tss, get_cpu()); 300 tss = &per_cpu(init_tss, get_cpu());
301 tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0; 301 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)
717 irqbits |= irq_bit; 717 irqbits |= irq_bit;
718 if (vm86_irqs[intno].sig) 718 if (vm86_irqs[intno].sig)
719 send_sig(vm86_irqs[intno].sig, vm86_irqs[intno].tsk, 1); 719 send_sig(vm86_irqs[intno].sig, vm86_irqs[intno].tsk, 1);
720 spin_unlock_irqrestore(&irqbits_lock, flags);
721 /* 720 /*
722 * IRQ will be re-enabled when user asks for the irq (whether 721 * IRQ will be re-enabled when user asks for the irq (whether
723 * polling or as a result of the signal) 722 * polling or as a result of the signal)
724 */ 723 */
725 disable_irq(intno); 724 disable_irq_nosync(intno);
725 spin_unlock_irqrestore(&irqbits_lock, flags);
726 return IRQ_HANDLED; 726 return IRQ_HANDLED;
727 727
728out: 728out:
@@ -754,17 +754,20 @@ static inline int get_and_reset_irq(int irqnumber)
754{ 754{
755 int bit; 755 int bit;
756 unsigned long flags; 756 unsigned long flags;
757 int ret = 0;
757 758
758 if (invalid_vm86_irq(irqnumber)) return 0; 759 if (invalid_vm86_irq(irqnumber)) return 0;
759 if (vm86_irqs[irqnumber].tsk != current) return 0; 760 if (vm86_irqs[irqnumber].tsk != current) return 0;
760 spin_lock_irqsave(&irqbits_lock, flags); 761 spin_lock_irqsave(&irqbits_lock, flags);
761 bit = irqbits & (1 << irqnumber); 762 bit = irqbits & (1 << irqnumber);
762 irqbits &= ~bit; 763 irqbits &= ~bit;
764 if (bit) {
765 enable_irq(irqnumber);
766 ret = 1;
767 }
768
763 spin_unlock_irqrestore(&irqbits_lock, flags); 769 spin_unlock_irqrestore(&irqbits_lock, flags);
764 if (!bit) 770 return ret;
765 return 0;
766 enable_irq(irqnumber);
767 return 1;
768} 771}
769 772
770 773
diff --git a/arch/i386/oprofile/nmi_timer_int.c b/arch/i386/oprofile/nmi_timer_int.c
index b2e462abf337..c58d0c14f274 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)
36{ 36{
37 enable_timer_nmi_watchdog(); 37 enable_timer_nmi_watchdog();
38 unset_nmi_callback(); 38 unset_nmi_callback();
39 synchronize_kernel(); 39 synchronize_sched(); /* Allow already-started NMIs to complete. */
40} 40}
41 41
42 42
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
index e07589d04f64..d6598da4b67b 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
495 case PCI_DEVICE_ID_INTEL_ICH6_1: 495 case PCI_DEVICE_ID_INTEL_ICH6_1:
496 case PCI_DEVICE_ID_INTEL_ICH7_0: 496 case PCI_DEVICE_ID_INTEL_ICH7_0:
497 case PCI_DEVICE_ID_INTEL_ICH7_1: 497 case PCI_DEVICE_ID_INTEL_ICH7_1:
498 case PCI_DEVICE_ID_INTEL_ICH7_30:
499 case PCI_DEVICE_ID_INTEL_ICH7_31:
498 case PCI_DEVICE_ID_INTEL_ESB2_0: 500 case PCI_DEVICE_ID_INTEL_ESB2_0:
499 r->name = "PIIX/ICH"; 501 r->name = "PIIX/ICH";
500 r->get = pirq_piix_get; 502 r->get = pirq_piix_get;
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index bd86fea49a0c..d3f093820bc7 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -1417,7 +1417,7 @@ sys_call_table:
1417 data8 sys_msgrcv 1417 data8 sys_msgrcv
1418 data8 sys_msgctl 1418 data8 sys_msgctl
1419 data8 sys_shmget 1419 data8 sys_shmget
1420 data8 ia64_shmat 1420 data8 sys_shmat
1421 data8 sys_shmdt // 1115 1421 data8 sys_shmdt // 1115
1422 data8 sys_shmctl 1422 data8 sys_shmctl
1423 data8 sys_syslog 1423 data8 sys_syslog
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index 8dde0b16d4c8..907464ee7273 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -17,6 +17,7 @@
17#include <linux/user.h> 17#include <linux/user.h>
18#include <linux/security.h> 18#include <linux/security.h>
19#include <linux/audit.h> 19#include <linux/audit.h>
20#include <linux/signal.h>
20 21
21#include <asm/pgtable.h> 22#include <asm/pgtable.h>
22#include <asm/processor.h> 23#include <asm/processor.h>
@@ -1481,7 +1482,7 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data)
1481 case PTRACE_CONT: 1482 case PTRACE_CONT:
1482 /* restart after signal. */ 1483 /* restart after signal. */
1483 ret = -EIO; 1484 ret = -EIO;
1484 if (data > _NSIG) 1485 if (!valid_signal(data))
1485 goto out_tsk; 1486 goto out_tsk;
1486 if (request == PTRACE_SYSCALL) 1487 if (request == PTRACE_SYSCALL)
1487 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 1488 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)
1520 /* let child execute for one instruction */ 1521 /* let child execute for one instruction */
1521 case PTRACE_SINGLEBLOCK: 1522 case PTRACE_SINGLEBLOCK:
1522 ret = -EIO; 1523 ret = -EIO;
1523 if (data > _NSIG) 1524 if (!valid_signal(data))
1524 goto out_tsk; 1525 goto out_tsk;
1525 1526
1526 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 1527 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 3ac216e1c8bb..a8cf6d8a509c 100644
--- a/arch/ia64/kernel/sys_ia64.c
+++ b/arch/ia64/kernel/sys_ia64.c
@@ -93,20 +93,6 @@ sys_getpagesize (void)
93} 93}
94 94
95asmlinkage unsigned long 95asmlinkage unsigned long
96ia64_shmat (int shmid, void __user *shmaddr, int shmflg)
97{
98 unsigned long raddr;
99 int retval;
100
101 retval = do_shmat(shmid, shmaddr, shmflg, &raddr);
102 if (retval < 0)
103 return retval;
104
105 force_successful_syscall_return();
106 return raddr;
107}
108
109asmlinkage unsigned long
110ia64_brk (unsigned long brk) 96ia64_brk (unsigned long brk)
111{ 97{
112 unsigned long rlim, retval, newbrk, oldbrk; 98 unsigned long rlim, retval, newbrk, oldbrk;
diff --git a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c
index 8b40f362dd6f..124f7c1b775e 100644
--- a/arch/m32r/kernel/ptrace.c
+++ b/arch/m32r/kernel/ptrace.c
@@ -24,6 +24,7 @@
24#include <linux/ptrace.h> 24#include <linux/ptrace.h>
25#include <linux/user.h> 25#include <linux/user.h>
26#include <linux/string.h> 26#include <linux/string.h>
27#include <linux/signal.h>
27 28
28#include <asm/cacheflush.h> 29#include <asm/cacheflush.h>
29#include <asm/io.h> 30#include <asm/io.h>
@@ -665,7 +666,7 @@ do_ptrace(long request, struct task_struct *child, long addr, long data)
665 case PTRACE_SYSCALL: 666 case PTRACE_SYSCALL:
666 case PTRACE_CONT: 667 case PTRACE_CONT:
667 ret = -EIO; 668 ret = -EIO;
668 if ((unsigned long) data > _NSIG) 669 if (!valid_signal(data))
669 break; 670 break;
670 if (request == PTRACE_SYSCALL) 671 if (request == PTRACE_SYSCALL)
671 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 672 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -700,7 +701,7 @@ do_ptrace(long request, struct task_struct *child, long addr, long data)
700 unsigned long pc, insn; 701 unsigned long pc, insn;
701 702
702 ret = -EIO; 703 ret = -EIO;
703 if ((unsigned long) data > _NSIG) 704 if (!valid_signal(data))
704 break; 705 break;
705 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 706 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
706 if ((child->ptrace & PT_DTRACE) == 0) { 707 if ((child->ptrace & PT_DTRACE) == 0) {
diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c
index 0beb53333ba3..f4e1e5eb8e12 100644
--- a/arch/m68k/kernel/ptrace.c
+++ b/arch/m68k/kernel/ptrace.c
@@ -19,6 +19,7 @@
19#include <linux/ptrace.h> 19#include <linux/ptrace.h>
20#include <linux/user.h> 20#include <linux/user.h>
21#include <linux/config.h> 21#include <linux/config.h>
22#include <linux/signal.h>
22 23
23#include <asm/uaccess.h> 24#include <asm/uaccess.h>
24#include <asm/page.h> 25#include <asm/page.h>
@@ -251,7 +252,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
251 long tmp; 252 long tmp;
252 253
253 ret = -EIO; 254 ret = -EIO;
254 if ((unsigned long) data > _NSIG) 255 if (!valid_signal(data))
255 break; 256 break;
256 if (request == PTRACE_SYSCALL) { 257 if (request == PTRACE_SYSCALL) {
257 child->thread.work.syscall_trace = ~0; 258 child->thread.work.syscall_trace = ~0;
@@ -292,7 +293,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
292 long tmp; 293 long tmp;
293 294
294 ret = -EIO; 295 ret = -EIO;
295 if ((unsigned long) data > _NSIG) 296 if (!valid_signal(data))
296 break; 297 break;
297 child->thread.work.syscall_trace = 0; 298 child->thread.work.syscall_trace = 0;
298 tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16); 299 tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16);
diff --git a/arch/m68knommu/kernel/ptrace.c b/arch/m68knommu/kernel/ptrace.c
index 15cf79080b15..9724e1cd82e5 100644
--- a/arch/m68knommu/kernel/ptrace.c
+++ b/arch/m68knommu/kernel/ptrace.c
@@ -19,6 +19,7 @@
19#include <linux/ptrace.h> 19#include <linux/ptrace.h>
20#include <linux/user.h> 20#include <linux/user.h>
21#include <linux/config.h> 21#include <linux/config.h>
22#include <linux/signal.h>
22 23
23#include <asm/uaccess.h> 24#include <asm/uaccess.h>
24#include <asm/page.h> 25#include <asm/page.h>
@@ -240,7 +241,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
240 long tmp; 241 long tmp;
241 242
242 ret = -EIO; 243 ret = -EIO;
243 if ((unsigned long) data > _NSIG) 244 if (!valid_signal(data))
244 break; 245 break;
245 if (request == PTRACE_SYSCALL) 246 if (request == PTRACE_SYSCALL)
246 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 247 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -278,7 +279,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
278 long tmp; 279 long tmp;
279 280
280 ret = -EIO; 281 ret = -EIO;
281 if ((unsigned long) data > _NSIG) 282 if (!valid_signal(data))
282 break; 283 break;
283 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 284 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
284 tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16); 285 tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16);
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 4abc2ee53b46..92e70ca3bff9 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -26,6 +26,7 @@
26#include <linux/smp_lock.h> 26#include <linux/smp_lock.h>
27#include <linux/user.h> 27#include <linux/user.h>
28#include <linux/security.h> 28#include <linux/security.h>
29#include <linux/signal.h>
29 30
30#include <asm/cpu.h> 31#include <asm/cpu.h>
31#include <asm/fpu.h> 32#include <asm/fpu.h>
@@ -257,7 +258,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
257 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ 258 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
258 case PTRACE_CONT: { /* restart after signal. */ 259 case PTRACE_CONT: { /* restart after signal. */
259 ret = -EIO; 260 ret = -EIO;
260 if ((unsigned long) data > _NSIG) 261 if (!valid_signal(data))
261 break; 262 break;
262 if (request == PTRACE_SYSCALL) { 263 if (request == PTRACE_SYSCALL) {
263 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 264 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c
index 611dee919d50..eee207969c21 100644
--- a/arch/mips/kernel/ptrace32.c
+++ b/arch/mips/kernel/ptrace32.c
@@ -24,6 +24,7 @@
24#include <linux/smp_lock.h> 24#include <linux/smp_lock.h>
25#include <linux/user.h> 25#include <linux/user.h>
26#include <linux/security.h> 26#include <linux/security.h>
27#include <linux/signal.h>
27 28
28#include <asm/cpu.h> 29#include <asm/cpu.h>
29#include <asm/fpu.h> 30#include <asm/fpu.h>
@@ -241,7 +242,7 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
241 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ 242 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
242 case PTRACE_CONT: { /* restart after signal. */ 243 case PTRACE_CONT: { /* restart after signal. */
243 ret = -EIO; 244 ret = -EIO;
244 if ((unsigned int) data > _NSIG) 245 if (!valid_signal(data))
245 break; 246 break;
246 if (request == PTRACE_SYSCALL) { 247 if (request == PTRACE_SYSCALL) {
247 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 248 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 598bfe7426a2..ae2a1312d4ef 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,
374} 374}
375 375
376/* 376/*
377 * Native ABI that is O32 or N64 version
378 */
379asmlinkage long sys_shmat(int shmid, char __user *shmaddr,
380 int shmflg, unsigned long *addr)
381{
382 unsigned long raddr;
383 int err;
384
385 err = do_shmat(shmid, shmaddr, shmflg, &raddr);
386 if (err)
387 return err;
388
389 return put_user(raddr, addr);
390}
391
392/*
393 * No implemented yet ... 377 * No implemented yet ...
394 */ 378 */
395asmlinkage int sys_cachectl(char *addr, int nbytes, int op) 379asmlinkage int sys_cachectl(char *addr, int nbytes, int op)
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index 2937a9236384..c07db9dff7cd 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -17,6 +17,7 @@
17#include <linux/personality.h> 17#include <linux/personality.h>
18#include <linux/security.h> 18#include <linux/security.h>
19#include <linux/compat.h> 19#include <linux/compat.h>
20#include <linux/signal.h>
20 21
21#include <asm/uaccess.h> 22#include <asm/uaccess.h>
22#include <asm/pgtable.h> 23#include <asm/pgtable.h>
@@ -285,7 +286,7 @@ long sys_ptrace(long request, pid_t pid, long addr, long data)
285 ret = -EIO; 286 ret = -EIO;
286 DBG("sys_ptrace(%s)\n", 287 DBG("sys_ptrace(%s)\n",
287 request == PTRACE_SYSCALL ? "SYSCALL" : "CONT"); 288 request == PTRACE_SYSCALL ? "SYSCALL" : "CONT");
288 if ((unsigned long) data > _NSIG) 289 if (!valid_signal(data))
289 goto out_tsk; 290 goto out_tsk;
290 child->ptrace &= ~(PT_SINGLESTEP|PT_BLOCKSTEP); 291 child->ptrace &= ~(PT_SINGLESTEP|PT_BLOCKSTEP);
291 if (request == PTRACE_SYSCALL) { 292 if (request == PTRACE_SYSCALL) {
@@ -311,7 +312,7 @@ long sys_ptrace(long request, pid_t pid, long addr, long data)
311 case PTRACE_SINGLEBLOCK: 312 case PTRACE_SINGLEBLOCK:
312 DBG("sys_ptrace(SINGLEBLOCK)\n"); 313 DBG("sys_ptrace(SINGLEBLOCK)\n");
313 ret = -EIO; 314 ret = -EIO;
314 if ((unsigned long) data > _NSIG) 315 if (!valid_signal(data))
315 goto out_tsk; 316 goto out_tsk;
316 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 317 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
317 child->ptrace &= ~PT_SINGLESTEP; 318 child->ptrace &= ~PT_SINGLESTEP;
@@ -328,7 +329,7 @@ long sys_ptrace(long request, pid_t pid, long addr, long data)
328 case PTRACE_SINGLESTEP: 329 case PTRACE_SINGLESTEP:
329 DBG("sys_ptrace(SINGLESTEP)\n"); 330 DBG("sys_ptrace(SINGLESTEP)\n");
330 ret = -EIO; 331 ret = -EIO;
331 if ((unsigned long) data > _NSIG) 332 if (!valid_signal(data))
332 goto out_tsk; 333 goto out_tsk;
333 334
334 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 335 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 7958cd8c8bf8..d15a1d53e101 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,
161 } 161 }
162} 162}
163 163
164long sys_shmat_wrapper(int shmid, char __user *shmaddr, int shmflag)
165{
166 unsigned long raddr;
167 int r;
168
169 r = do_shmat(shmid, shmaddr, shmflag, &raddr);
170 if (r < 0)
171 return r;
172 return raddr;
173}
174
175/* Fucking broken ABI */ 164/* Fucking broken ABI */
176 165
177#ifdef CONFIG_64BIT 166#ifdef CONFIG_64BIT
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
index 779b537100ec..dcfa4d3d0e7d 100644
--- a/arch/parisc/kernel/syscall_table.S
+++ b/arch/parisc/kernel/syscall_table.S
@@ -297,7 +297,7 @@
297 ENTRY_DIFF(msgrcv) 297 ENTRY_DIFF(msgrcv)
298 ENTRY_SAME(msgget) /* 190 */ 298 ENTRY_SAME(msgget) /* 190 */
299 ENTRY_SAME(msgctl) 299 ENTRY_SAME(msgctl)
300 ENTRY_SAME(shmat_wrapper) 300 ENTRY_SAME(shmat)
301 ENTRY_SAME(shmdt) 301 ENTRY_SAME(shmdt)
302 ENTRY_SAME(shmget) 302 ENTRY_SAME(shmget)
303 ENTRY_SAME(shmctl) /* 195 */ 303 ENTRY_SAME(shmctl) /* 195 */
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 74aa1e92a395..c3d941345e3d 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -53,6 +53,7 @@ choice
53 53
54config 6xx 54config 6xx
55 bool "6xx/7xx/74xx/52xx/82xx/83xx" 55 bool "6xx/7xx/74xx/52xx/82xx/83xx"
56 select PPC_FPU
56 help 57 help
57 There are four types of PowerPC chips supported. The more common 58 There are four types of PowerPC chips supported. The more common
58 types (601, 603, 604, 740, 750, 7400), the Motorola embedded 59 types (601, 603, 604, 740, 750, 7400), the Motorola embedded
@@ -86,6 +87,9 @@ config E500
86 87
87endchoice 88endchoice
88 89
90config PPC_FPU
91 bool
92
89config BOOKE 93config BOOKE
90 bool 94 bool
91 depends on E500 95 depends on E500
diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile
index 73cbdda5b597..0432a25b4735 100644
--- a/arch/ppc/Makefile
+++ b/arch/ppc/Makefile
@@ -53,6 +53,7 @@ head-$(CONFIG_FSL_BOOKE) := arch/ppc/kernel/head_fsl_booke.o
53 53
54head-$(CONFIG_6xx) += arch/ppc/kernel/idle_6xx.o 54head-$(CONFIG_6xx) += arch/ppc/kernel/idle_6xx.o
55head-$(CONFIG_POWER4) += arch/ppc/kernel/idle_power4.o 55head-$(CONFIG_POWER4) += arch/ppc/kernel/idle_power4.o
56head-$(CONFIG_PPC_FPU) += arch/ppc/kernel/fpu.o
56 57
57core-y += arch/ppc/kernel/ arch/ppc/platforms/ \ 58core-y += arch/ppc/kernel/ arch/ppc/platforms/ \
58 arch/ppc/mm/ arch/ppc/lib/ arch/ppc/syslib/ 59 arch/ppc/mm/ arch/ppc/lib/ arch/ppc/syslib/
diff --git a/arch/ppc/boot/images/Makefile b/arch/ppc/boot/images/Makefile
index 774de8e23871..f850fb0fb511 100644
--- a/arch/ppc/boot/images/Makefile
+++ b/arch/ppc/boot/images/Makefile
@@ -20,8 +20,9 @@ quiet_cmd_uimage = UIMAGE $@
20 20
21targets += uImage 21targets += uImage
22$(obj)/uImage: $(obj)/vmlinux.gz 22$(obj)/uImage: $(obj)/vmlinux.gz
23 $(Q)rm -f $@
23 $(call if_changed,uimage) 24 $(call if_changed,uimage)
24 @echo ' Image $@ is ready' 25 @echo ' Image: $@' $(if $(wildcard $@),'is ready','not made')
25 26
26# Files generated that shall be removed upon make clean 27# Files generated that shall be removed upon make clean
27clean-files := sImage vmapus vmlinux* miboot* zImage* uImage 28clean-files := sImage vmapus vmlinux* miboot* zImage* uImage
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index 86bc878cb3ee..b284451802c9 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -9,6 +9,7 @@ extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o
9extra-$(CONFIG_8xx) := head_8xx.o 9extra-$(CONFIG_8xx) := head_8xx.o
10extra-$(CONFIG_6xx) += idle_6xx.o 10extra-$(CONFIG_6xx) += idle_6xx.o
11extra-$(CONFIG_POWER4) += idle_power4.o 11extra-$(CONFIG_POWER4) += idle_power4.o
12extra-$(CONFIG_PPC_FPU) += fpu.o
12extra-y += vmlinux.lds 13extra-y += vmlinux.lds
13 14
14obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ 15obj-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 79c929475037..ff81da9598d8 100644
--- a/arch/ppc/kernel/align.c
+++ b/arch/ppc/kernel/align.c
@@ -290,6 +290,10 @@ fix_alignment(struct pt_regs *regs)
290 /* lwm, stmw */ 290 /* lwm, stmw */
291 nb = (32 - reg) * 4; 291 nb = (32 - reg) * 4;
292 } 292 }
293
294 if (!access_ok((flags & ST? VERIFY_WRITE: VERIFY_READ), addr, nb+nb0))
295 return -EFAULT; /* bad address */
296
293 rptr = (unsigned char *) &regs->gpr[reg]; 297 rptr = (unsigned char *) &regs->gpr[reg];
294 if (flags & LD) { 298 if (flags & LD) {
295 for (i = 0; i < nb; ++i) 299 for (i = 0; i < nb; ++i)
@@ -368,16 +372,24 @@ fix_alignment(struct pt_regs *regs)
368 372
369 /* Single-precision FP load and store require conversions... */ 373 /* Single-precision FP load and store require conversions... */
370 case LD+F+S: 374 case LD+F+S:
375#ifdef CONFIG_PPC_FPU
371 preempt_disable(); 376 preempt_disable();
372 enable_kernel_fp(); 377 enable_kernel_fp();
373 cvt_fd(&data.f, &data.d, &current->thread.fpscr); 378 cvt_fd(&data.f, &data.d, &current->thread.fpscr);
374 preempt_enable(); 379 preempt_enable();
380#else
381 return 0;
382#endif
375 break; 383 break;
376 case ST+F+S: 384 case ST+F+S:
385#ifdef CONFIG_PPC_FPU
377 preempt_disable(); 386 preempt_disable();
378 enable_kernel_fp(); 387 enable_kernel_fp();
379 cvt_df(&data.d, &data.f, &current->thread.fpscr); 388 cvt_df(&data.d, &data.f, &current->thread.fpscr);
380 preempt_enable(); 389 preempt_enable();
390#else
391 return 0;
392#endif
381 break; 393 break;
382 } 394 }
383 395
diff --git a/arch/ppc/kernel/cpu_setup_6xx.S b/arch/ppc/kernel/cpu_setup_6xx.S
index 74f781b486a3..468721d9ebd2 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)
30 blr 30 blr
31_GLOBAL(__setup_cpu_750) 31_GLOBAL(__setup_cpu_750)
32 mflr r4 32 mflr r4
33 bl __init_fpu_registers
33 bl setup_common_caches 34 bl setup_common_caches
34 bl setup_750_7400_hid0 35 bl setup_750_7400_hid0
35 mtlr r4 36 mtlr r4
36 blr 37 blr
37_GLOBAL(__setup_cpu_750cx) 38_GLOBAL(__setup_cpu_750cx)
38 mflr r4 39 mflr r4
40 bl __init_fpu_registers
39 bl setup_common_caches 41 bl setup_common_caches
40 bl setup_750_7400_hid0 42 bl setup_750_7400_hid0
41 bl setup_750cx 43 bl setup_750cx
@@ -43,6 +45,7 @@ _GLOBAL(__setup_cpu_750cx)
43 blr 45 blr
44_GLOBAL(__setup_cpu_750fx) 46_GLOBAL(__setup_cpu_750fx)
45 mflr r4 47 mflr r4
48 bl __init_fpu_registers
46 bl setup_common_caches 49 bl setup_common_caches
47 bl setup_750_7400_hid0 50 bl setup_750_7400_hid0
48 bl setup_750fx 51 bl setup_750fx
@@ -50,6 +53,7 @@ _GLOBAL(__setup_cpu_750fx)
50 blr 53 blr
51_GLOBAL(__setup_cpu_7400) 54_GLOBAL(__setup_cpu_7400)
52 mflr r4 55 mflr r4
56 bl __init_fpu_registers
53 bl setup_7400_workarounds 57 bl setup_7400_workarounds
54 bl setup_common_caches 58 bl setup_common_caches
55 bl setup_750_7400_hid0 59 bl setup_750_7400_hid0
@@ -57,6 +61,7 @@ _GLOBAL(__setup_cpu_7400)
57 blr 61 blr
58_GLOBAL(__setup_cpu_7410) 62_GLOBAL(__setup_cpu_7410)
59 mflr r4 63 mflr r4
64 bl __init_fpu_registers
60 bl setup_7410_workarounds 65 bl setup_7410_workarounds
61 bl setup_common_caches 66 bl setup_common_caches
62 bl setup_750_7400_hid0 67 bl setup_750_7400_hid0
@@ -80,7 +85,7 @@ setup_common_caches:
80 bne 1f /* don't invalidate the D-cache */ 85 bne 1f /* don't invalidate the D-cache */
81 ori r8,r8,HID0_DCI /* unless it wasn't enabled */ 86 ori r8,r8,HID0_DCI /* unless it wasn't enabled */
821: sync 871: sync
83 mtspr SPRN_HID0,r8 /* enable and invalidate caches */ 88 mtspr SPRN_HID0,r8 /* enable and invalidate caches */
84 sync 89 sync
85 mtspr SPRN_HID0,r11 /* enable caches */ 90 mtspr SPRN_HID0,r11 /* enable caches */
86 sync 91 sync
@@ -152,9 +157,13 @@ setup_7410_workarounds:
152setup_750_7400_hid0: 157setup_750_7400_hid0:
153 mfspr r11,SPRN_HID0 158 mfspr r11,SPRN_HID0
154 ori r11,r11,HID0_SGE | HID0_ABE | HID0_BHTE | HID0_BTIC 159 ori r11,r11,HID0_SGE | HID0_ABE | HID0_BHTE | HID0_BTIC
160 oris r11,r11,HID0_DPM@h
155BEGIN_FTR_SECTION 161BEGIN_FTR_SECTION
156 oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */ 162 xori r11,r11,HID0_BTIC
157END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM) 163END_FTR_SECTION_IFSET(CPU_FTR_NO_BTIC)
164BEGIN_FTR_SECTION
165 xoris r11,r11,HID0_DPM@h /* disable dynamic power mgmt */
166END_FTR_SECTION_IFSET(CPU_FTR_NO_DPM)
158 li r3,HID0_SPD 167 li r3,HID0_SPD
159 andc r11,r11,r3 /* clear SPD: enable speculative */ 168 andc r11,r11,r3 /* clear SPD: enable speculative */
160 li r3,0 169 li r3,0
@@ -218,13 +227,15 @@ setup_745x_specifics:
218 227
219 /* All of the bits we have to set..... 228 /* All of the bits we have to set.....
220 */ 229 */
221 ori r11,r11,HID0_SGE | HID0_FOLD | HID0_BHTE | HID0_LRSTK | HID0_BTIC 230 ori r11,r11,HID0_SGE | HID0_FOLD | HID0_BHTE
231 ori r11,r11,HID0_LRSTK | HID0_BTIC
232 oris r11,r11,HID0_DPM@h
222BEGIN_FTR_SECTION 233BEGIN_FTR_SECTION
223 xori r11,r11,HID0_BTIC 234 xori r11,r11,HID0_BTIC
224END_FTR_SECTION_IFSET(CPU_FTR_NO_BTIC) 235END_FTR_SECTION_IFSET(CPU_FTR_NO_BTIC)
225BEGIN_FTR_SECTION 236BEGIN_FTR_SECTION
226 oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */ 237 xoris r11,r11,HID0_DPM@h /* disable dynamic power mgmt */
227END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM) 238END_FTR_SECTION_IFSET(CPU_FTR_NO_DPM)
228 239
229 /* All of the bits we have to clear.... 240 /* All of the bits we have to clear....
230 */ 241 */
@@ -248,6 +259,25 @@ END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM)
248 isync 259 isync
249 blr 260 blr
250 261
262/*
263 * Initialize the FPU registers. This is needed to work around an errata
264 * in some 750 cpus where using a not yet initialized FPU register after
265 * power on reset may hang the CPU
266 */
267_GLOBAL(__init_fpu_registers)
268 mfmsr r10
269 ori r11,r10,MSR_FP
270 mtmsr r11
271 isync
272 addis r9,r3,empty_zero_page@ha
273 addi r9,r9,empty_zero_page@l
274 REST_32FPRS(0,r9)
275 sync
276 mtmsr r10
277 isync
278 blr
279
280
251/* Definitions for the table use to save CPU states */ 281/* Definitions for the table use to save CPU states */
252#define CS_HID0 0 282#define CS_HID0 0
253#define CS_HID1 4 283#define CS_HID1 4
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
index 035217d6c0f1..5f075dbc4ee7 100644
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -563,6 +563,65 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
563 addi r1,r1,INT_FRAME_SIZE 563 addi r1,r1,INT_FRAME_SIZE
564 blr 564 blr
565 565
566 .globl fast_exception_return
567fast_exception_return:
568#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
569 andi. r10,r9,MSR_RI /* check for recoverable interrupt */
570 beq 1f /* if not, we've got problems */
571#endif
572
5732: REST_4GPRS(3, r11)
574 lwz r10,_CCR(r11)
575 REST_GPR(1, r11)
576 mtcr r10
577 lwz r10,_LINK(r11)
578 mtlr r10
579 REST_GPR(10, r11)
580 mtspr SPRN_SRR1,r9
581 mtspr SPRN_SRR0,r12
582 REST_GPR(9, r11)
583 REST_GPR(12, r11)
584 lwz r11,GPR11(r11)
585 SYNC
586 RFI
587
588#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
589/* check if the exception happened in a restartable section */
5901: lis r3,exc_exit_restart_end@ha
591 addi r3,r3,exc_exit_restart_end@l
592 cmplw r12,r3
593 bge 3f
594 lis r4,exc_exit_restart@ha
595 addi r4,r4,exc_exit_restart@l
596 cmplw r12,r4
597 blt 3f
598 lis r3,fee_restarts@ha
599 tophys(r3,r3)
600 lwz r5,fee_restarts@l(r3)
601 addi r5,r5,1
602 stw r5,fee_restarts@l(r3)
603 mr r12,r4 /* restart at exc_exit_restart */
604 b 2b
605
606 .comm fee_restarts,4
607
608/* aargh, a nonrecoverable interrupt, panic */
609/* aargh, we don't know which trap this is */
610/* but the 601 doesn't implement the RI bit, so assume it's OK */
6113:
612BEGIN_FTR_SECTION
613 b 2b
614END_FTR_SECTION_IFSET(CPU_FTR_601)
615 li r10,-1
616 stw r10,TRAP(r11)
617 addi r3,r1,STACK_FRAME_OVERHEAD
618 lis r10,MSR_KERNEL@h
619 ori r10,r10,MSR_KERNEL@l
620 bl transfer_to_handler_full
621 .long nonrecoverable_exception
622 .long ret_from_except
623#endif
624
566 .globl sigreturn_exit 625 .globl sigreturn_exit
567sigreturn_exit: 626sigreturn_exit:
568 subi r1,r3,STACK_FRAME_OVERHEAD 627 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 000000000000..6189b26f640f
--- /dev/null
+++ b/arch/ppc/kernel/fpu.S
@@ -0,0 +1,133 @@
1/*
2 * FPU support code, moved here from head.S so that it can be used
3 * by chips which use other head-whatever.S files.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version
8 * 2 of the License, or (at your option) any later version.
9 *
10 */
11
12#include <linux/config.h>
13#include <asm/processor.h>
14#include <asm/page.h>
15#include <asm/mmu.h>
16#include <asm/pgtable.h>
17#include <asm/cputable.h>
18#include <asm/cache.h>
19#include <asm/thread_info.h>
20#include <asm/ppc_asm.h>
21#include <asm/offsets.h>
22
23/*
24 * This task wants to use the FPU now.
25 * On UP, disable FP for the task which had the FPU previously,
26 * and save its floating-point registers in its thread_struct.
27 * Load up this task's FP registers from its thread_struct,
28 * enable the FPU for the current task and return to the task.
29 */
30 .globl load_up_fpu
31load_up_fpu:
32 mfmsr r5
33 ori r5,r5,MSR_FP
34#ifdef CONFIG_PPC64BRIDGE
35 clrldi r5,r5,1 /* turn off 64-bit mode */
36#endif /* CONFIG_PPC64BRIDGE */
37 SYNC
38 MTMSRD(r5) /* enable use of fpu now */
39 isync
40/*
41 * For SMP, we don't do lazy FPU switching because it just gets too
42 * horrendously complex, especially when a task switches from one CPU
43 * to another. Instead we call giveup_fpu in switch_to.
44 */
45#ifndef CONFIG_SMP
46 tophys(r6,0) /* get __pa constant */
47 addis r3,r6,last_task_used_math@ha
48 lwz r4,last_task_used_math@l(r3)
49 cmpwi 0,r4,0
50 beq 1f
51 add r4,r4,r6
52 addi r4,r4,THREAD /* want last_task_used_math->thread */
53 SAVE_32FPRS(0, r4)
54 mffs fr0
55 stfd fr0,THREAD_FPSCR-4(r4)
56 lwz r5,PT_REGS(r4)
57 add r5,r5,r6
58 lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
59 li r10,MSR_FP|MSR_FE0|MSR_FE1
60 andc r4,r4,r10 /* disable FP for previous task */
61 stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
621:
63#endif /* CONFIG_SMP */
64 /* enable use of FP after return */
65 mfspr r5,SPRN_SPRG3 /* current task's THREAD (phys) */
66 lwz r4,THREAD_FPEXC_MODE(r5)
67 ori r9,r9,MSR_FP /* enable FP for current */
68 or r9,r9,r4
69 lfd fr0,THREAD_FPSCR-4(r5)
70 mtfsf 0xff,fr0
71 REST_32FPRS(0, r5)
72#ifndef CONFIG_SMP
73 subi r4,r5,THREAD
74 sub r4,r4,r6
75 stw r4,last_task_used_math@l(r3)
76#endif /* CONFIG_SMP */
77 /* restore registers and return */
78 /* we haven't used ctr or xer or lr */
79 b fast_exception_return
80
81/*
82 * FP unavailable trap from kernel - print a message, but let
83 * the task use FP in the kernel until it returns to user mode.
84 */
85 .globl KernelFP
86KernelFP:
87 lwz r3,_MSR(r1)
88 ori r3,r3,MSR_FP
89 stw r3,_MSR(r1) /* enable use of FP after return */
90 lis r3,86f@h
91 ori r3,r3,86f@l
92 mr r4,r2 /* current */
93 lwz r5,_NIP(r1)
94 bl printk
95 b ret_from_except
9686: .string "floating point used in kernel (task=%p, pc=%x)\n"
97 .align 4,0
98
99/*
100 * giveup_fpu(tsk)
101 * Disable FP for the task given as the argument,
102 * and save the floating-point registers in its thread_struct.
103 * Enables the FPU for use in the kernel on return.
104 */
105 .globl giveup_fpu
106giveup_fpu:
107 mfmsr r5
108 ori r5,r5,MSR_FP
109 SYNC_601
110 ISYNC_601
111 MTMSRD(r5) /* enable use of fpu now */
112 SYNC_601
113 isync
114 cmpwi 0,r3,0
115 beqlr- /* if no previous owner, done */
116 addi r3,r3,THREAD /* want THREAD of task */
117 lwz r5,PT_REGS(r3)
118 cmpwi 0,r5,0
119 SAVE_32FPRS(0, r3)
120 mffs fr0
121 stfd fr0,THREAD_FPSCR-4(r3)
122 beq 1f
123 lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
124 li r3,MSR_FP|MSR_FE0|MSR_FE1
125 andc r4,r4,r3 /* disable FP for previous task */
126 stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1271:
128#ifndef CONFIG_SMP
129 li r5,0
130 lis r4,last_task_used_math@ha
131 stw r5,last_task_used_math@l(r4)
132#endif /* CONFIG_SMP */
133 blr
diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S
index 1a89a71e0acc..a931d773715f 100644
--- a/arch/ppc/kernel/head.S
+++ b/arch/ppc/kernel/head.S
@@ -775,133 +775,6 @@ InstructionSegment:
775 EXC_XFER_STD(0x480, UnknownException) 775 EXC_XFER_STD(0x480, UnknownException)
776#endif /* CONFIG_PPC64BRIDGE */ 776#endif /* CONFIG_PPC64BRIDGE */
777 777
778/*
779 * This task wants to use the FPU now.
780 * On UP, disable FP for the task which had the FPU previously,
781 * and save its floating-point registers in its thread_struct.
782 * Load up this task's FP registers from its thread_struct,
783 * enable the FPU for the current task and return to the task.
784 */
785load_up_fpu:
786 mfmsr r5
787 ori r5,r5,MSR_FP
788#ifdef CONFIG_PPC64BRIDGE
789 clrldi r5,r5,1 /* turn off 64-bit mode */
790#endif /* CONFIG_PPC64BRIDGE */
791 SYNC
792 MTMSRD(r5) /* enable use of fpu now */
793 isync
794/*
795 * For SMP, we don't do lazy FPU switching because it just gets too
796 * horrendously complex, especially when a task switches from one CPU
797 * to another. Instead we call giveup_fpu in switch_to.
798 */
799#ifndef CONFIG_SMP
800 tophys(r6,0) /* get __pa constant */
801 addis r3,r6,last_task_used_math@ha
802 lwz r4,last_task_used_math@l(r3)
803 cmpwi 0,r4,0
804 beq 1f
805 add r4,r4,r6
806 addi r4,r4,THREAD /* want last_task_used_math->thread */
807 SAVE_32FPRS(0, r4)
808 mffs fr0
809 stfd fr0,THREAD_FPSCR-4(r4)
810 lwz r5,PT_REGS(r4)
811 add r5,r5,r6
812 lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
813 li r10,MSR_FP|MSR_FE0|MSR_FE1
814 andc r4,r4,r10 /* disable FP for previous task */
815 stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
8161:
817#endif /* CONFIG_SMP */
818 /* enable use of FP after return */
819 mfspr r5,SPRN_SPRG3 /* current task's THREAD (phys) */
820 lwz r4,THREAD_FPEXC_MODE(r5)
821 ori r9,r9,MSR_FP /* enable FP for current */
822 or r9,r9,r4
823 lfd fr0,THREAD_FPSCR-4(r5)
824 mtfsf 0xff,fr0
825 REST_32FPRS(0, r5)
826#ifndef CONFIG_SMP
827 subi r4,r5,THREAD
828 sub r4,r4,r6
829 stw r4,last_task_used_math@l(r3)
830#endif /* CONFIG_SMP */
831 /* restore registers and return */
832 /* we haven't used ctr or xer or lr */
833 /* fall through to fast_exception_return */
834
835 .globl fast_exception_return
836fast_exception_return:
837 andi. r10,r9,MSR_RI /* check for recoverable interrupt */
838 beq 1f /* if not, we've got problems */
8392: REST_4GPRS(3, r11)
840 lwz r10,_CCR(r11)
841 REST_GPR(1, r11)
842 mtcr r10
843 lwz r10,_LINK(r11)
844 mtlr r10
845 REST_GPR(10, r11)
846 mtspr SPRN_SRR1,r9
847 mtspr SPRN_SRR0,r12
848 REST_GPR(9, r11)
849 REST_GPR(12, r11)
850 lwz r11,GPR11(r11)
851 SYNC
852 RFI
853
854/* check if the exception happened in a restartable section */
8551: lis r3,exc_exit_restart_end@ha
856 addi r3,r3,exc_exit_restart_end@l
857 cmplw r12,r3
858 bge 3f
859 lis r4,exc_exit_restart@ha
860 addi r4,r4,exc_exit_restart@l
861 cmplw r12,r4
862 blt 3f
863 lis r3,fee_restarts@ha
864 tophys(r3,r3)
865 lwz r5,fee_restarts@l(r3)
866 addi r5,r5,1
867 stw r5,fee_restarts@l(r3)
868 mr r12,r4 /* restart at exc_exit_restart */
869 b 2b
870
871 .comm fee_restarts,4
872
873/* aargh, a nonrecoverable interrupt, panic */
874/* aargh, we don't know which trap this is */
875/* but the 601 doesn't implement the RI bit, so assume it's OK */
8763:
877BEGIN_FTR_SECTION
878 b 2b
879END_FTR_SECTION_IFSET(CPU_FTR_601)
880 li r10,-1
881 stw r10,TRAP(r11)
882 addi r3,r1,STACK_FRAME_OVERHEAD
883 li r10,MSR_KERNEL
884 bl transfer_to_handler_full
885 .long nonrecoverable_exception
886 .long ret_from_except
887
888/*
889 * FP unavailable trap from kernel - print a message, but let
890 * the task use FP in the kernel until it returns to user mode.
891 */
892KernelFP:
893 lwz r3,_MSR(r1)
894 ori r3,r3,MSR_FP
895 stw r3,_MSR(r1) /* enable use of FP after return */
896 lis r3,86f@h
897 ori r3,r3,86f@l
898 mr r4,r2 /* current */
899 lwz r5,_NIP(r1)
900 bl printk
901 b ret_from_except
90286: .string "floating point used in kernel (task=%p, pc=%x)\n"
903 .align 4,0
904
905#ifdef CONFIG_ALTIVEC 778#ifdef CONFIG_ALTIVEC
906/* Note that the AltiVec support is closely modeled after the FP 779/* Note that the AltiVec support is closely modeled after the FP
907 * support. Changes to one are likely to be applicable to the 780 * support. Changes to one are likely to be applicable to the
@@ -1016,42 +889,6 @@ giveup_altivec:
1016#endif /* CONFIG_ALTIVEC */ 889#endif /* CONFIG_ALTIVEC */
1017 890
1018/* 891/*
1019 * giveup_fpu(tsk)
1020 * Disable FP for the task given as the argument,
1021 * and save the floating-point registers in its thread_struct.
1022 * Enables the FPU for use in the kernel on return.
1023 */
1024 .globl giveup_fpu
1025giveup_fpu:
1026 mfmsr r5
1027 ori r5,r5,MSR_FP
1028 SYNC_601
1029 ISYNC_601
1030 MTMSRD(r5) /* enable use of fpu now */
1031 SYNC_601
1032 isync
1033 cmpwi 0,r3,0
1034 beqlr- /* if no previous owner, done */
1035 addi r3,r3,THREAD /* want THREAD of task */
1036 lwz r5,PT_REGS(r3)
1037 cmpwi 0,r5,0
1038 SAVE_32FPRS(0, r3)
1039 mffs fr0
1040 stfd fr0,THREAD_FPSCR-4(r3)
1041 beq 1f
1042 lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
1043 li r3,MSR_FP|MSR_FE0|MSR_FE1
1044 andc r4,r4,r3 /* disable FP for previous task */
1045 stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
10461:
1047#ifndef CONFIG_SMP
1048 li r5,0
1049 lis r4,last_task_used_math@ha
1050 stw r5,last_task_used_math@l(r4)
1051#endif /* CONFIG_SMP */
1052 blr
1053
1054/*
1055 * This code is jumped to from the startup code to copy 892 * This code is jumped to from the startup code to copy
1056 * the kernel image to physical address 0. 893 * the kernel image to physical address 0.
1057 */ 894 */
diff --git a/arch/ppc/kernel/head_44x.S b/arch/ppc/kernel/head_44x.S
index 9ed8165a3d6c..9b6a8e513657 100644
--- a/arch/ppc/kernel/head_44x.S
+++ b/arch/ppc/kernel/head_44x.S
@@ -426,7 +426,11 @@ interrupt_base:
426 PROGRAM_EXCEPTION 426 PROGRAM_EXCEPTION
427 427
428 /* Floating Point Unavailable Interrupt */ 428 /* Floating Point Unavailable Interrupt */
429#ifdef CONFIG_PPC_FPU
430 FP_UNAVAILABLE_EXCEPTION
431#else
429 EXCEPTION(0x2010, FloatingPointUnavailable, UnknownException, EXC_XFER_EE) 432 EXCEPTION(0x2010, FloatingPointUnavailable, UnknownException, EXC_XFER_EE)
433#endif
430 434
431 /* System Call Interrupt */ 435 /* System Call Interrupt */
432 START_EXCEPTION(SystemCall) 436 START_EXCEPTION(SystemCall)
@@ -686,8 +690,10 @@ _GLOBAL(giveup_altivec)
686 * 690 *
687 * The 44x core does not have an FPU. 691 * The 44x core does not have an FPU.
688 */ 692 */
693#ifndef CONFIG_PPC_FPU
689_GLOBAL(giveup_fpu) 694_GLOBAL(giveup_fpu)
690 blr 695 blr
696#endif
691 697
692/* 698/*
693 * extern void abort(void) 699 * extern void abort(void)
diff --git a/arch/ppc/kernel/head_booke.h b/arch/ppc/kernel/head_booke.h
index 884dac916bce..f213d12eec08 100644
--- a/arch/ppc/kernel/head_booke.h
+++ b/arch/ppc/kernel/head_booke.h
@@ -337,4 +337,11 @@ label:
337 addi r3,r1,STACK_FRAME_OVERHEAD; \ 337 addi r3,r1,STACK_FRAME_OVERHEAD; \
338 EXC_XFER_LITE(0x0900, timer_interrupt) 338 EXC_XFER_LITE(0x0900, timer_interrupt)
339 339
340#define FP_UNAVAILABLE_EXCEPTION \
341 START_EXCEPTION(FloatingPointUnavailable) \
342 NORMAL_EXCEPTION_PROLOG; \
343 bne load_up_fpu; /* if from user, just load it up */ \
344 addi r3,r1,STACK_FRAME_OVERHEAD; \
345 EXC_XFER_EE_LITE(0x800, KernelFP)
346
340#endif /* __HEAD_BOOKE_H__ */ 347#endif /* __HEAD_BOOKE_H__ */
diff --git a/arch/ppc/kernel/head_fsl_booke.S b/arch/ppc/kernel/head_fsl_booke.S
index d64bf61d2b1f..f22ddce36135 100644
--- a/arch/ppc/kernel/head_fsl_booke.S
+++ b/arch/ppc/kernel/head_fsl_booke.S
@@ -504,7 +504,11 @@ interrupt_base:
504 PROGRAM_EXCEPTION 504 PROGRAM_EXCEPTION
505 505
506 /* Floating Point Unavailable Interrupt */ 506 /* Floating Point Unavailable Interrupt */
507#ifdef CONFIG_PPC_FPU
508 FP_UNAVAILABLE_EXCEPTION
509#else
507 EXCEPTION(0x0800, FloatingPointUnavailable, UnknownException, EXC_XFER_EE) 510 EXCEPTION(0x0800, FloatingPointUnavailable, UnknownException, EXC_XFER_EE)
511#endif
508 512
509 /* System Call Interrupt */ 513 /* System Call Interrupt */
510 START_EXCEPTION(SystemCall) 514 START_EXCEPTION(SystemCall)
@@ -916,10 +920,12 @@ _GLOBAL(giveup_spe)
916/* 920/*
917 * extern void giveup_fpu(struct task_struct *prev) 921 * extern void giveup_fpu(struct task_struct *prev)
918 * 922 *
919 * The e500 core does not have an FPU. 923 * Not all FSL Book-E cores have an FPU
920 */ 924 */
925#ifndef CONFIG_PPC_FPU
921_GLOBAL(giveup_fpu) 926_GLOBAL(giveup_fpu)
922 blr 927 blr
928#endif
923 929
924/* 930/*
925 * extern void abort(void) 931 * extern void abort(void)
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index 73f7c23b0dd4..e4f1615ec13f 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -1096,17 +1096,7 @@ _GLOBAL(_get_SP)
1096 * and exceptions as if the cpu had performed the load or store. 1096 * and exceptions as if the cpu had performed the load or store.
1097 */ 1097 */
1098 1098
1099#if defined(CONFIG_4xx) || defined(CONFIG_E500) 1099#ifdef CONFIG_PPC_FPU
1100_GLOBAL(cvt_fd)
1101 lfs 0,0(r3)
1102 stfd 0,0(r4)
1103 blr
1104
1105_GLOBAL(cvt_df)
1106 lfd 0,0(r3)
1107 stfs 0,0(r4)
1108 blr
1109#else
1110_GLOBAL(cvt_fd) 1100_GLOBAL(cvt_fd)
1111 lfd 0,-4(r5) /* load up fpscr value */ 1101 lfd 0,-4(r5) /* load up fpscr value */
1112 mtfsf 0xff,0 1102 mtfsf 0xff,0
diff --git a/arch/ppc/kernel/ptrace.c b/arch/ppc/kernel/ptrace.c
index 426b6f7d9de3..59d59a8dc249 100644
--- a/arch/ppc/kernel/ptrace.c
+++ b/arch/ppc/kernel/ptrace.c
@@ -26,6 +26,7 @@
26#include <linux/ptrace.h> 26#include <linux/ptrace.h>
27#include <linux/user.h> 27#include <linux/user.h>
28#include <linux/security.h> 28#include <linux/security.h>
29#include <linux/signal.h>
29 30
30#include <asm/uaccess.h> 31#include <asm/uaccess.h>
31#include <asm/page.h> 32#include <asm/page.h>
@@ -356,7 +357,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
356 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ 357 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
357 case PTRACE_CONT: { /* restart after signal. */ 358 case PTRACE_CONT: { /* restart after signal. */
358 ret = -EIO; 359 ret = -EIO;
359 if ((unsigned long) data > _NSIG) 360 if (!valid_signal(data))
360 break; 361 break;
361 if (request == PTRACE_SYSCALL) { 362 if (request == PTRACE_SYSCALL) {
362 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 363 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -389,7 +390,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
389 390
390 case PTRACE_SINGLESTEP: { /* set the trap flag. */ 391 case PTRACE_SINGLESTEP: { /* set the trap flag. */
391 ret = -EIO; 392 ret = -EIO;
392 if ((unsigned long) data > _NSIG) 393 if (!valid_signal(data))
393 break; 394 break;
394 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 395 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
395 set_single_step(child); 396 set_single_step(child);
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index 361865c4bc84..f8e7e324a173 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)
176#else 176#else
177#define get_mc_reason(regs) (mfspr(SPRN_MCSR)) 177#define get_mc_reason(regs) (mfspr(SPRN_MCSR))
178#endif 178#endif
179#define REASON_FP 0 179#define REASON_FP ESR_FP
180#define REASON_ILLEGAL ESR_PIL 180#define REASON_ILLEGAL ESR_PIL
181#define REASON_PRIVILEGED ESR_PPR 181#define REASON_PRIVILEGED ESR_PPR
182#define REASON_TRAP ESR_PTR 182#define REASON_TRAP ESR_PTR
diff --git a/arch/ppc/platforms/pmac_cache.S b/arch/ppc/platforms/pmac_cache.S
index da34a9bc9299..fb977de6b704 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)
64 mtspr SPRN_HID0,r4 /* Disable DPM */ 64 mtspr SPRN_HID0,r4 /* Disable DPM */
65 sync 65 sync
66 66
67 /* disp-flush L1 */ 67 /* Disp-flush L1. We have a weird problem here that I never
68 li r4,0x4000 68 * totally figured out. On 750FX, using the ROM for the flush
69 mtctr r4 69 * results in a non-working flush. We use that workaround for
70 * now until I finally understand what's going on. --BenH
71 */
72
73 /* ROM base by default */
70 lis r4,0xfff0 74 lis r4,0xfff0
711: lwzx r0,r0,r4 75 mfpvr r3
76 srwi r3,r3,16
77 cmplwi cr0,r3,0x7000
78 bne+ 1f
79 /* RAM base on 750FX */
80 li r4,0
811: li r4,0x4000
82 mtctr r4
831: lwz r0,0(r4)
72 addi r4,r4,32 84 addi r4,r4,32
73 bdnz 1b 85 bdnz 1b
74 sync 86 sync
75 isync 87 isync
76 88
77 /* disable / invalidate / enable L1 data */ 89 /* Disable / invalidate / enable L1 data */
78 mfspr r3,SPRN_HID0 90 mfspr r3,SPRN_HID0
79 rlwinm r0,r0,0,~HID0_DCE 91 rlwinm r3,r3,0,~(HID0_DCE | HID0_ICE)
80 mtspr SPRN_HID0,r3 92 mtspr SPRN_HID0,r3
81 sync 93 sync
82 isync 94 isync
83 ori r3,r3,HID0_DCE|HID0_DCI 95 ori r3,r3,(HID0_DCE|HID0_DCI|HID0_ICE|HID0_ICFI)
84 sync 96 sync
85 isync 97 isync
86 mtspr SPRN_HID0,r3 98 mtspr SPRN_HID0,r3
87 xori r3,r3,HID0_DCI 99 xori r3,r3,(HID0_DCI|HID0_ICFI)
88 mtspr SPRN_HID0,r3 100 mtspr SPRN_HID0,r3
89 sync 101 sync
90 102
@@ -110,11 +122,20 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
110 lis r4,2 122 lis r4,2
111 mtctr r4 123 mtctr r4
112 lis r4,0xfff0 124 lis r4,0xfff0
1131: lwzx r0,r0,r4 1251: lwz r0,0(r4)
126 addi r4,r4,32
127 bdnz 1b
128 sync
129 isync
130 lis r4,2
131 mtctr r4
132 lis r4,0xfff0
1331: dcbf 0,r4
114 addi r4,r4,32 134 addi r4,r4,32
115 bdnz 1b 135 bdnz 1b
116 sync 136 sync
117 isync 137 isync
138
118 /* now disable L2 */ 139 /* now disable L2 */
119 rlwinm r5,r5,0,~L2CR_L2E 140 rlwinm r5,r5,0,~L2CR_L2E
120 b 2f 141 b 2f
@@ -135,6 +156,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
135 mtspr SPRN_L2CR,r4 156 mtspr SPRN_L2CR,r4
136 sync 157 sync
137 isync 158 isync
159
160 /* Wait for the invalidation to complete */
1611: mfspr r3,SPRN_L2CR
162 rlwinm. r0,r3,0,31,31
163 bne 1b
164
165 /* Clear L2I */
138 xoris r4,r4,L2CR_L2I@h 166 xoris r4,r4,L2CR_L2I@h
139 sync 167 sync
140 mtspr SPRN_L2CR,r4 168 mtspr SPRN_L2CR,r4
@@ -142,14 +170,16 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
142 170
143 /* now disable the L1 data cache */ 171 /* now disable the L1 data cache */
144 mfspr r0,SPRN_HID0 172 mfspr r0,SPRN_HID0
145 rlwinm r0,r0,0,~HID0_DCE 173 rlwinm r0,r0,0,~(HID0_DCE|HID0_ICE)
146 mtspr SPRN_HID0,r0 174 mtspr SPRN_HID0,r0
147 sync 175 sync
148 isync 176 isync
149 177
150 /* Restore HID0[DPM] to whatever it was before */ 178 /* Restore HID0[DPM] to whatever it was before */
151 sync 179 sync
152 mtspr SPRN_HID0,r8 180 mfspr r0,SPRN_HID0
181 rlwimi r0,r8,0,11,11 /* Turn back HID0[DPM] */
182 mtspr SPRN_HID0,r0
153 sync 183 sync
154 184
155 /* restore DR and EE */ 185 /* restore DR and EE */
@@ -201,7 +231,7 @@ flush_disable_745x:
201 mtctr r4 231 mtctr r4
202 li r4,0 232 li r4,0
2031: 2331:
204 lwzx r0,r0,r4 234 lwz r0,0(r4)
205 addi r4,r4,32 /* Go to start of next cache line */ 235 addi r4,r4,32 /* Go to start of next cache line */
206 bdnz 1b 236 bdnz 1b
207 isync 237 isync
diff --git a/arch/ppc/platforms/pmac_feature.c b/arch/ppc/platforms/pmac_feature.c
index 46cbf36722db..867336ad5d36 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)
1590 mdelay(10); 1590 mdelay(10);
1591} 1591}
1592 1592
1593
1594void __pmac pmac_tweak_clock_spreading(int enable)
1595{
1596 struct macio_chip* macio = &macio_chips[0];
1597
1598 /* Hack for doing clock spreading on some machines PowerBooks and
1599 * iBooks. This implements the "platform-do-clockspreading" OF
1600 * property as decoded manually on various models. For safety, we also
1601 * check the product ID in the device-tree in cases we'll whack the i2c
1602 * chip to make reasonably sure we won't set wrong values in there
1603 *
1604 * Of course, ultimately, we have to implement a real parser for
1605 * the platform-do-* stuff...
1606 */
1607
1608 if (macio->type == macio_intrepid) {
1609 if (enable)
1610 UN_OUT(UNI_N_CLOCK_SPREADING, 2);
1611 else
1612 UN_OUT(UNI_N_CLOCK_SPREADING, 0);
1613 mdelay(40);
1614 }
1615
1616 while (machine_is_compatible("PowerBook5,2") ||
1617 machine_is_compatible("PowerBook5,3") ||
1618 machine_is_compatible("PowerBook6,2") ||
1619 machine_is_compatible("PowerBook6,3")) {
1620 struct device_node *ui2c = of_find_node_by_type(NULL, "i2c");
1621 struct device_node *dt = of_find_node_by_name(NULL, "device-tree");
1622 u8 buffer[9];
1623 u32 *productID;
1624 int i, rc, changed = 0;
1625
1626 if (dt == NULL)
1627 break;
1628 productID = (u32 *)get_property(dt, "pid#", NULL);
1629 if (productID == NULL)
1630 break;
1631 while(ui2c) {
1632 struct device_node *p = of_get_parent(ui2c);
1633 if (p && !strcmp(p->name, "uni-n"))
1634 break;
1635 ui2c = of_find_node_by_type(ui2c, "i2c");
1636 }
1637 if (ui2c == NULL)
1638 break;
1639 DBG("Trying to bump clock speed for PID: %08x...\n", *productID);
1640 rc = pmac_low_i2c_open(ui2c, 1);
1641 if (rc != 0)
1642 break;
1643 pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined);
1644 rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9);
1645 DBG("read result: %d,", rc);
1646 if (rc != 0) {
1647 pmac_low_i2c_close(ui2c);
1648 break;
1649 }
1650 for (i=0; i<9; i++)
1651 DBG(" %02x", buffer[i]);
1652 DBG("\n");
1653
1654 switch(*productID) {
1655 case 0x1182: /* AlBook 12" rev 2 */
1656 case 0x1183: /* iBook G4 12" */
1657 buffer[0] = (buffer[0] & 0x8f) | 0x70;
1658 buffer[2] = (buffer[2] & 0x7f) | 0x00;
1659 buffer[5] = (buffer[5] & 0x80) | 0x31;
1660 buffer[6] = (buffer[6] & 0x40) | 0xb0;
1661 buffer[7] = (buffer[7] & 0x00) | (enable ? 0xc0 : 0xba);
1662 buffer[8] = (buffer[8] & 0x00) | 0x30;
1663 changed = 1;
1664 break;
1665 case 0x3142: /* AlBook 15" (ATI M10) */
1666 case 0x3143: /* AlBook 17" (ATI M10) */
1667 buffer[0] = (buffer[0] & 0xaf) | 0x50;
1668 buffer[2] = (buffer[2] & 0x7f) | 0x00;
1669 buffer[5] = (buffer[5] & 0x80) | 0x31;
1670 buffer[6] = (buffer[6] & 0x40) | 0xb0;
1671 buffer[7] = (buffer[7] & 0x00) | (enable ? 0xd0 : 0xc0);
1672 buffer[8] = (buffer[8] & 0x00) | 0x30;
1673 changed = 1;
1674 break;
1675 default:
1676 DBG("i2c-hwclock: Machine model not handled\n");
1677 break;
1678 }
1679 if (!changed) {
1680 pmac_low_i2c_close(ui2c);
1681 break;
1682 }
1683 pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_stdsub);
1684 rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_write, 0x80, buffer, 9);
1685 DBG("write result: %d,", rc);
1686 pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined);
1687 rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9);
1688 DBG("read result: %d,", rc);
1689 if (rc != 0) {
1690 pmac_low_i2c_close(ui2c);
1691 break;
1692 }
1693 for (i=0; i<9; i++)
1694 DBG(" %02x", buffer[i]);
1695 pmac_low_i2c_close(ui2c);
1696 break;
1697 }
1698}
1699
1700
1593static int __pmac 1701static int __pmac
1594core99_sleep(void) 1702core99_sleep(void)
1595{ 1703{
@@ -1601,12 +1709,6 @@ core99_sleep(void)
1601 macio->type != macio_intrepid) 1709 macio->type != macio_intrepid)
1602 return -ENODEV; 1710 return -ENODEV;
1603 1711
1604 /* The device-tree contains that in the hwclock node */
1605 if (macio->type == macio_intrepid) {
1606 UN_OUT(UNI_N_CLOCK_SPREADING, 0);
1607 mdelay(40);
1608 }
1609
1610 /* We power off the wireless slot in case it was not done 1712 /* We power off the wireless slot in case it was not done
1611 * by the driver. We don't power it on automatically however 1713 * by the driver. We don't power it on automatically however
1612 */ 1714 */
@@ -1749,12 +1851,6 @@ core99_wake_up(void)
1749 UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl); 1851 UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl);
1750 udelay(100); 1852 udelay(100);
1751 1853
1752 /* Restore clock spreading */
1753 if (macio->type == macio_intrepid) {
1754 UN_OUT(UNI_N_CLOCK_SPREADING, 2);
1755 mdelay(40);
1756 }
1757
1758 return 0; 1854 return 0;
1759} 1855}
1760 1856
@@ -2149,7 +2245,7 @@ static struct pmac_mb_def pmac_mb_defs[] __pmacdata = {
2149 }, 2245 },
2150 { "PowerBook1,1", "PowerBook 101 (Lombard)", 2246 { "PowerBook1,1", "PowerBook 101 (Lombard)",
2151 PMAC_TYPE_101_PBOOK, paddington_features, 2247 PMAC_TYPE_101_PBOOK, paddington_features,
2152 PMAC_MB_MAY_SLEEP | PMAC_MB_MOBILE 2248 PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
2153 }, 2249 },
2154 { "PowerBook2,1", "iBook (first generation)", 2250 { "PowerBook2,1", "iBook (first generation)",
2155 PMAC_TYPE_ORIG_IBOOK, core99_features, 2251 PMAC_TYPE_ORIG_IBOOK, core99_features,
@@ -2718,97 +2814,11 @@ set_initial_features(void)
2718 MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N); 2814 MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N);
2719 } 2815 }
2720 2816
2721 /* Hack for bumping clock speed on the new PowerBooks and the 2817 /* Some machine models need the clock chip to be properly setup for
2722 * iBook G4. This implements the "platform-do-clockspreading" OF 2818 * clock spreading now. This should be a platform function but we
2723 * property. For safety, we also check the product ID in the 2819 * don't do these at the moment
2724 * device-tree to make reasonably sure we won't set wrong values
2725 * in the clock chip.
2726 *
2727 * Of course, ultimately, we have to implement a real parser for
2728 * the platform-do-* stuff...
2729 */ 2820 */
2730 while (machine_is_compatible("PowerBook5,2") || 2821 pmac_tweak_clock_spreading(1);
2731 machine_is_compatible("PowerBook5,3") ||
2732 machine_is_compatible("PowerBook6,2") ||
2733 machine_is_compatible("PowerBook6,3")) {
2734 struct device_node *ui2c = of_find_node_by_type(NULL, "i2c");
2735 struct device_node *dt = of_find_node_by_name(NULL, "device-tree");
2736 u8 buffer[9];
2737 u32 *productID;
2738 int i, rc, changed = 0;
2739
2740 if (dt == NULL)
2741 break;
2742 productID = (u32 *)get_property(dt, "pid#", NULL);
2743 if (productID == NULL)
2744 break;
2745 while(ui2c) {
2746 struct device_node *p = of_get_parent(ui2c);
2747 if (p && !strcmp(p->name, "uni-n"))
2748 break;
2749 ui2c = of_find_node_by_type(ui2c, "i2c");
2750 }
2751 if (ui2c == NULL)
2752 break;
2753 DBG("Trying to bump clock speed for PID: %08x...\n", *productID);
2754 rc = pmac_low_i2c_open(ui2c, 1);
2755 if (rc != 0)
2756 break;
2757 pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined);
2758 rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9);
2759 DBG("read result: %d,", rc);
2760 if (rc != 0) {
2761 pmac_low_i2c_close(ui2c);
2762 break;
2763 }
2764 for (i=0; i<9; i++)
2765 DBG(" %02x", buffer[i]);
2766 DBG("\n");
2767
2768 switch(*productID) {
2769 case 0x1182: /* AlBook 12" rev 2 */
2770 case 0x1183: /* iBook G4 12" */
2771 buffer[0] = (buffer[0] & 0x8f) | 0x70;
2772 buffer[2] = (buffer[2] & 0x7f) | 0x00;
2773 buffer[5] = (buffer[5] & 0x80) | 0x31;
2774 buffer[6] = (buffer[6] & 0x40) | 0xb0;
2775 buffer[7] = (buffer[7] & 0x00) | 0xc0;
2776 buffer[8] = (buffer[8] & 0x00) | 0x30;
2777 changed = 1;
2778 break;
2779 case 0x3142: /* AlBook 15" (ATI M10) */
2780 case 0x3143: /* AlBook 17" (ATI M10) */
2781 buffer[0] = (buffer[0] & 0xaf) | 0x50;
2782 buffer[2] = (buffer[2] & 0x7f) | 0x00;
2783 buffer[5] = (buffer[5] & 0x80) | 0x31;
2784 buffer[6] = (buffer[6] & 0x40) | 0xb0;
2785 buffer[7] = (buffer[7] & 0x00) | 0xd0;
2786 buffer[8] = (buffer[8] & 0x00) | 0x30;
2787 changed = 1;
2788 break;
2789 default:
2790 DBG("i2c-hwclock: Machine model not handled\n");
2791 break;
2792 }
2793 if (!changed) {
2794 pmac_low_i2c_close(ui2c);
2795 break;
2796 }
2797 pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_stdsub);
2798 rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_write, 0x80, buffer, 9);
2799 DBG("write result: %d,", rc);
2800 pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined);
2801 rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9);
2802 DBG("read result: %d,", rc);
2803 if (rc != 0) {
2804 pmac_low_i2c_close(ui2c);
2805 break;
2806 }
2807 for (i=0; i<9; i++)
2808 DBG(" %02x", buffer[i]);
2809 pmac_low_i2c_close(ui2c);
2810 break;
2811 }
2812 2822
2813#endif /* CONFIG_POWER4 */ 2823#endif /* CONFIG_POWER4 */
2814 2824
diff --git a/arch/ppc/platforms/pmac_sleep.S b/arch/ppc/platforms/pmac_sleep.S
index 3139b6766ad3..f459ade1bd63 100644
--- a/arch/ppc/platforms/pmac_sleep.S
+++ b/arch/ppc/platforms/pmac_sleep.S
@@ -267,6 +267,10 @@ grackle_wake_up:
267 /* Restore various CPU config stuffs */ 267 /* Restore various CPU config stuffs */
268 bl __restore_cpu_setup 268 bl __restore_cpu_setup
269 269
270 /* Make sure all FPRs have been initialized */
271 bl reloc_offset
272 bl __init_fpu_registers
273
270 /* Invalidate & enable L1 cache, we don't care about 274 /* Invalidate & enable L1 cache, we don't care about
271 * whatever the ROM may have tried to write to memory 275 * whatever the ROM may have tried to write to memory
272 */ 276 */
diff --git a/arch/ppc/platforms/radstone_ppc7d.c b/arch/ppc/platforms/radstone_ppc7d.c
index 2a99b43737a8..c30607a972d8 100644
--- a/arch/ppc/platforms/radstone_ppc7d.c
+++ b/arch/ppc/platforms/radstone_ppc7d.c
@@ -68,6 +68,7 @@
68#define PPC7D_RST_PIN 17 /* GPP17 */ 68#define PPC7D_RST_PIN 17 /* GPP17 */
69 69
70extern u32 mv64360_irq_base; 70extern u32 mv64360_irq_base;
71extern spinlock_t rtc_lock;
71 72
72static struct mv64x60_handle bh; 73static struct mv64x60_handle bh;
73static int ppc7d_has_alma; 74static int ppc7d_has_alma;
@@ -75,6 +76,11 @@ static int ppc7d_has_alma;
75extern void gen550_progress(char *, unsigned short); 76extern void gen550_progress(char *, unsigned short);
76extern void gen550_init(int, struct uart_port *); 77extern void gen550_init(int, struct uart_port *);
77 78
79/* FIXME - move to h file */
80extern int ds1337_do_command(int id, int cmd, void *arg);
81#define DS1337_GET_DATE 0
82#define DS1337_SET_DATE 1
83
78/* residual data */ 84/* residual data */
79unsigned char __res[sizeof(bd_t)]; 85unsigned char __res[sizeof(bd_t)];
80 86
@@ -253,6 +259,8 @@ static int ppc7d_show_cpuinfo(struct seq_file *m)
253 u8 val1, val2; 259 u8 val1, val2;
254 static int flash_sizes[4] = { 64, 32, 0, 16 }; 260 static int flash_sizes[4] = { 64, 32, 0, 16 };
255 static int flash_banks[4] = { 4, 3, 2, 1 }; 261 static int flash_banks[4] = { 4, 3, 2, 1 };
262 static int sdram_bank_sizes[4] = { 128, 256, 512, 1 };
263 int sdram_num_banks = 2;
256 static char *pci_modes[] = { "PCI33", "PCI66", 264 static char *pci_modes[] = { "PCI33", "PCI66",
257 "Unknown", "Unknown", 265 "Unknown", "Unknown",
258 "PCIX33", "PCIX66", 266 "PCIX33", "PCIX66",
@@ -279,13 +287,17 @@ static int ppc7d_show_cpuinfo(struct seq_file *m)
279 (val1 == PPC7D_CPLD_MB_TYPE_PLL_100) ? 100 : 287 (val1 == PPC7D_CPLD_MB_TYPE_PLL_100) ? 100 :
280 (val1 == PPC7D_CPLD_MB_TYPE_PLL_64) ? 64 : 0); 288 (val1 == PPC7D_CPLD_MB_TYPE_PLL_64) ? 64 : 0);
281 289
290 val = inb(PPC7D_CPLD_MEM_CONFIG);
291 if (val & PPC7D_CPLD_SDRAM_BANK_NUM_MASK) sdram_num_banks--;
292
282 val = inb(PPC7D_CPLD_MEM_CONFIG_EXTEND); 293 val = inb(PPC7D_CPLD_MEM_CONFIG_EXTEND);
283 val1 = val & PPC7D_CPLD_SDRAM_BANK_SIZE_MASK; 294 val1 = (val & PPC7D_CPLD_SDRAM_BANK_SIZE_MASK) >> 6;
284 seq_printf(m, "SDRAM\t\t: %d%c", 295 seq_printf(m, "SDRAM\t\t: %d banks of %d%c, total %d%c",
285 (val1 == PPC7D_CPLD_SDRAM_BANK_SIZE_128M) ? 128 : 296 sdram_num_banks,
286 (val1 == PPC7D_CPLD_SDRAM_BANK_SIZE_256M) ? 256 : 297 sdram_bank_sizes[val1],
287 (val1 == PPC7D_CPLD_SDRAM_BANK_SIZE_512M) ? 512 : 1, 298 (sdram_bank_sizes[val1] < 128) ? 'G' : 'M',
288 (val1 == PPC7D_CPLD_SDRAM_BANK_SIZE_1G) ? 'G' : 'M'); 299 sdram_num_banks * sdram_bank_sizes[val1],
300 (sdram_bank_sizes[val1] < 128) ? 'G' : 'M');
289 if (val2 & PPC7D_CPLD_MB_TYPE_ECC_FITTED_MASK) { 301 if (val2 & PPC7D_CPLD_MB_TYPE_ECC_FITTED_MASK) {
290 seq_printf(m, " [ECC %sabled]", 302 seq_printf(m, " [ECC %sabled]",
291 (val2 & PPC7D_CPLD_MB_TYPE_ECC_ENABLE_MASK) ? "en" : 303 (val2 & PPC7D_CPLD_MB_TYPE_ECC_ENABLE_MASK) ? "en" :
@@ -1236,6 +1248,38 @@ static void __init ppc7d_setup_arch(void)
1236 printk(KERN_INFO "Radstone Technology PPC7D\n"); 1248 printk(KERN_INFO "Radstone Technology PPC7D\n");
1237 if (ppc_md.progress) 1249 if (ppc_md.progress)
1238 ppc_md.progress("ppc7d_setup_arch: exit", 0); 1250 ppc_md.progress("ppc7d_setup_arch: exit", 0);
1251
1252}
1253
1254/* Real Time Clock support.
1255 * PPC7D has a DS1337 accessed by I2C.
1256 */
1257static ulong ppc7d_get_rtc_time(void)
1258{
1259 struct rtc_time tm;
1260 int result;
1261
1262 spin_lock(&rtc_lock);
1263 result = ds1337_do_command(0, DS1337_GET_DATE, &tm);
1264 spin_unlock(&rtc_lock);
1265
1266 if (result == 0)
1267 result = mktime(tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
1268
1269 return result;
1270}
1271
1272static int ppc7d_set_rtc_time(unsigned long nowtime)
1273{
1274 struct rtc_time tm;
1275 int result;
1276
1277 spin_lock(&rtc_lock);
1278 to_tm(nowtime, &tm);
1279 result = ds1337_do_command(0, DS1337_SET_DATE, &tm);
1280 spin_unlock(&rtc_lock);
1281
1282 return result;
1239} 1283}
1240 1284
1241/* This kernel command line parameter can be used to have the target 1285/* This kernel command line parameter can be used to have the target
@@ -1293,6 +1337,10 @@ static void ppc7d_init2(void)
1293 data8 |= 0x07; 1337 data8 |= 0x07;
1294 outb(data8, PPC7D_CPLD_LEDS); 1338 outb(data8, PPC7D_CPLD_LEDS);
1295 1339
1340 /* Hook up RTC. We couldn't do this earlier because we need the I2C subsystem */
1341 ppc_md.set_rtc_time = ppc7d_set_rtc_time;
1342 ppc_md.get_rtc_time = ppc7d_get_rtc_time;
1343
1296 pr_debug("%s: exit\n", __FUNCTION__); 1344 pr_debug("%s: exit\n", __FUNCTION__);
1297} 1345}
1298 1346
diff --git a/arch/ppc/platforms/radstone_ppc7d.h b/arch/ppc/platforms/radstone_ppc7d.h
index 4546fff2b0c3..938375510be4 100644
--- a/arch/ppc/platforms/radstone_ppc7d.h
+++ b/arch/ppc/platforms/radstone_ppc7d.h
@@ -240,6 +240,7 @@
240#define PPC7D_CPLD_FLASH_CNTL 0x086E 240#define PPC7D_CPLD_FLASH_CNTL 0x086E
241 241
242/* MEMORY_CONFIG_EXTEND */ 242/* MEMORY_CONFIG_EXTEND */
243#define PPC7D_CPLD_SDRAM_BANK_NUM_MASK 0x02
243#define PPC7D_CPLD_SDRAM_BANK_SIZE_MASK 0xc0 244#define PPC7D_CPLD_SDRAM_BANK_SIZE_MASK 0xc0
244#define PPC7D_CPLD_SDRAM_BANK_SIZE_128M 0 245#define PPC7D_CPLD_SDRAM_BANK_SIZE_128M 0
245#define PPC7D_CPLD_SDRAM_BANK_SIZE_256M 0x40 246#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 954b07fc1df3..c867be6981cb 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)
107 simr = &(cpm2_immr->im_intctl.ic_simrh); 107 simr = &(cpm2_immr->im_intctl.ic_simrh);
108 ppc_cached_irq_mask[word] |= 1 << bit; 108 ppc_cached_irq_mask[word] |= 1 << bit;
109 simr[word] = ppc_cached_irq_mask[word]; 109 simr[word] = ppc_cached_irq_mask[word];
110 /*
111 * Work around large numbers of spurious IRQs on PowerPC 82xx
112 * systems.
113 */
114 mb();
110 } 115 }
111} 116}
112 117
diff --git a/arch/ppc64/boot/addnote.c b/arch/ppc64/boot/addnote.c
index 66ff8103bf4d..719663a694bb 100644
--- a/arch/ppc64/boot/addnote.c
+++ b/arch/ppc64/boot/addnote.c
@@ -19,6 +19,7 @@
19#include <unistd.h> 19#include <unistd.h>
20#include <string.h> 20#include <string.h>
21 21
22/* CHRP note section */
22char arch[] = "PowerPC"; 23char arch[] = "PowerPC";
23 24
24#define N_DESCR 6 25#define N_DESCR 6
@@ -31,6 +32,29 @@ unsigned int descr[N_DESCR] = {
31 0x4000, /* load-base */ 32 0x4000, /* load-base */
32}; 33};
33 34
35/* RPA note section */
36char rpaname[] = "IBM,RPA-Client-Config";
37
38/*
39 * Note: setting ignore_my_client_config *should* mean that OF ignores
40 * all the other fields, but there is a firmware bug which means that
41 * it looks at the splpar field at least. So these values need to be
42 * reasonable.
43 */
44#define N_RPA_DESCR 8
45unsigned int rpanote[N_RPA_DESCR] = {
46 0, /* lparaffinity */
47 64, /* min_rmo_size */
48 0, /* min_rmo_percent */
49 40, /* max_pft_size */
50 1, /* splpar */
51 -1, /* min_load */
52 0, /* new_mem_def */
53 1, /* ignore_my_client_config */
54};
55
56#define ROUNDUP(len) (((len) + 3) & ~3)
57
34unsigned char buf[512]; 58unsigned char buf[512];
35 59
36#define GET_16BE(off) ((buf[off] << 8) + (buf[(off)+1])) 60#define GET_16BE(off) ((buf[off] << 8) + (buf[(off)+1]))
@@ -69,7 +93,7 @@ main(int ac, char **av)
69{ 93{
70 int fd, n, i; 94 int fd, n, i;
71 int ph, ps, np; 95 int ph, ps, np;
72 int nnote, ns; 96 int nnote, nnote2, ns;
73 97
74 if (ac != 2) { 98 if (ac != 2) {
75 fprintf(stderr, "Usage: %s elf-file\n", av[0]); 99 fprintf(stderr, "Usage: %s elf-file\n", av[0]);
@@ -81,7 +105,8 @@ main(int ac, char **av)
81 exit(1); 105 exit(1);
82 } 106 }
83 107
84 nnote = strlen(arch) + 1 + (N_DESCR + 3) * 4; 108 nnote = 12 + ROUNDUP(strlen(arch) + 1) + sizeof(descr);
109 nnote2 = 12 + ROUNDUP(strlen(rpaname) + 1) + sizeof(rpanote);
85 110
86 n = read(fd, buf, sizeof(buf)); 111 n = read(fd, buf, sizeof(buf));
87 if (n < 0) { 112 if (n < 0) {
@@ -104,7 +129,7 @@ main(int ac, char **av)
104 np = GET_16BE(E_PHNUM); 129 np = GET_16BE(E_PHNUM);
105 if (ph < E_HSIZE || ps < PH_HSIZE || np < 1) 130 if (ph < E_HSIZE || ps < PH_HSIZE || np < 1)
106 goto notelf; 131 goto notelf;
107 if (ph + (np + 1) * ps + nnote > n) 132 if (ph + (np + 2) * ps + nnote + nnote2 > n)
108 goto nospace; 133 goto nospace;
109 134
110 for (i = 0; i < np; ++i) { 135 for (i = 0; i < np; ++i) {
@@ -117,12 +142,12 @@ main(int ac, char **av)
117 } 142 }
118 143
119 /* XXX check that the area we want to use is all zeroes */ 144 /* XXX check that the area we want to use is all zeroes */
120 for (i = 0; i < ps + nnote; ++i) 145 for (i = 0; i < 2 * ps + nnote + nnote2; ++i)
121 if (buf[ph + i] != 0) 146 if (buf[ph + i] != 0)
122 goto nospace; 147 goto nospace;
123 148
124 /* fill in the program header entry */ 149 /* fill in the program header entry */
125 ns = ph + ps; 150 ns = ph + 2 * ps;
126 PUT_32BE(ph + PH_TYPE, PT_NOTE); 151 PUT_32BE(ph + PH_TYPE, PT_NOTE);
127 PUT_32BE(ph + PH_OFFSET, ns); 152 PUT_32BE(ph + PH_OFFSET, ns);
128 PUT_32BE(ph + PH_FILESZ, nnote); 153 PUT_32BE(ph + PH_FILESZ, nnote);
@@ -134,11 +159,26 @@ main(int ac, char **av)
134 PUT_32BE(ns + 8, 0x1275); 159 PUT_32BE(ns + 8, 0x1275);
135 strcpy(&buf[ns + 12], arch); 160 strcpy(&buf[ns + 12], arch);
136 ns += 12 + strlen(arch) + 1; 161 ns += 12 + strlen(arch) + 1;
137 for (i = 0; i < N_DESCR; ++i) 162 for (i = 0; i < N_DESCR; ++i, ns += 4)
138 PUT_32BE(ns + i * 4, descr[i]); 163 PUT_32BE(ns, descr[i]);
164
165 /* fill in the second program header entry and the RPA note area */
166 ph += ps;
167 PUT_32BE(ph + PH_TYPE, PT_NOTE);
168 PUT_32BE(ph + PH_OFFSET, ns);
169 PUT_32BE(ph + PH_FILESZ, nnote2);
170
171 /* fill in the note area we point to */
172 PUT_32BE(ns, strlen(rpaname) + 1);
173 PUT_32BE(ns + 4, sizeof(rpanote));
174 PUT_32BE(ns + 8, 0x12759999);
175 strcpy(&buf[ns + 12], rpaname);
176 ns += 12 + ROUNDUP(strlen(rpaname) + 1);
177 for (i = 0; i < N_RPA_DESCR; ++i, ns += 4)
178 PUT_32BE(ns, rpanote[i]);
139 179
140 /* Update the number of program headers */ 180 /* Update the number of program headers */
141 PUT_16BE(E_PHNUM, np + 1); 181 PUT_16BE(E_PHNUM, np + 2);
142 182
143 /* write back */ 183 /* write back */
144 lseek(fd, (long) 0, SEEK_SET); 184 lseek(fd, (long) 0, SEEK_SET);
@@ -155,11 +195,11 @@ main(int ac, char **av)
155 exit(0); 195 exit(0);
156 196
157 notelf: 197 notelf:
158 fprintf(stderr, "%s does not appear to be an ELF file\n", av[0]); 198 fprintf(stderr, "%s does not appear to be an ELF file\n", av[1]);
159 exit(1); 199 exit(1);
160 200
161 nospace: 201 nospace:
162 fprintf(stderr, "sorry, I can't find space in %s to put the note\n", 202 fprintf(stderr, "sorry, I can't find space in %s to put the note\n",
163 av[0]); 203 av[1]);
164 exit(1); 204 exit(1);
165} 205}
diff --git a/arch/ppc64/kernel/HvLpEvent.c b/arch/ppc64/kernel/HvLpEvent.c
index 9802beefa217..f8f19637f73f 100644
--- a/arch/ppc64/kernel/HvLpEvent.c
+++ b/arch/ppc64/kernel/HvLpEvent.c
@@ -45,7 +45,7 @@ int HvLpEvent_unregisterHandler( HvLpEvent_Type eventType )
45 /* We now sleep until all other CPUs have scheduled. This ensures that 45 /* We now sleep until all other CPUs have scheduled. This ensures that
46 * the deletion is seen by all other CPUs, and that the deleted handler 46 * the deletion is seen by all other CPUs, and that the deleted handler
47 * isn't still running on another CPU when we return. */ 47 * isn't still running on another CPU when we return. */
48 synchronize_kernel(); 48 synchronize_rcu();
49 } 49 }
50 } 50 }
51 return rc; 51 return rc;
diff --git a/arch/ppc64/kernel/nvram.c b/arch/ppc64/kernel/nvram.c
index b9069c2d1933..4e71781a4414 100644
--- a/arch/ppc64/kernel/nvram.c
+++ b/arch/ppc64/kernel/nvram.c
@@ -339,9 +339,9 @@ static int nvram_remove_os_partition(void)
339static int nvram_create_os_partition(void) 339static int nvram_create_os_partition(void)
340{ 340{
341 struct list_head * p; 341 struct list_head * p;
342 struct nvram_partition * part; 342 struct nvram_partition *part = NULL;
343 struct nvram_partition * new_part = NULL; 343 struct nvram_partition *new_part = NULL;
344 struct nvram_partition * free_part = NULL; 344 struct nvram_partition *free_part = NULL;
345 int seq_init[2] = { 0, 0 }; 345 int seq_init[2] = { 0, 0 };
346 loff_t tmp_index; 346 loff_t tmp_index;
347 long size = 0; 347 long size = 0;
@@ -364,13 +364,11 @@ static int nvram_create_os_partition(void)
364 free_part = part; 364 free_part = part;
365 } 365 }
366 } 366 }
367 if (!size) { 367 if (!size)
368 return -ENOSPC; 368 return -ENOSPC;
369 }
370 369
371 /* Create our OS partition */ 370 /* Create our OS partition */
372 new_part = (struct nvram_partition *) 371 new_part = kmalloc(sizeof(*new_part), GFP_KERNEL);
373 kmalloc(sizeof(struct nvram_partition), GFP_KERNEL);
374 if (!new_part) { 372 if (!new_part) {
375 printk(KERN_ERR "nvram_create_os_partition: kmalloc failed\n"); 373 printk(KERN_ERR "nvram_create_os_partition: kmalloc failed\n");
376 return -ENOMEM; 374 return -ENOMEM;
@@ -379,7 +377,7 @@ static int nvram_create_os_partition(void)
379 new_part->index = free_part->index; 377 new_part->index = free_part->index;
380 new_part->header.signature = NVRAM_SIG_OS; 378 new_part->header.signature = NVRAM_SIG_OS;
381 new_part->header.length = size; 379 new_part->header.length = size;
382 sprintf(new_part->header.name, "ppc64,linux"); 380 strcpy(new_part->header.name, "ppc64,linux");
383 new_part->header.checksum = nvram_checksum(&new_part->header); 381 new_part->header.checksum = nvram_checksum(&new_part->header);
384 382
385 rc = nvram_write_header(new_part); 383 rc = nvram_write_header(new_part);
@@ -394,7 +392,8 @@ static int nvram_create_os_partition(void)
394 tmp_index = new_part->index + NVRAM_HEADER_LEN; 392 tmp_index = new_part->index + NVRAM_HEADER_LEN;
395 rc = ppc_md.nvram_write((char *)&seq_init, sizeof(seq_init), &tmp_index); 393 rc = ppc_md.nvram_write((char *)&seq_init, sizeof(seq_init), &tmp_index);
396 if (rc <= 0) { 394 if (rc <= 0) {
397 printk(KERN_ERR "nvram_create_os_partition: nvram_write failed (%d)\n", rc); 395 printk(KERN_ERR "nvram_create_os_partition: nvram_write "
396 "failed (%d)\n", rc);
398 return rc; 397 return rc;
399 } 398 }
400 399
diff --git a/arch/ppc64/kernel/pSeries_hvCall.S b/arch/ppc64/kernel/pSeries_hvCall.S
index 0715d3038019..176e8da76466 100644
--- a/arch/ppc64/kernel/pSeries_hvCall.S
+++ b/arch/ppc64/kernel/pSeries_hvCall.S
@@ -28,6 +28,8 @@
28 unsigned long *out3); R10 28 unsigned long *out3); R10
29 */ 29 */
30_GLOBAL(plpar_hcall) 30_GLOBAL(plpar_hcall)
31 HMT_MEDIUM
32
31 mfcr r0 33 mfcr r0
32 34
33 std r8,STK_PARM(r8)(r1) /* Save out ptrs */ 35 std r8,STK_PARM(r8)(r1) /* Save out ptrs */
@@ -53,6 +55,8 @@ _GLOBAL(plpar_hcall)
53 55
54/* Simple interface with no output values (other than status) */ 56/* Simple interface with no output values (other than status) */
55_GLOBAL(plpar_hcall_norets) 57_GLOBAL(plpar_hcall_norets)
58 HMT_MEDIUM
59
56 mfcr r0 60 mfcr r0
57 stw r0,8(r1) 61 stw r0,8(r1)
58 62
@@ -75,6 +79,8 @@ _GLOBAL(plpar_hcall_norets)
75 unsigned long *out1); 120(R1) 79 unsigned long *out1); 120(R1)
76 */ 80 */
77_GLOBAL(plpar_hcall_8arg_2ret) 81_GLOBAL(plpar_hcall_8arg_2ret)
82 HMT_MEDIUM
83
78 mfcr r0 84 mfcr r0
79 ld r11,STK_PARM(r11)(r1) /* put arg8 in R11 */ 85 ld r11,STK_PARM(r11)(r1) /* put arg8 in R11 */
80 stw r0,8(r1) 86 stw r0,8(r1)
@@ -99,6 +105,8 @@ _GLOBAL(plpar_hcall_8arg_2ret)
99 unsigned long *out4); 112(R1) 105 unsigned long *out4); 112(R1)
100 */ 106 */
101_GLOBAL(plpar_hcall_4out) 107_GLOBAL(plpar_hcall_4out)
108 HMT_MEDIUM
109
102 mfcr r0 110 mfcr r0
103 stw r0,8(r1) 111 stw r0,8(r1)
104 112
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c
index 45a4ad08fbc2..fe2946c58314 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,
321 char *name = get_property(ic->parent, "name", NULL); 321 char *name = get_property(ic->parent, "name", NULL);
322 if (name && !strcmp(name, "u3")) 322 if (name && !strcmp(name, "u3"))
323 np->intrs[intrcount].line += 128; 323 np->intrs[intrcount].line += 128;
324 else if (!(name && !strcmp(name, "mac-io")))
325 /* ignore other cascaded controllers, such as
326 the k2-sata-root */
327 break;
324 } 328 }
325 np->intrs[intrcount].sense = 1; 329 np->intrs[intrcount].sense = 1;
326 if (n > 1) 330 if (n > 1)
diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c
index 8dffa9ae2623..35ec42de962e 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)
493} 493}
494 494
495/* 495/*
496 * To tell the firmware what our capabilities are, we have to pass
497 * it a fake 32-bit ELF header containing a couple of PT_NOTE sections
498 * that contain structures that contain the actual values.
499 */
500static struct fake_elf {
501 Elf32_Ehdr elfhdr;
502 Elf32_Phdr phdr[2];
503 struct chrpnote {
504 u32 namesz;
505 u32 descsz;
506 u32 type;
507 char name[8]; /* "PowerPC" */
508 struct chrpdesc {
509 u32 real_mode;
510 u32 real_base;
511 u32 real_size;
512 u32 virt_base;
513 u32 virt_size;
514 u32 load_base;
515 } chrpdesc;
516 } chrpnote;
517 struct rpanote {
518 u32 namesz;
519 u32 descsz;
520 u32 type;
521 char name[24]; /* "IBM,RPA-Client-Config" */
522 struct rpadesc {
523 u32 lpar_affinity;
524 u32 min_rmo_size;
525 u32 min_rmo_percent;
526 u32 max_pft_size;
527 u32 splpar;
528 u32 min_load;
529 u32 new_mem_def;
530 u32 ignore_me;
531 } rpadesc;
532 } rpanote;
533} fake_elf = {
534 .elfhdr = {
535 .e_ident = { 0x7f, 'E', 'L', 'F',
536 ELFCLASS32, ELFDATA2MSB, EV_CURRENT },
537 .e_type = ET_EXEC, /* yeah right */
538 .e_machine = EM_PPC,
539 .e_version = EV_CURRENT,
540 .e_phoff = offsetof(struct fake_elf, phdr),
541 .e_phentsize = sizeof(Elf32_Phdr),
542 .e_phnum = 2
543 },
544 .phdr = {
545 [0] = {
546 .p_type = PT_NOTE,
547 .p_offset = offsetof(struct fake_elf, chrpnote),
548 .p_filesz = sizeof(struct chrpnote)
549 }, [1] = {
550 .p_type = PT_NOTE,
551 .p_offset = offsetof(struct fake_elf, rpanote),
552 .p_filesz = sizeof(struct rpanote)
553 }
554 },
555 .chrpnote = {
556 .namesz = sizeof("PowerPC"),
557 .descsz = sizeof(struct chrpdesc),
558 .type = 0x1275,
559 .name = "PowerPC",
560 .chrpdesc = {
561 .real_mode = ~0U, /* ~0 means "don't care" */
562 .real_base = ~0U,
563 .real_size = ~0U,
564 .virt_base = ~0U,
565 .virt_size = ~0U,
566 .load_base = ~0U
567 },
568 },
569 .rpanote = {
570 .namesz = sizeof("IBM,RPA-Client-Config"),
571 .descsz = sizeof(struct rpadesc),
572 .type = 0x12759999,
573 .name = "IBM,RPA-Client-Config",
574 .rpadesc = {
575 .lpar_affinity = 0,
576 .min_rmo_size = 64, /* in megabytes */
577 .min_rmo_percent = 0,
578 .max_pft_size = 48, /* 2^48 bytes max PFT size */
579 .splpar = 1,
580 .min_load = ~0U,
581 .new_mem_def = 0
582 }
583 }
584};
585
586static void __init prom_send_capabilities(void)
587{
588 unsigned long offset = reloc_offset();
589 ihandle elfloader;
590 int ret;
591
592 elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader"));
593 if (elfloader == 0) {
594 prom_printf("couldn't open /packages/elf-loader\n");
595 return;
596 }
597 ret = call_prom("call-method", 3, 1, ADDR("process-elf-header"),
598 elfloader, ADDR(&fake_elf));
599 call_prom("close", 1, 0, elfloader);
600}
601
602/*
496 * Memory allocation strategy... our layout is normally: 603 * Memory allocation strategy... our layout is normally:
497 * 604 *
498 * at 14Mb or more we vmlinux, then a gap and initrd. In some rare cases, initrd 605 * 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,
1448 } 1555 }
1449} 1556}
1450 1557
1558/*
1559 * The Open Firmware 1275 specification states properties must be 31 bytes or
1560 * less, however not all firmwares obey this. Make it 64 bytes to be safe.
1561 */
1562#define MAX_PROPERTY_NAME 64
1563
1451static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, 1564static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
1452 unsigned long *mem_end) 1565 unsigned long *mem_end)
1453{ 1566{
@@ -1457,7 +1570,7 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
1457 unsigned long soff; 1570 unsigned long soff;
1458 unsigned char *valp; 1571 unsigned char *valp;
1459 unsigned long offset = reloc_offset(); 1572 unsigned long offset = reloc_offset();
1460 char pname[32]; 1573 char pname[MAX_PROPERTY_NAME];
1461 char *path; 1574 char *path;
1462 1575
1463 path = RELOC(prom_scratch); 1576 path = RELOC(prom_scratch);
diff --git a/arch/ppc64/kernel/ptrace.c b/arch/ppc64/kernel/ptrace.c
index 3c76333ec3a9..9f8c6087ae56 100644
--- a/arch/ppc64/kernel/ptrace.c
+++ b/arch/ppc64/kernel/ptrace.c
@@ -28,6 +28,7 @@
28#include <linux/security.h> 28#include <linux/security.h>
29#include <linux/audit.h> 29#include <linux/audit.h>
30#include <linux/seccomp.h> 30#include <linux/seccomp.h>
31#include <linux/signal.h>
31 32
32#include <asm/uaccess.h> 33#include <asm/uaccess.h>
33#include <asm/page.h> 34#include <asm/page.h>
@@ -162,7 +163,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
162 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ 163 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
163 case PTRACE_CONT: { /* restart after signal. */ 164 case PTRACE_CONT: { /* restart after signal. */
164 ret = -EIO; 165 ret = -EIO;
165 if ((unsigned long) data > _NSIG) 166 if (!valid_signal(data))
166 break; 167 break;
167 if (request == PTRACE_SYSCALL) 168 if (request == PTRACE_SYSCALL)
168 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 169 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -194,7 +195,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
194 195
195 case PTRACE_SINGLESTEP: { /* set the trap flag. */ 196 case PTRACE_SINGLESTEP: { /* set the trap flag. */
196 ret = -EIO; 197 ret = -EIO;
197 if ((unsigned long) data > _NSIG) 198 if (!valid_signal(data))
198 break; 199 break;
199 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 200 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
200 set_single_step(child); 201 set_single_step(child);
diff --git a/arch/ppc64/kernel/ptrace32.c b/arch/ppc64/kernel/ptrace32.c
index ee81b1b776cc..16436426c7e2 100644
--- a/arch/ppc64/kernel/ptrace32.c
+++ b/arch/ppc64/kernel/ptrace32.c
@@ -26,6 +26,7 @@
26#include <linux/ptrace.h> 26#include <linux/ptrace.h>
27#include <linux/user.h> 27#include <linux/user.h>
28#include <linux/security.h> 28#include <linux/security.h>
29#include <linux/signal.h>
29 30
30#include <asm/uaccess.h> 31#include <asm/uaccess.h>
31#include <asm/page.h> 32#include <asm/page.h>
@@ -293,7 +294,7 @@ int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data)
293 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ 294 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
294 case PTRACE_CONT: { /* restart after signal. */ 295 case PTRACE_CONT: { /* restart after signal. */
295 ret = -EIO; 296 ret = -EIO;
296 if ((unsigned long) data > _NSIG) 297 if (!valid_signal(data))
297 break; 298 break;
298 if (request == PTRACE_SYSCALL) 299 if (request == PTRACE_SYSCALL)
299 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 300 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)
325 326
326 case PTRACE_SINGLESTEP: { /* set the trap flag. */ 327 case PTRACE_SINGLESTEP: { /* set the trap flag. */
327 ret = -EIO; 328 ret = -EIO;
328 if ((unsigned long) data > _NSIG) 329 if (!valid_signal(data))
329 break; 330 break;
330 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 331 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
331 set_single_step(child); 332 set_single_step(child);
diff --git a/arch/ppc64/kernel/signal32.c b/arch/ppc64/kernel/signal32.c
index b0e167db6af9..3c2fa5c284c0 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,
657 657
658 /* Save user registers on the stack */ 658 /* Save user registers on the stack */
659 frame = &rt_sf->uc.uc_mcontext; 659 frame = &rt_sf->uc.uc_mcontext;
660 if (put_user(regs->gpr[1], (unsigned long __user *)newsp)) 660 if (put_user(regs->gpr[1], (u32 __user *)newsp))
661 goto badframe; 661 goto badframe;
662 662
663 if (vdso32_rt_sigtramp && current->thread.vdso_base) { 663 if (vdso32_rt_sigtramp && current->thread.vdso_base) {
@@ -842,7 +842,7 @@ static int handle_signal32(unsigned long sig, struct k_sigaction *ka,
842 regs->link = (unsigned long) frame->mctx.tramp; 842 regs->link = (unsigned long) frame->mctx.tramp;
843 } 843 }
844 844
845 if (put_user(regs->gpr[1], (unsigned long __user *)newsp)) 845 if (put_user(regs->gpr[1], (u32 __user *)newsp))
846 goto badframe; 846 goto badframe;
847 regs->gpr[1] = (unsigned long) newsp; 847 regs->gpr[1] = (unsigned long) newsp;
848 regs->gpr[3] = sig; 848 regs->gpr[3] = sig;
diff --git a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c
index 1c92da3e4525..3b906cd94037 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)
125 * the processor will continue on to secondary_start 125 * the processor will continue on to secondary_start
126 */ 126 */
127 paca[nr].cpu_start = 1; 127 paca[nr].cpu_start = 1;
128 mb(); 128 smp_mb();
129} 129}
130 130
131#endif /* CONFIG_PPC_MULTIPLATFORM */ 131#endif /* CONFIG_PPC_MULTIPLATFORM */
@@ -256,7 +256,7 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
256 } 256 }
257 257
258 call_data = &data; 258 call_data = &data;
259 wmb(); 259 smp_wmb();
260 /* Send a message to all other CPUs and wait for them to respond */ 260 /* Send a message to all other CPUs and wait for them to respond */
261 smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_CALL_FUNCTION); 261 smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_CALL_FUNCTION);
262 262
@@ -431,7 +431,7 @@ int generic_cpu_enable(unsigned int cpu)
431 431
432 /* get the target out of it's holding state */ 432 /* get the target out of it's holding state */
433 per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; 433 per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
434 wmb(); 434 smp_wmb();
435 435
436 while (!cpu_online(cpu)) 436 while (!cpu_online(cpu))
437 cpu_relax(); 437 cpu_relax();
@@ -447,7 +447,7 @@ void generic_cpu_die(unsigned int cpu)
447 int i; 447 int i;
448 448
449 for (i = 0; i < 100; i++) { 449 for (i = 0; i < 100; i++) {
450 rmb(); 450 smp_rmb();
451 if (per_cpu(cpu_state, cpu) == CPU_DEAD) 451 if (per_cpu(cpu_state, cpu) == CPU_DEAD)
452 return; 452 return;
453 msleep(100); 453 msleep(100);
@@ -463,7 +463,7 @@ void generic_mach_cpu_die(void)
463 cpu = smp_processor_id(); 463 cpu = smp_processor_id();
464 printk(KERN_DEBUG "CPU%d offline\n", cpu); 464 printk(KERN_DEBUG "CPU%d offline\n", cpu);
465 __get_cpu_var(cpu_state) = CPU_DEAD; 465 __get_cpu_var(cpu_state) = CPU_DEAD;
466 wmb(); 466 smp_wmb();
467 while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE) 467 while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE)
468 cpu_relax(); 468 cpu_relax();
469 469
@@ -515,7 +515,7 @@ int __devinit __cpu_up(unsigned int cpu)
515 * be written out to main store before we release 515 * be written out to main store before we release
516 * the processor. 516 * the processor.
517 */ 517 */
518 mb(); 518 smp_mb();
519 519
520 /* wake up cpus */ 520 /* wake up cpus */
521 DBG("smp: kicking cpu %d\n", cpu); 521 DBG("smp: kicking cpu %d\n", cpu);
diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c
index 77ded5a363b6..772a465b49f9 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)
221 temp_varp->tb_to_xs = do_gtod.varp->tb_to_xs; 221 temp_varp->tb_to_xs = do_gtod.varp->tb_to_xs;
222 temp_varp->tb_orig_stamp = new_tb_orig_stamp; 222 temp_varp->tb_orig_stamp = new_tb_orig_stamp;
223 temp_varp->stamp_xsec = new_stamp_xsec; 223 temp_varp->stamp_xsec = new_stamp_xsec;
224 mb(); 224 smp_mb();
225 do_gtod.varp = temp_varp; 225 do_gtod.varp = temp_varp;
226 do_gtod.var_idx = temp_idx; 226 do_gtod.var_idx = temp_idx;
227 227
228 ++(systemcfg->tb_update_count); 228 ++(systemcfg->tb_update_count);
229 wmb(); 229 smp_wmb();
230 systemcfg->tb_orig_stamp = new_tb_orig_stamp; 230 systemcfg->tb_orig_stamp = new_tb_orig_stamp;
231 systemcfg->stamp_xsec = new_stamp_xsec; 231 systemcfg->stamp_xsec = new_stamp_xsec;
232 wmb(); 232 smp_wmb();
233 ++(systemcfg->tb_update_count); 233 ++(systemcfg->tb_update_count);
234} 234}
235 235
@@ -648,7 +648,7 @@ void ppc_adjtimex(void)
648 temp_varp->tb_to_xs = new_tb_to_xs; 648 temp_varp->tb_to_xs = new_tb_to_xs;
649 temp_varp->stamp_xsec = new_stamp_xsec; 649 temp_varp->stamp_xsec = new_stamp_xsec;
650 temp_varp->tb_orig_stamp = do_gtod.varp->tb_orig_stamp; 650 temp_varp->tb_orig_stamp = do_gtod.varp->tb_orig_stamp;
651 mb(); 651 smp_mb();
652 do_gtod.varp = temp_varp; 652 do_gtod.varp = temp_varp;
653 do_gtod.var_idx = temp_idx; 653 do_gtod.var_idx = temp_idx;
654 654
@@ -662,10 +662,10 @@ void ppc_adjtimex(void)
662 * loops back and reads them again until this criteria is met. 662 * loops back and reads them again until this criteria is met.
663 */ 663 */
664 ++(systemcfg->tb_update_count); 664 ++(systemcfg->tb_update_count);
665 wmb(); 665 smp_wmb();
666 systemcfg->tb_to_xs = new_tb_to_xs; 666 systemcfg->tb_to_xs = new_tb_to_xs;
667 systemcfg->stamp_xsec = new_stamp_xsec; 667 systemcfg->stamp_xsec = new_stamp_xsec;
668 wmb(); 668 smp_wmb();
669 ++(systemcfg->tb_update_count); 669 ++(systemcfg->tb_update_count);
670 670
671 write_sequnlock_irqrestore( &xtime_lock, flags ); 671 write_sequnlock_irqrestore( &xtime_lock, flags );
diff --git a/arch/ppc64/kernel/vdso32/Makefile b/arch/ppc64/kernel/vdso32/Makefile
index ede2f7e477c2..0b1b0df973eb 100644
--- a/arch/ppc64/kernel/vdso32/Makefile
+++ b/arch/ppc64/kernel/vdso32/Makefile
@@ -1,7 +1,7 @@
1 1
2# List of files in the vdso, has to be asm only for now 2# List of files in the vdso, has to be asm only for now
3 3
4obj-vdso32 = sigtramp.o gettimeofday.o datapage.o cacheflush.o 4obj-vdso32 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o
5 5
6# Build rules 6# Build rules
7 7
diff --git a/arch/ppc64/kernel/vdso32/note.S b/arch/ppc64/kernel/vdso32/note.S
new file mode 100644
index 000000000000..d4b5be4f3d5f
--- /dev/null
+++ b/arch/ppc64/kernel/vdso32/note.S
@@ -0,0 +1,25 @@
1/*
2 * This supplies .note.* sections to go into the PT_NOTE inside the vDSO text.
3 * Here we can supply some information useful to userland.
4 */
5
6#include <linux/uts.h>
7#include <linux/version.h>
8
9#define ASM_ELF_NOTE_BEGIN(name, flags, vendor, type) \
10 .section name, flags; \
11 .balign 4; \
12 .long 1f - 0f; /* name length */ \
13 .long 3f - 2f; /* data length */ \
14 .long type; /* note type */ \
150: .asciz vendor; /* vendor name */ \
161: .balign 4; \
172:
18
19#define ASM_ELF_NOTE_END \
203: .balign 4; /* pad out section */ \
21 .previous
22
23 ASM_ELF_NOTE_BEGIN(".note.kernel-version", "a", UTS_SYSNAME, 0)
24 .long LINUX_VERSION_CODE
25 ASM_ELF_NOTE_END
diff --git a/arch/ppc64/kernel/vdso32/vdso32.lds.S b/arch/ppc64/kernel/vdso32/vdso32.lds.S
index cca27bd03a57..11290c902ba3 100644
--- a/arch/ppc64/kernel/vdso32/vdso32.lds.S
+++ b/arch/ppc64/kernel/vdso32/vdso32.lds.S
@@ -20,6 +20,8 @@ SECTIONS
20 .gnu.version_d : { *(.gnu.version_d) } 20 .gnu.version_d : { *(.gnu.version_d) }
21 .gnu.version_r : { *(.gnu.version_r) } 21 .gnu.version_r : { *(.gnu.version_r) }
22 22
23 .note : { *(.note.*) } :text :note
24
23 . = ALIGN (16); 25 . = ALIGN (16);
24 .text : 26 .text :
25 { 27 {
@@ -87,6 +89,7 @@ SECTIONS
87PHDRS 89PHDRS
88{ 90{
89 text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */ 91 text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */
92 note PT_NOTE FLAGS(4); /* PF_R */
90 dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ 93 dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
91 eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */ 94 eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */
92} 95}
diff --git a/arch/ppc64/kernel/vdso64/Makefile b/arch/ppc64/kernel/vdso64/Makefile
index bd3f70b1a384..ab39988452cc 100644
--- a/arch/ppc64/kernel/vdso64/Makefile
+++ b/arch/ppc64/kernel/vdso64/Makefile
@@ -1,6 +1,6 @@
1# List of files in the vdso, has to be asm only for now 1# List of files in the vdso, has to be asm only for now
2 2
3obj-vdso64 = sigtramp.o gettimeofday.o datapage.o cacheflush.o 3obj-vdso64 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o
4 4
5# Build rules 5# Build rules
6 6
diff --git a/arch/ppc64/kernel/vdso64/note.S b/arch/ppc64/kernel/vdso64/note.S
new file mode 100644
index 000000000000..dc2a509f7e8a
--- /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 942c815c7bc7..9cb28181da80 100644
--- a/arch/ppc64/kernel/vdso64/vdso64.lds.S
+++ b/arch/ppc64/kernel/vdso64/vdso64.lds.S
@@ -18,12 +18,14 @@ SECTIONS
18 .gnu.version_d : { *(.gnu.version_d) } 18 .gnu.version_d : { *(.gnu.version_d) }
19 .gnu.version_r : { *(.gnu.version_r) } 19 .gnu.version_r : { *(.gnu.version_r) }
20 20
21 .note : { *(.note.*) } :text :note
22
21 . = ALIGN (16); 23 . = ALIGN (16);
22 .text : 24 .text :
23 { 25 {
24 *(.text .stub .text.* .gnu.linkonce.t.*) 26 *(.text .stub .text.* .gnu.linkonce.t.*)
25 *(.sfpr .glink) 27 *(.sfpr .glink)
26 } 28 } :text
27 PROVIDE (__etext = .); 29 PROVIDE (__etext = .);
28 PROVIDE (_etext = .); 30 PROVIDE (_etext = .);
29 PROVIDE (etext = .); 31 PROVIDE (etext = .);
@@ -88,6 +90,7 @@ SECTIONS
88PHDRS 90PHDRS
89{ 91{
90 text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */ 92 text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */
93 note PT_NOTE FLAGS(4); /* PF_R */
91 dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ 94 dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
92 eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */ 95 eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */
93} 96}
diff --git a/arch/ppc64/mm/hash_low.S b/arch/ppc64/mm/hash_low.S
index 8c0156a37001..c23d46956dd9 100644
--- a/arch/ppc64/mm/hash_low.S
+++ b/arch/ppc64/mm/hash_low.S
@@ -85,7 +85,10 @@ _GLOBAL(__hash_page)
85 bne- htab_wrong_access 85 bne- htab_wrong_access
86 /* Check if PTE is busy */ 86 /* Check if PTE is busy */
87 andi. r0,r31,_PAGE_BUSY 87 andi. r0,r31,_PAGE_BUSY
88 bne- 1b 88 /* If so, just bail out and refault if needed. Someone else
89 * is changing this PTE anyway and might hash it.
90 */
91 bne- bail_ok
89 /* Prepare new PTE value (turn access RW into DIRTY, then 92 /* Prepare new PTE value (turn access RW into DIRTY, then
90 * add BUSY,HASHPTE and ACCESSED) 93 * add BUSY,HASHPTE and ACCESSED)
91 */ 94 */
@@ -215,6 +218,10 @@ _GLOBAL(htab_call_hpte_remove)
215 /* Try all again */ 218 /* Try all again */
216 b htab_insert_pte 219 b htab_insert_pte
217 220
221bail_ok:
222 li r3,0
223 b bail
224
218htab_pte_insert_ok: 225htab_pte_insert_ok:
219 /* Insert slot number & secondary bit in PTE */ 226 /* Insert slot number & secondary bit in PTE */
220 rldimi r30,r3,12,63-15 227 rldimi r30,r3,12,63-15
diff --git a/arch/ppc64/mm/hugetlbpage.c b/arch/ppc64/mm/hugetlbpage.c
index 390296efe3e0..d3bf86a5c1ad 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)
42 return (addr & ~REGION_MASK) >> HUGEPGDIR_SHIFT; 42 return (addr & ~REGION_MASK) >> HUGEPGDIR_SHIFT;
43} 43}
44 44
45static pgd_t *hugepgd_offset(struct mm_struct *mm, unsigned long addr) 45static pud_t *hugepgd_offset(struct mm_struct *mm, unsigned long addr)
46{ 46{
47 int index; 47 int index;
48 48
@@ -52,21 +52,21 @@ static pgd_t *hugepgd_offset(struct mm_struct *mm, unsigned long addr)
52 52
53 index = hugepgd_index(addr); 53 index = hugepgd_index(addr);
54 BUG_ON(index >= PTRS_PER_HUGEPGD); 54 BUG_ON(index >= PTRS_PER_HUGEPGD);
55 return mm->context.huge_pgdir + index; 55 return (pud_t *)(mm->context.huge_pgdir + index);
56} 56}
57 57
58static inline pte_t *hugepte_offset(pgd_t *dir, unsigned long addr) 58static inline pte_t *hugepte_offset(pud_t *dir, unsigned long addr)
59{ 59{
60 int index; 60 int index;
61 61
62 if (pgd_none(*dir)) 62 if (pud_none(*dir))
63 return NULL; 63 return NULL;
64 64
65 index = (addr >> HPAGE_SHIFT) % PTRS_PER_HUGEPTE; 65 index = (addr >> HPAGE_SHIFT) % PTRS_PER_HUGEPTE;
66 return (pte_t *)pgd_page(*dir) + index; 66 return (pte_t *)pud_page(*dir) + index;
67} 67}
68 68
69static pgd_t *hugepgd_alloc(struct mm_struct *mm, unsigned long addr) 69static pud_t *hugepgd_alloc(struct mm_struct *mm, unsigned long addr)
70{ 70{
71 BUG_ON(! in_hugepage_area(mm->context, addr)); 71 BUG_ON(! in_hugepage_area(mm->context, addr));
72 72
@@ -90,10 +90,9 @@ static pgd_t *hugepgd_alloc(struct mm_struct *mm, unsigned long addr)
90 return hugepgd_offset(mm, addr); 90 return hugepgd_offset(mm, addr);
91} 91}
92 92
93static pte_t *hugepte_alloc(struct mm_struct *mm, pgd_t *dir, 93static pte_t *hugepte_alloc(struct mm_struct *mm, pud_t *dir, unsigned long addr)
94 unsigned long addr)
95{ 94{
96 if (! pgd_present(*dir)) { 95 if (! pud_present(*dir)) {
97 pte_t *new; 96 pte_t *new;
98 97
99 spin_unlock(&mm->page_table_lock); 98 spin_unlock(&mm->page_table_lock);
@@ -104,7 +103,7 @@ static pte_t *hugepte_alloc(struct mm_struct *mm, pgd_t *dir,
104 * Because we dropped the lock, we should re-check the 103 * Because we dropped the lock, we should re-check the
105 * entry, as somebody else could have populated it.. 104 * entry, as somebody else could have populated it..
106 */ 105 */
107 if (pgd_present(*dir)) { 106 if (pud_present(*dir)) {
108 if (new) 107 if (new)
109 kmem_cache_free(zero_cache, new); 108 kmem_cache_free(zero_cache, new);
110 } else { 109 } else {
@@ -115,7 +114,7 @@ static pte_t *hugepte_alloc(struct mm_struct *mm, pgd_t *dir,
115 ptepage = virt_to_page(new); 114 ptepage = virt_to_page(new);
116 ptepage->mapping = (void *) mm; 115 ptepage->mapping = (void *) mm;
117 ptepage->index = addr & HUGEPGDIR_MASK; 116 ptepage->index = addr & HUGEPGDIR_MASK;
118 pgd_populate(mm, dir, new); 117 pud_populate(mm, dir, new);
119 } 118 }
120 } 119 }
121 120
@@ -124,28 +123,28 @@ static pte_t *hugepte_alloc(struct mm_struct *mm, pgd_t *dir,
124 123
125static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) 124static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
126{ 125{
127 pgd_t *pgd; 126 pud_t *pud;
128 127
129 BUG_ON(! in_hugepage_area(mm->context, addr)); 128 BUG_ON(! in_hugepage_area(mm->context, addr));
130 129
131 pgd = hugepgd_offset(mm, addr); 130 pud = hugepgd_offset(mm, addr);
132 if (! pgd) 131 if (! pud)
133 return NULL; 132 return NULL;
134 133
135 return hugepte_offset(pgd, addr); 134 return hugepte_offset(pud, addr);
136} 135}
137 136
138static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) 137static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
139{ 138{
140 pgd_t *pgd; 139 pud_t *pud;
141 140
142 BUG_ON(! in_hugepage_area(mm->context, addr)); 141 BUG_ON(! in_hugepage_area(mm->context, addr));
143 142
144 pgd = hugepgd_alloc(mm, addr); 143 pud = hugepgd_alloc(mm, addr);
145 if (! pgd) 144 if (! pud)
146 return NULL; 145 return NULL;
147 146
148 return hugepte_alloc(mm, pgd, addr); 147 return hugepte_alloc(mm, pud, addr);
149} 148}
150 149
151static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma, 150static 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)
709 708
710 /* cleanup any hugepte pages leftover */ 709 /* cleanup any hugepte pages leftover */
711 for (i = 0; i < PTRS_PER_HUGEPGD; i++) { 710 for (i = 0; i < PTRS_PER_HUGEPGD; i++) {
712 pgd_t *pgd = pgdir + i; 711 pud_t *pud = (pud_t *)(pgdir + i);
713 712
714 if (! pgd_none(*pgd)) { 713 if (! pud_none(*pud)) {
715 pte_t *pte = (pte_t *)pgd_page(*pgd); 714 pte_t *pte = (pte_t *)pud_page(*pud);
716 struct page *ptepage = virt_to_page(pte); 715 struct page *ptepage = virt_to_page(pte);
717 716
718 ptepage->mapping = NULL; 717 ptepage->mapping = NULL;
@@ -720,7 +719,7 @@ void hugetlb_mm_free_pgd(struct mm_struct *mm)
720 BUG_ON(memcmp(pte, empty_zero_page, PAGE_SIZE)); 719 BUG_ON(memcmp(pte, empty_zero_page, PAGE_SIZE));
721 kmem_cache_free(zero_cache, pte); 720 kmem_cache_free(zero_cache, pte);
722 } 721 }
723 pgd_clear(pgd); 722 pud_clear(pud);
724 } 723 }
725 724
726 BUG_ON(memcmp(pgdir, empty_zero_page, PAGE_SIZE)); 725 BUG_ON(memcmp(pgdir, empty_zero_page, PAGE_SIZE));
diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c
index a7149b9fc35c..cf33d7ec2e29 100644
--- a/arch/ppc64/mm/init.c
+++ b/arch/ppc64/mm/init.c
@@ -136,14 +136,78 @@ void iounmap(volatile void __iomem *addr)
136 136
137#else 137#else
138 138
139static void unmap_im_area_pte(pmd_t *pmd, unsigned long addr,
140 unsigned long end)
141{
142 pte_t *pte;
143
144 pte = pte_offset_kernel(pmd, addr);
145 do {
146 pte_t ptent = ptep_get_and_clear(&ioremap_mm, addr, pte);
147 WARN_ON(!pte_none(ptent) && !pte_present(ptent));
148 } while (pte++, addr += PAGE_SIZE, addr != end);
149}
150
151static inline void unmap_im_area_pmd(pud_t *pud, unsigned long addr,
152 unsigned long end)
153{
154 pmd_t *pmd;
155 unsigned long next;
156
157 pmd = pmd_offset(pud, addr);
158 do {
159 next = pmd_addr_end(addr, end);
160 if (pmd_none_or_clear_bad(pmd))
161 continue;
162 unmap_im_area_pte(pmd, addr, next);
163 } while (pmd++, addr = next, addr != end);
164}
165
166static inline void unmap_im_area_pud(pgd_t *pgd, unsigned long addr,
167 unsigned long end)
168{
169 pud_t *pud;
170 unsigned long next;
171
172 pud = pud_offset(pgd, addr);
173 do {
174 next = pud_addr_end(addr, end);
175 if (pud_none_or_clear_bad(pud))
176 continue;
177 unmap_im_area_pmd(pud, addr, next);
178 } while (pud++, addr = next, addr != end);
179}
180
181static void unmap_im_area(unsigned long addr, unsigned long end)
182{
183 struct mm_struct *mm = &ioremap_mm;
184 unsigned long next;
185 pgd_t *pgd;
186
187 spin_lock(&mm->page_table_lock);
188
189 pgd = pgd_offset_i(addr);
190 flush_cache_vunmap(addr, end);
191 do {
192 next = pgd_addr_end(addr, end);
193 if (pgd_none_or_clear_bad(pgd))
194 continue;
195 unmap_im_area_pud(pgd, addr, next);
196 } while (pgd++, addr = next, addr != end);
197 flush_tlb_kernel_range(start, end);
198
199 spin_unlock(&mm->page_table_lock);
200}
201
139/* 202/*
140 * map_io_page currently only called by __ioremap 203 * map_io_page currently only called by __ioremap
141 * map_io_page adds an entry to the ioremap page table 204 * map_io_page adds an entry to the ioremap page table
142 * and adds an entry to the HPT, possibly bolting it 205 * and adds an entry to the HPT, possibly bolting it
143 */ 206 */
144static void map_io_page(unsigned long ea, unsigned long pa, int flags) 207static int map_io_page(unsigned long ea, unsigned long pa, int flags)
145{ 208{
146 pgd_t *pgdp; 209 pgd_t *pgdp;
210 pud_t *pudp;
147 pmd_t *pmdp; 211 pmd_t *pmdp;
148 pte_t *ptep; 212 pte_t *ptep;
149 unsigned long vsid; 213 unsigned long vsid;
@@ -151,9 +215,15 @@ static void map_io_page(unsigned long ea, unsigned long pa, int flags)
151 if (mem_init_done) { 215 if (mem_init_done) {
152 spin_lock(&ioremap_mm.page_table_lock); 216 spin_lock(&ioremap_mm.page_table_lock);
153 pgdp = pgd_offset_i(ea); 217 pgdp = pgd_offset_i(ea);
154 pmdp = pmd_alloc(&ioremap_mm, pgdp, ea); 218 pudp = pud_alloc(&ioremap_mm, pgdp, ea);
219 if (!pudp)
220 return -ENOMEM;
221 pmdp = pmd_alloc(&ioremap_mm, pudp, ea);
222 if (!pmdp)
223 return -ENOMEM;
155 ptep = pte_alloc_kernel(&ioremap_mm, pmdp, ea); 224 ptep = pte_alloc_kernel(&ioremap_mm, pmdp, ea);
156 225 if (!ptep)
226 return -ENOMEM;
157 pa = abs_to_phys(pa); 227 pa = abs_to_phys(pa);
158 set_pte_at(&ioremap_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT, 228 set_pte_at(&ioremap_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT,
159 __pgprot(flags))); 229 __pgprot(flags)));
@@ -181,6 +251,7 @@ static void map_io_page(unsigned long ea, unsigned long pa, int flags)
181 panic("map_io_page: could not insert mapping"); 251 panic("map_io_page: could not insert mapping");
182 } 252 }
183 } 253 }
254 return 0;
184} 255}
185 256
186 257
@@ -194,9 +265,14 @@ static void __iomem * __ioremap_com(unsigned long addr, unsigned long pa,
194 flags |= pgprot_val(PAGE_KERNEL); 265 flags |= pgprot_val(PAGE_KERNEL);
195 266
196 for (i = 0; i < size; i += PAGE_SIZE) 267 for (i = 0; i < size; i += PAGE_SIZE)
197 map_io_page(ea+i, pa+i, flags); 268 if (map_io_page(ea+i, pa+i, flags))
269 goto failure;
198 270
199 return (void __iomem *) (ea + (addr & ~PAGE_MASK)); 271 return (void __iomem *) (ea + (addr & ~PAGE_MASK));
272 failure:
273 if (mem_init_done)
274 unmap_im_area(ea, ea + size);
275 return NULL;
200} 276}
201 277
202 278
@@ -206,10 +282,11 @@ ioremap(unsigned long addr, unsigned long size)
206 return __ioremap(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED); 282 return __ioremap(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED);
207} 283}
208 284
209void __iomem * 285void __iomem * __ioremap(unsigned long addr, unsigned long size,
210__ioremap(unsigned long addr, unsigned long size, unsigned long flags) 286 unsigned long flags)
211{ 287{
212 unsigned long pa, ea; 288 unsigned long pa, ea;
289 void __iomem *ret;
213 290
214 /* 291 /*
215 * Choose an address to map it to. 292 * Choose an address to map it to.
@@ -232,12 +309,16 @@ __ioremap(unsigned long addr, unsigned long size, unsigned long flags)
232 if (area == NULL) 309 if (area == NULL)
233 return NULL; 310 return NULL;
234 ea = (unsigned long)(area->addr); 311 ea = (unsigned long)(area->addr);
312 ret = __ioremap_com(addr, pa, ea, size, flags);
313 if (!ret)
314 im_free(area->addr);
235 } else { 315 } else {
236 ea = ioremap_bot; 316 ea = ioremap_bot;
237 ioremap_bot += size; 317 ret = __ioremap_com(addr, pa, ea, size, flags);
318 if (ret)
319 ioremap_bot += size;
238 } 320 }
239 321 return ret;
240 return __ioremap_com(addr, pa, ea, size, flags);
241} 322}
242 323
243#define IS_PAGE_ALIGNED(_val) ((_val) == ((_val) & PAGE_MASK)) 324#define IS_PAGE_ALIGNED(_val) ((_val) == ((_val) & PAGE_MASK))
@@ -246,6 +327,7 @@ int __ioremap_explicit(unsigned long pa, unsigned long ea,
246 unsigned long size, unsigned long flags) 327 unsigned long size, unsigned long flags)
247{ 328{
248 struct vm_struct *area; 329 struct vm_struct *area;
330 void __iomem *ret;
249 331
250 /* For now, require page-aligned values for pa, ea, and size */ 332 /* For now, require page-aligned values for pa, ea, and size */
251 if (!IS_PAGE_ALIGNED(pa) || !IS_PAGE_ALIGNED(ea) || 333 if (!IS_PAGE_ALIGNED(pa) || !IS_PAGE_ALIGNED(ea) ||
@@ -276,7 +358,12 @@ int __ioremap_explicit(unsigned long pa, unsigned long ea,
276 } 358 }
277 } 359 }
278 360
279 if (__ioremap_com(pa, pa, ea, size, flags) != (void *) ea) { 361 ret = __ioremap_com(pa, pa, ea, size, flags);
362 if (ret == NULL) {
363 printk(KERN_ERR "ioremap_explicit() allocation failure !\n");
364 return 1;
365 }
366 if (ret != (void *) ea) {
280 printk(KERN_ERR "__ioremap_com() returned unexpected addr\n"); 367 printk(KERN_ERR "__ioremap_com() returned unexpected addr\n");
281 return 1; 368 return 1;
282 } 369 }
@@ -284,69 +371,6 @@ int __ioremap_explicit(unsigned long pa, unsigned long ea,
284 return 0; 371 return 0;
285} 372}
286 373
287static void unmap_im_area_pte(pmd_t *pmd, unsigned long address,
288 unsigned long size)
289{
290 unsigned long base, end;
291 pte_t *pte;
292
293 if (pmd_none(*pmd))
294 return;
295 if (pmd_bad(*pmd)) {
296 pmd_ERROR(*pmd);
297 pmd_clear(pmd);
298 return;
299 }
300
301 pte = pte_offset_kernel(pmd, address);
302 base = address & PMD_MASK;
303 address &= ~PMD_MASK;
304 end = address + size;
305 if (end > PMD_SIZE)
306 end = PMD_SIZE;
307
308 do {
309 pte_t page;
310 page = ptep_get_and_clear(&ioremap_mm, base + address, pte);
311 address += PAGE_SIZE;
312 pte++;
313 if (pte_none(page))
314 continue;
315 if (pte_present(page))
316 continue;
317 printk(KERN_CRIT "Whee.. Swapped out page in kernel page"
318 " table\n");
319 } while (address < end);
320}
321
322static void unmap_im_area_pmd(pgd_t *dir, unsigned long address,
323 unsigned long size)
324{
325 unsigned long base, end;
326 pmd_t *pmd;
327
328 if (pgd_none(*dir))
329 return;
330 if (pgd_bad(*dir)) {
331 pgd_ERROR(*dir);
332 pgd_clear(dir);
333 return;
334 }
335
336 pmd = pmd_offset(dir, address);
337 base = address & PGDIR_MASK;
338 address &= ~PGDIR_MASK;
339 end = address + size;
340 if (end > PGDIR_SIZE)
341 end = PGDIR_SIZE;
342
343 do {
344 unmap_im_area_pte(pmd, base + address, end - address);
345 address = (address + PMD_SIZE) & PMD_MASK;
346 pmd++;
347 } while (address < end);
348}
349
350/* 374/*
351 * Unmap an IO region and remove it from imalloc'd list. 375 * Unmap an IO region and remove it from imalloc'd list.
352 * Access to IO memory should be serialized by driver. 376 * 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,
356 */ 380 */
357void iounmap(volatile void __iomem *token) 381void iounmap(volatile void __iomem *token)
358{ 382{
359 unsigned long address, start, end, size; 383 unsigned long address, size;
360 struct mm_struct *mm;
361 pgd_t *dir;
362 void *addr; 384 void *addr;
363 385
364 if (!mem_init_done) { 386 if (!mem_init_done)
365 return; 387 return;
366 }
367 388
368 addr = (void *) ((unsigned long __force) token & PAGE_MASK); 389 addr = (void *) ((unsigned long __force) token & PAGE_MASK);
369 390
370 if ((size = im_free(addr)) == 0) { 391 if ((size = im_free(addr)) == 0)
371 return; 392 return;
372 }
373 393
374 address = (unsigned long)addr; 394 address = (unsigned long)addr;
375 start = address; 395 unmap_im_area(address, address + size);
376 end = address + size;
377
378 mm = &ioremap_mm;
379 spin_lock(&mm->page_table_lock);
380
381 dir = pgd_offset_i(address);
382 flush_cache_vunmap(address, end);
383 do {
384 unmap_im_area_pmd(dir, address, end - address);
385 address = (address + PGDIR_SIZE) & PGDIR_MASK;
386 dir++;
387 } while (address && (address < end));
388 flush_tlb_kernel_range(start, end);
389
390 spin_unlock(&mm->page_table_lock);
391 return;
392} 396}
393 397
394static int iounmap_subset_regions(unsigned long addr, unsigned long size) 398static 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 6a20773f695d..244150a0bc18 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)
33 return (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | flags; 33 return (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | flags;
34} 34}
35 35
36static inline void create_slbe(unsigned long ea, unsigned long vsid, 36static inline void create_slbe(unsigned long ea, unsigned long flags,
37 unsigned long flags, unsigned long entry) 37 unsigned long entry)
38{ 38{
39 asm volatile("slbmte %0,%1" : 39 asm volatile("slbmte %0,%1" :
40 : "r" (mk_vsid_data(ea, flags)), 40 : "r" (mk_vsid_data(ea, flags)),
@@ -145,9 +145,8 @@ void slb_initialize(void)
145 asm volatile("isync":::"memory"); 145 asm volatile("isync":::"memory");
146 asm volatile("slbmte %0,%0"::"r" (0) : "memory"); 146 asm volatile("slbmte %0,%0"::"r" (0) : "memory");
147 asm volatile("isync; slbia; isync":::"memory"); 147 asm volatile("isync; slbia; isync":::"memory");
148 create_slbe(KERNELBASE, get_kernel_vsid(KERNELBASE), flags, 0); 148 create_slbe(KERNELBASE, flags, 0);
149 create_slbe(VMALLOCBASE, get_kernel_vsid(KERNELBASE), 149 create_slbe(VMALLOCBASE, SLB_VSID_KERNEL, 1);
150 SLB_VSID_KERNEL, 1);
151 /* We don't bolt the stack for the time being - we're in boot, 150 /* We don't bolt the stack for the time being - we're in boot,
152 * so the stack is in the bolted segment. By the time it goes 151 * so the stack is in the bolted segment. By the time it goes
153 * elsewhere, we'll call _switch() which will bolt in the new 152 * elsewhere, we'll call _switch() which will bolt in the new
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index 1358b4201701..07fd0414a4bf 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11 3# Linux kernel version: 2.6.12-rc3
4# Wed Mar 2 16:57:55 2005 4# Fri Apr 22 15:30:58 2005
5# 5#
6CONFIG_MMU=y 6CONFIG_MMU=y
7CONFIG_RWSEM_XCHGADD_ALGORITHM=y 7CONFIG_RWSEM_XCHGADD_ALGORITHM=y
@@ -15,6 +15,7 @@ CONFIG_UID16=y
15CONFIG_EXPERIMENTAL=y 15CONFIG_EXPERIMENTAL=y
16CONFIG_CLEAN_COMPILE=y 16CONFIG_CLEAN_COMPILE=y
17CONFIG_LOCK_KERNEL=y 17CONFIG_LOCK_KERNEL=y
18CONFIG_INIT_ENV_ARG_LIMIT=32
18 19
19# 20#
20# General setup 21# General setup
@@ -26,24 +27,25 @@ CONFIG_SYSVIPC=y
26# CONFIG_BSD_PROCESS_ACCT is not set 27# CONFIG_BSD_PROCESS_ACCT is not set
27CONFIG_SYSCTL=y 28CONFIG_SYSCTL=y
28# CONFIG_AUDIT is not set 29# CONFIG_AUDIT is not set
29CONFIG_LOG_BUF_SHIFT=17
30CONFIG_HOTPLUG=y 30CONFIG_HOTPLUG=y
31CONFIG_KOBJECT_UEVENT=y 31CONFIG_KOBJECT_UEVENT=y
32CONFIG_IKCONFIG=y 32CONFIG_IKCONFIG=y
33CONFIG_IKCONFIG_PROC=y 33CONFIG_IKCONFIG_PROC=y
34# CONFIG_CPUSETS is not set
34# CONFIG_EMBEDDED is not set 35# CONFIG_EMBEDDED is not set
35CONFIG_KALLSYMS=y 36CONFIG_KALLSYMS=y
36# CONFIG_KALLSYMS_ALL is not set 37# CONFIG_KALLSYMS_ALL is not set
37# CONFIG_KALLSYMS_EXTRA_PASS is not set 38# CONFIG_KALLSYMS_EXTRA_PASS is not set
39CONFIG_BASE_FULL=y
38CONFIG_FUTEX=y 40CONFIG_FUTEX=y
39CONFIG_EPOLL=y 41CONFIG_EPOLL=y
40# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
41CONFIG_SHMEM=y 42CONFIG_SHMEM=y
42CONFIG_CC_ALIGN_FUNCTIONS=0 43CONFIG_CC_ALIGN_FUNCTIONS=0
43CONFIG_CC_ALIGN_LABELS=0 44CONFIG_CC_ALIGN_LABELS=0
44CONFIG_CC_ALIGN_LOOPS=0 45CONFIG_CC_ALIGN_LOOPS=0
45CONFIG_CC_ALIGN_JUMPS=0 46CONFIG_CC_ALIGN_JUMPS=0
46# CONFIG_TINY_SHMEM is not set 47# CONFIG_TINY_SHMEM is not set
48CONFIG_BASE_SMALL=0
47 49
48# 50#
49# Loadable module support 51# Loadable module support
@@ -261,7 +263,6 @@ CONFIG_NET=y
261# 263#
262CONFIG_PACKET=y 264CONFIG_PACKET=y
263# CONFIG_PACKET_MMAP is not set 265# CONFIG_PACKET_MMAP is not set
264# CONFIG_NETLINK_DEV is not set
265CONFIG_UNIX=y 266CONFIG_UNIX=y
266CONFIG_NET_KEY=y 267CONFIG_NET_KEY=y
267CONFIG_INET=y 268CONFIG_INET=y
@@ -329,6 +330,7 @@ CONFIG_NET_SCH_DSMARK=m
329CONFIG_NET_QOS=y 330CONFIG_NET_QOS=y
330CONFIG_NET_ESTIMATOR=y 331CONFIG_NET_ESTIMATOR=y
331CONFIG_NET_CLS=y 332CONFIG_NET_CLS=y
333# CONFIG_NET_CLS_BASIC is not set
332CONFIG_NET_CLS_TCINDEX=m 334CONFIG_NET_CLS_TCINDEX=m
333CONFIG_NET_CLS_ROUTE4=m 335CONFIG_NET_CLS_ROUTE4=m
334CONFIG_NET_CLS_ROUTE=y 336CONFIG_NET_CLS_ROUTE=y
@@ -338,6 +340,7 @@ CONFIG_NET_CLS_U32=m
338# CONFIG_NET_CLS_IND is not set 340# CONFIG_NET_CLS_IND is not set
339CONFIG_NET_CLS_RSVP=m 341CONFIG_NET_CLS_RSVP=m
340CONFIG_NET_CLS_RSVP6=m 342CONFIG_NET_CLS_RSVP6=m
343# CONFIG_NET_EMATCH is not set
341# CONFIG_NET_CLS_ACT is not set 344# CONFIG_NET_CLS_ACT is not set
342CONFIG_NET_CLS_POLICE=y 345CONFIG_NET_CLS_POLICE=y
343 346
@@ -393,6 +396,8 @@ CONFIG_CTC=m
393CONFIG_IUCV=m 396CONFIG_IUCV=m
394# CONFIG_NETIUCV is not set 397# CONFIG_NETIUCV is not set
395# CONFIG_SMSGIUCV is not set 398# CONFIG_SMSGIUCV is not set
399# CONFIG_CLAW is not set
400# CONFIG_MPC is not set
396CONFIG_QETH=y 401CONFIG_QETH=y
397 402
398# 403#
@@ -532,10 +537,13 @@ CONFIG_MSDOS_PARTITION=y
532# 537#
533# Kernel hacking 538# Kernel hacking
534# 539#
540# CONFIG_PRINTK_TIME is not set
535CONFIG_DEBUG_KERNEL=y 541CONFIG_DEBUG_KERNEL=y
536CONFIG_MAGIC_SYSRQ=y 542CONFIG_MAGIC_SYSRQ=y
543CONFIG_LOG_BUF_SHIFT=17
537# CONFIG_SCHEDSTATS is not set 544# CONFIG_SCHEDSTATS is not set
538# CONFIG_DEBUG_SLAB is not set 545# CONFIG_DEBUG_SLAB is not set
546# CONFIG_DEBUG_SPINLOCK is not set
539# CONFIG_DEBUG_SPINLOCK_SLEEP is not set 547# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
540# CONFIG_DEBUG_KOBJECT is not set 548# CONFIG_DEBUG_KOBJECT is not set
541# CONFIG_DEBUG_INFO is not set 549# CONFIG_DEBUG_INFO is not set
@@ -560,6 +568,7 @@ CONFIG_CRYPTO=y
560# CONFIG_CRYPTO_SHA256 is not set 568# CONFIG_CRYPTO_SHA256 is not set
561# CONFIG_CRYPTO_SHA512 is not set 569# CONFIG_CRYPTO_SHA512 is not set
562# CONFIG_CRYPTO_WP512 is not set 570# CONFIG_CRYPTO_WP512 is not set
571# CONFIG_CRYPTO_TGR192 is not set
563# CONFIG_CRYPTO_DES is not set 572# CONFIG_CRYPTO_DES is not set
564# CONFIG_CRYPTO_DES_Z990 is not set 573# CONFIG_CRYPTO_DES_Z990 is not set
565# CONFIG_CRYPTO_BLOWFISH is not set 574# CONFIG_CRYPTO_BLOWFISH is not set
diff --git a/arch/s390/kernel/compat_ioctl.c b/arch/s390/kernel/compat_ioctl.c
index 96571ff7115d..03d03c6d3cbb 100644
--- a/arch/s390/kernel/compat_ioctl.c
+++ b/arch/s390/kernel/compat_ioctl.c
@@ -16,6 +16,7 @@
16#define CODE 16#define CODE
17#include "../../../fs/compat_ioctl.c" 17#include "../../../fs/compat_ioctl.c"
18#include <asm/dasd.h> 18#include <asm/dasd.h>
19#include <asm/cmb.h>
19#include <asm/tape390.h> 20#include <asm/tape390.h>
20 21
21static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd, 22static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd,
@@ -58,7 +59,11 @@ COMPATIBLE_IOCTL(BIODASDPRRD)
58COMPATIBLE_IOCTL(BIODASDPSRD) 59COMPATIBLE_IOCTL(BIODASDPSRD)
59COMPATIBLE_IOCTL(BIODASDGATTR) 60COMPATIBLE_IOCTL(BIODASDGATTR)
60COMPATIBLE_IOCTL(BIODASDSATTR) 61COMPATIBLE_IOCTL(BIODASDSATTR)
61 62#if defined(CONFIG_DASD_CMB) || defined(CONFIG_DASD_CMB_MODULE)
63COMPATIBLE_IOCTL(BIODASDCMFENABLE)
64COMPATIBLE_IOCTL(BIODASDCMFDISABLE)
65COMPATIBLE_IOCTL(BIODASDREADALLCMB)
66#endif
62#endif 67#endif
63 68
64#if defined(CONFIG_S390_TAPE) || defined(CONFIG_S390_TAPE_MODULE) 69#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 2d546c67f7c3..26889366929a 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -32,6 +32,7 @@
32#include <linux/user.h> 32#include <linux/user.h>
33#include <linux/security.h> 33#include <linux/security.h>
34#include <linux/audit.h> 34#include <linux/audit.h>
35#include <linux/signal.h>
35 36
36#include <asm/segment.h> 37#include <asm/segment.h>
37#include <asm/page.h> 38#include <asm/page.h>
@@ -609,7 +610,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data)
609 /* continue and stop at next (return from) syscall */ 610 /* continue and stop at next (return from) syscall */
610 case PTRACE_CONT: 611 case PTRACE_CONT:
611 /* restart after signal. */ 612 /* restart after signal. */
612 if ((unsigned long) data >= _NSIG) 613 if (!valid_signal(data))
613 return -EIO; 614 return -EIO;
614 if (request == PTRACE_SYSCALL) 615 if (request == PTRACE_SYSCALL)
615 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 616 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -637,7 +638,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data)
637 638
638 case PTRACE_SINGLESTEP: 639 case PTRACE_SINGLESTEP:
639 /* set the trap flag. */ 640 /* set the trap flag. */
640 if ((unsigned long) data >= _NSIG) 641 if (!valid_signal(data))
641 return -EIO; 642 return -EIO;
642 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 643 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
643 child->exit_code = data; 644 child->exit_code = data;
diff --git a/arch/s390/kernel/s390_ksyms.c b/arch/s390/kernel/s390_ksyms.c
index 11fd6d556d8f..bee654abb6d3 100644
--- a/arch/s390/kernel/s390_ksyms.c
+++ b/arch/s390/kernel/s390_ksyms.c
@@ -34,7 +34,6 @@ EXPORT_SYMBOL(__clear_user_asm);
34EXPORT_SYMBOL(__strncpy_from_user_asm); 34EXPORT_SYMBOL(__strncpy_from_user_asm);
35EXPORT_SYMBOL(__strnlen_user_asm); 35EXPORT_SYMBOL(__strnlen_user_asm);
36EXPORT_SYMBOL(diag10); 36EXPORT_SYMBOL(diag10);
37EXPORT_SYMBOL(default_storage_key);
38 37
39/* 38/*
40 * semaphore ops 39 * semaphore ops
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index c879c40aa7a5..df83215beac3 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -44,6 +44,8 @@
44#include <asm/cpcmd.h> 44#include <asm/cpcmd.h>
45#include <asm/lowcore.h> 45#include <asm/lowcore.h>
46#include <asm/irq.h> 46#include <asm/irq.h>
47#include <asm/page.h>
48#include <asm/ptrace.h>
47 49
48/* 50/*
49 * Machine setup.. 51 * Machine setup..
@@ -53,13 +55,14 @@ unsigned int console_devno = -1;
53unsigned int console_irq = -1; 55unsigned int console_irq = -1;
54unsigned long memory_size = 0; 56unsigned long memory_size = 0;
55unsigned long machine_flags = 0; 57unsigned long machine_flags = 0;
56unsigned int default_storage_key = 0;
57struct { 58struct {
58 unsigned long addr, size, type; 59 unsigned long addr, size, type;
59} memory_chunk[MEMORY_CHUNKS] = { { 0 } }; 60} memory_chunk[MEMORY_CHUNKS] = { { 0 } };
60#define CHUNK_READ_WRITE 0 61#define CHUNK_READ_WRITE 0
61#define CHUNK_READ_ONLY 1 62#define CHUNK_READ_ONLY 1
62volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ 63volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */
64unsigned long __initdata zholes_size[MAX_NR_ZONES];
65static unsigned long __initdata memory_end;
63 66
64/* 67/*
65 * Setup options 68 * Setup options
@@ -78,11 +81,15 @@ static char command_line[COMMAND_LINE_SIZE] = { 0, };
78 81
79static struct resource code_resource = { 82static struct resource code_resource = {
80 .name = "Kernel code", 83 .name = "Kernel code",
84 .start = (unsigned long) &_text,
85 .end = (unsigned long) &_etext - 1,
81 .flags = IORESOURCE_BUSY | IORESOURCE_MEM, 86 .flags = IORESOURCE_BUSY | IORESOURCE_MEM,
82}; 87};
83 88
84static struct resource data_resource = { 89static struct resource data_resource = {
85 .name = "Kernel data", 90 .name = "Kernel data",
91 .start = (unsigned long) &_etext,
92 .end = (unsigned long) &_edata - 1,
86 .flags = IORESOURCE_BUSY | IORESOURCE_MEM, 93 .flags = IORESOURCE_BUSY | IORESOURCE_MEM,
87}; 94};
88 95
@@ -310,90 +317,50 @@ void machine_power_off(void)
310 317
311EXPORT_SYMBOL(machine_power_off); 318EXPORT_SYMBOL(machine_power_off);
312 319
313/* 320static void __init
314 * Setup function called from init/main.c just after the banner 321add_memory_hole(unsigned long start, unsigned long end)
315 * was printed. 322{
316 */ 323 unsigned long dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT;
317extern char _pstart, _pend, _stext; 324
325 if (end <= dma_pfn)
326 zholes_size[ZONE_DMA] += end - start + 1;
327 else if (start > dma_pfn)
328 zholes_size[ZONE_NORMAL] += end - start + 1;
329 else {
330 zholes_size[ZONE_DMA] += dma_pfn - start + 1;
331 zholes_size[ZONE_NORMAL] += end - dma_pfn;
332 }
333}
318 334
319void __init setup_arch(char **cmdline_p) 335static void __init
336parse_cmdline_early(char **cmdline_p)
320{ 337{
321 unsigned long bootmap_size; 338 char c = ' ', cn, *to = command_line, *from = COMMAND_LINE;
322 unsigned long memory_start, memory_end; 339 unsigned long delay = 0;
323 char c = ' ', cn, *to = command_line, *from = COMMAND_LINE;
324 unsigned long start_pfn, end_pfn;
325 static unsigned int smptrap=0;
326 unsigned long delay = 0;
327 struct _lowcore *lc;
328 int i;
329 340
330 if (smptrap) 341 /* Save unparsed command line copy for /proc/cmdline */
331 return; 342 memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
332 smptrap=1; 343 saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
333 344
334 /* 345 for (;;) {
335 * print what head.S has found out about the machine 346 /*
336 */ 347 * "mem=XXX[kKmM]" sets memsize
337#ifndef CONFIG_ARCH_S390X 348 */
338 printk((MACHINE_IS_VM) ? 349 if (c == ' ' && strncmp(from, "mem=", 4) == 0) {
339 "We are running under VM (31 bit mode)\n" : 350 memory_end = simple_strtoul(from+4, &from, 0);
340 "We are running native (31 bit mode)\n"); 351 if ( *from == 'K' || *from == 'k' ) {
341 printk((MACHINE_HAS_IEEE) ? 352 memory_end = memory_end << 10;
342 "This machine has an IEEE fpu\n" : 353 from++;
343 "This machine has no IEEE fpu\n"); 354 } else if ( *from == 'M' || *from == 'm' ) {
344#else /* CONFIG_ARCH_S390X */ 355 memory_end = memory_end << 20;
345 printk((MACHINE_IS_VM) ? 356 from++;
346 "We are running under VM (64 bit mode)\n" : 357 }
347 "We are running native (64 bit mode)\n"); 358 }
348#endif /* CONFIG_ARCH_S390X */ 359 /*
349 360 * "ipldelay=XXX[sm]" sets ipl delay in seconds or minutes
350 ROOT_DEV = Root_RAM0; 361 */
351 memory_start = (unsigned long) &_end; /* fixit if use $CODELO etc*/ 362 if (c == ' ' && strncmp(from, "ipldelay=", 9) == 0) {
352#ifndef CONFIG_ARCH_S390X 363 delay = simple_strtoul(from+9, &from, 0);
353 memory_end = memory_size & ~0x400000UL; /* align memory end to 4MB */
354 /*
355 * We need some free virtual space to be able to do vmalloc.
356 * On a machine with 2GB memory we make sure that we have at
357 * least 128 MB free space for vmalloc.
358 */
359 if (memory_end > 1920*1024*1024)
360 memory_end = 1920*1024*1024;
361#else /* CONFIG_ARCH_S390X */
362 memory_end = memory_size & ~0x200000UL; /* detected in head.s */
363#endif /* CONFIG_ARCH_S390X */
364 init_mm.start_code = PAGE_OFFSET;
365 init_mm.end_code = (unsigned long) &_etext;
366 init_mm.end_data = (unsigned long) &_edata;
367 init_mm.brk = (unsigned long) &_end;
368
369 code_resource.start = (unsigned long) &_text;
370 code_resource.end = (unsigned long) &_etext - 1;
371 data_resource.start = (unsigned long) &_etext;
372 data_resource.end = (unsigned long) &_edata - 1;
373
374 /* Save unparsed command line copy for /proc/cmdline */
375 memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
376 saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
377
378 for (;;) {
379 /*
380 * "mem=XXX[kKmM]" sets memsize
381 */
382 if (c == ' ' && strncmp(from, "mem=", 4) == 0) {
383 memory_end = simple_strtoul(from+4, &from, 0);
384 if ( *from == 'K' || *from == 'k' ) {
385 memory_end = memory_end << 10;
386 from++;
387 } else if ( *from == 'M' || *from == 'm' ) {
388 memory_end = memory_end << 20;
389 from++;
390 }
391 }
392 /*
393 * "ipldelay=XXX[sm]" sets ipl delay in seconds or minutes
394 */
395 if (c == ' ' && strncmp(from, "ipldelay=", 9) == 0) {
396 delay = simple_strtoul(from+9, &from, 0);
397 if (*from == 's' || *from == 'S') { 364 if (*from == 's' || *from == 'S') {
398 delay = delay*1000000; 365 delay = delay*1000000;
399 from++; 366 from++;
@@ -403,24 +370,110 @@ void __init setup_arch(char **cmdline_p)
403 } 370 }
404 /* now wait for the requested amount of time */ 371 /* now wait for the requested amount of time */
405 udelay(delay); 372 udelay(delay);
406 } 373 }
407 cn = *(from++); 374 cn = *(from++);
408 if (!cn) 375 if (!cn)
409 break; 376 break;
410 if (cn == '\n') 377 if (cn == '\n')
411 cn = ' '; /* replace newlines with space */ 378 cn = ' '; /* replace newlines with space */
412 if (cn == 0x0d) 379 if (cn == 0x0d)
413 cn = ' '; /* replace 0x0d with space */ 380 cn = ' '; /* replace 0x0d with space */
414 if (cn == ' ' && c == ' ') 381 if (cn == ' ' && c == ' ')
415 continue; /* remove additional spaces */ 382 continue; /* remove additional spaces */
416 c = cn; 383 c = cn;
417 if (to - command_line >= COMMAND_LINE_SIZE) 384 if (to - command_line >= COMMAND_LINE_SIZE)
418 break; 385 break;
419 *(to++) = c; 386 *(to++) = c;
420 } 387 }
421 if (c == ' ' && to > command_line) to--; 388 if (c == ' ' && to > command_line) to--;
422 *to = '\0'; 389 *to = '\0';
423 *cmdline_p = command_line; 390 *cmdline_p = command_line;
391}
392
393static void __init
394setup_lowcore(void)
395{
396 struct _lowcore *lc;
397 int lc_pages;
398
399 /*
400 * Setup lowcore for boot cpu
401 */
402 lc_pages = sizeof(void *) == 8 ? 2 : 1;
403 lc = (struct _lowcore *)
404 __alloc_bootmem(lc_pages * PAGE_SIZE, lc_pages * PAGE_SIZE, 0);
405 memset(lc, 0, lc_pages * PAGE_SIZE);
406 lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
407 lc->restart_psw.addr =
408 PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
409 lc->external_new_psw.mask = PSW_KERNEL_BITS;
410 lc->external_new_psw.addr =
411 PSW_ADDR_AMODE | (unsigned long) ext_int_handler;
412 lc->svc_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_IO | PSW_MASK_EXT;
413 lc->svc_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) system_call;
414 lc->program_new_psw.mask = PSW_KERNEL_BITS;
415 lc->program_new_psw.addr =
416 PSW_ADDR_AMODE | (unsigned long)pgm_check_handler;
417 lc->mcck_new_psw.mask = PSW_KERNEL_BITS;
418 lc->mcck_new_psw.addr =
419 PSW_ADDR_AMODE | (unsigned long) mcck_int_handler;
420 lc->io_new_psw.mask = PSW_KERNEL_BITS;
421 lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler;
422 lc->ipl_device = S390_lowcore.ipl_device;
423 lc->jiffy_timer = -1LL;
424 lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE;
425 lc->async_stack = (unsigned long)
426 __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) + ASYNC_SIZE;
427#ifdef CONFIG_CHECK_STACK
428 lc->panic_stack = (unsigned long)
429 __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0) + PAGE_SIZE;
430#endif
431 lc->current_task = (unsigned long) init_thread_union.thread_info.task;
432 lc->thread_info = (unsigned long) &init_thread_union;
433#ifdef CONFIG_ARCH_S390X
434 if (MACHINE_HAS_DIAG44)
435 lc->diag44_opcode = 0x83000044;
436 else
437 lc->diag44_opcode = 0x07000700;
438#endif /* CONFIG_ARCH_S390X */
439 set_prefix((u32)(unsigned long) lc);
440}
441
442static void __init
443setup_resources(void)
444{
445 struct resource *res;
446 int i;
447
448 for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) {
449 res = alloc_bootmem_low(sizeof(struct resource));
450 res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
451 switch (memory_chunk[i].type) {
452 case CHUNK_READ_WRITE:
453 res->name = "System RAM";
454 break;
455 case CHUNK_READ_ONLY:
456 res->name = "System ROM";
457 res->flags |= IORESOURCE_READONLY;
458 break;
459 default:
460 res->name = "reserved";
461 }
462 res->start = memory_chunk[i].addr;
463 res->end = memory_chunk[i].addr + memory_chunk[i].size - 1;
464 request_resource(&iomem_resource, res);
465 request_resource(res, &code_resource);
466 request_resource(res, &data_resource);
467 }
468}
469
470static void __init
471setup_memory(void)
472{
473 unsigned long bootmap_size;
474 unsigned long start_pfn, end_pfn, init_pfn;
475 unsigned long last_rw_end;
476 int i;
424 477
425 /* 478 /*
426 * partially used pages are not usable - thus 479 * partially used pages are not usable - thus
@@ -429,6 +482,10 @@ void __init setup_arch(char **cmdline_p)
429 start_pfn = (__pa(&_end) + PAGE_SIZE - 1) >> PAGE_SHIFT; 482 start_pfn = (__pa(&_end) + PAGE_SIZE - 1) >> PAGE_SHIFT;
430 end_pfn = max_pfn = memory_end >> PAGE_SHIFT; 483 end_pfn = max_pfn = memory_end >> PAGE_SHIFT;
431 484
485 /* Initialize storage key for kernel pages */
486 for (init_pfn = 0 ; init_pfn < start_pfn; init_pfn++)
487 page_set_storage_key(init_pfn << PAGE_SHIFT, PAGE_DEFAULT_KEY);
488
432 /* 489 /*
433 * Initialize the boot-time allocator (with low memory only): 490 * Initialize the boot-time allocator (with low memory only):
434 */ 491 */
@@ -437,7 +494,9 @@ void __init setup_arch(char **cmdline_p)
437 /* 494 /*
438 * Register RAM areas with the bootmem allocator. 495 * Register RAM areas with the bootmem allocator.
439 */ 496 */
440 for (i = 0; i < 16 && memory_chunk[i].size > 0; i++) { 497 last_rw_end = start_pfn;
498
499 for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) {
441 unsigned long start_chunk, end_chunk; 500 unsigned long start_chunk, end_chunk;
442 501
443 if (memory_chunk[i].type != CHUNK_READ_WRITE) 502 if (memory_chunk[i].type != CHUNK_READ_WRITE)
@@ -450,102 +509,98 @@ void __init setup_arch(char **cmdline_p)
450 start_chunk = start_pfn; 509 start_chunk = start_pfn;
451 if (end_chunk > end_pfn) 510 if (end_chunk > end_pfn)
452 end_chunk = end_pfn; 511 end_chunk = end_pfn;
453 if (start_chunk < end_chunk) 512 if (start_chunk < end_chunk) {
513 /* Initialize storage key for RAM pages */
514 for (init_pfn = start_chunk ; init_pfn < end_chunk;
515 init_pfn++)
516 page_set_storage_key(init_pfn << PAGE_SHIFT,
517 PAGE_DEFAULT_KEY);
454 free_bootmem(start_chunk << PAGE_SHIFT, 518 free_bootmem(start_chunk << PAGE_SHIFT,
455 (end_chunk - start_chunk) << PAGE_SHIFT); 519 (end_chunk - start_chunk) << PAGE_SHIFT);
520 if (last_rw_end < start_chunk)
521 add_memory_hole(last_rw_end, start_chunk - 1);
522 last_rw_end = end_chunk;
523 }
456 } 524 }
457 525
458 /* 526 psw_set_key(PAGE_DEFAULT_KEY);
459 * Reserve the bootmem bitmap itself as well. We do this in two 527
460 * steps (first step was init_bootmem()) because this catches 528 if (last_rw_end < end_pfn - 1)
461 * the (very unlikely) case of us accidentally initializing the 529 add_memory_hole(last_rw_end, end_pfn - 1);
462 * bootmem allocator with an invalid RAM area. 530
463 */ 531 /*
464 reserve_bootmem(start_pfn << PAGE_SHIFT, bootmap_size); 532 * Reserve the bootmem bitmap itself as well. We do this in two
533 * steps (first step was init_bootmem()) because this catches
534 * the (very unlikely) case of us accidentally initializing the
535 * bootmem allocator with an invalid RAM area.
536 */
537 reserve_bootmem(start_pfn << PAGE_SHIFT, bootmap_size);
465 538
466#ifdef CONFIG_BLK_DEV_INITRD 539#ifdef CONFIG_BLK_DEV_INITRD
467 if (INITRD_START) { 540 if (INITRD_START) {
468 if (INITRD_START + INITRD_SIZE <= memory_end) { 541 if (INITRD_START + INITRD_SIZE <= memory_end) {
469 reserve_bootmem(INITRD_START, INITRD_SIZE); 542 reserve_bootmem(INITRD_START, INITRD_SIZE);
470 initrd_start = INITRD_START; 543 initrd_start = INITRD_START;
471 initrd_end = initrd_start + INITRD_SIZE; 544 initrd_end = initrd_start + INITRD_SIZE;
472 } else { 545 } else {
473 printk("initrd extends beyond end of memory " 546 printk("initrd extends beyond end of memory "
474 "(0x%08lx > 0x%08lx)\ndisabling initrd\n", 547 "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
475 initrd_start + INITRD_SIZE, memory_end); 548 initrd_start + INITRD_SIZE, memory_end);
476 initrd_start = initrd_end = 0; 549 initrd_start = initrd_end = 0;
477 } 550 }
478 } 551 }
479#endif 552#endif
553}
480 554
481 for (i = 0; i < 16 && memory_chunk[i].size > 0; i++) { 555/*
482 struct resource *res; 556 * Setup function called from init/main.c just after the banner
483 557 * was printed.
484 res = alloc_bootmem_low(sizeof(struct resource)); 558 */
485 res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
486
487 switch (memory_chunk[i].type) {
488 case CHUNK_READ_WRITE:
489 res->name = "System RAM";
490 break;
491 case CHUNK_READ_ONLY:
492 res->name = "System ROM";
493 res->flags |= IORESOURCE_READONLY;
494 break;
495 default:
496 res->name = "reserved";
497 }
498 res->start = memory_chunk[i].addr;
499 res->end = memory_chunk[i].addr + memory_chunk[i].size - 1;
500 request_resource(&iomem_resource, res);
501 request_resource(res, &code_resource);
502 request_resource(res, &data_resource);
503 }
504 559
560void __init
561setup_arch(char **cmdline_p)
562{
505 /* 563 /*
506 * Setup lowcore for boot cpu 564 * print what head.S has found out about the machine
507 */ 565 */
508#ifndef CONFIG_ARCH_S390X 566#ifndef CONFIG_ARCH_S390X
509 lc = (struct _lowcore *) __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0); 567 printk((MACHINE_IS_VM) ?
510 memset(lc, 0, PAGE_SIZE); 568 "We are running under VM (31 bit mode)\n" :
569 "We are running native (31 bit mode)\n");
570 printk((MACHINE_HAS_IEEE) ?
571 "This machine has an IEEE fpu\n" :
572 "This machine has no IEEE fpu\n");
511#else /* CONFIG_ARCH_S390X */ 573#else /* CONFIG_ARCH_S390X */
512 lc = (struct _lowcore *) __alloc_bootmem(2*PAGE_SIZE, 2*PAGE_SIZE, 0); 574 printk((MACHINE_IS_VM) ?
513 memset(lc, 0, 2*PAGE_SIZE); 575 "We are running under VM (64 bit mode)\n" :
576 "We are running native (64 bit mode)\n");
514#endif /* CONFIG_ARCH_S390X */ 577#endif /* CONFIG_ARCH_S390X */
515 lc->restart_psw.mask = PSW_BASE_BITS; 578
516 lc->restart_psw.addr = 579 ROOT_DEV = Root_RAM0;
517 PSW_ADDR_AMODE | (unsigned long) restart_int_handler; 580#ifndef CONFIG_ARCH_S390X
518 lc->external_new_psw.mask = PSW_KERNEL_BITS; 581 memory_end = memory_size & ~0x400000UL; /* align memory end to 4MB */
519 lc->external_new_psw.addr = 582 /*
520 PSW_ADDR_AMODE | (unsigned long) ext_int_handler; 583 * We need some free virtual space to be able to do vmalloc.
521 lc->svc_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_IO | PSW_MASK_EXT; 584 * On a machine with 2GB memory we make sure that we have at
522 lc->svc_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) system_call; 585 * least 128 MB free space for vmalloc.
523 lc->program_new_psw.mask = PSW_KERNEL_BITS; 586 */
524 lc->program_new_psw.addr = 587 if (memory_end > 1920*1024*1024)
525 PSW_ADDR_AMODE | (unsigned long)pgm_check_handler; 588 memory_end = 1920*1024*1024;
526 lc->mcck_new_psw.mask = PSW_KERNEL_BITS; 589#else /* CONFIG_ARCH_S390X */
527 lc->mcck_new_psw.addr = 590 memory_end = memory_size & ~0x200000UL; /* detected in head.s */
528 PSW_ADDR_AMODE | (unsigned long) mcck_int_handler;
529 lc->io_new_psw.mask = PSW_KERNEL_BITS;
530 lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler;
531 lc->ipl_device = S390_lowcore.ipl_device;
532 lc->jiffy_timer = -1LL;
533 lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE;
534 lc->async_stack = (unsigned long)
535 __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) + ASYNC_SIZE;
536#ifdef CONFIG_CHECK_STACK
537 lc->panic_stack = (unsigned long)
538 __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0) + PAGE_SIZE;
539#endif
540 lc->current_task = (unsigned long) init_thread_union.thread_info.task;
541 lc->thread_info = (unsigned long) &init_thread_union;
542#ifdef CONFIG_ARCH_S390X
543 if (MACHINE_HAS_DIAG44)
544 lc->diag44_opcode = 0x83000044;
545 else
546 lc->diag44_opcode = 0x07000700;
547#endif /* CONFIG_ARCH_S390X */ 591#endif /* CONFIG_ARCH_S390X */
548 set_prefix((u32)(unsigned long) lc); 592
593 init_mm.start_code = PAGE_OFFSET;
594 init_mm.end_code = (unsigned long) &_etext;
595 init_mm.end_data = (unsigned long) &_edata;
596 init_mm.brk = (unsigned long) &_end;
597
598 parse_cmdline_early(cmdline_p);
599
600 setup_memory();
601 setup_resources();
602 setup_lowcore();
603
549 cpu_init(); 604 cpu_init();
550 __cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr; 605 __cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr;
551 606
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 061e81138dc2..8ca485676780 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -244,7 +244,7 @@ int sysctl_hz_timer = 1;
244 */ 244 */
245static inline void stop_hz_timer(void) 245static inline void stop_hz_timer(void)
246{ 246{
247 __u64 timer; 247 __u64 timer, todval;
248 248
249 if (sysctl_hz_timer != 0) 249 if (sysctl_hz_timer != 0)
250 return; 250 return;
@@ -265,8 +265,14 @@ static inline void stop_hz_timer(void)
265 * for the next event. 265 * for the next event.
266 */ 266 */
267 timer = (__u64) (next_timer_interrupt() - jiffies) + jiffies_64; 267 timer = (__u64) (next_timer_interrupt() - jiffies) + jiffies_64;
268 timer = jiffies_timer_cc + timer * CLK_TICKS_PER_JIFFY; 268 todval = -1ULL;
269 asm volatile ("SCKC %0" : : "m" (timer)); 269 /* Be careful about overflows. */
270 if (timer < (-1ULL / CLK_TICKS_PER_JIFFY)) {
271 timer = jiffies_timer_cc + timer * CLK_TICKS_PER_JIFFY;
272 if (timer >= jiffies_timer_cc)
273 todval = timer;
274 }
275 asm volatile ("SCKC %0" : : "m" (todval));
270} 276}
271 277
272/* 278/*
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index bb6cf02418a2..fa0726507b3d 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -122,12 +122,17 @@ static void start_cpu_timer(void)
122 struct vtimer_queue *vt_list; 122 struct vtimer_queue *vt_list;
123 123
124 vt_list = &per_cpu(virt_cpu_timer, smp_processor_id()); 124 vt_list = &per_cpu(virt_cpu_timer, smp_processor_id());
125 set_vtimer(vt_list->idle); 125
126 /* CPU timer interrupt is pending, don't reprogramm it */
127 if (vt_list->idle & 1LL<<63)
128 return;
129
130 if (!list_empty(&vt_list->list))
131 set_vtimer(vt_list->idle);
126} 132}
127 133
128static void stop_cpu_timer(void) 134static void stop_cpu_timer(void)
129{ 135{
130 __u64 done;
131 struct vtimer_queue *vt_list; 136 struct vtimer_queue *vt_list;
132 137
133 vt_list = &per_cpu(virt_cpu_timer, smp_processor_id()); 138 vt_list = &per_cpu(virt_cpu_timer, smp_processor_id());
@@ -138,21 +143,17 @@ static void stop_cpu_timer(void)
138 goto fire; 143 goto fire;
139 } 144 }
140 145
141 /* store progress */ 146 /* store the actual expire value */
142 asm volatile ("STPT %0" : "=m" (done)); 147 asm volatile ("STPT %0" : "=m" (vt_list->idle));
143 148
144 /* 149 /*
145 * If done is negative we do not stop the CPU timer 150 * If the CPU timer is negative we don't reprogramm
146 * because we will get instantly an interrupt that 151 * it because we will get instantly an interrupt.
147 * will start the CPU timer again.
148 */ 152 */
149 if (done & 1LL<<63) 153 if (vt_list->idle & 1LL<<63)
150 return; 154 return;
151 else
152 vt_list->offset += vt_list->to_expire - done;
153 155
154 /* save the actual expire value */ 156 vt_list->offset += vt_list->to_expire - vt_list->idle;
155 vt_list->idle = done;
156 157
157 /* 158 /*
158 * We cannot halt the CPU timer, we just write a value that 159 * 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 d30cdb4248a9..f5a5bc09b8fa 100644
--- a/arch/s390/mm/cmm.c
+++ b/arch/s390/mm/cmm.c
@@ -20,6 +20,11 @@
20#include <asm/pgalloc.h> 20#include <asm/pgalloc.h>
21#include <asm/uaccess.h> 21#include <asm/uaccess.h>
22 22
23static char *sender = "VMRMSVM";
24module_param(sender, charp, 0);
25MODULE_PARM_DESC(sender,
26 "Guest name that may send SMSG messages (default VMRMSVM)");
27
23#include "../../../drivers/s390/net/smsgiucv.h" 28#include "../../../drivers/s390/net/smsgiucv.h"
24 29
25#define CMM_NR_PAGES ((PAGE_SIZE / sizeof(unsigned long)) - 2) 30#define CMM_NR_PAGES ((PAGE_SIZE / sizeof(unsigned long)) - 2)
@@ -367,10 +372,12 @@ static struct ctl_table cmm_dir_table[] = {
367#ifdef CONFIG_CMM_IUCV 372#ifdef CONFIG_CMM_IUCV
368#define SMSG_PREFIX "CMM" 373#define SMSG_PREFIX "CMM"
369static void 374static void
370cmm_smsg_target(char *msg) 375cmm_smsg_target(char *from, char *msg)
371{ 376{
372 long pages, seconds; 377 long pages, seconds;
373 378
379 if (strlen(sender) > 0 && strcmp(from, sender) != 0)
380 return;
374 if (!cmm_skip_blanks(msg + strlen(SMSG_PREFIX), &msg)) 381 if (!cmm_skip_blanks(msg + strlen(SMSG_PREFIX), &msg))
375 return; 382 return;
376 if (strncmp(msg, "SHRINK", 6) == 0) { 383 if (strncmp(msg, "SHRINK", 6) == 0) {
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index 8e723bc7f795..6ec5cd981e74 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -101,6 +101,7 @@ extern unsigned long _end;
101extern unsigned long __init_begin; 101extern unsigned long __init_begin;
102extern unsigned long __init_end; 102extern unsigned long __init_end;
103 103
104extern unsigned long __initdata zholes_size[];
104/* 105/*
105 * paging_init() sets up the page tables 106 * paging_init() sets up the page tables
106 */ 107 */
@@ -163,10 +164,13 @@ void __init paging_init(void)
163 local_flush_tlb(); 164 local_flush_tlb();
164 165
165 { 166 {
166 unsigned long zones_size[MAX_NR_ZONES] = { 0, 0, 0}; 167 unsigned long zones_size[MAX_NR_ZONES];
167 168
169 memset(zones_size, 0, sizeof(zones_size));
168 zones_size[ZONE_DMA] = max_low_pfn; 170 zones_size[ZONE_DMA] = max_low_pfn;
169 free_area_init(zones_size); 171 free_area_init_node(0, &contig_page_data, zones_size,
172 __pa(PAGE_OFFSET) >> PAGE_SHIFT,
173 zholes_size);
170 } 174 }
171 return; 175 return;
172} 176}
@@ -184,9 +188,10 @@ void __init paging_init(void)
184 _KERN_REGION_TABLE; 188 _KERN_REGION_TABLE;
185 static const int ssm_mask = 0x04000000L; 189 static const int ssm_mask = 0x04000000L;
186 190
187 unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0}; 191 unsigned long zones_size[MAX_NR_ZONES];
188 unsigned long dma_pfn, high_pfn; 192 unsigned long dma_pfn, high_pfn;
189 193
194 memset(zones_size, 0, sizeof(zones_size));
190 dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT; 195 dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT;
191 high_pfn = max_low_pfn; 196 high_pfn = max_low_pfn;
192 197
@@ -198,8 +203,8 @@ void __init paging_init(void)
198 } 203 }
199 204
200 /* Initialize mem_map[]. */ 205 /* Initialize mem_map[]. */
201 free_area_init(zones_size); 206 free_area_init_node(0, &contig_page_data, zones_size,
202 207 __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size);
203 208
204 /* 209 /*
205 * map whole physical memory to virtual memory (identity mapping) 210 * map whole physical memory to virtual memory (identity mapping)
diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c
index 1b0dfb4d8ea4..b28919b65682 100644
--- a/arch/sh/kernel/ptrace.c
+++ b/arch/sh/kernel/ptrace.c
@@ -20,6 +20,7 @@
20#include <linux/user.h> 20#include <linux/user.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/security.h> 22#include <linux/security.h>
23#include <linux/signal.h>
23 24
24#include <asm/io.h> 25#include <asm/io.h>
25#include <asm/uaccess.h> 26#include <asm/uaccess.h>
@@ -197,7 +198,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
197 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ 198 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
198 case PTRACE_CONT: { /* restart after signal. */ 199 case PTRACE_CONT: { /* restart after signal. */
199 ret = -EIO; 200 ret = -EIO;
200 if ((unsigned long) data > _NSIG) 201 if (!valid_signal(data))
201 break; 202 break;
202 if (request == PTRACE_SYSCALL) 203 if (request == PTRACE_SYSCALL)
203 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 204 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -228,7 +229,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
228 struct pt_regs *dummy = NULL; 229 struct pt_regs *dummy = NULL;
229 230
230 ret = -EIO; 231 ret = -EIO;
231 if ((unsigned long) data > _NSIG) 232 if (!valid_signal(data))
232 break; 233 break;
233 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 234 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
234 if ((child->ptrace & PT_DTRACE) == 0) { 235 if ((child->ptrace & PT_DTRACE) == 0) {
diff --git a/arch/sh64/kernel/ptrace.c b/arch/sh64/kernel/ptrace.c
index 800288c1562b..fd2000956dae 100644
--- a/arch/sh64/kernel/ptrace.c
+++ b/arch/sh64/kernel/ptrace.c
@@ -27,6 +27,7 @@
27#include <linux/errno.h> 27#include <linux/errno.h>
28#include <linux/ptrace.h> 28#include <linux/ptrace.h>
29#include <linux/user.h> 29#include <linux/user.h>
30#include <linux/signal.h>
30 31
31#include <asm/io.h> 32#include <asm/io.h>
32#include <asm/uaccess.h> 33#include <asm/uaccess.h>
@@ -255,7 +256,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
255 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ 256 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
256 case PTRACE_CONT: { /* restart after signal. */ 257 case PTRACE_CONT: { /* restart after signal. */
257 ret = -EIO; 258 ret = -EIO;
258 if ((unsigned long) data > _NSIG) 259 if (!valid_signal(data))
259 break; 260 break;
260 if (request == PTRACE_SYSCALL) 261 if (request == PTRACE_SYSCALL)
261 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 262 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -285,7 +286,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
285 struct pt_regs *regs; 286 struct pt_regs *regs;
286 287
287 ret = -EIO; 288 ret = -EIO;
288 if ((unsigned long) data > _NSIG) 289 if (!valid_signal(data))
289 break; 290 break;
290 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 291 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
291 if ((child->ptrace & PT_DTRACE) == 0) { 292 if ((child->ptrace & PT_DTRACE) == 0) {
diff --git a/arch/sh64/kernel/sys_sh64.c b/arch/sh64/kernel/sys_sh64.c
index 4546845b9caf..58ff7d522d81 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)
283 up_read(&uts_sem); 283 up_read(&uts_sem);
284 return err?-EFAULT:0; 284 return err?-EFAULT:0;
285} 285}
286
287/* Copy from mips version */
288asmlinkage long sys_shmatcall(int shmid, char __user *shmaddr,
289 int shmflg)
290{
291 unsigned long raddr;
292 int err;
293
294 err = do_shmat(shmid, shmaddr, shmflg, &raddr);
295 if (err)
296 return err;
297
298 err = raddr;
299 return err;
300}
diff --git a/arch/sh64/kernel/syscalls.S b/arch/sh64/kernel/syscalls.S
index 8ed417df3dc6..6aabc63e4518 100644
--- a/arch/sh64/kernel/syscalls.S
+++ b/arch/sh64/kernel/syscalls.S
@@ -268,7 +268,7 @@ sys_call_table:
268 .long sys_msgrcv 268 .long sys_msgrcv
269 .long sys_msgget 269 .long sys_msgget
270 .long sys_msgctl 270 .long sys_msgctl
271 .long sys_shmatcall 271 .long sys_shmat
272 .long sys_shmdt /* 245 */ 272 .long sys_shmdt /* 245 */
273 .long sys_shmget 273 .long sys_shmget
274 .long sys_shmctl 274 .long sys_shmctl
diff --git a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c
index c4f93bd2daf2..475c4c13462c 100644
--- a/arch/sparc/kernel/ptrace.c
+++ b/arch/sparc/kernel/ptrace.c
@@ -18,6 +18,7 @@
18#include <linux/smp.h> 18#include <linux/smp.h>
19#include <linux/smp_lock.h> 19#include <linux/smp_lock.h>
20#include <linux/security.h> 20#include <linux/security.h>
21#include <linux/signal.h>
21 22
22#include <asm/pgtable.h> 23#include <asm/pgtable.h>
23#include <asm/system.h> 24#include <asm/system.h>
@@ -526,7 +527,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
526 addr = 1; 527 addr = 1;
527 528
528 case PTRACE_CONT: { /* restart after signal. */ 529 case PTRACE_CONT: { /* restart after signal. */
529 if (data > _NSIG) { 530 if (!valid_signal(data)) {
530 pt_error_return(regs, EIO); 531 pt_error_return(regs, EIO);
531 goto out_tsk; 532 goto out_tsk;
532 } 533 }
diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c
index 5f080cf04b33..80a76e2ad732 100644
--- a/arch/sparc64/kernel/ptrace.c
+++ b/arch/sparc64/kernel/ptrace.c
@@ -19,6 +19,7 @@
19#include <linux/smp.h> 19#include <linux/smp.h>
20#include <linux/smp_lock.h> 20#include <linux/smp_lock.h>
21#include <linux/security.h> 21#include <linux/security.h>
22#include <linux/signal.h>
22 23
23#include <asm/asi.h> 24#include <asm/asi.h>
24#include <asm/pgtable.h> 25#include <asm/pgtable.h>
@@ -559,7 +560,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
559 addr = 1; 560 addr = 1;
560 561
561 case PTRACE_CONT: { /* restart after signal. */ 562 case PTRACE_CONT: { /* restart after signal. */
562 if (data > _NSIG) { 563 if (!valid_signal(data)) {
563 pt_error_return(regs, EIO); 564 pt_error_return(regs, EIO);
564 goto out_tsk; 565 goto out_tsk;
565 } 566 }
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index 9a23df182123..c5292181a664 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -244,6 +244,7 @@ config KERNEL_HALF_GIGS
244 244
245config HIGHMEM 245config HIGHMEM
246 bool "Highmem support" 246 bool "Highmem support"
247 depends on !64BIT
247 248
248config KERNEL_STACK_ORDER 249config KERNEL_STACK_ORDER
249 int "Kernel stack size order" 250 int "Kernel stack size order"
diff --git a/arch/um/Kconfig_i386 b/arch/um/Kconfig_i386
index 203c242201b6..e41f3748d30f 100644
--- a/arch/um/Kconfig_i386
+++ b/arch/um/Kconfig_i386
@@ -1,4 +1,8 @@
1config 64_BIT 1config UML_X86
2 bool
3 default y
4
5config 64BIT
2 bool 6 bool
3 default n 7 default n
4 8
diff --git a/arch/um/Kconfig_x86_64 b/arch/um/Kconfig_x86_64
index 768dc6626a8d..fd8d7e8982b1 100644
--- a/arch/um/Kconfig_x86_64
+++ b/arch/um/Kconfig_x86_64
@@ -1,4 +1,8 @@
1config 64_BIT 1config UML_X86
2 bool
3 default y
4
5config 64BIT
2 bool 6 bool
3 default y 7 default y
4 8
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
index 97b223bfa78e..f9e3c0f06541 100644
--- a/arch/um/Makefile-i386
+++ b/arch/um/Makefile-i386
@@ -1,4 +1,4 @@
1SUBARCH_CORE := arch/um/sys-i386/ 1SUBARCH_CORE := arch/um/sys-i386/ arch/i386/crypto/
2 2
3TOP_ADDR := $(CONFIG_TOP_ADDR) 3TOP_ADDR := $(CONFIG_TOP_ADDR)
4 4
diff --git a/arch/um/defconfig b/arch/um/defconfig
index fc3075c589d8..4067c3aa5b60 100644
--- a/arch/um/defconfig
+++ b/arch/um/defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.12-rc1-bk1 3# Linux kernel version: 2.6.12-rc3-skas3-v9-pre2
4# Sun Mar 20 16:53:00 2005 4# Sun Apr 24 19:46:10 2005
5# 5#
6CONFIG_GENERIC_HARDIRQS=y 6CONFIG_GENERIC_HARDIRQS=y
7CONFIG_UML=y 7CONFIG_UML=y
@@ -15,7 +15,8 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
15# 15#
16CONFIG_MODE_TT=y 16CONFIG_MODE_TT=y
17CONFIG_MODE_SKAS=y 17CONFIG_MODE_SKAS=y
18# CONFIG_64_BIT is not set 18CONFIG_UML_X86=y
19# CONFIG_64BIT is not set
19CONFIG_TOP_ADDR=0xc0000000 20CONFIG_TOP_ADDR=0xc0000000
20# CONFIG_3_LEVEL_PGTABLES is not set 21# CONFIG_3_LEVEL_PGTABLES is not set
21CONFIG_ARCH_HAS_SC_SIGNALS=y 22CONFIG_ARCH_HAS_SC_SIGNALS=y
@@ -41,6 +42,7 @@ CONFIG_UML_REAL_TIME_CLOCK=y
41CONFIG_EXPERIMENTAL=y 42CONFIG_EXPERIMENTAL=y
42CONFIG_CLEAN_COMPILE=y 43CONFIG_CLEAN_COMPILE=y
43CONFIG_BROKEN_ON_SMP=y 44CONFIG_BROKEN_ON_SMP=y
45CONFIG_INIT_ENV_ARG_LIMIT=32
44 46
45# 47#
46# General setup 48# General setup
@@ -158,7 +160,6 @@ CONFIG_UML_NET_SLIRP=y
158# 160#
159CONFIG_PACKET=y 161CONFIG_PACKET=y
160CONFIG_PACKET_MMAP=y 162CONFIG_PACKET_MMAP=y
161# CONFIG_NETLINK_DEV is not set
162CONFIG_UNIX=y 163CONFIG_UNIX=y
163# CONFIG_NET_KEY is not set 164# CONFIG_NET_KEY is not set
164CONFIG_INET=y 165CONFIG_INET=y
@@ -412,6 +413,5 @@ CONFIG_DEBUG_INFO=y
412# CONFIG_DEBUG_FS is not set 413# CONFIG_DEBUG_FS is not set
413CONFIG_FRAME_POINTER=y 414CONFIG_FRAME_POINTER=y
414CONFIG_PT_PROXY=y 415CONFIG_PT_PROXY=y
415# CONFIG_GPROF is not set
416# CONFIG_GCOV is not set 416# CONFIG_GCOV is not set
417# CONFIG_SYSCALL_DEBUG is not set 417# CONFIG_SYSCALL_DEBUG is not set
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 1f77deb3fd23..0150038af795 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -22,7 +22,7 @@
22#ifdef CONFIG_NOCONFIG_CHAN 22#ifdef CONFIG_NOCONFIG_CHAN
23static void *not_configged_init(char *str, int device, struct chan_opts *opts) 23static void *not_configged_init(char *str, int device, struct chan_opts *opts)
24{ 24{
25 printk(KERN_ERR "Using a channel type which is configured out of " 25 printf(KERN_ERR "Using a channel type which is configured out of "
26 "UML\n"); 26 "UML\n");
27 return(NULL); 27 return(NULL);
28} 28}
@@ -30,27 +30,27 @@ static void *not_configged_init(char *str, int device, struct chan_opts *opts)
30static int not_configged_open(int input, int output, int primary, void *data, 30static int not_configged_open(int input, int output, int primary, void *data,
31 char **dev_out) 31 char **dev_out)
32{ 32{
33 printk(KERN_ERR "Using a channel type which is configured out of " 33 printf(KERN_ERR "Using a channel type which is configured out of "
34 "UML\n"); 34 "UML\n");
35 return(-ENODEV); 35 return(-ENODEV);
36} 36}
37 37
38static void not_configged_close(int fd, void *data) 38static void not_configged_close(int fd, void *data)
39{ 39{
40 printk(KERN_ERR "Using a channel type which is configured out of " 40 printf(KERN_ERR "Using a channel type which is configured out of "
41 "UML\n"); 41 "UML\n");
42} 42}
43 43
44static int not_configged_read(int fd, char *c_out, void *data) 44static int not_configged_read(int fd, char *c_out, void *data)
45{ 45{
46 printk(KERN_ERR "Using a channel type which is configured out of " 46 printf(KERN_ERR "Using a channel type which is configured out of "
47 "UML\n"); 47 "UML\n");
48 return(-EIO); 48 return(-EIO);
49} 49}
50 50
51static int not_configged_write(int fd, const char *buf, int len, void *data) 51static int not_configged_write(int fd, const char *buf, int len, void *data)
52{ 52{
53 printk(KERN_ERR "Using a channel type which is configured out of " 53 printf(KERN_ERR "Using a channel type which is configured out of "
54 "UML\n"); 54 "UML\n");
55 return(-EIO); 55 return(-EIO);
56} 56}
@@ -58,7 +58,7 @@ static int not_configged_write(int fd, const char *buf, int len, void *data)
58static int not_configged_console_write(int fd, const char *buf, int len, 58static int not_configged_console_write(int fd, const char *buf, int len,
59 void *data) 59 void *data)
60{ 60{
61 printk(KERN_ERR "Using a channel type which is configured out of " 61 printf(KERN_ERR "Using a channel type which is configured out of "
62 "UML\n"); 62 "UML\n");
63 return(-EIO); 63 return(-EIO);
64} 64}
@@ -66,14 +66,14 @@ static int not_configged_console_write(int fd, const char *buf, int len,
66static int not_configged_window_size(int fd, void *data, unsigned short *rows, 66static int not_configged_window_size(int fd, void *data, unsigned short *rows,
67 unsigned short *cols) 67 unsigned short *cols)
68{ 68{
69 printk(KERN_ERR "Using a channel type which is configured out of " 69 printf(KERN_ERR "Using a channel type which is configured out of "
70 "UML\n"); 70 "UML\n");
71 return(-ENODEV); 71 return(-ENODEV);
72} 72}
73 73
74static void not_configged_free(void *data) 74static void not_configged_free(void *data)
75{ 75{
76 printk(KERN_ERR "Using a channel type which is configured out of " 76 printf(KERN_ERR "Using a channel type which is configured out of "
77 "UML\n"); 77 "UML\n");
78} 78}
79 79
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 6924f273ced9..d0f97127adf6 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -39,19 +39,69 @@ static void line_timer_cb(void *arg)
39 line_interrupt(line->driver->read_irq, arg, NULL); 39 line_interrupt(line->driver->read_irq, arg, NULL);
40} 40}
41 41
42static int write_room(struct line *dev) 42/* Returns the free space inside the ring buffer of this line.
43 *
44 * Should be called while holding line->lock (this does not modify datas).
45 */
46static int write_room(struct line *line)
43{ 47{
44 int n; 48 int n;
45 49
46 if (dev->buffer == NULL) 50 if (line->buffer == NULL)
47 return (LINE_BUFSIZE - 1); 51 return LINE_BUFSIZE - 1;
52
53 /* This is for the case where the buffer is wrapped! */
54 n = line->head - line->tail;
48 55
49 n = dev->head - dev->tail;
50 if (n <= 0) 56 if (n <= 0)
51 n = LINE_BUFSIZE + n; 57 n = LINE_BUFSIZE + n; /* The other case */
52 return (n - 1); 58 return n - 1;
59}
60
61int line_write_room(struct tty_struct *tty)
62{
63 struct line *line = tty->driver_data;
64 unsigned long flags;
65 int room;
66
67 if (tty->stopped)
68 return 0;
69
70 spin_lock_irqsave(&line->lock, flags);
71 room = write_room(line);
72 spin_unlock_irqrestore(&line->lock, flags);
73
74 /*XXX: Warning to remove */
75 if (0 == room)
76 printk(KERN_DEBUG "%s: %s: no room left in buffer\n",
77 __FUNCTION__,tty->name);
78 return room;
53} 79}
54 80
81int line_chars_in_buffer(struct tty_struct *tty)
82{
83 struct line *line = tty->driver_data;
84 unsigned long flags;
85 int ret;
86
87 spin_lock_irqsave(&line->lock, flags);
88
89 /*write_room subtracts 1 for the needed NULL, so we readd it.*/
90 ret = LINE_BUFSIZE - (write_room(line) + 1);
91 spin_unlock_irqrestore(&line->lock, flags);
92
93 return ret;
94}
95
96/*
97 * This copies the content of buf into the circular buffer associated with
98 * this line.
99 * The return value is the number of characters actually copied, i.e. the ones
100 * for which there was space: this function is not supposed to ever flush out
101 * the circular buffer.
102 *
103 * Must be called while holding line->lock!
104 */
55static int buffer_data(struct line *line, const char *buf, int len) 105static int buffer_data(struct line *line, const char *buf, int len)
56{ 106{
57 int end, room; 107 int end, room;
@@ -70,48 +120,95 @@ static int buffer_data(struct line *line, const char *buf, int len)
70 len = (len > room) ? room : len; 120 len = (len > room) ? room : len;
71 121
72 end = line->buffer + LINE_BUFSIZE - line->tail; 122 end = line->buffer + LINE_BUFSIZE - line->tail;
73 if(len < end){ 123
124 if (len < end){
74 memcpy(line->tail, buf, len); 125 memcpy(line->tail, buf, len);
75 line->tail += len; 126 line->tail += len;
76 } 127 } else {
77 else { 128 /* The circular buffer is wrapping */
78 memcpy(line->tail, buf, end); 129 memcpy(line->tail, buf, end);
79 buf += end; 130 buf += end;
80 memcpy(line->buffer, buf, len - end); 131 memcpy(line->buffer, buf, len - end);
81 line->tail = line->buffer + len - end; 132 line->tail = line->buffer + len - end;
82 } 133 }
83 134
84 return(len); 135 return len;
85} 136}
86 137
138/*
139 * Flushes the ring buffer to the output channels. That is, write_chan is
140 * called, passing it line->head as buffer, and an appropriate count.
141 *
142 * On exit, returns 1 when the buffer is empty,
143 * 0 when the buffer is not empty on exit,
144 * and -errno when an error occurred.
145 *
146 * Must be called while holding line->lock!*/
87static int flush_buffer(struct line *line) 147static int flush_buffer(struct line *line)
88{ 148{
89 int n, count; 149 int n, count;
90 150
91 if ((line->buffer == NULL) || (line->head == line->tail)) 151 if ((line->buffer == NULL) || (line->head == line->tail))
92 return(1); 152 return 1;
93 153
94 if (line->tail < line->head) { 154 if (line->tail < line->head) {
155 /* line->buffer + LINE_BUFSIZE is the end of the buffer! */
95 count = line->buffer + LINE_BUFSIZE - line->head; 156 count = line->buffer + LINE_BUFSIZE - line->head;
157
96 n = write_chan(&line->chan_list, line->head, count, 158 n = write_chan(&line->chan_list, line->head, count,
97 line->driver->write_irq); 159 line->driver->write_irq);
98 if (n < 0) 160 if (n < 0)
99 return(n); 161 return n;
100 if (n == count) 162 if (n == count) {
163 /* We have flushed from ->head to buffer end, now we
164 * must flush only from the beginning to ->tail.*/
101 line->head = line->buffer; 165 line->head = line->buffer;
102 else { 166 } else {
103 line->head += n; 167 line->head += n;
104 return(0); 168 return 0;
105 } 169 }
106 } 170 }
107 171
108 count = line->tail - line->head; 172 count = line->tail - line->head;
109 n = write_chan(&line->chan_list, line->head, count, 173 n = write_chan(&line->chan_list, line->head, count,
110 line->driver->write_irq); 174 line->driver->write_irq);
111 if(n < 0) return(n); 175
176 if(n < 0)
177 return n;
112 178
113 line->head += n; 179 line->head += n;
114 return(line->head == line->tail); 180 return line->head == line->tail;
181}
182
183void line_flush_buffer(struct tty_struct *tty)
184{
185 struct line *line = tty->driver_data;
186 unsigned long flags;
187 int err;
188
189 /*XXX: copied from line_write, verify if it is correct!*/
190 if(tty->stopped)
191 return;
192 //return 0;
193
194 spin_lock_irqsave(&line->lock, flags);
195 err = flush_buffer(line);
196 /*if (err == 1)
197 err = 0;*/
198 spin_unlock_irqrestore(&line->lock, flags);
199 //return err;
200}
201
202/* We map both ->flush_chars and ->put_char (which go in pair) onto ->flush_buffer
203 * and ->write. Hope it's not that bad.*/
204void line_flush_chars(struct tty_struct *tty)
205{
206 line_flush_buffer(tty);
207}
208
209void line_put_char(struct tty_struct *tty, unsigned char ch)
210{
211 line_write(tty, &ch, sizeof(ch));
115} 212}
116 213
117int line_write(struct tty_struct *tty, const unsigned char *buf, int len) 214int 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)
120 unsigned long flags; 217 unsigned long flags;
121 int n, err, ret = 0; 218 int n, err, ret = 0;
122 219
123 if(tty->stopped) return 0; 220 if(tty->stopped)
221 return 0;
124 222
125 down(&line->sem); 223 spin_lock_irqsave(&line->lock, flags);
126 if(line->head != line->tail){ 224 if (line->head != line->tail) {
127 local_irq_save(flags);
128 ret = buffer_data(line, buf, len); 225 ret = buffer_data(line, buf, len);
129 err = flush_buffer(line); 226 err = flush_buffer(line);
130 local_irq_restore(flags); 227 if (err <= 0 && (err != -EAGAIN || !ret))
131 if(err <= 0 && (err != -EAGAIN || !ret))
132 ret = err; 228 ret = err;
133 } 229 } else {
134 else {
135 n = write_chan(&line->chan_list, buf, len, 230 n = write_chan(&line->chan_list, buf, len,
136 line->driver->write_irq); 231 line->driver->write_irq);
137 if(n < 0){ 232 if (n < 0) {
138 ret = n; 233 ret = n;
139 goto out_up; 234 goto out_up;
140 } 235 }
141 236
142 len -= n; 237 len -= n;
143 ret += n; 238 ret += n;
144 if(len > 0) 239 if (len > 0)
145 ret += buffer_data(line, buf + n, len); 240 ret += buffer_data(line, buf + n, len);
146 } 241 }
147 out_up: 242out_up:
148 up(&line->sem); 243 spin_unlock_irqrestore(&line->lock, flags);
149 return(ret); 244 return ret;
150}
151
152void line_put_char(struct tty_struct *tty, unsigned char ch)
153{
154 line_write(tty, &ch, sizeof(ch));
155} 245}
156 246
157void line_set_termios(struct tty_struct *tty, struct termios * old) 247void 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)
159 /* nothing */ 249 /* nothing */
160} 250}
161 251
162int line_chars_in_buffer(struct tty_struct *tty)
163{
164 return 0;
165}
166
167static struct { 252static struct {
168 int cmd; 253 int cmd;
169 char *level; 254 char *level;
@@ -250,7 +335,7 @@ int line_ioctl(struct tty_struct *tty, struct file * file,
250 ret = -ENOIOCTLCMD; 335 ret = -ENOIOCTLCMD;
251 break; 336 break;
252 } 337 }
253 return(ret); 338 return ret;
254} 339}
255 340
256static irqreturn_t line_write_interrupt(int irq, void *data, 341static irqreturn_t line_write_interrupt(int irq, void *data,
@@ -260,18 +345,23 @@ static irqreturn_t line_write_interrupt(int irq, void *data,
260 struct line *line = tty->driver_data; 345 struct line *line = tty->driver_data;
261 int err; 346 int err;
262 347
348 /* Interrupts are enabled here because we registered the interrupt with
349 * SA_INTERRUPT (see line_setup_irq).*/
350
351 spin_lock_irq(&line->lock);
263 err = flush_buffer(line); 352 err = flush_buffer(line);
264 if(err == 0) 353 if (err == 0) {
265 return(IRQ_NONE); 354 return IRQ_NONE;
266 else if(err < 0){ 355 } else if(err < 0) {
267 line->head = line->buffer; 356 line->head = line->buffer;
268 line->tail = line->buffer; 357 line->tail = line->buffer;
269 } 358 }
359 spin_unlock_irq(&line->lock);
270 360
271 if(tty == NULL) 361 if(tty == NULL)
272 return(IRQ_NONE); 362 return IRQ_NONE;
273 363
274 if(test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && 364 if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
275 (tty->ldisc.write_wakeup != NULL)) 365 (tty->ldisc.write_wakeup != NULL))
276 (tty->ldisc.write_wakeup)(tty); 366 (tty->ldisc.write_wakeup)(tty);
277 367
@@ -281,9 +371,9 @@ static irqreturn_t line_write_interrupt(int irq, void *data,
281 * writes. 371 * writes.
282 */ 372 */
283 373
284 if(waitqueue_active(&tty->write_wait)) 374 if (waitqueue_active(&tty->write_wait))
285 wake_up_interruptible(&tty->write_wait); 375 wake_up_interruptible(&tty->write_wait);
286 return(IRQ_HANDLED); 376 return IRQ_HANDLED;
287} 377}
288 378
289int line_setup_irq(int fd, int input, int output, struct tty_struct *tty) 379int 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)
292 struct line_driver *driver = line->driver; 382 struct line_driver *driver = line->driver;
293 int err = 0, flags = SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM; 383 int err = 0, flags = SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM;
294 384
295 if(input) err = um_request_irq(driver->read_irq, fd, IRQ_READ, 385 if (input)
386 err = um_request_irq(driver->read_irq, fd, IRQ_READ,
296 line_interrupt, flags, 387 line_interrupt, flags,
297 driver->read_irq_name, tty); 388 driver->read_irq_name, tty);
298 if(err) return(err); 389 if (err)
299 if(output) err = um_request_irq(driver->write_irq, fd, IRQ_WRITE, 390 return err;
391 if (output)
392 err = um_request_irq(driver->write_irq, fd, IRQ_WRITE,
300 line_write_interrupt, flags, 393 line_write_interrupt, flags,
301 driver->write_irq_name, tty); 394 driver->write_irq_name, tty);
302 line->have_irq = 1; 395 line->have_irq = 1;
303 return(err); 396 return err;
304} 397}
305 398
306void line_disable(struct tty_struct *tty, int current_irq) 399void line_disable(struct tty_struct *tty, int current_irq)
@@ -336,7 +429,9 @@ int line_open(struct line *lines, struct tty_struct *tty,
336 line = &lines[tty->index]; 429 line = &lines[tty->index];
337 tty->driver_data = line; 430 tty->driver_data = line;
338 431
339 down(&line->sem); 432 /* The IRQ which takes this lock is not yet enabled and won't be run
433 * before the end, so we don't need to use spin_lock_irq.*/
434 spin_lock(&line->lock);
340 if (tty->count == 1) { 435 if (tty->count == 1) {
341 if (!line->valid) { 436 if (!line->valid) {
342 err = -ENODEV; 437 err = -ENODEV;
@@ -349,6 +444,7 @@ int line_open(struct line *lines, struct tty_struct *tty,
349 err = open_chan(&line->chan_list); 444 err = open_chan(&line->chan_list);
350 if(err) goto out; 445 if(err) goto out;
351 } 446 }
447 /* Here the interrupt is registered.*/
352 enable_chan(&line->chan_list, tty); 448 enable_chan(&line->chan_list, tty);
353 INIT_WORK(&line->task, line_timer_cb, tty); 449 INIT_WORK(&line->task, line_timer_cb, tty);
354 } 450 }
@@ -362,21 +458,27 @@ int line_open(struct line *lines, struct tty_struct *tty,
362 line->count++; 458 line->count++;
363 459
364out: 460out:
365 up(&line->sem); 461 spin_unlock(&line->lock);
366 return(err); 462 return err;
367} 463}
368 464
369void line_close(struct tty_struct *tty, struct file * filp) 465void line_close(struct tty_struct *tty, struct file * filp)
370{ 466{
371 struct line *line = tty->driver_data; 467 struct line *line = tty->driver_data;
372 468
373 down(&line->sem); 469 /* XXX: I assume this should be called in process context, not with interrupt
470 * disabled!*/
471 spin_lock_irq(&line->lock);
472
473 /* We ignore the error anyway! */
474 flush_buffer(line);
475
374 line->count--; 476 line->count--;
375 if (tty->count == 1) { 477 if (tty->count == 1) {
376 line_disable(tty, -1); 478 line_disable(tty, -1);
377 tty->driver_data = NULL; 479 tty->driver_data = NULL;
378 } 480 }
379 up(&line->sem); 481 spin_unlock_irq(&line->lock);
380} 482}
381 483
382void close_lines(struct line *lines, int nlines) 484void close_lines(struct line *lines, int nlines)
@@ -387,31 +489,41 @@ void close_lines(struct line *lines, int nlines)
387 close_chan(&lines[i].chan_list); 489 close_chan(&lines[i].chan_list);
388} 490}
389 491
390int line_setup(struct line *lines, int num, char *init, int all_allowed) 492/* Common setup code for both startup command line and mconsole initialization.
493 * @lines contains the the array (of size @num) to modify;
494 * @init is the setup string;
495 * @all_allowed is a boolean saying if we can setup the whole @lines
496 * at once. For instance, it will be usually true for startup init. (where we
497 * can use con=xterm) and false for mconsole.*/
498
499int line_setup(struct line *lines, unsigned int num, char *init, int all_allowed)
391{ 500{
392 int i, n; 501 int i, n;
393 char *end; 502 char *end;
394 503
395 if(*init == '=') n = -1; 504 if(*init == '=') {
396 else { 505 /* We said con=/ssl= instead of con#=, so we are configuring all
506 * consoles at once.*/
507 n = -1;
508 } else {
397 n = simple_strtoul(init, &end, 0); 509 n = simple_strtoul(init, &end, 0);
398 if(*end != '='){ 510 if(*end != '='){
399 printk(KERN_ERR "line_setup failed to parse \"%s\"\n", 511 printk(KERN_ERR "line_setup failed to parse \"%s\"\n",
400 init); 512 init);
401 return(0); 513 return 0;
402 } 514 }
403 init = end; 515 init = end;
404 } 516 }
405 init++; 517 init++;
406 if((n >= 0) && (n >= num)){ 518
519 if (n >= (signed int) num) {
407 printk("line_setup - %d out of range ((0 ... %d) allowed)\n", 520 printk("line_setup - %d out of range ((0 ... %d) allowed)\n",
408 n, num - 1); 521 n, num - 1);
409 return(0); 522 return 0;
410 } 523 } else if (n >= 0){
411 else if (n >= 0){
412 if (lines[n].count > 0) { 524 if (lines[n].count > 0) {
413 printk("line_setup - device %d is open\n", n); 525 printk("line_setup - device %d is open\n", n);
414 return(0); 526 return 0;
415 } 527 }
416 if (lines[n].init_pri <= INIT_ONE){ 528 if (lines[n].init_pri <= INIT_ONE){
417 lines[n].init_pri = INIT_ONE; 529 lines[n].init_pri = INIT_ONE;
@@ -422,13 +534,11 @@ int line_setup(struct line *lines, int num, char *init, int all_allowed)
422 lines[n].valid = 1; 534 lines[n].valid = 1;
423 } 535 }
424 } 536 }
425 } 537 } else if(!all_allowed){
426 else if(!all_allowed){
427 printk("line_setup - can't configure all devices from " 538 printk("line_setup - can't configure all devices from "
428 "mconsole\n"); 539 "mconsole\n");
429 return(0); 540 return 0;
430 } 541 } else {
431 else {
432 for(i = 0; i < num; i++){ 542 for(i = 0; i < num; i++){
433 if(lines[i].init_pri <= INIT_ALL){ 543 if(lines[i].init_pri <= INIT_ALL){
434 lines[i].init_pri = INIT_ALL; 544 lines[i].init_pri = INIT_ALL;
@@ -440,21 +550,21 @@ int line_setup(struct line *lines, int num, char *init, int all_allowed)
440 } 550 }
441 } 551 }
442 } 552 }
443 return(1); 553 return 1;
444} 554}
445 555
446int line_config(struct line *lines, int num, char *str) 556int line_config(struct line *lines, unsigned int num, char *str)
447{ 557{
448 char *new = uml_strdup(str); 558 char *new = uml_strdup(str);
449 559
450 if(new == NULL){ 560 if(new == NULL){
451 printk("line_config - uml_strdup failed\n"); 561 printk("line_config - uml_strdup failed\n");
452 return(-ENOMEM); 562 return -ENOMEM;
453 } 563 }
454 return(!line_setup(lines, num, new, 0)); 564 return !line_setup(lines, num, new, 0);
455} 565}
456 566
457int line_get_config(char *name, struct line *lines, int num, char *str, 567int line_get_config(char *name, struct line *lines, unsigned int num, char *str,
458 int size, char **error_out) 568 int size, char **error_out)
459{ 569{
460 struct line *line; 570 struct line *line;
@@ -464,47 +574,33 @@ int line_get_config(char *name, struct line *lines, int num, char *str,
464 dev = simple_strtoul(name, &end, 0); 574 dev = simple_strtoul(name, &end, 0);
465 if((*end != '\0') || (end == name)){ 575 if((*end != '\0') || (end == name)){
466 *error_out = "line_get_config failed to parse device number"; 576 *error_out = "line_get_config failed to parse device number";
467 return(0); 577 return 0;
468 } 578 }
469 579
470 if((dev < 0) || (dev >= num)){ 580 if((dev < 0) || (dev >= num)){
471 *error_out = "device number of of range"; 581 *error_out = "device number out of range";
472 return(0); 582 return 0;
473 } 583 }
474 584
475 line = &lines[dev]; 585 line = &lines[dev];
476 586
477 down(&line->sem); 587 spin_lock(&line->lock);
478 if(!line->valid) 588 if(!line->valid)
479 CONFIG_CHUNK(str, size, n, "none", 1); 589 CONFIG_CHUNK(str, size, n, "none", 1);
480 else if(line->count == 0) 590 else if(line->count == 0)
481 CONFIG_CHUNK(str, size, n, line->init_str, 1); 591 CONFIG_CHUNK(str, size, n, line->init_str, 1);
482 else n = chan_config_string(&line->chan_list, str, size, error_out); 592 else n = chan_config_string(&line->chan_list, str, size, error_out);
483 up(&line->sem); 593 spin_unlock(&line->lock);
484 594
485 return(n); 595 return n;
486} 596}
487 597
488int line_remove(struct line *lines, int num, char *str) 598int line_remove(struct line *lines, unsigned int num, char *str)
489{ 599{
490 char config[sizeof("conxxxx=none\0")]; 600 char config[sizeof("conxxxx=none\0")];
491 601
492 sprintf(config, "%s=none", str); 602 sprintf(config, "%s=none", str);
493 return(!line_setup(lines, num, config, 0)); 603 return !line_setup(lines, num, config, 0);
494}
495
496int line_write_room(struct tty_struct *tty)
497{
498 struct line *dev = tty->driver_data;
499 int room;
500
501 if (tty->stopped)
502 return 0;
503 room = write_room(dev);
504 if (0 == room)
505 printk(KERN_DEBUG "%s: %s: no room left in buffer\n",
506 __FUNCTION__,tty->name);
507 return room;
508} 604}
509 605
510struct tty_driver *line_register_devfs(struct lines *set, 606struct tty_driver *line_register_devfs(struct lines *set,
@@ -553,7 +649,7 @@ void lines_init(struct line *lines, int nlines)
553 for(i = 0; i < nlines; i++){ 649 for(i = 0; i < nlines; i++){
554 line = &lines[i]; 650 line = &lines[i];
555 INIT_LIST_HEAD(&line->chan_list); 651 INIT_LIST_HEAD(&line->chan_list);
556 sema_init(&line->sem, 1); 652 spin_lock_init(&line->lock);
557 if(line->init_str != NULL){ 653 if(line->init_str != NULL){
558 line->init_str = uml_strdup(line->init_str); 654 line->init_str = uml_strdup(line->init_str);
559 if(line->init_str == NULL) 655 if(line->init_str == NULL)
@@ -587,7 +683,7 @@ irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused)
587 "errno = %d\n", -err); 683 "errno = %d\n", -err);
588 printk("fd %d is losing SIGWINCH support\n", 684 printk("fd %d is losing SIGWINCH support\n",
589 winch->tty_fd); 685 winch->tty_fd);
590 return(IRQ_HANDLED); 686 return IRQ_HANDLED;
591 } 687 }
592 goto out; 688 goto out;
593 } 689 }
@@ -603,7 +699,7 @@ irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused)
603 out: 699 out:
604 if(winch->fd != -1) 700 if(winch->fd != -1)
605 reactivate_fd(winch->fd, WINCH_IRQ); 701 reactivate_fd(winch->fd, WINCH_IRQ);
606 return(IRQ_HANDLED); 702 return IRQ_HANDLED;
607} 703}
608 704
609DECLARE_MUTEX(winch_handler_sem); 705DECLARE_MUTEX(winch_handler_sem);
@@ -625,7 +721,7 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty)
625 .pid = pid, 721 .pid = pid,
626 .tty = tty }); 722 .tty = tty });
627 list_add(&winch->list, &winch_handlers); 723 list_add(&winch->list, &winch_handlers);
628 if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, 724 if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
629 SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 725 SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
630 "winch", winch) < 0) 726 "winch", winch) < 0)
631 printk("register_winch_irq - failed to register IRQ\n"); 727 printk("register_winch_irq - failed to register IRQ\n");
@@ -656,26 +752,16 @@ char *add_xterm_umid(char *base)
656 int len; 752 int len;
657 753
658 umid = get_umid(1); 754 umid = get_umid(1);
659 if(umid == NULL) return(base); 755 if(umid == NULL)
756 return base;
660 757
661 len = strlen(base) + strlen(" ()") + strlen(umid) + 1; 758 len = strlen(base) + strlen(" ()") + strlen(umid) + 1;
662 title = kmalloc(len, GFP_KERNEL); 759 title = kmalloc(len, GFP_KERNEL);
663 if(title == NULL){ 760 if(title == NULL){
664 printk("Failed to allocate buffer for xterm title\n"); 761 printk("Failed to allocate buffer for xterm title\n");
665 return(base); 762 return base;
666 } 763 }
667 764
668 snprintf(title, len, "%s (%s)", base, umid); 765 snprintf(title, len, "%s (%s)", base, umid);
669 return(title); 766 return title;
670} 767}
671
672/*
673 * Overrides for Emacs so that we follow Linus's tabbing style.
674 * Emacs will notice this stuff at the end of the file and automatically
675 * adjust the settings for this buffer only. This must remain at the end
676 * of the file.
677 * ---------------------------------------------------------------------------
678 * Local variables:
679 * c-file-style: "linux"
680 * End:
681 */
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
index c5839c3141f8..a2bac429f3d4 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)
107} 107}
108 108
109#if 0 109#if 0
110static int ssl_chars_in_buffer(struct tty_struct *tty)
111{
112 return(0);
113}
114
115static void ssl_flush_buffer(struct tty_struct *tty) 110static void ssl_flush_buffer(struct tty_struct *tty)
116{ 111{
117 return; 112 return;
@@ -149,11 +144,11 @@ static struct tty_operations ssl_ops = {
149 .put_char = line_put_char, 144 .put_char = line_put_char,
150 .write_room = line_write_room, 145 .write_room = line_write_room,
151 .chars_in_buffer = line_chars_in_buffer, 146 .chars_in_buffer = line_chars_in_buffer,
147 .flush_buffer = line_flush_buffer,
148 .flush_chars = line_flush_chars,
152 .set_termios = line_set_termios, 149 .set_termios = line_set_termios,
153 .ioctl = line_ioctl, 150 .ioctl = line_ioctl,
154#if 0 151#if 0
155 .flush_chars = ssl_flush_chars,
156 .flush_buffer = ssl_flush_buffer,
157 .throttle = ssl_throttle, 152 .throttle = ssl_throttle,
158 .unthrottle = ssl_unthrottle, 153 .unthrottle = ssl_unthrottle,
159 .stop = ssl_stop, 154 .stop = ssl_stop,
@@ -171,10 +166,11 @@ static void ssl_console_write(struct console *c, const char *string,
171 unsigned len) 166 unsigned len)
172{ 167{
173 struct line *line = &serial_lines[c->index]; 168 struct line *line = &serial_lines[c->index];
169 unsigned long flags;
174 170
175 down(&line->sem); 171 spin_lock_irqsave(&line->lock, flags);
176 console_write_chan(&line->chan_list, string, len); 172 console_write_chan(&line->chan_list, string, len);
177 up(&line->sem); 173 spin_unlock_irqrestore(&line->lock, flags);
178} 174}
179 175
180static struct tty_driver *ssl_console_device(struct console *c, int *index) 176static struct tty_driver *ssl_console_device(struct console *c, int *index)
@@ -238,14 +234,3 @@ static int ssl_chan_setup(char *str)
238 234
239__setup("ssl", ssl_chan_setup); 235__setup("ssl", ssl_chan_setup);
240__channel_help(ssl_chan_setup, "ssl"); 236__channel_help(ssl_chan_setup, "ssl");
241
242/*
243 * Overrides for Emacs so that we follow Linus's tabbing style.
244 * Emacs will notice this stuff at the end of the file and automatically
245 * adjust the settings for this buffer only. This must remain at the end
246 * of the file.
247 * ---------------------------------------------------------------------------
248 * Local variables:
249 * c-file-style: "linux"
250 * End:
251 */
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index e604d7c87695..361d0be342b3 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 = {
116 .open = con_open, 116 .open = con_open,
117 .close = line_close, 117 .close = line_close,
118 .write = line_write, 118 .write = line_write,
119 .put_char = line_put_char,
119 .write_room = line_write_room, 120 .write_room = line_write_room,
120 .chars_in_buffer = line_chars_in_buffer, 121 .chars_in_buffer = line_chars_in_buffer,
122 .flush_buffer = line_flush_buffer,
123 .flush_chars = line_flush_chars,
121 .set_termios = line_set_termios, 124 .set_termios = line_set_termios,
122 .ioctl = line_ioctl, 125 .ioctl = line_ioctl,
123}; 126};
@@ -126,10 +129,11 @@ static void uml_console_write(struct console *console, const char *string,
126 unsigned len) 129 unsigned len)
127{ 130{
128 struct line *line = &vts[console->index]; 131 struct line *line = &vts[console->index];
132 unsigned long flags;
129 133
130 down(&line->sem); 134 spin_lock_irqsave(&line->lock, flags);
131 console_write_chan(&line->chan_list, string, len); 135 console_write_chan(&line->chan_list, string, len);
132 up(&line->sem); 136 spin_unlock_irqrestore(&line->lock, flags);
133} 137}
134 138
135static struct tty_driver *uml_console_device(struct console *c, int *index) 139static struct tty_driver *uml_console_device(struct console *c, int *index)
@@ -192,14 +196,3 @@ static int console_chan_setup(char *str)
192} 196}
193__setup("con", console_chan_setup); 197__setup("con", console_chan_setup);
194__channel_help(console_chan_setup, "con"); 198__channel_help(console_chan_setup, "con");
195
196/*
197 * Overrides for Emacs so that we follow Linus's tabbing style.
198 * Emacs will notice this stuff at the end of the file and automatically
199 * adjust the settings for this buffer only. This must remain at the end
200 * of the file.
201 * ---------------------------------------------------------------------------
202 * Local variables:
203 * c-file-style: "linux"
204 * End:
205 */
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 4d8b165bfa48..9a56ff94308d 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];
156static struct openflags global_openflags = OPEN_FLAGS; 156static struct openflags global_openflags = OPEN_FLAGS;
157 157
158struct cow { 158struct cow {
159 /* This is the backing file, actually */
159 char *file; 160 char *file;
160 int fd; 161 int fd;
161 unsigned long *bitmap; 162 unsigned long *bitmap;
@@ -927,10 +928,14 @@ static int ubd_open(struct inode *inode, struct file *filp)
927 } 928 }
928 } 929 }
929 dev->count++; 930 dev->count++;
930 if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){ 931 set_disk_ro(disk, !dev->openflags.w);
932
933 /* This should no more be needed. And it didn't work anyway to exclude
934 * read-write remounting of filesystems.*/
935 /*if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){
931 if(--dev->count == 0) ubd_close(dev); 936 if(--dev->count == 0) ubd_close(dev);
932 err = -EROFS; 937 err = -EROFS;
933 } 938 }*/
934 out: 939 out:
935 return(err); 940 return(err);
936} 941}
@@ -1096,6 +1101,7 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
1096 1101
1097 if(req->rq_status == RQ_INACTIVE) return(1); 1102 if(req->rq_status == RQ_INACTIVE) return(1);
1098 1103
1104 /* This should be impossible now */
1099 if((rq_data_dir(req) == WRITE) && !dev->openflags.w){ 1105 if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
1100 printk("Write attempted on readonly ubd device %s\n", 1106 printk("Write attempted on readonly ubd device %s\n",
1101 disk->disk_name); 1107 disk->disk_name);
@@ -1243,6 +1249,7 @@ static int ubd_check_remapped(int fd, unsigned long address, int is_write,
1243 1249
1244 /* It's a write to a ubd device */ 1250 /* It's a write to a ubd device */
1245 1251
1252 /* This should be impossible now */
1246 if(!dev->openflags.w){ 1253 if(!dev->openflags.w){
1247 /* It's a write access on a read-only device - probably 1254 /* It's a write access on a read-only device - probably
1248 * shouldn't happen. If the kernel is trying to change 1255 * shouldn't happen. If the kernel is trying to change
@@ -1605,8 +1612,7 @@ void do_io(struct io_thread_req *req)
1605 } 1612 }
1606 } while((n < len) && (n != 0)); 1613 } while((n < len) && (n != 0));
1607 if (n < len) memset(&buf[n], 0, len - n); 1614 if (n < len) memset(&buf[n], 0, len - n);
1608 } 1615 } else {
1609 else {
1610 n = os_write_file(req->fds[bit], buf, len); 1616 n = os_write_file(req->fds[bit], buf, len);
1611 if(n != len){ 1617 if(n != len){
1612 printk("do_io - write failed err = %d " 1618 printk("do_io - write failed err = %d "
diff --git a/arch/um/include/line.h b/arch/um/include/line.h
index 6d81ecc17be5..4c5e92c04ccb 100644
--- a/arch/um/include/line.h
+++ b/arch/um/include/line.h
@@ -10,7 +10,7 @@
10#include "linux/workqueue.h" 10#include "linux/workqueue.h"
11#include "linux/tty.h" 11#include "linux/tty.h"
12#include "linux/interrupt.h" 12#include "linux/interrupt.h"
13#include "asm/semaphore.h" 13#include "linux/spinlock.h"
14#include "chan_user.h" 14#include "chan_user.h"
15#include "mconsole_kern.h" 15#include "mconsole_kern.h"
16 16
@@ -37,10 +37,18 @@ struct line {
37 struct list_head chan_list; 37 struct list_head chan_list;
38 int valid; 38 int valid;
39 int count; 39 int count;
40 struct semaphore sem; 40 /*This lock is actually, mostly, local to*/
41 spinlock_t lock;
42
43 /* Yes, this is a real circular buffer.
44 * XXX: And this should become a struct kfifo!
45 *
46 * buffer points to a buffer allocated on demand, of length
47 * LINE_BUFSIZE, head to the start of the ring, tail to the end.*/
41 char *buffer; 48 char *buffer;
42 char *head; 49 char *head;
43 char *tail; 50 char *tail;
51
44 int sigio; 52 int sigio;
45 struct work_struct task; 53 struct work_struct task;
46 struct line_driver *driver; 54 struct line_driver *driver;
@@ -52,7 +60,6 @@ struct line {
52 init_pri : INIT_STATIC, \ 60 init_pri : INIT_STATIC, \
53 chan_list : { }, \ 61 chan_list : { }, \
54 valid : 1, \ 62 valid : 1, \
55 sem : { }, \
56 buffer : NULL, \ 63 buffer : NULL, \
57 head : NULL, \ 64 head : NULL, \
58 tail : NULL, \ 65 tail : NULL, \
@@ -69,15 +76,18 @@ struct lines {
69extern void line_close(struct tty_struct *tty, struct file * filp); 76extern void line_close(struct tty_struct *tty, struct file * filp);
70extern int line_open(struct line *lines, struct tty_struct *tty, 77extern int line_open(struct line *lines, struct tty_struct *tty,
71 struct chan_opts *opts); 78 struct chan_opts *opts);
72extern int line_setup(struct line *lines, int num, char *init, 79extern int line_setup(struct line *lines, unsigned int sizeof_lines, char *init,
73 int all_allowed); 80 int all_allowed);
74extern int line_write(struct tty_struct *tty, const unsigned char *buf, int len); 81extern int line_write(struct tty_struct *tty, const unsigned char *buf, int len);
75extern void line_put_char(struct tty_struct *tty, unsigned char ch); 82extern void line_put_char(struct tty_struct *tty, unsigned char ch);
76extern void line_set_termios(struct tty_struct *tty, struct termios * old); 83extern void line_set_termios(struct tty_struct *tty, struct termios * old);
77extern int line_chars_in_buffer(struct tty_struct *tty); 84extern int line_chars_in_buffer(struct tty_struct *tty);
85extern void line_flush_buffer(struct tty_struct *tty);
86extern void line_flush_chars(struct tty_struct *tty);
78extern int line_write_room(struct tty_struct *tty); 87extern int line_write_room(struct tty_struct *tty);
79extern int line_ioctl(struct tty_struct *tty, struct file * file, 88extern int line_ioctl(struct tty_struct *tty, struct file * file,
80 unsigned int cmd, unsigned long arg); 89 unsigned int cmd, unsigned long arg);
90
81extern char *add_xterm_umid(char *base); 91extern char *add_xterm_umid(char *base);
82extern int line_setup_irq(int fd, int input, int output, struct tty_struct *tty); 92extern int line_setup_irq(int fd, int input, int output, struct tty_struct *tty);
83extern void line_close_chan(struct line *line); 93extern void line_close_chan(struct line *line);
@@ -89,20 +99,10 @@ extern struct tty_driver * line_register_devfs(struct lines *set,
89 int nlines); 99 int nlines);
90extern void lines_init(struct line *lines, int nlines); 100extern void lines_init(struct line *lines, int nlines);
91extern void close_lines(struct line *lines, int nlines); 101extern void close_lines(struct line *lines, int nlines);
92extern int line_config(struct line *lines, int num, char *str); 102
93extern int line_remove(struct line *lines, int num, char *str); 103extern int line_config(struct line *lines, unsigned int sizeof_lines, char *str);
94extern int line_get_config(char *dev, struct line *lines, int num, char *str, 104extern int line_remove(struct line *lines, unsigned int sizeof_lines, char *str);
105extern int line_get_config(char *dev, struct line *lines, unsigned int sizeof_lines, char *str,
95 int size, char **error_out); 106 int size, char **error_out);
96 107
97#endif 108#endif
98
99/*
100 * Overrides for Emacs so that we follow Linus's tabbing style.
101 * Emacs will notice this stuff at the end of the file and automatically
102 * adjust the settings for this buffer only. This must remain at the end
103 * of the file.
104 * ---------------------------------------------------------------------------
105 * Local variables:
106 * c-file-style: "linux"
107 * End:
108 */
diff --git a/arch/um/include/sysdep-i386/syscalls.h b/arch/um/include/sysdep-i386/syscalls.h
index 5db81ec9087d..be0a3e3469eb 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;
22extern long sys_mmap2(unsigned long addr, unsigned long len, 22extern long sys_mmap2(unsigned long addr, unsigned long len,
23 unsigned long prot, unsigned long flags, 23 unsigned long prot, unsigned long flags,
24 unsigned long fd, unsigned long pgoff); 24 unsigned long fd, unsigned long pgoff);
25
26/* On i386 they choose a meaningless naming.*/
27#define __NR_kexec_load __NR_sys_kexec_load
28
29#define ARCH_SYSCALLS \
30 [ __NR_waitpid ] = (syscall_handler_t *) sys_waitpid, \
31 [ __NR_break ] = (syscall_handler_t *) sys_ni_syscall, \
32 [ __NR_oldstat ] = (syscall_handler_t *) sys_stat, \
33 [ __NR_umount ] = (syscall_handler_t *) sys_oldumount, \
34 [ __NR_stime ] = um_stime, \
35 [ __NR_oldfstat ] = (syscall_handler_t *) sys_fstat, \
36 [ __NR_stty ] = (syscall_handler_t *) sys_ni_syscall, \
37 [ __NR_gtty ] = (syscall_handler_t *) sys_ni_syscall, \
38 [ __NR_nice ] = (syscall_handler_t *) sys_nice, \
39 [ __NR_ftime ] = (syscall_handler_t *) sys_ni_syscall, \
40 [ __NR_prof ] = (syscall_handler_t *) sys_ni_syscall, \
41 [ __NR_signal ] = (syscall_handler_t *) sys_signal, \
42 [ __NR_lock ] = (syscall_handler_t *) sys_ni_syscall, \
43 [ __NR_mpx ] = (syscall_handler_t *) sys_ni_syscall, \
44 [ __NR_ulimit ] = (syscall_handler_t *) sys_ni_syscall, \
45 [ __NR_oldolduname ] = (syscall_handler_t *) sys_olduname, \
46 [ __NR_sigaction ] = (syscall_handler_t *) sys_sigaction, \
47 [ __NR_sgetmask ] = (syscall_handler_t *) sys_sgetmask, \
48 [ __NR_ssetmask ] = (syscall_handler_t *) sys_ssetmask, \
49 [ __NR_sigsuspend ] = (syscall_handler_t *) sys_sigsuspend, \
50 [ __NR_sigpending ] = (syscall_handler_t *) sys_sigpending, \
51 [ __NR_oldlstat ] = (syscall_handler_t *) sys_lstat, \
52 [ __NR_readdir ] = old_readdir, \
53 [ __NR_profil ] = (syscall_handler_t *) sys_ni_syscall, \
54 [ __NR_socketcall ] = (syscall_handler_t *) sys_socketcall, \
55 [ __NR_olduname ] = (syscall_handler_t *) sys_uname, \
56 [ __NR_iopl ] = (syscall_handler_t *) sys_ni_syscall, \
57 [ __NR_idle ] = (syscall_handler_t *) sys_ni_syscall, \
58 [ __NR_ipc ] = (syscall_handler_t *) sys_ipc, \
59 [ __NR_sigreturn ] = (syscall_handler_t *) sys_sigreturn, \
60 [ __NR_sigprocmask ] = (syscall_handler_t *) sys_sigprocmask, \
61 [ __NR_bdflush ] = (syscall_handler_t *) sys_bdflush, \
62 [ __NR__llseek ] = (syscall_handler_t *) sys_llseek, \
63 [ __NR__newselect ] = (syscall_handler_t *) sys_select, \
64 [ __NR_vm86 ] = (syscall_handler_t *) sys_ni_syscall, \
65 [ __NR_mmap ] = (syscall_handler_t *) old_mmap_i386, \
66 [ __NR_ugetrlimit ] = (syscall_handler_t *) sys_getrlimit, \
67 [ __NR_mmap2 ] = (syscall_handler_t *) sys_mmap2, \
68 [ __NR_truncate64 ] = (syscall_handler_t *) sys_truncate64, \
69 [ __NR_ftruncate64 ] = (syscall_handler_t *) sys_ftruncate64, \
70 [ __NR_stat64 ] = (syscall_handler_t *) sys_stat64, \
71 [ __NR_lstat64 ] = (syscall_handler_t *) sys_lstat64, \
72 [ __NR_fstat64 ] = (syscall_handler_t *) sys_fstat64, \
73 [ __NR_fcntl64 ] = (syscall_handler_t *) sys_fcntl64, \
74 [ __NR_sendfile64 ] = (syscall_handler_t *) sys_sendfile64, \
75 [ __NR_statfs64 ] = (syscall_handler_t *) sys_statfs64, \
76 [ __NR_fstatfs64 ] = (syscall_handler_t *) sys_fstatfs64, \
77 [ __NR_fadvise64_64 ] = (syscall_handler_t *) sys_fadvise64_64, \
78 [ __NR_select ] = (syscall_handler_t *) old_select, \
79 [ __NR_vm86old ] = (syscall_handler_t *) sys_ni_syscall, \
80 [ __NR_modify_ldt ] = (syscall_handler_t *) sys_modify_ldt, \
81 [ __NR_lchown32 ] = (syscall_handler_t *) sys_lchown, \
82 [ __NR_getuid32 ] = (syscall_handler_t *) sys_getuid, \
83 [ __NR_getgid32 ] = (syscall_handler_t *) sys_getgid, \
84 [ __NR_geteuid32 ] = (syscall_handler_t *) sys_geteuid, \
85 [ __NR_getegid32 ] = (syscall_handler_t *) sys_getegid, \
86 [ __NR_setreuid32 ] = (syscall_handler_t *) sys_setreuid, \
87 [ __NR_setregid32 ] = (syscall_handler_t *) sys_setregid, \
88 [ __NR_getgroups32 ] = (syscall_handler_t *) sys_getgroups, \
89 [ __NR_setgroups32 ] = (syscall_handler_t *) sys_setgroups, \
90 [ __NR_fchown32 ] = (syscall_handler_t *) sys_fchown, \
91 [ __NR_setresuid32 ] = (syscall_handler_t *) sys_setresuid, \
92 [ __NR_getresuid32 ] = (syscall_handler_t *) sys_getresuid, \
93 [ __NR_setresgid32 ] = (syscall_handler_t *) sys_setresgid, \
94 [ __NR_getresgid32 ] = (syscall_handler_t *) sys_getresgid, \
95 [ __NR_chown32 ] = (syscall_handler_t *) sys_chown, \
96 [ __NR_setuid32 ] = (syscall_handler_t *) sys_setuid, \
97 [ __NR_setgid32 ] = (syscall_handler_t *) sys_setgid, \
98 [ __NR_setfsuid32 ] = (syscall_handler_t *) sys_setfsuid, \
99 [ __NR_setfsgid32 ] = (syscall_handler_t *) sys_setfsgid, \
100 [ __NR_pivot_root ] = (syscall_handler_t *) sys_pivot_root, \
101 [ __NR_mincore ] = (syscall_handler_t *) sys_mincore, \
102 [ __NR_madvise ] = (syscall_handler_t *) sys_madvise, \
103 [ 222 ] = (syscall_handler_t *) sys_ni_syscall, \
104 [ 223 ] = (syscall_handler_t *) sys_ni_syscall, \
105 [ __NR_set_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
106 [ __NR_get_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
107 [ 251 ] = (syscall_handler_t *) sys_ni_syscall, \
108 [ 285 ] = (syscall_handler_t *) sys_ni_syscall,
109
110/* 222 doesn't yet have a name in include/asm-i386/unistd.h */
111
112#define LAST_ARCH_SYSCALL 285
113
114/*
115 * Overrides for Emacs so that we follow Linus's tabbing style.
116 * Emacs will notice this stuff at the end of the file and automatically
117 * adjust the settings for this buffer only. This must remain at the end
118 * of the file.
119 * ---------------------------------------------------------------------------
120 * Local variables:
121 * c-file-style: "linux"
122 * End:
123 */
diff --git a/arch/um/include/sysdep-x86_64/syscalls.h b/arch/um/include/sysdep-x86_64/syscalls.h
index b187a4157ff3..67923cca5691 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[];
26extern long old_mmap(unsigned long addr, unsigned long len, 26extern long old_mmap(unsigned long addr, unsigned long len,
27 unsigned long prot, unsigned long flags, 27 unsigned long prot, unsigned long flags,
28 unsigned long fd, unsigned long pgoff); 28 unsigned long fd, unsigned long pgoff);
29extern syscall_handler_t wrap_sys_shmat;
30extern syscall_handler_t sys_modify_ldt; 29extern syscall_handler_t sys_modify_ldt;
31extern syscall_handler_t sys_arch_prctl; 30extern syscall_handler_t sys_arch_prctl;
32 31
33#define ARCH_SYSCALLS \ 32#define NR_syscalls (__NR_syscall_max + 1)
34 [ __NR_mmap ] = (syscall_handler_t *) old_mmap, \
35 [ __NR_select ] = (syscall_handler_t *) sys_select, \
36 [ __NR_mincore ] = (syscall_handler_t *) sys_mincore, \
37 [ __NR_madvise ] = (syscall_handler_t *) sys_madvise, \
38 [ __NR_shmget ] = (syscall_handler_t *) sys_shmget, \
39 [ __NR_shmat ] = (syscall_handler_t *) wrap_sys_shmat, \
40 [ __NR_shmctl ] = (syscall_handler_t *) sys_shmctl, \
41 [ __NR_semop ] = (syscall_handler_t *) sys_semop, \
42 [ __NR_semget ] = (syscall_handler_t *) sys_semget, \
43 [ __NR_semctl ] = (syscall_handler_t *) sys_semctl, \
44 [ __NR_shmdt ] = (syscall_handler_t *) sys_shmdt, \
45 [ __NR_msgget ] = (syscall_handler_t *) sys_msgget, \
46 [ __NR_msgsnd ] = (syscall_handler_t *) sys_msgsnd, \
47 [ __NR_msgrcv ] = (syscall_handler_t *) sys_msgrcv, \
48 [ __NR_msgctl ] = (syscall_handler_t *) sys_msgctl, \
49 [ __NR_pivot_root ] = (syscall_handler_t *) sys_pivot_root, \
50 [ __NR_tuxcall ] = (syscall_handler_t *) sys_ni_syscall, \
51 [ __NR_security ] = (syscall_handler_t *) sys_ni_syscall, \
52 [ __NR_epoll_ctl_old ] = (syscall_handler_t *) sys_ni_syscall, \
53 [ __NR_epoll_wait_old ] = (syscall_handler_t *) sys_ni_syscall, \
54 [ __NR_modify_ldt ] = (syscall_handler_t *) sys_modify_ldt, \
55 [ __NR_arch_prctl ] = (syscall_handler_t *) sys_arch_prctl, \
56 [ __NR_socket ] = (syscall_handler_t *) sys_socket, \
57 [ __NR_connect ] = (syscall_handler_t *) sys_connect, \
58 [ __NR_accept ] = (syscall_handler_t *) sys_accept, \
59 [ __NR_recvfrom ] = (syscall_handler_t *) sys_recvfrom, \
60 [ __NR_recvmsg ] = (syscall_handler_t *) sys_recvmsg, \
61 [ __NR_sendmsg ] = (syscall_handler_t *) sys_sendmsg, \
62 [ __NR_bind ] = (syscall_handler_t *) sys_bind, \
63 [ __NR_listen ] = (syscall_handler_t *) sys_listen, \
64 [ __NR_getsockname ] = (syscall_handler_t *) sys_getsockname, \
65 [ __NR_getpeername ] = (syscall_handler_t *) sys_getpeername, \
66 [ __NR_socketpair ] = (syscall_handler_t *) sys_socketpair, \
67 [ __NR_sendto ] = (syscall_handler_t *) sys_sendto, \
68 [ __NR_shutdown ] = (syscall_handler_t *) sys_shutdown, \
69 [ __NR_setsockopt ] = (syscall_handler_t *) sys_setsockopt, \
70 [ __NR_getsockopt ] = (syscall_handler_t *) sys_getsockopt, \
71 [ __NR_iopl ] = (syscall_handler_t *) sys_ni_syscall, \
72 [ __NR_set_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
73 [ __NR_get_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
74 [ __NR_semtimedop ] = (syscall_handler_t *) sys_semtimedop, \
75 [ 251 ] = (syscall_handler_t *) sys_ni_syscall,
76
77#define LAST_ARCH_SYSCALL 251
78#define NR_syscalls 1024
79 33
80#endif 34#endif
81
82/*
83 * Overrides for Emacs so that we follow Linus's tabbing style.
84 * Emacs will notice this stuff at the end of the file and automatically
85 * adjust the settings for this buffer only. This must remain at the end
86 * of the file.
87 * ---------------------------------------------------------------------------
88 * Local variables:
89 * c-file-style: "linux"
90 * End:
91 */
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index dc796c1bf39e..246f0e7fb4cc 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 \
10 helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o mem_user.o \ 10 helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o mem_user.o \
11 physmem.o process.o process_kern.o ptrace.o reboot.o resource.o \ 11 physmem.o process.o process_kern.o ptrace.o reboot.o resource.o \
12 sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \ 12 sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \
13 syscall_kern.o sysrq.o sys_call_table.o tempfile.o time.o time_kern.o \ 13 syscall_kern.o sysrq.o tempfile.o time.o time_kern.o \
14 tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o umid.o \ 14 tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o umid.o \
15 user_util.o 15 user_util.o
16 16
@@ -53,6 +53,7 @@ quiet_cmd_quote2 = QUOTE $@
53 cmd_quote2 = sed -e '/CONFIG/{' \ 53 cmd_quote2 = sed -e '/CONFIG/{' \
54 -e 's/"CONFIG"\;/""/' \ 54 -e 's/"CONFIG"\;/""/' \
55 -e 'r $(obj)/config.tmp' \ 55 -e 'r $(obj)/config.tmp' \
56 -e 'a""\;' \ 56 -e 'a \' \
57 -e '""\;' \
57 -e '}' \ 58 -e '}' \
58 $< > $@ 59 $< > $@
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
index 1d719d5b4bb9..7a943696f950 100644
--- a/arch/um/kernel/process_kern.c
+++ b/arch/um/kernel/process_kern.c
@@ -161,10 +161,6 @@ void *get_current(void)
161 return(current); 161 return(current);
162} 162}
163 163
164void prepare_to_copy(struct task_struct *tsk)
165{
166}
167
168int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, 164int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
169 unsigned long stack_top, struct task_struct * p, 165 unsigned long stack_top, struct task_struct * p,
170 struct pt_regs *regs) 166 struct pt_regs *regs)
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index 7b259a22447e..959b2d2490df 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)
143 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ 143 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
144 case PTRACE_CONT: { /* restart after signal. */ 144 case PTRACE_CONT: { /* restart after signal. */
145 ret = -EIO; 145 ret = -EIO;
146 if ((unsigned long) data > _NSIG) 146 if (!valid_signal(data))
147 break; 147 break;
148 148
149 child->ptrace &= ~PT_DTRACE; 149 child->ptrace &= ~PT_DTRACE;
@@ -179,7 +179,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
179 179
180 case PTRACE_SINGLESTEP: { /* set the trap flag. */ 180 case PTRACE_SINGLESTEP: { /* set the trap flag. */
181 ret = -EIO; 181 ret = -EIO;
182 if ((unsigned long) data > _NSIG) 182 if (!valid_signal(data))
183 break; 183 break;
184 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 184 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
185 child->ptrace |= PT_DTRACE; 185 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 11986c9b9ddf..c35620385da0 100644
--- a/arch/um/kernel/skas/include/uaccess-skas.h
+++ b/arch/um/kernel/skas/include/uaccess-skas.h
@@ -18,7 +18,7 @@
18 ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \ 18 ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \
19 ((unsigned long) (addr) + (size) >= (unsigned long)(addr)))) 19 ((unsigned long) (addr) + (size) >= (unsigned long)(addr))))
20 20
21static inline int verify_area_skas(int type, const void * addr, 21static inline int __deprecated verify_area_skas(int type, const void * addr,
22 unsigned long size) 22 unsigned long size)
23{ 23{
24 return(access_ok_skas(type, addr, size) ? 0 : -EFAULT); 24 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 7575ec489b63..f7da9d027672 100644
--- a/arch/um/kernel/skas/uaccess.c
+++ b/arch/um/kernel/skas/uaccess.c
@@ -3,6 +3,7 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/compiler.h"
6#include "linux/stddef.h" 7#include "linux/stddef.h"
7#include "linux/kernel.h" 8#include "linux/kernel.h"
8#include "linux/string.h" 9#include "linux/string.h"
@@ -61,8 +62,7 @@ static void do_buffer_op(void *jmpbuf, void *arg_ptr)
61 void *arg; 62 void *arg;
62 int *res; 63 int *res;
63 64
64 /* Some old gccs recognize __va_copy, but not va_copy */ 65 va_copy(args, *(va_list *)arg_ptr);
65 __va_copy(args, *(va_list *)arg_ptr);
66 addr = va_arg(args, unsigned long); 66 addr = va_arg(args, unsigned long);
67 len = va_arg(args, int); 67 len = va_arg(args, int);
68 is_write = va_arg(args, int); 68 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 7fc06c85b29d..000000000000
--- a/arch/um/kernel/sys_call_table.c
+++ /dev/null
@@ -1,276 +0,0 @@
1/*
2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
3 * Copyright 2003 PathScale, Inc.
4 * Licensed under the GPL
5 */
6
7#include "linux/config.h"
8#include "linux/unistd.h"
9#include "linux/sys.h"
10#include "linux/swap.h"
11#include "linux/syscalls.h"
12#include "linux/sysctl.h"
13#include "asm/signal.h"
14#include "sysdep/syscalls.h"
15#include "kern_util.h"
16
17#ifdef CONFIG_NFSD
18#define NFSSERVCTL sys_nfsservctl
19#else
20#define NFSSERVCTL sys_ni_syscall
21#endif
22
23#define LAST_GENERIC_SYSCALL __NR_keyctl
24
25#if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL
26#define LAST_SYSCALL LAST_GENERIC_SYSCALL
27#else
28#define LAST_SYSCALL LAST_ARCH_SYSCALL
29#endif
30
31extern syscall_handler_t sys_fork;
32extern syscall_handler_t sys_execve;
33extern syscall_handler_t um_time;
34extern syscall_handler_t um_stime;
35extern syscall_handler_t sys_pipe;
36extern syscall_handler_t sys_olduname;
37extern syscall_handler_t sys_sigaction;
38extern syscall_handler_t sys_sigsuspend;
39extern syscall_handler_t old_readdir;
40extern syscall_handler_t sys_uname;
41extern syscall_handler_t sys_ipc;
42extern syscall_handler_t sys_sigreturn;
43extern syscall_handler_t sys_clone;
44extern syscall_handler_t sys_rt_sigreturn;
45extern syscall_handler_t sys_sigaltstack;
46extern syscall_handler_t sys_vfork;
47extern syscall_handler_t old_select;
48extern syscall_handler_t sys_modify_ldt;
49extern syscall_handler_t sys_rt_sigsuspend;
50extern syscall_handler_t sys_mbind;
51extern syscall_handler_t sys_get_mempolicy;
52extern syscall_handler_t sys_set_mempolicy;
53extern syscall_handler_t sys_sys_setaltroot;
54
55syscall_handler_t *sys_call_table[] = {
56 [ __NR_restart_syscall ] = (syscall_handler_t *) sys_restart_syscall,
57 [ __NR_exit ] = (syscall_handler_t *) sys_exit,
58 [ __NR_fork ] = (syscall_handler_t *) sys_fork,
59 [ __NR_read ] = (syscall_handler_t *) sys_read,
60 [ __NR_write ] = (syscall_handler_t *) sys_write,
61
62 /* These three are declared differently in asm/unistd.h */
63 [ __NR_open ] = (syscall_handler_t *) sys_open,
64 [ __NR_close ] = (syscall_handler_t *) sys_close,
65 [ __NR_creat ] = (syscall_handler_t *) sys_creat,
66 [ __NR_link ] = (syscall_handler_t *) sys_link,
67 [ __NR_unlink ] = (syscall_handler_t *) sys_unlink,
68 [ __NR_execve ] = (syscall_handler_t *) sys_execve,
69
70 /* declared differently in kern_util.h */
71 [ __NR_chdir ] = (syscall_handler_t *) sys_chdir,
72 [ __NR_time ] = um_time,
73 [ __NR_mknod ] = (syscall_handler_t *) sys_mknod,
74 [ __NR_chmod ] = (syscall_handler_t *) sys_chmod,
75 [ __NR_lchown ] = (syscall_handler_t *) sys_lchown16,
76 [ __NR_lseek ] = (syscall_handler_t *) sys_lseek,
77 [ __NR_getpid ] = (syscall_handler_t *) sys_getpid,
78 [ __NR_mount ] = (syscall_handler_t *) sys_mount,
79 [ __NR_setuid ] = (syscall_handler_t *) sys_setuid16,
80 [ __NR_getuid ] = (syscall_handler_t *) sys_getuid16,
81 [ __NR_ptrace ] = (syscall_handler_t *) sys_ptrace,
82 [ __NR_alarm ] = (syscall_handler_t *) sys_alarm,
83 [ __NR_pause ] = (syscall_handler_t *) sys_pause,
84 [ __NR_utime ] = (syscall_handler_t *) sys_utime,
85 [ __NR_access ] = (syscall_handler_t *) sys_access,
86 [ __NR_sync ] = (syscall_handler_t *) sys_sync,
87 [ __NR_kill ] = (syscall_handler_t *) sys_kill,
88 [ __NR_rename ] = (syscall_handler_t *) sys_rename,
89 [ __NR_mkdir ] = (syscall_handler_t *) sys_mkdir,
90 [ __NR_rmdir ] = (syscall_handler_t *) sys_rmdir,
91
92 /* Declared differently in asm/unistd.h */
93 [ __NR_dup ] = (syscall_handler_t *) sys_dup,
94 [ __NR_pipe ] = (syscall_handler_t *) sys_pipe,
95 [ __NR_times ] = (syscall_handler_t *) sys_times,
96 [ __NR_brk ] = (syscall_handler_t *) sys_brk,
97 [ __NR_setgid ] = (syscall_handler_t *) sys_setgid16,
98 [ __NR_getgid ] = (syscall_handler_t *) sys_getgid16,
99 [ __NR_geteuid ] = (syscall_handler_t *) sys_geteuid16,
100 [ __NR_getegid ] = (syscall_handler_t *) sys_getegid16,
101 [ __NR_acct ] = (syscall_handler_t *) sys_acct,
102 [ __NR_umount2 ] = (syscall_handler_t *) sys_umount,
103 [ __NR_ioctl ] = (syscall_handler_t *) sys_ioctl,
104 [ __NR_fcntl ] = (syscall_handler_t *) sys_fcntl,
105 [ __NR_setpgid ] = (syscall_handler_t *) sys_setpgid,
106 [ __NR_umask ] = (syscall_handler_t *) sys_umask,
107 [ __NR_chroot ] = (syscall_handler_t *) sys_chroot,
108 [ __NR_ustat ] = (syscall_handler_t *) sys_ustat,
109 [ __NR_dup2 ] = (syscall_handler_t *) sys_dup2,
110 [ __NR_getppid ] = (syscall_handler_t *) sys_getppid,
111 [ __NR_getpgrp ] = (syscall_handler_t *) sys_getpgrp,
112 [ __NR_setsid ] = (syscall_handler_t *) sys_setsid,
113 [ __NR_setreuid ] = (syscall_handler_t *) sys_setreuid16,
114 [ __NR_setregid ] = (syscall_handler_t *) sys_setregid16,
115 [ __NR_sethostname ] = (syscall_handler_t *) sys_sethostname,
116 [ __NR_setrlimit ] = (syscall_handler_t *) sys_setrlimit,
117 [ __NR_getrlimit ] = (syscall_handler_t *) sys_old_getrlimit,
118 [ __NR_getrusage ] = (syscall_handler_t *) sys_getrusage,
119 [ __NR_gettimeofday ] = (syscall_handler_t *) sys_gettimeofday,
120 [ __NR_settimeofday ] = (syscall_handler_t *) sys_settimeofday,
121 [ __NR_getgroups ] = (syscall_handler_t *) sys_getgroups16,
122 [ __NR_setgroups ] = (syscall_handler_t *) sys_setgroups16,
123 [ __NR_symlink ] = (syscall_handler_t *) sys_symlink,
124 [ __NR_readlink ] = (syscall_handler_t *) sys_readlink,
125 [ __NR_uselib ] = (syscall_handler_t *) sys_uselib,
126 [ __NR_swapon ] = (syscall_handler_t *) sys_swapon,
127 [ __NR_reboot ] = (syscall_handler_t *) sys_reboot,
128 [ __NR_munmap ] = (syscall_handler_t *) sys_munmap,
129 [ __NR_truncate ] = (syscall_handler_t *) sys_truncate,
130 [ __NR_ftruncate ] = (syscall_handler_t *) sys_ftruncate,
131 [ __NR_fchmod ] = (syscall_handler_t *) sys_fchmod,
132 [ __NR_fchown ] = (syscall_handler_t *) sys_fchown16,
133 [ __NR_getpriority ] = (syscall_handler_t *) sys_getpriority,
134 [ __NR_setpriority ] = (syscall_handler_t *) sys_setpriority,
135 [ __NR_statfs ] = (syscall_handler_t *) sys_statfs,
136 [ __NR_fstatfs ] = (syscall_handler_t *) sys_fstatfs,
137 [ __NR_ioperm ] = (syscall_handler_t *) sys_ni_syscall,
138 [ __NR_syslog ] = (syscall_handler_t *) sys_syslog,
139 [ __NR_setitimer ] = (syscall_handler_t *) sys_setitimer,
140 [ __NR_getitimer ] = (syscall_handler_t *) sys_getitimer,
141 [ __NR_stat ] = (syscall_handler_t *) sys_newstat,
142 [ __NR_lstat ] = (syscall_handler_t *) sys_newlstat,
143 [ __NR_fstat ] = (syscall_handler_t *) sys_newfstat,
144 [ __NR_vhangup ] = (syscall_handler_t *) sys_vhangup,
145 [ __NR_wait4 ] = (syscall_handler_t *) sys_wait4,
146 [ __NR_swapoff ] = (syscall_handler_t *) sys_swapoff,
147 [ __NR_sysinfo ] = (syscall_handler_t *) sys_sysinfo,
148 [ __NR_fsync ] = (syscall_handler_t *) sys_fsync,
149 [ __NR_clone ] = (syscall_handler_t *) sys_clone,
150 [ __NR_setdomainname ] = (syscall_handler_t *) sys_setdomainname,
151 [ __NR_uname ] = (syscall_handler_t *) sys_newuname,
152 [ __NR_adjtimex ] = (syscall_handler_t *) sys_adjtimex,
153 [ __NR_mprotect ] = (syscall_handler_t *) sys_mprotect,
154 [ __NR_create_module ] = (syscall_handler_t *) sys_ni_syscall,
155 [ __NR_init_module ] = (syscall_handler_t *) sys_init_module,
156 [ __NR_delete_module ] = (syscall_handler_t *) sys_delete_module,
157 [ __NR_get_kernel_syms ] = (syscall_handler_t *) sys_ni_syscall,
158 [ __NR_quotactl ] = (syscall_handler_t *) sys_quotactl,
159 [ __NR_getpgid ] = (syscall_handler_t *) sys_getpgid,
160 [ __NR_fchdir ] = (syscall_handler_t *) sys_fchdir,
161 [ __NR_sysfs ] = (syscall_handler_t *) sys_sysfs,
162 [ __NR_personality ] = (syscall_handler_t *) sys_personality,
163 [ __NR_afs_syscall ] = (syscall_handler_t *) sys_ni_syscall,
164 [ __NR_setfsuid ] = (syscall_handler_t *) sys_setfsuid16,
165 [ __NR_setfsgid ] = (syscall_handler_t *) sys_setfsgid16,
166 [ __NR_getdents ] = (syscall_handler_t *) sys_getdents,
167 [ __NR_flock ] = (syscall_handler_t *) sys_flock,
168 [ __NR_msync ] = (syscall_handler_t *) sys_msync,
169 [ __NR_readv ] = (syscall_handler_t *) sys_readv,
170 [ __NR_writev ] = (syscall_handler_t *) sys_writev,
171 [ __NR_getsid ] = (syscall_handler_t *) sys_getsid,
172 [ __NR_fdatasync ] = (syscall_handler_t *) sys_fdatasync,
173 [ __NR__sysctl ] = (syscall_handler_t *) sys_sysctl,
174 [ __NR_mlock ] = (syscall_handler_t *) sys_mlock,
175 [ __NR_munlock ] = (syscall_handler_t *) sys_munlock,
176 [ __NR_mlockall ] = (syscall_handler_t *) sys_mlockall,
177 [ __NR_munlockall ] = (syscall_handler_t *) sys_munlockall,
178 [ __NR_sched_setparam ] = (syscall_handler_t *) sys_sched_setparam,
179 [ __NR_sched_getparam ] = (syscall_handler_t *) sys_sched_getparam,
180 [ __NR_sched_setscheduler ] = (syscall_handler_t *) sys_sched_setscheduler,
181 [ __NR_sched_getscheduler ] = (syscall_handler_t *) sys_sched_getscheduler,
182 [ __NR_sched_yield ] = (syscall_handler_t *) yield,
183 [ __NR_sched_get_priority_max ] = (syscall_handler_t *) sys_sched_get_priority_max,
184 [ __NR_sched_get_priority_min ] = (syscall_handler_t *) sys_sched_get_priority_min,
185 [ __NR_sched_rr_get_interval ] = (syscall_handler_t *) sys_sched_rr_get_interval,
186 [ __NR_nanosleep ] = (syscall_handler_t *) sys_nanosleep,
187 [ __NR_mremap ] = (syscall_handler_t *) sys_mremap,
188 [ __NR_setresuid ] = (syscall_handler_t *) sys_setresuid16,
189 [ __NR_getresuid ] = (syscall_handler_t *) sys_getresuid16,
190 [ __NR_query_module ] = (syscall_handler_t *) sys_ni_syscall,
191 [ __NR_poll ] = (syscall_handler_t *) sys_poll,
192 [ __NR_nfsservctl ] = (syscall_handler_t *) NFSSERVCTL,
193 [ __NR_setresgid ] = (syscall_handler_t *) sys_setresgid16,
194 [ __NR_getresgid ] = (syscall_handler_t *) sys_getresgid16,
195 [ __NR_prctl ] = (syscall_handler_t *) sys_prctl,
196 [ __NR_rt_sigreturn ] = (syscall_handler_t *) sys_rt_sigreturn,
197 [ __NR_rt_sigaction ] = (syscall_handler_t *) sys_rt_sigaction,
198 [ __NR_rt_sigprocmask ] = (syscall_handler_t *) sys_rt_sigprocmask,
199 [ __NR_rt_sigpending ] = (syscall_handler_t *) sys_rt_sigpending,
200 [ __NR_rt_sigtimedwait ] = (syscall_handler_t *) sys_rt_sigtimedwait,
201 [ __NR_rt_sigqueueinfo ] = (syscall_handler_t *) sys_rt_sigqueueinfo,
202 [ __NR_rt_sigsuspend ] = (syscall_handler_t *) sys_rt_sigsuspend,
203 [ __NR_pread64 ] = (syscall_handler_t *) sys_pread64,
204 [ __NR_pwrite64 ] = (syscall_handler_t *) sys_pwrite64,
205 [ __NR_chown ] = (syscall_handler_t *) sys_chown16,
206 [ __NR_getcwd ] = (syscall_handler_t *) sys_getcwd,
207 [ __NR_capget ] = (syscall_handler_t *) sys_capget,
208 [ __NR_capset ] = (syscall_handler_t *) sys_capset,
209 [ __NR_sigaltstack ] = (syscall_handler_t *) sys_sigaltstack,
210 [ __NR_sendfile ] = (syscall_handler_t *) sys_sendfile,
211 [ __NR_getpmsg ] = (syscall_handler_t *) sys_ni_syscall,
212 [ __NR_putpmsg ] = (syscall_handler_t *) sys_ni_syscall,
213 [ __NR_vfork ] = (syscall_handler_t *) sys_vfork,
214 [ __NR_getdents64 ] = (syscall_handler_t *) sys_getdents64,
215 [ __NR_gettid ] = (syscall_handler_t *) sys_gettid,
216 [ __NR_readahead ] = (syscall_handler_t *) sys_readahead,
217 [ __NR_setxattr ] = (syscall_handler_t *) sys_setxattr,
218 [ __NR_lsetxattr ] = (syscall_handler_t *) sys_lsetxattr,
219 [ __NR_fsetxattr ] = (syscall_handler_t *) sys_fsetxattr,
220 [ __NR_getxattr ] = (syscall_handler_t *) sys_getxattr,
221 [ __NR_lgetxattr ] = (syscall_handler_t *) sys_lgetxattr,
222 [ __NR_fgetxattr ] = (syscall_handler_t *) sys_fgetxattr,
223 [ __NR_listxattr ] = (syscall_handler_t *) sys_listxattr,
224 [ __NR_llistxattr ] = (syscall_handler_t *) sys_llistxattr,
225 [ __NR_flistxattr ] = (syscall_handler_t *) sys_flistxattr,
226 [ __NR_removexattr ] = (syscall_handler_t *) sys_removexattr,
227 [ __NR_lremovexattr ] = (syscall_handler_t *) sys_lremovexattr,
228 [ __NR_fremovexattr ] = (syscall_handler_t *) sys_fremovexattr,
229 [ __NR_tkill ] = (syscall_handler_t *) sys_tkill,
230 [ __NR_futex ] = (syscall_handler_t *) sys_futex,
231 [ __NR_sched_setaffinity ] = (syscall_handler_t *) sys_sched_setaffinity,
232 [ __NR_sched_getaffinity ] = (syscall_handler_t *) sys_sched_getaffinity,
233 [ __NR_io_setup ] = (syscall_handler_t *) sys_io_setup,
234 [ __NR_io_destroy ] = (syscall_handler_t *) sys_io_destroy,
235 [ __NR_io_getevents ] = (syscall_handler_t *) sys_io_getevents,
236 [ __NR_io_submit ] = (syscall_handler_t *) sys_io_submit,
237 [ __NR_io_cancel ] = (syscall_handler_t *) sys_io_cancel,
238 [ __NR_exit_group ] = (syscall_handler_t *) sys_exit_group,
239 [ __NR_lookup_dcookie ] = (syscall_handler_t *) sys_lookup_dcookie,
240 [ __NR_epoll_create ] = (syscall_handler_t *) sys_epoll_create,
241 [ __NR_epoll_ctl ] = (syscall_handler_t *) sys_epoll_ctl,
242 [ __NR_epoll_wait ] = (syscall_handler_t *) sys_epoll_wait,
243 [ __NR_remap_file_pages ] = (syscall_handler_t *) sys_remap_file_pages,
244 [ __NR_set_tid_address ] = (syscall_handler_t *) sys_set_tid_address,
245 [ __NR_timer_create ] = (syscall_handler_t *) sys_timer_create,
246 [ __NR_timer_settime ] = (syscall_handler_t *) sys_timer_settime,
247 [ __NR_timer_gettime ] = (syscall_handler_t *) sys_timer_gettime,
248 [ __NR_timer_getoverrun ] = (syscall_handler_t *) sys_timer_getoverrun,
249 [ __NR_timer_delete ] = (syscall_handler_t *) sys_timer_delete,
250 [ __NR_clock_settime ] = (syscall_handler_t *) sys_clock_settime,
251 [ __NR_clock_gettime ] = (syscall_handler_t *) sys_clock_gettime,
252 [ __NR_clock_getres ] = (syscall_handler_t *) sys_clock_getres,
253 [ __NR_clock_nanosleep ] = (syscall_handler_t *) sys_clock_nanosleep,
254 [ __NR_tgkill ] = (syscall_handler_t *) sys_tgkill,
255 [ __NR_utimes ] = (syscall_handler_t *) sys_utimes,
256 [ __NR_fadvise64 ] = (syscall_handler_t *) sys_fadvise64,
257 [ __NR_vserver ] = (syscall_handler_t *) sys_ni_syscall,
258 [ __NR_mbind ] = (syscall_handler_t *) sys_mbind,
259 [ __NR_get_mempolicy ] = (syscall_handler_t *) sys_get_mempolicy,
260 [ __NR_set_mempolicy ] = (syscall_handler_t *) sys_set_mempolicy,
261 [ __NR_mq_open ] = (syscall_handler_t *) sys_mq_open,
262 [ __NR_mq_unlink ] = (syscall_handler_t *) sys_mq_unlink,
263 [ __NR_mq_timedsend ] = (syscall_handler_t *) sys_mq_timedsend,
264 [ __NR_mq_timedreceive ] = (syscall_handler_t *) sys_mq_timedreceive,
265 [ __NR_mq_notify ] = (syscall_handler_t *) sys_mq_notify,
266 [ __NR_mq_getsetattr ] = (syscall_handler_t *) sys_mq_getsetattr,
267 [ __NR_kexec_load ] = (syscall_handler_t *) sys_ni_syscall,
268 [ __NR_waitid ] = (syscall_handler_t *) sys_waitid,
269 [ __NR_add_key ] = (syscall_handler_t *) sys_add_key,
270 [ __NR_request_key ] = (syscall_handler_t *) sys_request_key,
271 [ __NR_keyctl ] = (syscall_handler_t *) sys_keyctl,
272
273 ARCH_SYSCALLS
274 [ LAST_SYSCALL + 1 ... NR_syscalls ] =
275 (syscall_handler_t *) sys_ni_syscall
276};
diff --git a/arch/um/kernel/tt/include/uaccess-tt.h b/arch/um/kernel/tt/include/uaccess-tt.h
index f0bad010cebd..bb69d6b7d022 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;
33 (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \ 33 (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \
34 (under_task_size(addr, size) || is_stack(addr, size)))) 34 (under_task_size(addr, size) || is_stack(addr, size))))
35 35
36static inline int verify_area_tt(int type, const void * addr, 36static inline int __deprecated verify_area_tt(int type, const void * addr,
37 unsigned long size) 37 unsigned long size)
38{ 38{
39 return(access_ok_tt(type, addr, size) ? 0 : -EFAULT); 39 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 148645b14480..9a0ad094d926 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)
105 panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", 105 panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
106 err); 106 err);
107 107
108 errno = 0;
108 err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs); 109 err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs);
109 if(!err) 110 if(!err)
110 return; 111 return;
112 if(errno != EIO)
113 panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d",
114 errno);
111 115
112 have_fpx_regs = 0; 116 have_fpx_regs = 0;
113 if(err != EIO)
114 panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d",
115 err);
116 117
117 err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs); 118 err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs);
118 if(err) 119 if(err)
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
index 71b47e618605..950781e354de 100644
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -1,5 +1,6 @@
1obj-y = bitops.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ 1obj-y = bitops.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \
2 ptrace_user.o semaphore.o signal.o sigcontext.o syscalls.o sysrq.o 2 ptrace_user.o semaphore.o signal.o sigcontext.o syscalls.o sysrq.o \
3 sys_call_table.o
3 4
4obj-$(CONFIG_HIGHMEM) += highmem.o 5obj-$(CONFIG_HIGHMEM) += highmem.o
5obj-$(CONFIG_MODULES) += module.o 6obj-$(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 000000000000..ad75c27afe38
--- /dev/null
+++ b/arch/um/sys-i386/sys_call_table.S
@@ -0,0 +1,16 @@
1#include <linux/linkage.h>
2/* Steal i386 syscall table for our purposes, but with some slight changes.*/
3
4#define sys_iopl sys_ni_syscall
5#define sys_ioperm sys_ni_syscall
6
7#define sys_vm86old sys_ni_syscall
8#define sys_vm86 sys_ni_syscall
9#define sys_set_thread_area sys_ni_syscall
10#define sys_get_thread_area sys_ni_syscall
11
12#define sys_stime um_stime
13#define sys_time um_time
14#define old_mmap old_mmap_i386
15
16#include "../../i386/kernel/syscall_table.S"
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile
index 2129e3143559..d7ed2f7908df 100644
--- a/arch/um/sys-x86_64/Makefile
+++ b/arch/um/sys-x86_64/Makefile
@@ -6,7 +6,7 @@
6 6
7lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \ 7lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \
8 ptrace.o ptrace_user.o semaphore.o sigcontext.o signal.o \ 8 ptrace.o ptrace_user.o semaphore.o sigcontext.o signal.o \
9 syscalls.o sysrq.o thunk.o 9 syscalls.o sysrq.o thunk.o syscall_table.o
10 10
11USER_OBJS := ptrace_user.o sigcontext.o 11USER_OBJS := ptrace_user.o sigcontext.o
12 12
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 000000000000..34b2e842864f
--- /dev/null
+++ b/arch/um/sys-x86_64/syscall_table.c
@@ -0,0 +1,59 @@
1/* System call table for UML/x86-64, copied from arch/x86_64/kernel/syscall.c
2 * with some changes for UML. */
3
4#include <linux/linkage.h>
5#include <linux/sys.h>
6#include <linux/cache.h>
7#include <linux/config.h>
8
9#define __NO_STUBS
10
11/* Below you can see, in terms of #define's, the differences between the x86-64
12 * and the UML syscall table. */
13
14/* Not going to be implemented by UML, since we have no hardware. */
15#define stub_iopl sys_ni_syscall
16#define sys_ioperm sys_ni_syscall
17
18/* The UML TLS problem. Note that x86_64 does not implement this, so the below
19 * is needed only for the ia32 compatibility. */
20/*#define sys_set_thread_area sys_ni_syscall
21#define sys_get_thread_area sys_ni_syscall*/
22
23/* For __NR_time. The x86-64 name hopefully will change from sys_time64 to
24 * sys_time (since the current situation is bogus). I've sent a patch to cleanup
25 * this. Remove below the obsoleted line. */
26#define sys_time64 um_time
27#define sys_time um_time
28
29/* On UML we call it this way ("old" means it's not mmap2) */
30#define sys_mmap old_mmap
31/* On x86-64 sys_uname is actually sys_newuname plus a compatibility trick.
32 * See arch/x86_64/kernel/sys_x86_64.c */
33#define sys_uname sys_uname64
34
35#define stub_clone sys_clone
36#define stub_fork sys_fork
37#define stub_vfork sys_vfork
38#define stub_execve sys_execve
39#define stub_rt_sigsuspend sys_rt_sigsuspend
40#define stub_sigaltstack sys_sigaltstack
41#define stub_rt_sigreturn sys_rt_sigreturn
42
43#define __SYSCALL(nr, sym) extern asmlinkage void sym(void) ;
44#undef _ASM_X86_64_UNISTD_H_
45#include <asm-x86_64/unistd.h>
46
47#undef __SYSCALL
48#define __SYSCALL(nr, sym) [ nr ] = sym,
49#undef _ASM_X86_64_UNISTD_H_
50
51typedef void (*sys_call_ptr_t)(void);
52
53extern void sys_ni_syscall(void);
54
55sys_call_ptr_t sys_call_table[__NR_syscall_max+1] __cacheline_aligned = {
56 /* Smells like a like a compiler bug -- it doesn't work when the & below is removed. */
57 [0 ... __NR_syscall_max] = &sys_ni_syscall,
58#include <asm-x86_64/unistd.h>
59};
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c
index 68205a03364c..ab4b0abf8af3 100644
--- a/arch/um/sys-x86_64/syscalls.c
+++ b/arch/um/sys-x86_64/syscalls.c
@@ -14,11 +14,15 @@
14#include "asm/prctl.h" /* XXX This should get the constants from libc */ 14#include "asm/prctl.h" /* XXX This should get the constants from libc */
15#include "choose-mode.h" 15#include "choose-mode.h"
16 16
17asmlinkage long wrap_sys_shmat(int shmid, char __user *shmaddr, int shmflg) 17asmlinkage long sys_uname64(struct new_utsname __user * name)
18{ 18{
19 unsigned long raddr; 19 int err;
20 20 down_read(&uts_sem);
21 return do_shmat(shmid, shmaddr, shmflg, &raddr) ?: (long) raddr; 21 err = copy_to_user(name, &system_utsname, sizeof (*name));
22 up_read(&uts_sem);
23 if (personality(current->personality) == PER_LINUX32)
24 err |= copy_to_user(&name->machine, "i686", 5);
25 return err ? -EFAULT : 0;
22} 26}
23 27
24#ifdef CONFIG_MODE_TT 28#ifdef CONFIG_MODE_TT
diff --git a/arch/v850/kernel/ptrace.c b/arch/v850/kernel/ptrace.c
index 8fa780757dcd..4726b87f5e5a 100644
--- a/arch/v850/kernel/ptrace.c
+++ b/arch/v850/kernel/ptrace.c
@@ -23,6 +23,7 @@
23#include <linux/sched.h> 23#include <linux/sched.h>
24#include <linux/smp_lock.h> 24#include <linux/smp_lock.h>
25#include <linux/ptrace.h> 25#include <linux/ptrace.h>
26#include <linux/signal.h>
26 27
27#include <asm/errno.h> 28#include <asm/errno.h>
28#include <asm/ptrace.h> 29#include <asm/ptrace.h>
@@ -208,7 +209,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
208 /* Execute a single instruction. */ 209 /* Execute a single instruction. */
209 case PTRACE_SINGLESTEP: 210 case PTRACE_SINGLESTEP:
210 rval = -EIO; 211 rval = -EIO;
211 if ((unsigned long) data > _NSIG) 212 if (!valid_signal(data))
212 break; 213 break;
213 214
214 /* Turn CHILD's single-step flag on or off. */ 215 /* 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 3e838be9dbe7..75d4d2ad93b3 100644
--- a/arch/x86_64/boot/setup.S
+++ b/arch/x86_64/boot/setup.S
@@ -160,7 +160,7 @@ ramdisk_max: .long 0xffffffff
160trampoline: call start_of_setup 160trampoline: call start_of_setup
161 .align 16 161 .align 16
162 # The offset at this point is 0x240 162 # The offset at this point is 0x240
163 .space (0x7ff-0x240+1) # E820 & EDD space (ending at 0x7ff) 163 .space (0xeff-0x240+1) # E820 & EDD space (ending at 0xeff)
164# End of setup header ##################################################### 164# End of setup header #####################################################
165 165
166start_of_setup: 166start_of_setup:
@@ -412,9 +412,9 @@ jmpe820:
412 # sizeof(e820rec). 412 # sizeof(e820rec).
413 # 413 #
414good820: 414good820:
415 movb (E820NR), %al # up to 32 entries 415 movb (E820NR), %al # up to 128 entries
416 cmpb $E820MAX, %al 416 cmpb $E820MAX, %al
417 jnl bail820 417 jae bail820
418 418
419 incb (E820NR) 419 incb (E820NR)
420 movw %di, %ax 420 movw %di, %ax
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c
index 56516ac92e5d..7c154dfff64a 100644
--- a/arch/x86_64/kernel/e820.c
+++ b/arch/x86_64/kernel/e820.c
@@ -2,6 +2,12 @@
2 * Handle the memory map. 2 * Handle the memory map.
3 * The functions here do the job until bootmem takes over. 3 * The functions here do the job until bootmem takes over.
4 * $Id: e820.c,v 1.4 2002/09/19 19:25:32 ak Exp $ 4 * $Id: e820.c,v 1.4 2002/09/19 19:25:32 ak Exp $
5 *
6 * Getting sanitize_e820_map() in sync with i386 version by applying change:
7 * - Provisions for empty E820 memory regions (reported by certain BIOSes).
8 * Alex Achenbach <xela@slit.de>, December 2002.
9 * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
10 *
5 */ 11 */
6#include <linux/config.h> 12#include <linux/config.h>
7#include <linux/kernel.h> 13#include <linux/kernel.h>
@@ -277,7 +283,7 @@ static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
277 int chgidx, still_changing; 283 int chgidx, still_changing;
278 int overlap_entries; 284 int overlap_entries;
279 int new_bios_entry; 285 int new_bios_entry;
280 int old_nr, new_nr; 286 int old_nr, new_nr, chg_nr;
281 int i; 287 int i;
282 288
283 /* 289 /*
@@ -331,20 +337,24 @@ static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
331 for (i=0; i < 2*old_nr; i++) 337 for (i=0; i < 2*old_nr; i++)
332 change_point[i] = &change_point_list[i]; 338 change_point[i] = &change_point_list[i];
333 339
334 /* record all known change-points (starting and ending addresses) */ 340 /* record all known change-points (starting and ending addresses),
341 omitting those that are for empty memory regions */
335 chgidx = 0; 342 chgidx = 0;
336 for (i=0; i < old_nr; i++) { 343 for (i=0; i < old_nr; i++) {
337 change_point[chgidx]->addr = biosmap[i].addr; 344 if (biosmap[i].size != 0) {
338 change_point[chgidx++]->pbios = &biosmap[i]; 345 change_point[chgidx]->addr = biosmap[i].addr;
339 change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size; 346 change_point[chgidx++]->pbios = &biosmap[i];
340 change_point[chgidx++]->pbios = &biosmap[i]; 347 change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size;
348 change_point[chgidx++]->pbios = &biosmap[i];
349 }
341 } 350 }
351 chg_nr = chgidx;
342 352
343 /* sort change-point list by memory addresses (low -> high) */ 353 /* sort change-point list by memory addresses (low -> high) */
344 still_changing = 1; 354 still_changing = 1;
345 while (still_changing) { 355 while (still_changing) {
346 still_changing = 0; 356 still_changing = 0;
347 for (i=1; i < 2*old_nr; i++) { 357 for (i=1; i < chg_nr; i++) {
348 /* if <current_addr> > <last_addr>, swap */ 358 /* if <current_addr> > <last_addr>, swap */
349 /* or, if current=<start_addr> & last=<end_addr>, swap */ 359 /* or, if current=<start_addr> & last=<end_addr>, swap */
350 if ((change_point[i]->addr < change_point[i-1]->addr) || 360 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)
367 last_type = 0; /* start with undefined memory type */ 377 last_type = 0; /* start with undefined memory type */
368 last_addr = 0; /* start with 0 as last starting address */ 378 last_addr = 0; /* start with 0 as last starting address */
369 /* loop through change-points, determining affect on the new bios map */ 379 /* loop through change-points, determining affect on the new bios map */
370 for (chgidx=0; chgidx < 2*old_nr; chgidx++) 380 for (chgidx=0; chgidx < chg_nr; chgidx++)
371 { 381 {
372 /* keep track of all overlapping bios entries */ 382 /* keep track of all overlapping bios entries */
373 if (change_point[chgidx]->addr == change_point[chgidx]->pbios->addr) 383 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 750bcd0655dc..e3a19e8ebbf8 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 = {
60 60
61/* Serial functions loosely based on a similar package from Klaus P. Gerlicher */ 61/* Serial functions loosely based on a similar package from Klaus P. Gerlicher */
62 62
63int early_serial_base = 0x3f8; /* ttyS0 */ 63static int early_serial_base = 0x3f8; /* ttyS0 */
64 64
65#define XMTRDY 0x20 65#define XMTRDY 0x20
66 66
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S
index 3233a15cc4e0..1086b5fcac21 100644
--- a/arch/x86_64/kernel/entry.S
+++ b/arch/x86_64/kernel/entry.S
@@ -296,6 +296,7 @@ int_very_careful:
296 call syscall_trace_leave 296 call syscall_trace_leave
297 popq %rdi 297 popq %rdi
298 andl $~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edi 298 andl $~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edi
299 cli
299 jmp int_restore_rest 300 jmp int_restore_rest
300 301
301int_signal: 302int_signal:
@@ -307,6 +308,7 @@ int_signal:
3071: movl $_TIF_NEED_RESCHED,%edi 3081: movl $_TIF_NEED_RESCHED,%edi
308int_restore_rest: 309int_restore_rest:
309 RESTORE_REST 310 RESTORE_REST
311 cli
310 jmp int_with_check 312 jmp int_with_check
311 CFI_ENDPROC 313 CFI_ENDPROC
312 314
@@ -490,7 +492,8 @@ retint_signal:
490 call do_notify_resume 492 call do_notify_resume
491 RESTORE_REST 493 RESTORE_REST
492 cli 494 cli
493 GET_THREAD_INFO(%rcx) 495 GET_THREAD_INFO(%rcx)
496 movl $_TIF_WORK_MASK,%edi
494 jmp retint_check 497 jmp retint_check
495 498
496#ifdef CONFIG_PREEMPT 499#ifdef CONFIG_PREEMPT
diff --git a/arch/x86_64/kernel/head64.c b/arch/x86_64/kernel/head64.c
index 6cad46c98a23..0f8c78dcd38c 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)
29 (unsigned long) __bss_end - (unsigned long) __bss_start); 29 (unsigned long) __bss_end - (unsigned long) __bss_start);
30} 30}
31 31
32extern char x86_boot_params[2048];
33
34#define NEW_CL_POINTER 0x228 /* Relative to real mode data */ 32#define NEW_CL_POINTER 0x228 /* Relative to real mode data */
35#define OLD_CL_MAGIC_ADDR 0x90020 33#define OLD_CL_MAGIC_ADDR 0x90020
36#define OLD_CL_MAGIC 0xA33F 34#define OLD_CL_MAGIC 0xA33F
@@ -44,7 +42,7 @@ static void __init copy_bootdata(char *real_mode_data)
44 int new_data; 42 int new_data;
45 char * command_line; 43 char * command_line;
46 44
47 memcpy(x86_boot_params, real_mode_data, 2048); 45 memcpy(x86_boot_params, real_mode_data, BOOT_PARAM_SIZE);
48 new_data = *(int *) (x86_boot_params + NEW_CL_POINTER); 46 new_data = *(int *) (x86_boot_params + NEW_CL_POINTER);
49 if (!new_data) { 47 if (!new_data) {
50 if (OLD_CL_MAGIC != * (u16 *) OLD_CL_MAGIC_ADDR) { 48 if (OLD_CL_MAGIC != * (u16 *) OLD_CL_MAGIC_ADDR) {
@@ -93,9 +91,6 @@ void __init x86_64_start_kernel(char * real_mode_data)
93#ifdef CONFIG_SMP 91#ifdef CONFIG_SMP
94 cpu_set(0, cpu_online_map); 92 cpu_set(0, cpu_online_map);
95#endif 93#endif
96 /* default console: */
97 if (!strstr(saved_command_line, "console="))
98 strcat(saved_command_line, " console=tty0");
99 s = strstr(saved_command_line, "earlyprintk="); 94 s = strstr(saved_command_line, "earlyprintk=");
100 if (s != NULL) 95 if (s != NULL)
101 setup_early_printk(s); 96 setup_early_printk(s);
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index 29a257295484..60be58617eb9 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)
1607 disable_8259A_irq(0); 1607 disable_8259A_irq(0);
1608 setup_nmi(); 1608 setup_nmi();
1609 enable_8259A_irq(0); 1609 enable_8259A_irq(0);
1610 check_nmi_watchdog();
1611 } 1610 }
1612 return; 1611 return;
1613 } 1612 }
@@ -1627,7 +1626,6 @@ static inline void check_timer(void)
1627 nmi_watchdog_default(); 1626 nmi_watchdog_default();
1628 if (nmi_watchdog == NMI_IO_APIC) { 1627 if (nmi_watchdog == NMI_IO_APIC) {
1629 setup_nmi(); 1628 setup_nmi();
1630 check_nmi_watchdog();
1631 } 1629 }
1632 return; 1630 return;
1633 } 1631 }
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
index e00d4adec36b..61de0b34a01e 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)
112 } 112 }
113} 113}
114 114
115int __init check_nmi_watchdog (void) 115static int __init check_nmi_watchdog (void)
116{ 116{
117 int counts[NR_CPUS]; 117 int counts[NR_CPUS];
118 int cpu; 118 int cpu;
119 119
120 if (nmi_watchdog == NMI_NONE)
121 return 0;
122
120 if (nmi_watchdog == NMI_LOCAL_APIC && !cpu_has_lapic()) { 123 if (nmi_watchdog == NMI_LOCAL_APIC && !cpu_has_lapic()) {
121 nmi_watchdog = NMI_NONE; 124 nmi_watchdog = NMI_NONE;
122 return -1; 125 return -1;
123 } 126 }
124 127
125 printk(KERN_INFO "testing NMI watchdog ... "); 128 printk(KERN_INFO "Testing NMI watchdog ... ");
126 129
127 for (cpu = 0; cpu < NR_CPUS; cpu++) 130 for (cpu = 0; cpu < NR_CPUS; cpu++)
128 counts[cpu] = cpu_pda[cpu].__nmi_count; 131 counts[cpu] = cpu_pda[cpu].__nmi_count;
@@ -148,6 +151,8 @@ int __init check_nmi_watchdog (void)
148 151
149 return 0; 152 return 0;
150} 153}
154/* Have this called later during boot so counters are updating */
155late_initcall(check_nmi_watchdog);
151 156
152int __init setup_nmi_watchdog(char *str) 157int __init setup_nmi_watchdog(char *str)
153{ 158{
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 9922d2ba24a3..761b6d35e338 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,
402 p->thread.fs = me->thread.fs; 402 p->thread.fs = me->thread.fs;
403 p->thread.gs = me->thread.gs; 403 p->thread.gs = me->thread.gs;
404 404
405 asm("movl %%gs,%0" : "=m" (p->thread.gsindex)); 405 asm("mov %%gs,%0" : "=m" (p->thread.gsindex));
406 asm("movl %%fs,%0" : "=m" (p->thread.fsindex)); 406 asm("mov %%fs,%0" : "=m" (p->thread.fsindex));
407 asm("movl %%es,%0" : "=m" (p->thread.es)); 407 asm("mov %%es,%0" : "=m" (p->thread.es));
408 asm("movl %%ds,%0" : "=m" (p->thread.ds)); 408 asm("mov %%ds,%0" : "=m" (p->thread.ds));
409 409
410 if (unlikely(me->thread.io_bitmap_ptr != NULL)) { 410 if (unlikely(me->thread.io_bitmap_ptr != NULL)) {
411 p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL); 411 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 *
468 * Switch DS and ES. 468 * Switch DS and ES.
469 * This won't pick up thread selector changes, but I guess that is ok. 469 * This won't pick up thread selector changes, but I guess that is ok.
470 */ 470 */
471 asm volatile("movl %%es,%0" : "=m" (prev->es)); 471 asm volatile("mov %%es,%0" : "=m" (prev->es));
472 if (unlikely(next->es | prev->es)) 472 if (unlikely(next->es | prev->es))
473 loadsegment(es, next->es); 473 loadsegment(es, next->es);
474 474
475 asm volatile ("movl %%ds,%0" : "=m" (prev->ds)); 475 asm volatile ("mov %%ds,%0" : "=m" (prev->ds));
476 if (unlikely(next->ds | prev->ds)) 476 if (unlikely(next->ds | prev->ds))
477 loadsegment(ds, next->ds); 477 loadsegment(ds, next->ds);
478 478
diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c
index ecbccbbf5c2a..19eba9aaedd1 100644
--- a/arch/x86_64/kernel/ptrace.c
+++ b/arch/x86_64/kernel/ptrace.c
@@ -18,6 +18,7 @@
18#include <linux/security.h> 18#include <linux/security.h>
19#include <linux/audit.h> 19#include <linux/audit.h>
20#include <linux/seccomp.h> 20#include <linux/seccomp.h>
21#include <linux/signal.h>
21 22
22#include <asm/uaccess.h> 23#include <asm/uaccess.h>
23#include <asm/pgtable.h> 24#include <asm/pgtable.h>
@@ -467,7 +468,7 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data
467 case PTRACE_CONT: /* restart after signal. */ 468 case PTRACE_CONT: /* restart after signal. */
468 469
469 ret = -EIO; 470 ret = -EIO;
470 if ((unsigned long) data > _NSIG) 471 if (!valid_signal(data))
471 break; 472 break;
472 if (request == PTRACE_SYSCALL) 473 if (request == PTRACE_SYSCALL)
473 set_tsk_thread_flag(child,TIF_SYSCALL_TRACE); 474 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
529 530
530 case PTRACE_SINGLESTEP: /* set the trap flag. */ 531 case PTRACE_SINGLESTEP: /* set the trap flag. */
531 ret = -EIO; 532 ret = -EIO;
532 if ((unsigned long) data > _NSIG) 533 if (!valid_signal(data))
533 break; 534 break;
534 clear_tsk_thread_flag(child,TIF_SYSCALL_TRACE); 535 clear_tsk_thread_flag(child,TIF_SYSCALL_TRACE);
535 set_singlestep(child); 536 set_singlestep(child);
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index b18c114c7648..2129cf9ba6b2 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)
977 if ((xlvl & 0xffff0000) == 0x80000000) { 977 if ((xlvl & 0xffff0000) == 0x80000000) {
978 if (xlvl >= 0x80000001) { 978 if (xlvl >= 0x80000001) {
979 c->x86_capability[1] = cpuid_edx(0x80000001); 979 c->x86_capability[1] = cpuid_edx(0x80000001);
980 c->x86_capability[5] = cpuid_ecx(0x80000001); 980 c->x86_capability[6] = cpuid_ecx(0x80000001);
981 } 981 }
982 if (xlvl >= 0x80000004) 982 if (xlvl >= 0x80000004)
983 get_model_name(c); /* Default name */ 983 get_model_name(c); /* Default name */
@@ -1076,7 +1076,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
1076 "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", NULL, 1076 "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", NULL,
1077 1077
1078 /* AMD-defined */ 1078 /* AMD-defined */
1079 "pni", NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1079 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1080 NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL, 1080 NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
1081 NULL, NULL, NULL, NULL, "nx", NULL, "mmxext", NULL, 1081 NULL, NULL, NULL, NULL, "nx", NULL, "mmxext", NULL,
1082 NULL, "fxsr_opt", NULL, NULL, NULL, "lm", "3dnowext", "3dnow", 1082 NULL, "fxsr_opt", NULL, NULL, NULL, "lm", "3dnowext", "3dnow",
@@ -1100,11 +1100,17 @@ static int show_cpuinfo(struct seq_file *m, void *v)
1100 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1100 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1101 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1101 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1102 1102
1103 /* VIA/Cyrix/Centaur-defined */
1104 NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en",
1105 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1106 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1107 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1108
1103 /* AMD-defined (#2) */ 1109 /* AMD-defined (#2) */
1104 "lahf_lm", "cmp_legacy", NULL, NULL, NULL, NULL, NULL, NULL, 1110 "lahf_lm", "cmp_legacy", NULL, NULL, NULL, NULL, NULL, NULL,
1105 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1111 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1106 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1112 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1107 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL 1113 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1108 }; 1114 };
1109 static char *x86_power_flags[] = { 1115 static char *x86_power_flags[] = {
1110 "ts", /* temperature sensor */ 1116 "ts", /* temperature sensor */
diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c
index b5305b04bc40..678b7ac33b8b 100644
--- a/arch/x86_64/kernel/setup64.c
+++ b/arch/x86_64/kernel/setup64.c
@@ -12,6 +12,7 @@
12#include <linux/string.h> 12#include <linux/string.h>
13#include <linux/bootmem.h> 13#include <linux/bootmem.h>
14#include <linux/bitops.h> 14#include <linux/bitops.h>
15#include <asm/bootsetup.h>
15#include <asm/pda.h> 16#include <asm/pda.h>
16#include <asm/pgtable.h> 17#include <asm/pgtable.h>
17#include <asm/processor.h> 18#include <asm/processor.h>
@@ -26,7 +27,7 @@
26#include <asm/mman.h> 27#include <asm/mman.h>
27#include <asm/numa.h> 28#include <asm/numa.h>
28 29
29char x86_boot_params[2048] __initdata = {0,}; 30char x86_boot_params[BOOT_PARAM_SIZE] __initdata = {0,};
30 31
31cpumask_t cpu_initialized __initdata = CPU_MASK_NONE; 32cpumask_t cpu_initialized __initdata = CPU_MASK_NONE;
32 33
diff --git a/arch/x86_64/kernel/sys_x86_64.c b/arch/x86_64/kernel/sys_x86_64.c
index 477d8be57d64..dbebd5ccba6b 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)
152 return err ? -EFAULT : 0; 152 return err ? -EFAULT : 0;
153} 153}
154 154
155asmlinkage long wrap_sys_shmat(int shmid, char __user *shmaddr, int shmflg)
156{
157 unsigned long raddr;
158 return do_shmat(shmid,shmaddr,shmflg,&raddr) ?: (long)raddr;
159}
160
161asmlinkage long sys_time64(long __user * tloc) 155asmlinkage long sys_time64(long __user * tloc)
162{ 156{
163 struct timeval now; 157 struct timeval now;