diff options
| author | Tony Luck <tony.luck@intel.com> | 2005-05-17 18:53:14 -0400 |
|---|---|---|
| committer | Tony Luck <tony.luck@intel.com> | 2005-05-17 18:53:14 -0400 |
| commit | 325a479c4c110db278ef3361460a48c4093252cc (patch) | |
| tree | bcfbf4d0647d9442045639a5c19da59d55190e81 /arch | |
| parent | ebcc80c1b6629a445f7471cc1ddb48faf8a84e70 (diff) | |
| parent | 7f9eaedf894dbaa08c157832e9a6c9c03ffed1ed (diff) | |
Merge with temp tree to get David's gdb inferior calls patch
Diffstat (limited to 'arch')
166 files changed, 2674 insertions, 1989 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 | ||
| 460 | asmlinkage long | ||
| 461 | osf_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/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index c0e7aff3dec2..7c7f475e213e 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S | |||
| @@ -18,48 +18,30 @@ | |||
| 18 | * Please select one of the following when turning on debugging. | 18 | * Please select one of the following when turning on debugging. |
| 19 | */ | 19 | */ |
| 20 | #ifdef DEBUG | 20 | #ifdef DEBUG |
| 21 | #if defined(CONFIG_DEBUG_DC21285_PORT) | 21 | |
| 22 | .macro loadsp, rb | 22 | #include <asm/arch/debug-macro.S> |
| 23 | mov \rb, #0x42000000 | 23 | |
| 24 | .endm | 24 | #if defined(CONFIG_DEBUG_ICEDCC) |
| 25 | .macro writeb, rb | ||
| 26 | str \rb, [r3, #0x160] | ||
| 27 | .endm | ||
| 28 | #elif defined(CONFIG_DEBUG_ICEDCC) | ||
| 29 | .macro loadsp, rb | 25 | .macro loadsp, rb |
| 30 | .endm | 26 | .endm |
| 31 | .macro writeb, rb | 27 | .macro writeb, ch, rb |
| 32 | mcr p14, 0, \rb, c0, c1, 0 | 28 | mcr p14, 0, \ch, c0, c1, 0 |
| 33 | .endm | ||
| 34 | #elif defined(CONFIG_FOOTBRIDGE) | ||
| 35 | .macro loadsp, rb | ||
| 36 | mov \rb, #0x7c000000 | ||
| 37 | .endm | 29 | .endm |
| 38 | .macro writeb, rb | 30 | #else |
| 39 | strb \rb, [r3, #0x3f8] | 31 | .macro writeb, ch, rb |
| 32 | senduart \ch, \rb | ||
| 40 | .endm | 33 | .endm |
| 41 | #elif defined(CONFIG_ARCH_RPC) | 34 | |
| 35 | #if defined(CONFIG_FOOTBRIDGE) || \ | ||
| 36 | defined(CONFIG_ARCH_RPC) || \ | ||
| 37 | defined(CONFIG_ARCH_INTEGRATOR) || \ | ||
| 38 | defined(CONFIG_ARCH_PXA) || \ | ||
| 39 | defined(CONFIG_ARCH_IXP4XX) || \ | ||
| 40 | defined(CONFIG_ARCH_IXP2000) || \ | ||
| 41 | defined(CONFIG_ARCH_LH7A40X) || \ | ||
| 42 | defined(CONFIG_ARCH_OMAP) | ||
| 42 | .macro loadsp, rb | 43 | .macro loadsp, rb |
| 43 | mov \rb, #0x03000000 | 44 | addruart \rb |
| 44 | orr \rb, \rb, #0x00010000 | ||
| 45 | .endm | ||
| 46 | .macro writeb, rb | ||
| 47 | strb \rb, [r3, #0x3f8 << 2] | ||
| 48 | .endm | ||
| 49 | #elif defined(CONFIG_ARCH_INTEGRATOR) | ||
| 50 | .macro loadsp, rb | ||
| 51 | mov \rb, #0x16000000 | ||
| 52 | .endm | ||
| 53 | .macro writeb, rb | ||
| 54 | strb \rb, [r3, #0] | ||
| 55 | .endm | ||
| 56 | #elif defined(CONFIG_ARCH_PXA) /* Xscale-type */ | ||
| 57 | .macro loadsp, rb | ||
| 58 | mov \rb, #0x40000000 | ||
| 59 | orr \rb, \rb, #0x00100000 | ||
| 60 | .endm | ||
| 61 | .macro writeb, rb | ||
| 62 | strb \rb, [r3, #0] | ||
| 63 | .endm | 45 | .endm |
| 64 | #elif defined(CONFIG_ARCH_SA1100) | 46 | #elif defined(CONFIG_ARCH_SA1100) |
| 65 | .macro loadsp, rb | 47 | .macro loadsp, rb |
| @@ -70,65 +52,22 @@ | |||
| 70 | add \rb, \rb, #0x00010000 @ Ser1 | 52 | add \rb, \rb, #0x00010000 @ Ser1 |
| 71 | # endif | 53 | # endif |
| 72 | .endm | 54 | .endm |
| 73 | .macro writeb, rb | ||
| 74 | str \rb, [r3, #0x14] @ UTDR | ||
| 75 | .endm | ||
| 76 | #elif defined(CONFIG_ARCH_IXP4XX) | ||
| 77 | .macro loadsp, rb | ||
| 78 | mov \rb, #0xc8000000 | ||
| 79 | .endm | ||
| 80 | .macro writeb, rb | ||
| 81 | str \rb, [r3, #0] | ||
| 82 | #elif defined(CONFIG_ARCH_IXP2000) | ||
| 83 | .macro loadsp, rb | ||
| 84 | mov \rb, #0xc0000000 | ||
| 85 | orr \rb, \rb, #0x00030000 | ||
| 86 | .endm | ||
| 87 | .macro writeb, rb | ||
| 88 | str \rb, [r3, #0] | ||
| 89 | .endm | ||
| 90 | #elif defined(CONFIG_ARCH_LH7A40X) | ||
| 91 | .macro loadsp, rb | ||
| 92 | ldr \rb, =0x80000700 @ UART2 UARTBASE | ||
| 93 | .endm | ||
| 94 | .macro writeb, rb | ||
| 95 | strb \rb, [r3, #0] | ||
| 96 | .endm | ||
| 97 | #elif defined(CONFIG_ARCH_OMAP) | ||
| 98 | .macro loadsp, rb | ||
| 99 | mov \rb, #0xff000000 @ physical base address | ||
| 100 | add \rb, \rb, #0x00fb0000 | ||
| 101 | #if defined(CONFIG_OMAP_LL_DEBUG_UART2) || defined(CONFIG_OMAP_LL_DEBUG_UART3) | ||
| 102 | add \rb, \rb, #0x00000800 | ||
| 103 | #endif | ||
| 104 | #ifdef CONFIG_OMAP_LL_DEBUG_UART3 | ||
| 105 | add \rb, \rb, #0x00009000 | ||
| 106 | #endif | ||
| 107 | .endm | ||
| 108 | .macro writeb, rb | ||
| 109 | strb \rb, [r3] | ||
| 110 | .endm | ||
| 111 | #elif defined(CONFIG_ARCH_IOP331) | 55 | #elif defined(CONFIG_ARCH_IOP331) |
| 112 | .macro loadsp, rb | 56 | .macro loadsp, rb |
| 113 | mov \rb, #0xff000000 | 57 | mov \rb, #0xff000000 |
| 114 | orr \rb, \rb, #0x00ff0000 | 58 | orr \rb, \rb, #0x00ff0000 |
| 115 | orr \rb, \rb, #0x0000f700 @ location of the UART | 59 | orr \rb, \rb, #0x0000f700 @ location of the UART |
| 116 | .endm | 60 | .endm |
| 117 | .macro writeb, rb | ||
| 118 | str \rb, [r3, #0] | ||
| 119 | .endm | ||
| 120 | #elif defined(CONFIG_ARCH_S3C2410) | 61 | #elif defined(CONFIG_ARCH_S3C2410) |
| 121 | .macro loadsp, rb | 62 | .macro loadsp, rb |
| 122 | mov \rb, #0x50000000 | 63 | mov \rb, #0x50000000 |
| 123 | add \rb, \rb, #0x4000 * CONFIG_S3C2410_LOWLEVEL_UART_PORT | 64 | add \rb, \rb, #0x4000 * CONFIG_S3C2410_LOWLEVEL_UART_PORT |
| 124 | .endm | 65 | .endm |
| 125 | .macro writeb, rb | ||
| 126 | strb \rb, [r3, #0x20] | ||
| 127 | .endm | ||
| 128 | #else | 66 | #else |
| 129 | #error no serial architecture defined | 67 | #error no serial architecture defined |
| 130 | #endif | 68 | #endif |
| 131 | #endif | 69 | #endif |
| 70 | #endif | ||
| 132 | 71 | ||
| 133 | .macro kputc,val | 72 | .macro kputc,val |
| 134 | mov r0, \val | 73 | mov r0, \val |
| @@ -734,7 +673,7 @@ puts: loadsp r3 | |||
| 734 | 1: ldrb r2, [r0], #1 | 673 | 1: ldrb r2, [r0], #1 |
| 735 | teq r2, #0 | 674 | teq r2, #0 |
| 736 | moveq pc, lr | 675 | moveq pc, lr |
| 737 | 2: writeb r2 | 676 | 2: writeb r2, r3 |
| 738 | mov r1, #0x00020000 | 677 | mov r1, #0x00020000 |
| 739 | 3: subs r1, r1, #1 | 678 | 3: subs r1, r1, #1 |
| 740 | bne 3b | 679 | bne 3b |
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 | ||
| 144 | static inline void rtc_read_time(struct rtc_ops *ops, struct rtc_time *tm) | 144 | static 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 | ||
| 150 | static inline int rtc_set_time(struct rtc_ops *ops, struct rtc_time *tm) | 150 | static inline int rtc_set_time(struct rtc_ops *ops, struct rtc_time *tm) |
| @@ -163,8 +163,7 @@ static inline int rtc_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) | |||
| 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 | # |
| 134 | CONFIG_ZBOOT_ROM_TEXT=0x0 | 134 | CONFIG_ZBOOT_ROM_TEXT=0x0 |
| 135 | CONFIG_ZBOOT_ROM_BSS=0x0 | 135 | CONFIG_ZBOOT_ROM_BSS=0x0 |
| 136 | CONFIG_CMDLINE="console=ttyS0,9600 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware" | 136 | CONFIG_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 | ||
| 230 | asmlinkage 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 | |||
| 507 | static 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 | |||
| 517 | static 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 | |||
| 525 | static int __init arm_mrc_hook_init(void) | ||
| 526 | { | ||
| 527 | register_undef_hook(&arm_mrc_hook); | ||
| 528 | return 0; | ||
| 529 | } | ||
| 530 | |||
| 531 | late_initcall(arm_mrc_hook_init); | ||
| 532 | |||
| 533 | #endif | ||
| 534 | |||
| 496 | void __bad_xchg(volatile void *ptr, int size) | 535 | void __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-imx/generic.c b/arch/arm/mach-imx/generic.c index 54377d0f578c..41e5849ae8da 100644 --- a/arch/arm/mach-imx/generic.c +++ b/arch/arm/mach-imx/generic.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
| 27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
| 28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
| 29 | #include <asm/arch/imxfb.h> | ||
| 29 | #include <asm/hardware.h> | 30 | #include <asm/hardware.h> |
| 30 | 31 | ||
| 31 | #include <asm/mach/map.h> | 32 | #include <asm/mach/map.h> |
| @@ -228,6 +229,14 @@ static struct platform_device imx_uart2_device = { | |||
| 228 | .resource = imx_uart2_resources, | 229 | .resource = imx_uart2_resources, |
| 229 | }; | 230 | }; |
| 230 | 231 | ||
| 232 | static struct imxfb_mach_info imx_fb_info; | ||
| 233 | |||
| 234 | void __init set_imx_fb_info(struct imxfb_mach_info *hard_imx_fb_info) | ||
| 235 | { | ||
| 236 | memcpy(&imx_fb_info,hard_imx_fb_info,sizeof(struct imxfb_mach_info)); | ||
| 237 | } | ||
| 238 | EXPORT_SYMBOL(set_imx_fb_info); | ||
| 239 | |||
| 231 | static struct resource imxfb_resources[] = { | 240 | static struct resource imxfb_resources[] = { |
| 232 | [0] = { | 241 | [0] = { |
| 233 | .start = 0x00205000, | 242 | .start = 0x00205000, |
| @@ -241,9 +250,16 @@ static struct resource imxfb_resources[] = { | |||
| 241 | }, | 250 | }, |
| 242 | }; | 251 | }; |
| 243 | 252 | ||
| 253 | static u64 fb_dma_mask = ~(u64)0; | ||
| 254 | |||
| 244 | static struct platform_device imxfb_device = { | 255 | static struct platform_device imxfb_device = { |
| 245 | .name = "imx-fb", | 256 | .name = "imx-fb", |
| 246 | .id = 0, | 257 | .id = 0, |
| 258 | .dev = { | ||
| 259 | .platform_data = &imx_fb_info, | ||
| 260 | .dma_mask = &fb_dma_mask, | ||
| 261 | .coherent_dma_mask = 0xffffffff, | ||
| 262 | }, | ||
| 247 | .num_resources = ARRAY_SIZE(imxfb_resources), | 263 | .num_resources = ARRAY_SIZE(imxfb_resources), |
| 248 | .resource = imxfb_resources, | 264 | .resource = imxfb_resources, |
| 249 | }; | 265 | }; |
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 86c50c3889b7..bd17b5154311 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c | |||
| @@ -216,7 +216,9 @@ integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
| 216 | 216 | ||
| 217 | write_seqlock(&xtime_lock); | 217 | write_seqlock(&xtime_lock); |
| 218 | 218 | ||
| 219 | // ...clear the interrupt | 219 | /* |
| 220 | * clear the interrupt | ||
| 221 | */ | ||
| 220 | timer1->TimerClear = 1; | 222 | timer1->TimerClear = 1; |
| 221 | 223 | ||
| 222 | timer_tick(regs); | 224 | timer_tick(regs); |
| @@ -264,7 +266,7 @@ void __init integrator_time_init(unsigned long reload, unsigned int ctrl) | |||
| 264 | timer1->TimerValue = timer_reload; | 266 | timer1->TimerValue = timer_reload; |
| 265 | timer1->TimerControl = timer_ctrl; | 267 | timer1->TimerControl = timer_ctrl; |
| 266 | 268 | ||
| 267 | /* | 269 | /* |
| 268 | * Make irqs happen for the system timer | 270 | * Make irqs happen for the system timer |
| 269 | */ | 271 | */ |
| 270 | setup_irq(IRQ_TIMERINT1, &integrator_timer_irq); | 272 | setup_irq(IRQ_TIMERINT1, &integrator_timer_irq); |
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 | */ |
| 421 | static void cp_clcd_enable(struct clcd_fb *fb) | 421 | static 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 | ||
| 426 | static unsigned long framesize = SZ_1M; | 441 | static unsigned long framesize = SZ_1M; |
diff --git a/arch/arm/mach-integrator/leds.c b/arch/arm/mach-integrator/leds.c index 9d182b77b312..d2c0ab21150c 100644 --- a/arch/arm/mach-integrator/leds.c +++ b/arch/arm/mach-integrator/leds.c | |||
| @@ -37,7 +37,7 @@ static void integrator_leds_event(led_event_t ledevt) | |||
| 37 | unsigned long flags; | 37 | unsigned long flags; |
| 38 | const unsigned int dbg_base = IO_ADDRESS(INTEGRATOR_DBG_BASE); | 38 | const unsigned int dbg_base = IO_ADDRESS(INTEGRATOR_DBG_BASE); |
| 39 | unsigned int update_alpha_leds; | 39 | unsigned int update_alpha_leds; |
| 40 | 40 | ||
| 41 | // yup, change the LEDs | 41 | // yup, change the LEDs |
| 42 | local_irq_save(flags); | 42 | local_irq_save(flags); |
| 43 | update_alpha_leds = 0; | 43 | update_alpha_leds = 0; |
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 | ||
| 43 | static void rtc_read_alarm(struct rtc_wkalrm *alrm) | 43 | static 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 | ||
| 48 | static int rtc_set_alarm(struct rtc_wkalrm *alrm) | 49 | static 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 | ||
| 59 | static void rtc_read_time(struct rtc_time *tm) | 65 | static 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 | */ |
| 72 | static int rtc_set_time(struct rtc_time *tm) | 79 | static 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 | *************************************************************************/ |
| 68 | static void __init ixdp2800_slave_disable_pci_master(void) | ||
| 69 | { | ||
| 70 | *IXP2000_PCI_CMDSTAT &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); | ||
| 71 | } | ||
| 72 | |||
| 73 | static 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 | |||
| 100 | static 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 | |||
| 68 | void __init ixdp2800_pci_preinit(void) | 108 | void __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 | ||
| 80 | int 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 | */ | ||
| 153 | static 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 | } | ||
| 161 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IXP2800, ixp2800_pci_fixup); | ||
| 162 | |||
| 163 | static 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 | ||
| 132 | static void ixdp2800_pci_postinit(void) | 215 | static 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 | ||
| 228 | static 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 | |||
| 241 | static 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 | |||
| 247 | static 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 | ||
| 147 | struct hw_pci ixdp2800_pci __initdata = { | 255 | struct __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 | ||
| 156 | int __init ixdp2800_pci_init(void) | 264 | int __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 | ||
| 38 | static int clear_master_aborts(void); | 38 | static int clear_master_aborts(void); |
| 39 | 39 | ||
| 40 | static u32 * | 40 | u32 * |
| 41 | ixp2000_pci_config_addr(unsigned int bus_nr, unsigned int devfn, int where) | 41 | ixp2000_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 | */ |
| 210 | static struct resource ixp2000_pci_mem_space = { | 210 | static 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 | ||
| 217 | static struct resource ixp2000_pci_io_space = { | 217 | static 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 | ||
| 223 | static 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 | |||
| 235 | static 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 | |||
| 242 | void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info) | ||
| 243 | { | ||
| 244 | i2c_device.dev.platform_data = info; | ||
| 245 | } | ||
| 246 | |||
| 223 | static struct platform_device *devices[] __initdata = { | 247 | static 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 | ||
| 232 | static int __init pxa_init(void) | 257 | static int __init pxa_init(void) |
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 5b670c9ac5ef..27892e34b060 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
| @@ -409,3 +409,18 @@ 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 | |||
| 413 | config HAS_TLS_REG | ||
| 414 | bool | ||
| 415 | depends on CPU_32v6 && !CPU_32v5 && !CPU_32v4 && !CPU_32v3 | ||
| 416 | default y | ||
| 417 | help | ||
| 418 | This selects support for the CP15 thread register. | ||
| 419 | It is defined to be available on ARMv6 or later. However | ||
| 420 | if the kernel is configured to support multiple CPUs including | ||
| 421 | a pre-ARMv6 processors, or if a given ARMv6 processor doesn't | ||
| 422 | implement the thread register for some reason, then access to | ||
| 423 | this register from user space must be trapped and emulated. | ||
| 424 | If user space is relying on the __kuser_get_tls code then | ||
| 425 | there should not be any impact. | ||
| 426 | |||
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 |
| 18 | ENTRY(v6_early_abort) | 22 | ENTRY(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); |
| 93 | again: | 93 | again: |
| 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 | ||
| 656 | config 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 | |||
| 656 | config MICROCODE | 674 | config 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) | |||
| 123 | boot := arch/i386/boot | 123 | boot := 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 | ||
| 128 | all: bzImage | 128 | all: bzImage |
| 129 | 129 | ||
| @@ -145,8 +145,9 @@ zdisk bzdisk: vmlinux | |||
| 145 | fdimage fdimage144 fdimage288: vmlinux | 145 | fdimage fdimage144 fdimage288: vmlinux |
| 146 | $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@ | 146 | $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@ |
| 147 | 147 | ||
| 148 | install: | 148 | install: vmlinux |
| 149 | $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@ | 149 | install kernel_install: |
| 150 | $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install | ||
| 150 | 151 | ||
| 151 | prepare: include/asm-$(ARCH)/asm_offsets.h | 152 | prepare: include/asm-$(ARCH)/asm_offsets.h |
| 152 | CLEAN_FILES += include/asm-$(ARCH)/asm_offsets.h | 153 | CLEAN_FILES += include/asm-$(ARCH)/asm_offsets.h |
diff --git a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c index 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 | |||
| 164 | trampoline: call start_of_setup | 164 | trampoline: 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 | ||
| 170 | start_of_setup: | 170 | start_of_setup: |
| @@ -333,9 +333,9 @@ jmpe820: | |||
| 333 | # sizeof(e820rec). | 333 | # sizeof(e820rec). |
| 334 | # | 334 | # |
| 335 | good820: | 335 | good820: |
| 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 | |||
| 23 | obj-$(CONFIG_X86_MPPARSE) += mpparse.o | 23 | obj-$(CONFIG_X86_MPPARSE) += mpparse.o |
| 24 | obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o | 24 | obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o |
| 25 | obj-$(CONFIG_X86_IO_APIC) += io_apic.o | 25 | obj-$(CONFIG_X86_IO_APIC) += io_apic.o |
| 26 | obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups.o | ||
| 26 | obj-$(CONFIG_X86_NUMAQ) += numaq.o | 27 | obj-$(CONFIG_X86_NUMAQ) += numaq.o |
| 27 | obj-$(CONFIG_X86_SUMMIT_NUMA) += summit.o | 28 | obj-$(CONFIG_X86_SUMMIT_NUMA) += summit.o |
| 28 | obj-$(CONFIG_KPROBES) += kprobes.o | 29 | obj-$(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 | ||
| 127 | void generic_get_mtrr(unsigned int reg, unsigned long *base, | 127 | static 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) | |||
| 72 | static int have_wrcomb(void) | 72 | static 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" |
| 261 | iret_exc: | 261 | iret_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 | ||
| 605 | ENTRY(overflow) | 599 | ENTRY(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" |
| 662 | ENTRY(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 | ||
| 953 | syscall_table_size=(.-sys_call_table) | 657 | syscall_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 |
| 381 | ignore_int: | 381 | ignore_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 | ||
| 105 | int __init check_nmi_watchdog (void) | 105 | static 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 */ | ||
| 144 | late_initcall(check_nmi_watchdog); | ||
| 142 | 145 | ||
| 143 | static int __init setup_nmi_watchdog(char *str) | 146 | static 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 b2f17640ceff..e8c965ce86eb 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 | |||
| 14 | static 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 | |||
| 23 | struct device_fixup { | ||
| 24 | unsigned int vendor; | ||
| 25 | unsigned int device; | ||
| 26 | void (*reboot_fixup)(struct pci_dev *); | ||
| 27 | }; | ||
| 28 | |||
| 29 | static 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 | */ | ||
| 39 | void 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 | ||
| 2 | ENTRY(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 @@ | |||
| 26 | static unsigned long hpet_period; /* fsecs / HPET clock */ | 26 | static unsigned long hpet_period; /* fsecs / HPET clock */ |
| 27 | unsigned long hpet_tick; /* hpet clks count per tick */ | 27 | unsigned long hpet_tick; /* hpet clks count per tick */ |
| 28 | unsigned long hpet_address; /* hpet memory map physical address */ | 28 | unsigned long hpet_address; /* hpet memory map physical address */ |
| 29 | int hpet_use_timer; | ||
| 29 | 30 | ||
| 30 | static int use_hpet; /* can be used for runtime check of hpet */ | 31 | static int use_hpet; /* can be used for runtime check of hpet */ |
| 31 | static int boot_hpet_disable; /* boottime override for HPET timer */ | 32 | static 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) | |||
| 451 | DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) | 451 | DO_ERROR(11, SIGBUS, "segment not present", segment_not_present) |
| 452 | DO_ERROR(12, SIGBUS, "stack segment", stack_segment) | 452 | DO_ERROR(12, SIGBUS, "stack segment", stack_segment) |
| 453 | DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0) | 453 | DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0) |
| 454 | DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0) | ||
| 454 | 455 | ||
| 455 | fastcall void do_general_protection(struct pt_regs * regs, long error_code) | 456 | fastcall 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 |
| 645 | fastcall int do_int3(struct pt_regs *regs, long error_code) | 646 | fastcall 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 | ||
| 728 | out: | 728 | out: |
| @@ -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 4517d4ab5ef1..9353adc18956 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S | |||
| @@ -1411,7 +1411,7 @@ sys_call_table: | |||
| 1411 | data8 sys_msgrcv | 1411 | data8 sys_msgrcv |
| 1412 | data8 sys_msgctl | 1412 | data8 sys_msgctl |
| 1413 | data8 sys_shmget | 1413 | data8 sys_shmget |
| 1414 | data8 ia64_shmat | 1414 | data8 sys_shmat |
| 1415 | data8 sys_shmdt // 1115 | 1415 | data8 sys_shmdt // 1115 |
| 1416 | data8 sys_shmctl | 1416 | data8 sys_shmctl |
| 1417 | data8 sys_syslog | 1417 | data8 sys_syslog |
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index 55789fcd7210..9e730c7bf0cd 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> |
| @@ -704,12 +705,32 @@ convert_to_non_syscall (struct task_struct *child, struct pt_regs *pt, | |||
| 704 | break; | 705 | break; |
| 705 | } | 706 | } |
| 706 | 707 | ||
| 708 | /* | ||
| 709 | * Note: at the time of this call, the target task is blocked | ||
| 710 | * in notify_resume_user() and by clearling PRED_LEAVE_SYSCALL | ||
| 711 | * (aka, "pLvSys") we redirect execution from | ||
| 712 | * .work_pending_syscall_end to .work_processed_kernel. | ||
| 713 | */ | ||
| 707 | unw_get_pr(&prev_info, &pr); | 714 | unw_get_pr(&prev_info, &pr); |
| 708 | pr &= ~(1UL << PRED_SYSCALL); | 715 | pr &= ~((1UL << PRED_SYSCALL) | (1UL << PRED_LEAVE_SYSCALL)); |
| 709 | pr |= (1UL << PRED_NON_SYSCALL); | 716 | pr |= (1UL << PRED_NON_SYSCALL); |
| 710 | unw_set_pr(&prev_info, pr); | 717 | unw_set_pr(&prev_info, pr); |
| 711 | 718 | ||
| 712 | pt->cr_ifs = (1UL << 63) | cfm; | 719 | pt->cr_ifs = (1UL << 63) | cfm; |
| 720 | /* | ||
| 721 | * Clear the memory that is NOT written on syscall-entry to | ||
| 722 | * ensure we do not leak kernel-state to user when execution | ||
| 723 | * resumes. | ||
| 724 | */ | ||
| 725 | pt->r2 = 0; | ||
| 726 | pt->r3 = 0; | ||
| 727 | pt->r14 = 0; | ||
| 728 | memset(&pt->r16, 0, 16*8); /* clear r16-r31 */ | ||
| 729 | memset(&pt->f6, 0, 6*16); /* clear f6-f11 */ | ||
| 730 | pt->b7 = 0; | ||
| 731 | pt->ar_ccv = 0; | ||
| 732 | pt->ar_csd = 0; | ||
| 733 | pt->ar_ssd = 0; | ||
| 713 | } | 734 | } |
| 714 | 735 | ||
| 715 | static int | 736 | static int |
| @@ -1481,7 +1502,7 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data) | |||
| 1481 | case PTRACE_CONT: | 1502 | case PTRACE_CONT: |
| 1482 | /* restart after signal. */ | 1503 | /* restart after signal. */ |
| 1483 | ret = -EIO; | 1504 | ret = -EIO; |
| 1484 | if (data > _NSIG) | 1505 | if (!valid_signal(data)) |
| 1485 | goto out_tsk; | 1506 | goto out_tsk; |
| 1486 | if (request == PTRACE_SYSCALL) | 1507 | if (request == PTRACE_SYSCALL) |
| 1487 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 1508 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
| @@ -1520,7 +1541,7 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data) | |||
| 1520 | /* let child execute for one instruction */ | 1541 | /* let child execute for one instruction */ |
| 1521 | case PTRACE_SINGLEBLOCK: | 1542 | case PTRACE_SINGLEBLOCK: |
| 1522 | ret = -EIO; | 1543 | ret = -EIO; |
| 1523 | if (data > _NSIG) | 1544 | if (!valid_signal(data)) |
| 1524 | goto out_tsk; | 1545 | goto out_tsk; |
| 1525 | 1546 | ||
| 1526 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 1547 | 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 | ||
| 95 | asmlinkage unsigned long | 95 | asmlinkage unsigned long |
| 96 | ia64_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 | |||
| 109 | asmlinkage unsigned long | ||
| 110 | ia64_brk (unsigned long brk) | 96 | ia64_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 92f2c39afe27..a2f899c2f4d4 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 | */ | ||
| 379 | asmlinkage 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 | */ |
| 395 | asmlinkage int sys_cachectl(char *addr, int nbytes, int op) | 379 | asmlinkage int sys_cachectl(char *addr, int nbytes, int op) |
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c index 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 | ||
| 164 | long 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 | ||
| 54 | config 6xx | 54 | config 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 | ||
| 87 | endchoice | 88 | endchoice |
| 88 | 89 | ||
| 90 | config PPC_FPU | ||
| 91 | bool | ||
| 92 | |||
| 89 | config BOOKE | 93 | config 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 | ||
| 54 | head-$(CONFIG_6xx) += arch/ppc/kernel/idle_6xx.o | 54 | head-$(CONFIG_6xx) += arch/ppc/kernel/idle_6xx.o |
| 55 | head-$(CONFIG_POWER4) += arch/ppc/kernel/idle_power4.o | 55 | head-$(CONFIG_POWER4) += arch/ppc/kernel/idle_power4.o |
| 56 | head-$(CONFIG_PPC_FPU) += arch/ppc/kernel/fpu.o | ||
| 56 | 57 | ||
| 57 | core-y += arch/ppc/kernel/ arch/ppc/platforms/ \ | 58 | core-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 | ||
| 21 | targets += uImage | 21 | targets += 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 |
| 27 | clean-files := sImage vmapus vmlinux* miboot* zImage* uImage | 28 | clean-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 | |||
| 9 | extra-$(CONFIG_8xx) := head_8xx.o | 9 | extra-$(CONFIG_8xx) := head_8xx.o |
| 10 | extra-$(CONFIG_6xx) += idle_6xx.o | 10 | extra-$(CONFIG_6xx) += idle_6xx.o |
| 11 | extra-$(CONFIG_POWER4) += idle_power4.o | 11 | extra-$(CONFIG_POWER4) += idle_power4.o |
| 12 | extra-$(CONFIG_PPC_FPU) += fpu.o | ||
| 12 | extra-y += vmlinux.lds | 13 | extra-y += vmlinux.lds |
| 13 | 14 | ||
| 14 | obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ | 15 | obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ |
diff --git a/arch/ppc/kernel/align.c b/arch/ppc/kernel/align.c index 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 *) ®s->gpr[reg]; | 297 | rptr = (unsigned char *) ®s->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, ¤t->thread.fpscr); | 378 | cvt_fd(&data.f, &data.d, ¤t->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, ¤t->thread.fpscr); | 388 | cvt_df(&data.d, &data.f, ¤t->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 */ |
| 82 | 1: sync | 87 | 1: 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: | |||
| 152 | setup_750_7400_hid0: | 157 | setup_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 | ||
| 155 | BEGIN_FTR_SECTION | 161 | BEGIN_FTR_SECTION |
| 156 | oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */ | 162 | xori r11,r11,HID0_BTIC |
| 157 | END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM) | 163 | END_FTR_SECTION_IFSET(CPU_FTR_NO_BTIC) |
| 164 | BEGIN_FTR_SECTION | ||
| 165 | xoris r11,r11,HID0_DPM@h /* disable dynamic power mgmt */ | ||
| 166 | END_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 | ||
| 222 | BEGIN_FTR_SECTION | 233 | BEGIN_FTR_SECTION |
| 223 | xori r11,r11,HID0_BTIC | 234 | xori r11,r11,HID0_BTIC |
| 224 | END_FTR_SECTION_IFSET(CPU_FTR_NO_BTIC) | 235 | END_FTR_SECTION_IFSET(CPU_FTR_NO_BTIC) |
| 225 | BEGIN_FTR_SECTION | 236 | BEGIN_FTR_SECTION |
| 226 | oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */ | 237 | xoris r11,r11,HID0_DPM@h /* disable dynamic power mgmt */ |
| 227 | END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM) | 238 | END_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 | ||
| 567 | fast_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 | |||
| 573 | 2: 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 */ | ||
| 590 | 1: 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 */ | ||
| 611 | 3: | ||
| 612 | BEGIN_FTR_SECTION | ||
| 613 | b 2b | ||
| 614 | END_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 |
| 567 | sigreturn_exit: | 626 | sigreturn_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 | ||
| 31 | load_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) | ||
| 62 | 1: | ||
| 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 | ||
| 86 | KernelFP: | ||
| 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 | ||
| 96 | 86: .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 | ||
| 106 | giveup_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) | ||
| 127 | 1: | ||
| 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 | */ | ||
| 785 | load_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) | ||
| 816 | 1: | ||
| 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 | ||
| 836 | fast_exception_return: | ||
| 837 | andi. r10,r9,MSR_RI /* check for recoverable interrupt */ | ||
| 838 | beq 1f /* if not, we've got problems */ | ||
| 839 | 2: 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 */ | ||
| 855 | 1: 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 */ | ||
| 876 | 3: | ||
| 877 | BEGIN_FTR_SECTION | ||
| 878 | b 2b | ||
| 879 | END_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 | */ | ||
| 892 | KernelFP: | ||
| 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 | ||
| 902 | 86: .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 | ||
| 1025 | giveup_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) | ||
| 1046 | 1: | ||
| 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 |
| 71 | 1: 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 | ||
| 81 | 1: li r4,0x4000 | ||
| 82 | mtctr r4 | ||
| 83 | 1: 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 |
| 113 | 1: lwzx r0,r0,r4 | 125 | 1: 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 | ||
| 133 | 1: 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 */ | ||
| 161 | 1: 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 |
| 203 | 1: | 233 | 1: |
| 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 | |||
| 1594 | void __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 | |||
| 1593 | static int __pmac | 1701 | static int __pmac |
| 1594 | core99_sleep(void) | 1702 | core99_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 | ||
| 70 | extern u32 mv64360_irq_base; | 70 | extern u32 mv64360_irq_base; |
| 71 | extern spinlock_t rtc_lock; | ||
| 71 | 72 | ||
| 72 | static struct mv64x60_handle bh; | 73 | static struct mv64x60_handle bh; |
| 73 | static int ppc7d_has_alma; | 74 | static int ppc7d_has_alma; |
| @@ -75,6 +76,11 @@ static int ppc7d_has_alma; | |||
| 75 | extern void gen550_progress(char *, unsigned short); | 76 | extern void gen550_progress(char *, unsigned short); |
| 76 | extern void gen550_init(int, struct uart_port *); | 77 | extern void gen550_init(int, struct uart_port *); |
| 77 | 78 | ||
| 79 | /* FIXME - move to h file */ | ||
| 80 | extern 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 */ |
| 79 | unsigned char __res[sizeof(bd_t)]; | 85 | unsigned 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 | */ | ||
| 1257 | static 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 | |||
| 1272 | static 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/Makefile b/arch/ppc64/Makefile index d33e20bcc52f..691f3008e698 100644 --- a/arch/ppc64/Makefile +++ b/arch/ppc64/Makefile | |||
| @@ -56,13 +56,20 @@ LDFLAGS_vmlinux := -Bstatic -e $(KERNELLOAD) -Ttext $(KERNELLOAD) | |||
| 56 | CFLAGS += -msoft-float -pipe -mminimal-toc -mtraceback=none \ | 56 | CFLAGS += -msoft-float -pipe -mminimal-toc -mtraceback=none \ |
| 57 | -mcall-aixdesc | 57 | -mcall-aixdesc |
| 58 | 58 | ||
| 59 | GCC_VERSION := $(call cc-version) | ||
| 60 | GCC_BROKEN_VEC := $(shell if [ $(GCC_VERSION) -lt 0400 ] ; then echo "y"; fi ;) | ||
| 61 | |||
| 59 | ifeq ($(CONFIG_POWER4_ONLY),y) | 62 | ifeq ($(CONFIG_POWER4_ONLY),y) |
| 60 | ifeq ($(CONFIG_ALTIVEC),y) | 63 | ifeq ($(CONFIG_ALTIVEC),y) |
| 64 | ifeq ($(GCC_BROKEN_VEC),y) | ||
| 61 | CFLAGS += $(call cc-option,-mcpu=970) | 65 | CFLAGS += $(call cc-option,-mcpu=970) |
| 62 | else | 66 | else |
| 63 | CFLAGS += $(call cc-option,-mcpu=power4) | 67 | CFLAGS += $(call cc-option,-mcpu=power4) |
| 64 | endif | 68 | endif |
| 65 | else | 69 | else |
| 70 | CFLAGS += $(call cc-option,-mcpu=power4) | ||
| 71 | endif | ||
| 72 | else | ||
| 66 | CFLAGS += $(call cc-option,-mtune=power4) | 73 | CFLAGS += $(call cc-option,-mtune=power4) |
| 67 | endif | 74 | endif |
| 68 | 75 | ||
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 */ | ||
| 22 | char arch[] = "PowerPC"; | 23 | char 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 */ | ||
| 36 | char 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 | ||
| 45 | unsigned 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 | |||
| 34 | unsigned char buf[512]; | 58 | unsigned 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) | |||
| 339 | static int nvram_create_os_partition(void) | 339 | static 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 | */ | ||
| 500 | static 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 | |||
| 586 | static 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 | |||
| 1451 | static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, | 1564 | static 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 354a287c67eb..5a846324ca8c 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 | ||
| 4 | obj-vdso32 = sigtramp.o gettimeofday.o datapage.o cacheflush.o | 4 | obj-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/cacheflush.S b/arch/ppc64/kernel/vdso32/cacheflush.S index c74fddb6afd4..0ed7ea721715 100644 --- a/arch/ppc64/kernel/vdso32/cacheflush.S +++ b/arch/ppc64/kernel/vdso32/cacheflush.S | |||
| @@ -47,6 +47,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache) | |||
| 47 | addi r6,r6,128 | 47 | addi r6,r6,128 |
| 48 | bdnz 1b | 48 | bdnz 1b |
| 49 | isync | 49 | isync |
| 50 | li r3,0 | ||
| 50 | blr | 51 | blr |
| 51 | .cfi_endproc | 52 | .cfi_endproc |
| 52 | V_FUNCTION_END(__kernel_sync_dicache) | 53 | V_FUNCTION_END(__kernel_sync_dicache) |
| @@ -59,6 +60,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache_p5) | |||
| 59 | .cfi_startproc | 60 | .cfi_startproc |
| 60 | sync | 61 | sync |
| 61 | isync | 62 | isync |
| 63 | li r3,0 | ||
| 62 | blr | 64 | blr |
| 63 | .cfi_endproc | 65 | .cfi_endproc |
| 64 | V_FUNCTION_END(__kernel_sync_dicache_p5) | 66 | V_FUNCTION_END(__kernel_sync_dicache_p5) |
diff --git a/arch/ppc64/kernel/vdso32/gettimeofday.S b/arch/ppc64/kernel/vdso32/gettimeofday.S index ca7f415195c4..2b48bf1fb109 100644 --- a/arch/ppc64/kernel/vdso32/gettimeofday.S +++ b/arch/ppc64/kernel/vdso32/gettimeofday.S | |||
| @@ -58,6 +58,7 @@ V_FUNCTION_BEGIN(__kernel_gettimeofday) | |||
| 58 | stw r5,TZONE_TZ_DSTTIME(r11) | 58 | stw r5,TZONE_TZ_DSTTIME(r11) |
| 59 | 59 | ||
| 60 | 1: mtlr r12 | 60 | 1: mtlr r12 |
| 61 | li r3,0 | ||
| 61 | blr | 62 | blr |
| 62 | 63 | ||
| 63 | 2: mr r3,r10 | 64 | 2: mr r3,r10 |
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 */ \ | ||
| 15 | 0: .asciz vendor; /* vendor name */ \ | ||
| 16 | 1: .balign 4; \ | ||
| 17 | 2: | ||
| 18 | |||
| 19 | #define ASM_ELF_NOTE_END \ | ||
| 20 | 3: .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 | |||
| 87 | PHDRS | 89 | PHDRS |
| 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 | ||
| 3 | obj-vdso64 = sigtramp.o gettimeofday.o datapage.o cacheflush.o | 3 | obj-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/cacheflush.S b/arch/ppc64/kernel/vdso64/cacheflush.S index d9696ffcf334..e0725b7b7003 100644 --- a/arch/ppc64/kernel/vdso64/cacheflush.S +++ b/arch/ppc64/kernel/vdso64/cacheflush.S | |||
| @@ -47,6 +47,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache) | |||
| 47 | addi r6,r6,128 | 47 | addi r6,r6,128 |
| 48 | bdnz 1b | 48 | bdnz 1b |
| 49 | isync | 49 | isync |
| 50 | li r3,0 | ||
| 50 | blr | 51 | blr |
| 51 | .cfi_endproc | 52 | .cfi_endproc |
| 52 | V_FUNCTION_END(__kernel_sync_dicache) | 53 | V_FUNCTION_END(__kernel_sync_dicache) |
| @@ -59,6 +60,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache_p5) | |||
| 59 | .cfi_startproc | 60 | .cfi_startproc |
| 60 | sync | 61 | sync |
| 61 | isync | 62 | isync |
| 63 | li r3,0 | ||
| 62 | blr | 64 | blr |
| 63 | .cfi_endproc | 65 | .cfi_endproc |
| 64 | V_FUNCTION_END(__kernel_sync_dicache_p5) | 66 | V_FUNCTION_END(__kernel_sync_dicache_p5) |
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 | |||
| 88 | PHDRS | 90 | PHDRS |
| 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 | ||
| 221 | bail_ok: | ||
| 222 | li r3,0 | ||
| 223 | b bail | ||
| 224 | |||
| 218 | htab_pte_insert_ok: | 225 | htab_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 | ||
| 45 | static pgd_t *hugepgd_offset(struct mm_struct *mm, unsigned long addr) | 45 | static 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 | ||
| 58 | static inline pte_t *hugepte_offset(pgd_t *dir, unsigned long addr) | 58 | static 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 | ||
| 69 | static pgd_t *hugepgd_alloc(struct mm_struct *mm, unsigned long addr) | 69 | static 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 | ||
| 93 | static pte_t *hugepte_alloc(struct mm_struct *mm, pgd_t *dir, | 93 | static 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 | ||
| 125 | static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) | 124 | static 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 | ||
| 138 | static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) | 137 | static 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 | ||
| 151 | static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma, | 150 | static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma, |
| @@ -709,10 +708,10 @@ void hugetlb_mm_free_pgd(struct mm_struct *mm) | |||
| 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 | ||
| 139 | static 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 | |||
| 151 | static 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 | |||
| 166 | static 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 | |||
| 181 | static 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 | */ |
| 144 | static void map_io_page(unsigned long ea, unsigned long pa, int flags) | 207 | static 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 | ||
| 209 | void __iomem * | 285 | void __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 | ||
| 287 | static 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 | |||
| 322 | static 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 | */ |
| 357 | void iounmap(volatile void __iomem *token) | 381 | void 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 | ||
| 394 | static int iounmap_subset_regions(unsigned long addr, unsigned long size) | 398 | static int iounmap_subset_regions(unsigned long addr, unsigned long size) |
diff --git a/arch/ppc64/mm/slb.c b/arch/ppc64/mm/slb.c index 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 | ||
| 36 | static inline void create_slbe(unsigned long ea, unsigned long vsid, | 36 | static 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 | # |
| 6 | CONFIG_MMU=y | 6 | CONFIG_MMU=y |
| 7 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y | 7 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y |
| @@ -15,6 +15,7 @@ CONFIG_UID16=y | |||
| 15 | CONFIG_EXPERIMENTAL=y | 15 | CONFIG_EXPERIMENTAL=y |
| 16 | CONFIG_CLEAN_COMPILE=y | 16 | CONFIG_CLEAN_COMPILE=y |
| 17 | CONFIG_LOCK_KERNEL=y | 17 | CONFIG_LOCK_KERNEL=y |
| 18 | CONFIG_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 |
| 27 | CONFIG_SYSCTL=y | 28 | CONFIG_SYSCTL=y |
| 28 | # CONFIG_AUDIT is not set | 29 | # CONFIG_AUDIT is not set |
| 29 | CONFIG_LOG_BUF_SHIFT=17 | ||
| 30 | CONFIG_HOTPLUG=y | 30 | CONFIG_HOTPLUG=y |
| 31 | CONFIG_KOBJECT_UEVENT=y | 31 | CONFIG_KOBJECT_UEVENT=y |
| 32 | CONFIG_IKCONFIG=y | 32 | CONFIG_IKCONFIG=y |
| 33 | CONFIG_IKCONFIG_PROC=y | 33 | CONFIG_IKCONFIG_PROC=y |
| 34 | # CONFIG_CPUSETS is not set | ||
| 34 | # CONFIG_EMBEDDED is not set | 35 | # CONFIG_EMBEDDED is not set |
| 35 | CONFIG_KALLSYMS=y | 36 | CONFIG_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 |
| 39 | CONFIG_BASE_FULL=y | ||
| 38 | CONFIG_FUTEX=y | 40 | CONFIG_FUTEX=y |
| 39 | CONFIG_EPOLL=y | 41 | CONFIG_EPOLL=y |
| 40 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
| 41 | CONFIG_SHMEM=y | 42 | CONFIG_SHMEM=y |
| 42 | CONFIG_CC_ALIGN_FUNCTIONS=0 | 43 | CONFIG_CC_ALIGN_FUNCTIONS=0 |
| 43 | CONFIG_CC_ALIGN_LABELS=0 | 44 | CONFIG_CC_ALIGN_LABELS=0 |
| 44 | CONFIG_CC_ALIGN_LOOPS=0 | 45 | CONFIG_CC_ALIGN_LOOPS=0 |
| 45 | CONFIG_CC_ALIGN_JUMPS=0 | 46 | CONFIG_CC_ALIGN_JUMPS=0 |
| 46 | # CONFIG_TINY_SHMEM is not set | 47 | # CONFIG_TINY_SHMEM is not set |
| 48 | CONFIG_BASE_SMALL=0 | ||
| 47 | 49 | ||
| 48 | # | 50 | # |
| 49 | # Loadable module support | 51 | # Loadable module support |
| @@ -261,7 +263,6 @@ CONFIG_NET=y | |||
| 261 | # | 263 | # |
| 262 | CONFIG_PACKET=y | 264 | CONFIG_PACKET=y |
| 263 | # CONFIG_PACKET_MMAP is not set | 265 | # CONFIG_PACKET_MMAP is not set |
| 264 | # CONFIG_NETLINK_DEV is not set | ||
| 265 | CONFIG_UNIX=y | 266 | CONFIG_UNIX=y |
| 266 | CONFIG_NET_KEY=y | 267 | CONFIG_NET_KEY=y |
| 267 | CONFIG_INET=y | 268 | CONFIG_INET=y |
| @@ -329,6 +330,7 @@ CONFIG_NET_SCH_DSMARK=m | |||
| 329 | CONFIG_NET_QOS=y | 330 | CONFIG_NET_QOS=y |
| 330 | CONFIG_NET_ESTIMATOR=y | 331 | CONFIG_NET_ESTIMATOR=y |
| 331 | CONFIG_NET_CLS=y | 332 | CONFIG_NET_CLS=y |
| 333 | # CONFIG_NET_CLS_BASIC is not set | ||
| 332 | CONFIG_NET_CLS_TCINDEX=m | 334 | CONFIG_NET_CLS_TCINDEX=m |
| 333 | CONFIG_NET_CLS_ROUTE4=m | 335 | CONFIG_NET_CLS_ROUTE4=m |
| 334 | CONFIG_NET_CLS_ROUTE=y | 336 | CONFIG_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 |
| 339 | CONFIG_NET_CLS_RSVP=m | 341 | CONFIG_NET_CLS_RSVP=m |
| 340 | CONFIG_NET_CLS_RSVP6=m | 342 | CONFIG_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 |
| 342 | CONFIG_NET_CLS_POLICE=y | 345 | CONFIG_NET_CLS_POLICE=y |
| 343 | 346 | ||
| @@ -393,6 +396,8 @@ CONFIG_CTC=m | |||
| 393 | CONFIG_IUCV=m | 396 | CONFIG_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 | ||
| 396 | CONFIG_QETH=y | 401 | CONFIG_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 | ||
| 535 | CONFIG_DEBUG_KERNEL=y | 541 | CONFIG_DEBUG_KERNEL=y |
| 536 | CONFIG_MAGIC_SYSRQ=y | 542 | CONFIG_MAGIC_SYSRQ=y |
| 543 | CONFIG_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 | ||
| 21 | static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd, | 22 | static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd, |
| @@ -58,7 +59,11 @@ COMPATIBLE_IOCTL(BIODASDPRRD) | |||
| 58 | COMPATIBLE_IOCTL(BIODASDPSRD) | 59 | COMPATIBLE_IOCTL(BIODASDPSRD) |
| 59 | COMPATIBLE_IOCTL(BIODASDGATTR) | 60 | COMPATIBLE_IOCTL(BIODASDGATTR) |
| 60 | COMPATIBLE_IOCTL(BIODASDSATTR) | 61 | COMPATIBLE_IOCTL(BIODASDSATTR) |
| 61 | 62 | #if defined(CONFIG_DASD_CMB) || defined(CONFIG_DASD_CMB_MODULE) | |
| 63 | COMPATIBLE_IOCTL(BIODASDCMFENABLE) | ||
| 64 | COMPATIBLE_IOCTL(BIODASDCMFDISABLE) | ||
| 65 | COMPATIBLE_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 647233c02fc8..9f0d73e3f5f7 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); | |||
| 34 | EXPORT_SYMBOL(__strncpy_from_user_asm); | 34 | EXPORT_SYMBOL(__strncpy_from_user_asm); |
| 35 | EXPORT_SYMBOL(__strnlen_user_asm); | 35 | EXPORT_SYMBOL(__strnlen_user_asm); |
| 36 | EXPORT_SYMBOL(diag10); | 36 | EXPORT_SYMBOL(diag10); |
| 37 | EXPORT_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; | |||
| 53 | unsigned int console_irq = -1; | 55 | unsigned int console_irq = -1; |
| 54 | unsigned long memory_size = 0; | 56 | unsigned long memory_size = 0; |
| 55 | unsigned long machine_flags = 0; | 57 | unsigned long machine_flags = 0; |
| 56 | unsigned int default_storage_key = 0; | ||
| 57 | struct { | 58 | struct { |
| 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 |
| 62 | volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ | 63 | volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ |
| 64 | unsigned long __initdata zholes_size[MAX_NR_ZONES]; | ||
| 65 | static 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 | ||
| 79 | static struct resource code_resource = { | 82 | static 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 | ||
| 84 | static struct resource data_resource = { | 89 | static 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 | ||
| 311 | EXPORT_SYMBOL(machine_power_off); | 318 | EXPORT_SYMBOL(machine_power_off); |
| 312 | 319 | ||
| 313 | /* | 320 | static void __init |
| 314 | * Setup function called from init/main.c just after the banner | 321 | add_memory_hole(unsigned long start, unsigned long end) |
| 315 | * was printed. | 322 | { |
| 316 | */ | 323 | unsigned long dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT; |
| 317 | extern 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 | ||
| 319 | void __init setup_arch(char **cmdline_p) | 335 | static void __init |
| 336 | parse_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 | |||
| 393 | static void __init | ||
| 394 | setup_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 | |||
| 442 | static void __init | ||
| 443 | setup_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 | |||
| 470 | static void __init | ||
| 471 | setup_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 | ||
| 560 | void __init | ||
| 561 | setup_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 | */ |
| 245 | static inline void stop_hz_timer(void) | 245 | static 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 | ||
| 128 | static void stop_cpu_timer(void) | 134 | static 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 | ||
| 23 | static char *sender = "VMRMSVM"; | ||
| 24 | module_param(sender, charp, 0); | ||
| 25 | MODULE_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" |
| 369 | static void | 374 | static void |
| 370 | cmm_smsg_target(char *msg) | 375 | cmm_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; | |||
| 101 | extern unsigned long __init_begin; | 101 | extern unsigned long __init_begin; |
| 102 | extern unsigned long __init_end; | 102 | extern unsigned long __init_end; |
| 103 | 103 | ||
| 104 | extern 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 */ | ||
| 288 | asmlinkage 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 | ||
| 245 | config HIGHMEM | 245 | config HIGHMEM |
| 246 | bool "Highmem support" | 246 | bool "Highmem support" |
| 247 | depends on !64BIT | ||
| 247 | 248 | ||
| 248 | config KERNEL_STACK_ORDER | 249 | config 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 @@ | |||
| 1 | config 64_BIT | 1 | config UML_X86 |
| 2 | bool | ||
| 3 | default y | ||
| 4 | |||
| 5 | config 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 @@ | |||
| 1 | config 64_BIT | 1 | config UML_X86 |
| 2 | bool | ||
| 3 | default y | ||
| 4 | |||
| 5 | config 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 @@ | |||
| 1 | SUBARCH_CORE := arch/um/sys-i386/ | 1 | SUBARCH_CORE := arch/um/sys-i386/ arch/i386/crypto/ |
| 2 | 2 | ||
| 3 | TOP_ADDR := $(CONFIG_TOP_ADDR) | 3 | TOP_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 | # |
| 6 | CONFIG_GENERIC_HARDIRQS=y | 6 | CONFIG_GENERIC_HARDIRQS=y |
| 7 | CONFIG_UML=y | 7 | CONFIG_UML=y |
| @@ -15,7 +15,8 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y | |||
| 15 | # | 15 | # |
| 16 | CONFIG_MODE_TT=y | 16 | CONFIG_MODE_TT=y |
| 17 | CONFIG_MODE_SKAS=y | 17 | CONFIG_MODE_SKAS=y |
| 18 | # CONFIG_64_BIT is not set | 18 | CONFIG_UML_X86=y |
| 19 | # CONFIG_64BIT is not set | ||
| 19 | CONFIG_TOP_ADDR=0xc0000000 | 20 | CONFIG_TOP_ADDR=0xc0000000 |
| 20 | # CONFIG_3_LEVEL_PGTABLES is not set | 21 | # CONFIG_3_LEVEL_PGTABLES is not set |
| 21 | CONFIG_ARCH_HAS_SC_SIGNALS=y | 22 | CONFIG_ARCH_HAS_SC_SIGNALS=y |
| @@ -41,6 +42,7 @@ CONFIG_UML_REAL_TIME_CLOCK=y | |||
| 41 | CONFIG_EXPERIMENTAL=y | 42 | CONFIG_EXPERIMENTAL=y |
| 42 | CONFIG_CLEAN_COMPILE=y | 43 | CONFIG_CLEAN_COMPILE=y |
| 43 | CONFIG_BROKEN_ON_SMP=y | 44 | CONFIG_BROKEN_ON_SMP=y |
| 45 | CONFIG_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 | # |
| 159 | CONFIG_PACKET=y | 161 | CONFIG_PACKET=y |
| 160 | CONFIG_PACKET_MMAP=y | 162 | CONFIG_PACKET_MMAP=y |
| 161 | # CONFIG_NETLINK_DEV is not set | ||
| 162 | CONFIG_UNIX=y | 163 | CONFIG_UNIX=y |
| 163 | # CONFIG_NET_KEY is not set | 164 | # CONFIG_NET_KEY is not set |
| 164 | CONFIG_INET=y | 165 | CONFIG_INET=y |
| @@ -412,6 +413,5 @@ CONFIG_DEBUG_INFO=y | |||
| 412 | # CONFIG_DEBUG_FS is not set | 413 | # CONFIG_DEBUG_FS is not set |
| 413 | CONFIG_FRAME_POINTER=y | 414 | CONFIG_FRAME_POINTER=y |
| 414 | CONFIG_PT_PROXY=y | 415 | CONFIG_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 |
| 23 | static void *not_configged_init(char *str, int device, struct chan_opts *opts) | 23 | static 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) | |||
| 30 | static int not_configged_open(int input, int output, int primary, void *data, | 30 | static 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 | ||
| 38 | static void not_configged_close(int fd, void *data) | 38 | static 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 | ||
| 44 | static int not_configged_read(int fd, char *c_out, void *data) | 44 | static 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 | ||
| 51 | static int not_configged_write(int fd, const char *buf, int len, void *data) | 51 | static 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) | |||
| 58 | static int not_configged_console_write(int fd, const char *buf, int len, | 58 | static 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, | |||
| 66 | static int not_configged_window_size(int fd, void *data, unsigned short *rows, | 66 | static 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 | ||
| 74 | static void not_configged_free(void *data) | 74 | static 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 | ||
| 42 | static 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 | */ | ||
| 46 | static 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 | |||
| 61 | int 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 | ||
| 81 | int 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 | */ | ||
| 55 | static int buffer_data(struct line *line, const char *buf, int len) | 105 | static 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!*/ | ||
| 87 | static int flush_buffer(struct line *line) | 147 | static 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 | |||
| 183 | void 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.*/ | ||
| 204 | void line_flush_chars(struct tty_struct *tty) | ||
| 205 | { | ||
| 206 | line_flush_buffer(tty); | ||
| 207 | } | ||
| 208 | |||
| 209 | void line_put_char(struct tty_struct *tty, unsigned char ch) | ||
| 210 | { | ||
| 211 | line_write(tty, &ch, sizeof(ch)); | ||
| 115 | } | 212 | } |
| 116 | 213 | ||
| 117 | int line_write(struct tty_struct *tty, const unsigned char *buf, int len) | 214 | int line_write(struct tty_struct *tty, const unsigned char *buf, int len) |
| @@ -120,38 +217,31 @@ int line_write(struct tty_struct *tty, const unsigned char *buf, int len) | |||
| 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: | 242 | out_up: |
| 148 | up(&line->sem); | 243 | spin_unlock_irqrestore(&line->lock, flags); |
| 149 | return(ret); | 244 | return ret; |
| 150 | } | ||
| 151 | |||
| 152 | void line_put_char(struct tty_struct *tty, unsigned char ch) | ||
| 153 | { | ||
| 154 | line_write(tty, &ch, sizeof(ch)); | ||
| 155 | } | 245 | } |
| 156 | 246 | ||
| 157 | void line_set_termios(struct tty_struct *tty, struct termios * old) | 247 | void line_set_termios(struct tty_struct *tty, struct termios * old) |
| @@ -159,11 +249,6 @@ void line_set_termios(struct tty_struct *tty, struct termios * old) | |||
| 159 | /* nothing */ | 249 | /* nothing */ |
| 160 | } | 250 | } |
| 161 | 251 | ||
| 162 | int line_chars_in_buffer(struct tty_struct *tty) | ||
| 163 | { | ||
| 164 | return 0; | ||
| 165 | } | ||
| 166 | |||
| 167 | static struct { | 252 | static 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 | ||
| 256 | static irqreturn_t line_write_interrupt(int irq, void *data, | 341 | static 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 | ||
| 289 | int line_setup_irq(int fd, int input, int output, struct tty_struct *tty) | 379 | int line_setup_irq(int fd, int input, int output, struct tty_struct *tty) |
| @@ -292,15 +382,18 @@ int line_setup_irq(int fd, int input, int output, struct tty_struct *tty) | |||
| 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 | ||
| 306 | void line_disable(struct tty_struct *tty, int current_irq) | 399 | void 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 | ||
| 364 | out: | 460 | out: |
| 365 | up(&line->sem); | 461 | spin_unlock(&line->lock); |
| 366 | return(err); | 462 | return err; |
| 367 | } | 463 | } |
| 368 | 464 | ||
| 369 | void line_close(struct tty_struct *tty, struct file * filp) | 465 | void 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 | ||
| 382 | void close_lines(struct line *lines, int nlines) | 484 | void 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 | ||
| 390 | int 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 | |||
| 499 | int 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 | ||
| 446 | int line_config(struct line *lines, int num, char *str) | 556 | int 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 | ||
| 457 | int line_get_config(char *name, struct line *lines, int num, char *str, | 567 | int 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 | ||
| 488 | int line_remove(struct line *lines, int num, char *str) | 598 | int 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 | |||
| 496 | int 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 | ||
| 510 | struct tty_driver *line_register_devfs(struct lines *set, | 606 | struct 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 | ||
| 609 | DECLARE_MUTEX(winch_handler_sem); | 705 | DECLARE_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 |
| 110 | static int ssl_chars_in_buffer(struct tty_struct *tty) | ||
| 111 | { | ||
| 112 | return(0); | ||
| 113 | } | ||
| 114 | |||
| 115 | static void ssl_flush_buffer(struct tty_struct *tty) | 110 | static 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 | ||
| 180 | static struct tty_driver *ssl_console_device(struct console *c, int *index) | 176 | static 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 | ||
| 135 | static struct tty_driver *uml_console_device(struct console *c, int *index) | 139 | static 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]; | |||
| 156 | static struct openflags global_openflags = OPEN_FLAGS; | 156 | static struct openflags global_openflags = OPEN_FLAGS; |
| 157 | 157 | ||
| 158 | struct cow { | 158 | struct 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 { | |||
| 69 | extern void line_close(struct tty_struct *tty, struct file * filp); | 76 | extern void line_close(struct tty_struct *tty, struct file * filp); |
| 70 | extern int line_open(struct line *lines, struct tty_struct *tty, | 77 | extern int line_open(struct line *lines, struct tty_struct *tty, |
| 71 | struct chan_opts *opts); | 78 | struct chan_opts *opts); |
| 72 | extern int line_setup(struct line *lines, int num, char *init, | 79 | extern int line_setup(struct line *lines, unsigned int sizeof_lines, char *init, |
| 73 | int all_allowed); | 80 | int all_allowed); |
| 74 | extern int line_write(struct tty_struct *tty, const unsigned char *buf, int len); | 81 | extern int line_write(struct tty_struct *tty, const unsigned char *buf, int len); |
| 75 | extern void line_put_char(struct tty_struct *tty, unsigned char ch); | 82 | extern void line_put_char(struct tty_struct *tty, unsigned char ch); |
| 76 | extern void line_set_termios(struct tty_struct *tty, struct termios * old); | 83 | extern void line_set_termios(struct tty_struct *tty, struct termios * old); |
| 77 | extern int line_chars_in_buffer(struct tty_struct *tty); | 84 | extern int line_chars_in_buffer(struct tty_struct *tty); |
| 85 | extern void line_flush_buffer(struct tty_struct *tty); | ||
| 86 | extern void line_flush_chars(struct tty_struct *tty); | ||
| 78 | extern int line_write_room(struct tty_struct *tty); | 87 | extern int line_write_room(struct tty_struct *tty); |
| 79 | extern int line_ioctl(struct tty_struct *tty, struct file * file, | 88 | extern 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 | |||
| 81 | extern char *add_xterm_umid(char *base); | 91 | extern char *add_xterm_umid(char *base); |
| 82 | extern int line_setup_irq(int fd, int input, int output, struct tty_struct *tty); | 92 | extern int line_setup_irq(int fd, int input, int output, struct tty_struct *tty); |
| 83 | extern void line_close_chan(struct line *line); | 93 | extern 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); |
| 90 | extern void lines_init(struct line *lines, int nlines); | 100 | extern void lines_init(struct line *lines, int nlines); |
| 91 | extern void close_lines(struct line *lines, int nlines); | 101 | extern void close_lines(struct line *lines, int nlines); |
| 92 | extern int line_config(struct line *lines, int num, char *str); | 102 | |
| 93 | extern int line_remove(struct line *lines, int num, char *str); | 103 | extern int line_config(struct line *lines, unsigned int sizeof_lines, char *str); |
| 94 | extern int line_get_config(char *dev, struct line *lines, int num, char *str, | 104 | extern int line_remove(struct line *lines, unsigned int sizeof_lines, char *str); |
| 105 | extern 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; | |||
| 22 | extern long sys_mmap2(unsigned long addr, unsigned long len, | 22 | extern 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[]; | |||
| 26 | extern long old_mmap(unsigned long addr, unsigned long len, | 26 | extern 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); |
| 29 | extern syscall_handler_t wrap_sys_shmat; | ||
| 30 | extern syscall_handler_t sys_modify_ldt; | 29 | extern syscall_handler_t sys_modify_ldt; |
| 31 | extern syscall_handler_t sys_arch_prctl; | 30 | extern 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 | ||
| 164 | void prepare_to_copy(struct task_struct *tsk) | ||
| 165 | { | ||
| 166 | } | ||
| 167 | |||
| 168 | int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, | 164 | int 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 3a99ee6d94eb..e50e60ff5d27 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 | ||
| 21 | static inline int verify_area_skas(int type, const void * addr, | 21 | static 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 | |||
| 31 | extern syscall_handler_t sys_fork; | ||
| 32 | extern syscall_handler_t sys_execve; | ||
| 33 | extern syscall_handler_t um_time; | ||
| 34 | extern syscall_handler_t um_stime; | ||
| 35 | extern syscall_handler_t sys_pipe; | ||
| 36 | extern syscall_handler_t sys_olduname; | ||
| 37 | extern syscall_handler_t sys_sigaction; | ||
| 38 | extern syscall_handler_t sys_sigsuspend; | ||
| 39 | extern syscall_handler_t old_readdir; | ||
| 40 | extern syscall_handler_t sys_uname; | ||
| 41 | extern syscall_handler_t sys_ipc; | ||
| 42 | extern syscall_handler_t sys_sigreturn; | ||
| 43 | extern syscall_handler_t sys_clone; | ||
| 44 | extern syscall_handler_t sys_rt_sigreturn; | ||
| 45 | extern syscall_handler_t sys_sigaltstack; | ||
| 46 | extern syscall_handler_t sys_vfork; | ||
| 47 | extern syscall_handler_t old_select; | ||
| 48 | extern syscall_handler_t sys_modify_ldt; | ||
| 49 | extern syscall_handler_t sys_rt_sigsuspend; | ||
| 50 | extern syscall_handler_t sys_mbind; | ||
| 51 | extern syscall_handler_t sys_get_mempolicy; | ||
| 52 | extern syscall_handler_t sys_set_mempolicy; | ||
| 53 | extern syscall_handler_t sys_sys_setaltroot; | ||
| 54 | |||
| 55 | syscall_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 | ||
| 36 | static inline int verify_area_tt(int type, const void * addr, | 36 | static 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 @@ | |||
| 1 | obj-y = bitops.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ | 1 | obj-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 | ||
| 4 | obj-$(CONFIG_HIGHMEM) += highmem.o | 5 | obj-$(CONFIG_HIGHMEM) += highmem.o |
| 5 | obj-$(CONFIG_MODULES) += module.o | 6 | obj-$(CONFIG_MODULES) += module.o |
diff --git a/arch/um/sys-i386/sys_call_table.S b/arch/um/sys-i386/sys_call_table.S new file mode 100644 index 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 | ||
| 7 | lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \ | 7 | lib-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 | ||
| 11 | USER_OBJS := ptrace_user.o sigcontext.o | 11 | USER_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 | |||
| 51 | typedef void (*sys_call_ptr_t)(void); | ||
| 52 | |||
| 53 | extern void sys_ni_syscall(void); | ||
| 54 | |||
| 55 | sys_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 | ||
| 17 | asmlinkage long wrap_sys_shmat(int shmid, char __user *shmaddr, int shmflg) | 17 | asmlinkage 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 | |||
| 160 | trampoline: call start_of_setup | 160 | trampoline: 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 | ||
| 166 | start_of_setup: | 166 | start_of_setup: |
| @@ -412,9 +412,9 @@ jmpe820: | |||
| 412 | # sizeof(e820rec). | 412 | # sizeof(e820rec). |
| 413 | # | 413 | # |
| 414 | good820: | 414 | good820: |
| 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/ia32/vsyscall.lds b/arch/x86_64/ia32/vsyscall.lds index fa4b4dd4a9ff..f2e75ed4c6c7 100644 --- a/arch/x86_64/ia32/vsyscall.lds +++ b/arch/x86_64/ia32/vsyscall.lds | |||
| @@ -36,6 +36,7 @@ SECTIONS | |||
| 36 | 36 | ||
| 37 | .text.rtsigreturn : { *(.text.rtsigreturn) } :text =0x90909090 | 37 | .text.rtsigreturn : { *(.text.rtsigreturn) } :text =0x90909090 |
| 38 | 38 | ||
| 39 | .note : { *(.note.*) } :text :note | ||
| 39 | .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr | 40 | .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr |
| 40 | .eh_frame : { KEEP (*(.eh_frame)) } :text | 41 | .eh_frame : { KEEP (*(.eh_frame)) } :text |
| 41 | .dynamic : { *(.dynamic) } :text :dynamic | 42 | .dynamic : { *(.dynamic) } :text :dynamic |
| @@ -55,6 +56,7 @@ PHDRS | |||
| 55 | { | 56 | { |
| 56 | text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */ | 57 | text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */ |
| 57 | dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ | 58 | dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ |
| 59 | note PT_NOTE FLAGS(4); /* PF_R */ | ||
| 58 | eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */ | 60 | eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */ |
| 59 | } | 61 | } |
| 60 | 62 | ||
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 | ||
| 63 | int early_serial_base = 0x3f8; /* ttyS0 */ | 63 | static 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 | ||
| 301 | int_signal: | 302 | int_signal: |
| @@ -307,6 +308,7 @@ int_signal: | |||
| 307 | 1: movl $_TIF_NEED_RESCHED,%edi | 308 | 1: movl $_TIF_NEED_RESCHED,%edi |
| 308 | int_restore_rest: | 309 | int_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 | ||
| 32 | extern 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 | ||
| 115 | int __init check_nmi_watchdog (void) | 115 | static 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 */ | ||
| 155 | late_initcall(check_nmi_watchdog); | ||
| 151 | 156 | ||
| 152 | int __init setup_nmi_watchdog(char *str) | 157 | int __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 c7011675007d..c64b9c97c745 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 | ||
| 29 | char x86_boot_params[2048] __initdata = {0,}; | 30 | char x86_boot_params[BOOT_PARAM_SIZE] __initdata = {0,}; |
| 30 | 31 | ||
| 31 | cpumask_t cpu_initialized __initdata = CPU_MASK_NONE; | 32 | cpumask_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 | ||
| 155 | asmlinkage 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 | |||
| 161 | asmlinkage long sys_time64(long __user * tloc) | 155 | asmlinkage long sys_time64(long __user * tloc) |
| 162 | { | 156 | { |
| 163 | struct timeval now; | 157 | struct timeval now; |
