diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-05-14 22:11:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-05-14 22:11:36 -0400 |
commit | 8978a318837d7acefca82645017c0534aeba5a36 (patch) | |
tree | f69f5bc9a11d1a3a5c6391a9b48c9bcae4615a5a /arch | |
parent | f7fd63c0b5e170efc20e7b9a0aad7f69dff62c64 (diff) | |
parent | 9a28dbf8af11d127bf1c644143e7882cb91515dd (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6:
sparc64: Use a TS_RESTORE_SIGMASK
lmb: Make lmb debugging more useful.
lmb: Fix inconsistent alignment of size argument.
sparc: Fix mremap address range validation.
Diffstat (limited to 'arch')
-rw-r--r-- | arch/sparc/kernel/sys_sparc.c | 48 | ||||
-rw-r--r-- | arch/sparc64/kernel/rtrap.S | 6 | ||||
-rw-r--r-- | arch/sparc64/kernel/signal.c | 21 | ||||
-rw-r--r-- | arch/sparc64/kernel/signal32.c | 13 | ||||
-rw-r--r-- | arch/sparc64/kernel/sys_sparc.c | 36 | ||||
-rw-r--r-- | arch/sparc64/kernel/sys_sparc32.c | 33 |
6 files changed, 31 insertions, 126 deletions
diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c index e995491c4436..3c6b49a53ae8 100644 --- a/arch/sparc/kernel/sys_sparc.c +++ b/arch/sparc/kernel/sys_sparc.c | |||
@@ -219,7 +219,7 @@ out: | |||
219 | return err; | 219 | return err; |
220 | } | 220 | } |
221 | 221 | ||
222 | int sparc_mmap_check(unsigned long addr, unsigned long len, unsigned long flags) | 222 | int sparc_mmap_check(unsigned long addr, unsigned long len) |
223 | { | 223 | { |
224 | if (ARCH_SUN4C_SUN4 && | 224 | if (ARCH_SUN4C_SUN4 && |
225 | (len > 0x20000000 || | 225 | (len > 0x20000000 || |
@@ -295,52 +295,14 @@ asmlinkage unsigned long sparc_mremap(unsigned long addr, | |||
295 | unsigned long old_len, unsigned long new_len, | 295 | unsigned long old_len, unsigned long new_len, |
296 | unsigned long flags, unsigned long new_addr) | 296 | unsigned long flags, unsigned long new_addr) |
297 | { | 297 | { |
298 | struct vm_area_struct *vma; | ||
299 | unsigned long ret = -EINVAL; | 298 | unsigned long ret = -EINVAL; |
300 | if (ARCH_SUN4C_SUN4) { | 299 | |
301 | if (old_len > 0x20000000 || new_len > 0x20000000) | 300 | if (unlikely(sparc_mmap_check(addr, old_len))) |
302 | goto out; | 301 | goto out; |
303 | if (addr < 0xe0000000 && addr + old_len > 0x20000000) | 302 | if (unlikely(sparc_mmap_check(new_addr, new_len))) |
304 | goto out; | ||
305 | } | ||
306 | if (old_len > TASK_SIZE - PAGE_SIZE || | ||
307 | new_len > TASK_SIZE - PAGE_SIZE) | ||
308 | goto out; | 303 | goto out; |
309 | down_write(¤t->mm->mmap_sem); | 304 | down_write(¤t->mm->mmap_sem); |
310 | if (flags & MREMAP_FIXED) { | ||
311 | if (ARCH_SUN4C_SUN4 && | ||
312 | new_addr < 0xe0000000 && | ||
313 | new_addr + new_len > 0x20000000) | ||
314 | goto out_sem; | ||
315 | if (new_addr + new_len > TASK_SIZE - PAGE_SIZE) | ||
316 | goto out_sem; | ||
317 | } else if ((ARCH_SUN4C_SUN4 && addr < 0xe0000000 && | ||
318 | addr + new_len > 0x20000000) || | ||
319 | addr + new_len > TASK_SIZE - PAGE_SIZE) { | ||
320 | unsigned long map_flags = 0; | ||
321 | struct file *file = NULL; | ||
322 | |||
323 | ret = -ENOMEM; | ||
324 | if (!(flags & MREMAP_MAYMOVE)) | ||
325 | goto out_sem; | ||
326 | |||
327 | vma = find_vma(current->mm, addr); | ||
328 | if (vma) { | ||
329 | if (vma->vm_flags & VM_SHARED) | ||
330 | map_flags |= MAP_SHARED; | ||
331 | file = vma->vm_file; | ||
332 | } | ||
333 | |||
334 | new_addr = get_unmapped_area(file, addr, new_len, | ||
335 | vma ? vma->vm_pgoff : 0, | ||
336 | map_flags); | ||
337 | ret = new_addr; | ||
338 | if (new_addr & ~PAGE_MASK) | ||
339 | goto out_sem; | ||
340 | flags |= MREMAP_FIXED; | ||
341 | } | ||
342 | ret = do_mremap(addr, old_len, new_len, flags, new_addr); | 305 | ret = do_mremap(addr, old_len, new_len, flags, new_addr); |
343 | out_sem: | ||
344 | up_write(¤t->mm->mmap_sem); | 306 | up_write(¤t->mm->mmap_sem); |
345 | out: | 307 | out: |
346 | return ret; | 308 | return ret; |
diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S index b9b785fd8b46..16689b2930db 100644 --- a/arch/sparc64/kernel/rtrap.S +++ b/arch/sparc64/kernel/rtrap.S | |||
@@ -46,7 +46,7 @@ __handle_user_windows: | |||
46 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate | 46 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate |
47 | ldx [%g6 + TI_FLAGS], %l0 | 47 | ldx [%g6 + TI_FLAGS], %l0 |
48 | 48 | ||
49 | 1: andcc %l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0 | 49 | 1: andcc %l0, _TIF_SIGPENDING, %g0 |
50 | be,pt %xcc, __handle_user_windows_continue | 50 | be,pt %xcc, __handle_user_windows_continue |
51 | nop | 51 | nop |
52 | mov %l5, %o1 | 52 | mov %l5, %o1 |
@@ -86,7 +86,7 @@ __handle_perfctrs: | |||
86 | wrpr %g0, RTRAP_PSTATE, %pstate | 86 | wrpr %g0, RTRAP_PSTATE, %pstate |
87 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate | 87 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate |
88 | ldx [%g6 + TI_FLAGS], %l0 | 88 | ldx [%g6 + TI_FLAGS], %l0 |
89 | 1: andcc %l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0 | 89 | 1: andcc %l0, _TIF_SIGPENDING, %g0 |
90 | 90 | ||
91 | be,pt %xcc, __handle_perfctrs_continue | 91 | be,pt %xcc, __handle_perfctrs_continue |
92 | sethi %hi(TSTATE_PEF), %o0 | 92 | sethi %hi(TSTATE_PEF), %o0 |
@@ -195,7 +195,7 @@ __handle_preemption_continue: | |||
195 | andcc %l1, %o0, %g0 | 195 | andcc %l1, %o0, %g0 |
196 | andcc %l0, _TIF_NEED_RESCHED, %g0 | 196 | andcc %l0, _TIF_NEED_RESCHED, %g0 |
197 | bne,pn %xcc, __handle_preemption | 197 | bne,pn %xcc, __handle_preemption |
198 | andcc %l0, (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), %g0 | 198 | andcc %l0, _TIF_SIGPENDING, %g0 |
199 | bne,pn %xcc, __handle_signal | 199 | bne,pn %xcc, __handle_signal |
200 | __handle_signal_continue: | 200 | __handle_signal_continue: |
201 | ldub [%g6 + TI_WSAVED], %o2 | 201 | ldub [%g6 + TI_WSAVED], %o2 |
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c index 2378482c2aab..6e4dc67d16af 100644 --- a/arch/sparc64/kernel/signal.c +++ b/arch/sparc64/kernel/signal.c | |||
@@ -247,7 +247,9 @@ static long _sigpause_common(old_sigset_t set) | |||
247 | 247 | ||
248 | current->state = TASK_INTERRUPTIBLE; | 248 | current->state = TASK_INTERRUPTIBLE; |
249 | schedule(); | 249 | schedule(); |
250 | set_thread_flag(TIF_RESTORE_SIGMASK); | 250 | |
251 | set_restore_sigmask(); | ||
252 | |||
251 | return -ERESTARTNOHAND; | 253 | return -ERESTARTNOHAND; |
252 | } | 254 | } |
253 | 255 | ||
@@ -537,7 +539,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) | |||
537 | } else | 539 | } else |
538 | restart_syscall = 0; | 540 | restart_syscall = 0; |
539 | 541 | ||
540 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | 542 | if (current_thread_info()->status & TS_RESTORE_SIGMASK) |
541 | oldset = ¤t->saved_sigmask; | 543 | oldset = ¤t->saved_sigmask; |
542 | else | 544 | else |
543 | oldset = ¤t->blocked; | 545 | oldset = ¤t->blocked; |
@@ -566,13 +568,12 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) | |||
566 | syscall_restart(orig_i0, regs, &ka.sa); | 568 | syscall_restart(orig_i0, regs, &ka.sa); |
567 | handle_signal(signr, &ka, &info, oldset, regs); | 569 | handle_signal(signr, &ka, &info, oldset, regs); |
568 | 570 | ||
569 | /* a signal was successfully delivered; the saved | 571 | /* A signal was successfully delivered; the saved |
570 | * sigmask will have been stored in the signal frame, | 572 | * sigmask will have been stored in the signal frame, |
571 | * and will be restored by sigreturn, so we can simply | 573 | * and will be restored by sigreturn, so we can simply |
572 | * clear the TIF_RESTORE_SIGMASK flag. | 574 | * clear the TS_RESTORE_SIGMASK flag. |
573 | */ | 575 | */ |
574 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | 576 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; |
575 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
576 | return; | 577 | return; |
577 | } | 578 | } |
578 | if (restart_syscall && | 579 | if (restart_syscall && |
@@ -591,17 +592,17 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) | |||
591 | regs->tnpc -= 4; | 592 | regs->tnpc -= 4; |
592 | } | 593 | } |
593 | 594 | ||
594 | /* if there's no signal to deliver, we just put the saved sigmask | 595 | /* If there's no signal to deliver, we just put the saved sigmask |
595 | * back | 596 | * back |
596 | */ | 597 | */ |
597 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { | 598 | if (current_thread_info()->status & TS_RESTORE_SIGMASK) { |
598 | clear_thread_flag(TIF_RESTORE_SIGMASK); | 599 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; |
599 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | 600 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); |
600 | } | 601 | } |
601 | } | 602 | } |
602 | 603 | ||
603 | void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags) | 604 | void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags) |
604 | { | 605 | { |
605 | if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) | 606 | if (thread_info_flags & _TIF_SIGPENDING) |
606 | do_signal(regs, orig_i0); | 607 | do_signal(regs, orig_i0); |
607 | } | 608 | } |
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c index 3f19e9af3d1b..97cdd1bf4a10 100644 --- a/arch/sparc64/kernel/signal32.c +++ b/arch/sparc64/kernel/signal32.c | |||
@@ -788,13 +788,12 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs, | |||
788 | syscall_restart32(orig_i0, regs, &ka.sa); | 788 | syscall_restart32(orig_i0, regs, &ka.sa); |
789 | handle_signal32(signr, &ka, &info, oldset, regs); | 789 | handle_signal32(signr, &ka, &info, oldset, regs); |
790 | 790 | ||
791 | /* a signal was successfully delivered; the saved | 791 | /* A signal was successfully delivered; the saved |
792 | * sigmask will have been stored in the signal frame, | 792 | * sigmask will have been stored in the signal frame, |
793 | * and will be restored by sigreturn, so we can simply | 793 | * and will be restored by sigreturn, so we can simply |
794 | * clear the TIF_RESTORE_SIGMASK flag. | 794 | * clear the TS_RESTORE_SIGMASK flag. |
795 | */ | 795 | */ |
796 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | 796 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; |
797 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
798 | return; | 797 | return; |
799 | } | 798 | } |
800 | if (restart_syscall && | 799 | if (restart_syscall && |
@@ -813,11 +812,11 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs, | |||
813 | regs->tnpc -= 4; | 812 | regs->tnpc -= 4; |
814 | } | 813 | } |
815 | 814 | ||
816 | /* if there's no signal to deliver, we just put the saved sigmask | 815 | /* If there's no signal to deliver, we just put the saved sigmask |
817 | * back | 816 | * back |
818 | */ | 817 | */ |
819 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { | 818 | if (current_thread_info()->status & TS_RESTORE_SIGMASK) { |
820 | clear_thread_flag(TIF_RESTORE_SIGMASK); | 819 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; |
821 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | 820 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); |
822 | } | 821 | } |
823 | } | 822 | } |
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c index 0dbc941f130e..ac1bff58c1ac 100644 --- a/arch/sparc64/kernel/sys_sparc.c +++ b/arch/sparc64/kernel/sys_sparc.c | |||
@@ -542,8 +542,7 @@ asmlinkage long sparc64_personality(unsigned long personality) | |||
542 | return ret; | 542 | return ret; |
543 | } | 543 | } |
544 | 544 | ||
545 | int sparc64_mmap_check(unsigned long addr, unsigned long len, | 545 | int sparc64_mmap_check(unsigned long addr, unsigned long len) |
546 | unsigned long flags) | ||
547 | { | 546 | { |
548 | if (test_thread_flag(TIF_32BIT)) { | 547 | if (test_thread_flag(TIF_32BIT)) { |
549 | if (len >= STACK_TOP32) | 548 | if (len >= STACK_TOP32) |
@@ -609,46 +608,19 @@ asmlinkage unsigned long sys64_mremap(unsigned long addr, | |||
609 | unsigned long old_len, unsigned long new_len, | 608 | unsigned long old_len, unsigned long new_len, |
610 | unsigned long flags, unsigned long new_addr) | 609 | unsigned long flags, unsigned long new_addr) |
611 | { | 610 | { |
612 | struct vm_area_struct *vma; | ||
613 | unsigned long ret = -EINVAL; | 611 | unsigned long ret = -EINVAL; |
614 | 612 | ||
615 | if (test_thread_flag(TIF_32BIT)) | 613 | if (test_thread_flag(TIF_32BIT)) |
616 | goto out; | 614 | goto out; |
617 | if (unlikely(new_len >= VA_EXCLUDE_START)) | 615 | if (unlikely(new_len >= VA_EXCLUDE_START)) |
618 | goto out; | 616 | goto out; |
619 | if (unlikely(invalid_64bit_range(addr, old_len))) | 617 | if (unlikely(sparc64_mmap_check(addr, old_len))) |
618 | goto out; | ||
619 | if (unlikely(sparc64_mmap_check(new_addr, new_len))) | ||
620 | goto out; | 620 | goto out; |
621 | 621 | ||
622 | down_write(¤t->mm->mmap_sem); | 622 | down_write(¤t->mm->mmap_sem); |
623 | if (flags & MREMAP_FIXED) { | ||
624 | if (invalid_64bit_range(new_addr, new_len)) | ||
625 | goto out_sem; | ||
626 | } else if (invalid_64bit_range(addr, new_len)) { | ||
627 | unsigned long map_flags = 0; | ||
628 | struct file *file = NULL; | ||
629 | |||
630 | ret = -ENOMEM; | ||
631 | if (!(flags & MREMAP_MAYMOVE)) | ||
632 | goto out_sem; | ||
633 | |||
634 | vma = find_vma(current->mm, addr); | ||
635 | if (vma) { | ||
636 | if (vma->vm_flags & VM_SHARED) | ||
637 | map_flags |= MAP_SHARED; | ||
638 | file = vma->vm_file; | ||
639 | } | ||
640 | |||
641 | /* MREMAP_FIXED checked above. */ | ||
642 | new_addr = get_unmapped_area(file, addr, new_len, | ||
643 | vma ? vma->vm_pgoff : 0, | ||
644 | map_flags); | ||
645 | ret = new_addr; | ||
646 | if (new_addr & ~PAGE_MASK) | ||
647 | goto out_sem; | ||
648 | flags |= MREMAP_FIXED; | ||
649 | } | ||
650 | ret = do_mremap(addr, old_len, new_len, flags, new_addr); | 623 | ret = do_mremap(addr, old_len, new_len, flags, new_addr); |
651 | out_sem: | ||
652 | up_write(¤t->mm->mmap_sem); | 624 | up_write(¤t->mm->mmap_sem); |
653 | out: | 625 | out: |
654 | return ret; | 626 | return ret; |
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index 1aa4288125f2..ba5bd626b39e 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c | |||
@@ -867,44 +867,15 @@ asmlinkage unsigned long sys32_mremap(unsigned long addr, | |||
867 | unsigned long old_len, unsigned long new_len, | 867 | unsigned long old_len, unsigned long new_len, |
868 | unsigned long flags, u32 __new_addr) | 868 | unsigned long flags, u32 __new_addr) |
869 | { | 869 | { |
870 | struct vm_area_struct *vma; | ||
871 | unsigned long ret = -EINVAL; | 870 | unsigned long ret = -EINVAL; |
872 | unsigned long new_addr = __new_addr; | 871 | unsigned long new_addr = __new_addr; |
873 | 872 | ||
874 | if (old_len > STACK_TOP32 || new_len > STACK_TOP32) | 873 | if (unlikely(sparc64_mmap_check(addr, old_len))) |
875 | goto out; | 874 | goto out; |
876 | if (addr > STACK_TOP32 - old_len) | 875 | if (unlikely(sparc64_mmap_check(new_addr, new_len))) |
877 | goto out; | 876 | goto out; |
878 | down_write(¤t->mm->mmap_sem); | 877 | down_write(¤t->mm->mmap_sem); |
879 | if (flags & MREMAP_FIXED) { | ||
880 | if (new_addr > STACK_TOP32 - new_len) | ||
881 | goto out_sem; | ||
882 | } else if (addr > STACK_TOP32 - new_len) { | ||
883 | unsigned long map_flags = 0; | ||
884 | struct file *file = NULL; | ||
885 | |||
886 | ret = -ENOMEM; | ||
887 | if (!(flags & MREMAP_MAYMOVE)) | ||
888 | goto out_sem; | ||
889 | |||
890 | vma = find_vma(current->mm, addr); | ||
891 | if (vma) { | ||
892 | if (vma->vm_flags & VM_SHARED) | ||
893 | map_flags |= MAP_SHARED; | ||
894 | file = vma->vm_file; | ||
895 | } | ||
896 | |||
897 | /* MREMAP_FIXED checked above. */ | ||
898 | new_addr = get_unmapped_area(file, addr, new_len, | ||
899 | vma ? vma->vm_pgoff : 0, | ||
900 | map_flags); | ||
901 | ret = new_addr; | ||
902 | if (new_addr & ~PAGE_MASK) | ||
903 | goto out_sem; | ||
904 | flags |= MREMAP_FIXED; | ||
905 | } | ||
906 | ret = do_mremap(addr, old_len, new_len, flags, new_addr); | 878 | ret = do_mremap(addr, old_len, new_len, flags, new_addr); |
907 | out_sem: | ||
908 | up_write(¤t->mm->mmap_sem); | 879 | up_write(¤t->mm->mmap_sem); |
909 | out: | 880 | out: |
910 | return ret; | 881 | return ret; |