diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /arch/sparc/kernel/sys_sparc_64.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'arch/sparc/kernel/sys_sparc_64.c')
-rw-r--r-- | arch/sparc/kernel/sys_sparc_64.c | 173 |
1 files changed, 17 insertions, 156 deletions
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index e2d102447a43..3d435c42e6db 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c | |||
@@ -27,7 +27,6 @@ | |||
27 | 27 | ||
28 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
29 | #include <asm/utrap.h> | 29 | #include <asm/utrap.h> |
30 | #include <asm/perfctr.h> | ||
31 | #include <asm/unistd.h> | 30 | #include <asm/unistd.h> |
32 | 31 | ||
33 | #include "entry.h" | 32 | #include "entry.h" |
@@ -317,10 +316,14 @@ bottomup: | |||
317 | unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, unsigned long len, unsigned long pgoff, unsigned long flags) | 316 | unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, unsigned long len, unsigned long pgoff, unsigned long flags) |
318 | { | 317 | { |
319 | unsigned long align_goal, addr = -ENOMEM; | 318 | unsigned long align_goal, addr = -ENOMEM; |
319 | unsigned long (*get_area)(struct file *, unsigned long, | ||
320 | unsigned long, unsigned long, unsigned long); | ||
321 | |||
322 | get_area = current->mm->get_unmapped_area; | ||
320 | 323 | ||
321 | if (flags & MAP_FIXED) { | 324 | if (flags & MAP_FIXED) { |
322 | /* Ok, don't mess with it. */ | 325 | /* Ok, don't mess with it. */ |
323 | return get_unmapped_area(NULL, orig_addr, len, pgoff, flags); | 326 | return get_area(NULL, orig_addr, len, pgoff, flags); |
324 | } | 327 | } |
325 | flags &= ~MAP_SHARED; | 328 | flags &= ~MAP_SHARED; |
326 | 329 | ||
@@ -333,7 +336,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u | |||
333 | align_goal = (64UL * 1024); | 336 | align_goal = (64UL * 1024); |
334 | 337 | ||
335 | do { | 338 | do { |
336 | addr = get_unmapped_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags); | 339 | addr = get_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags); |
337 | if (!(addr & ~PAGE_MASK)) { | 340 | if (!(addr & ~PAGE_MASK)) { |
338 | addr = (addr + (align_goal - 1UL)) & ~(align_goal - 1UL); | 341 | addr = (addr + (align_goal - 1UL)) & ~(align_goal - 1UL); |
339 | break; | 342 | break; |
@@ -351,7 +354,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u | |||
351 | * be obtained. | 354 | * be obtained. |
352 | */ | 355 | */ |
353 | if (addr & ~PAGE_MASK) | 356 | if (addr & ~PAGE_MASK) |
354 | addr = get_unmapped_area(NULL, orig_addr, len, pgoff, flags); | 357 | addr = get_area(NULL, orig_addr, len, pgoff, flags); |
355 | 358 | ||
356 | return addr; | 359 | return addr; |
357 | } | 360 | } |
@@ -361,6 +364,7 @@ EXPORT_SYMBOL(get_fb_unmapped_area); | |||
361 | void arch_pick_mmap_layout(struct mm_struct *mm) | 364 | void arch_pick_mmap_layout(struct mm_struct *mm) |
362 | { | 365 | { |
363 | unsigned long random_factor = 0UL; | 366 | unsigned long random_factor = 0UL; |
367 | unsigned long gap; | ||
364 | 368 | ||
365 | if (current->flags & PF_RANDOMIZE) { | 369 | if (current->flags & PF_RANDOMIZE) { |
366 | random_factor = get_random_int(); | 370 | random_factor = get_random_int(); |
@@ -375,9 +379,10 @@ void arch_pick_mmap_layout(struct mm_struct *mm) | |||
375 | * Fall back to the standard layout if the personality | 379 | * Fall back to the standard layout if the personality |
376 | * bit is set, or if the expected stack growth is unlimited: | 380 | * bit is set, or if the expected stack growth is unlimited: |
377 | */ | 381 | */ |
382 | gap = rlimit(RLIMIT_STACK); | ||
378 | if (!test_thread_flag(TIF_32BIT) || | 383 | if (!test_thread_flag(TIF_32BIT) || |
379 | (current->personality & ADDR_COMPAT_LAYOUT) || | 384 | (current->personality & ADDR_COMPAT_LAYOUT) || |
380 | current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY || | 385 | gap == RLIM_INFINITY || |
381 | sysctl_legacy_va_layout) { | 386 | sysctl_legacy_va_layout) { |
382 | mm->mmap_base = TASK_UNMAPPED_BASE + random_factor; | 387 | mm->mmap_base = TASK_UNMAPPED_BASE + random_factor; |
383 | mm->get_unmapped_area = arch_get_unmapped_area; | 388 | mm->get_unmapped_area = arch_get_unmapped_area; |
@@ -385,9 +390,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm) | |||
385 | } else { | 390 | } else { |
386 | /* We know it's 32-bit */ | 391 | /* We know it's 32-bit */ |
387 | unsigned long task_size = STACK_TOP32; | 392 | unsigned long task_size = STACK_TOP32; |
388 | unsigned long gap; | ||
389 | 393 | ||
390 | gap = current->signal->rlim[RLIMIT_STACK].rlim_cur; | ||
391 | if (gap < 128 * 1024 * 1024) | 394 | if (gap < 128 * 1024 * 1024) |
392 | gap = 128 * 1024 * 1024; | 395 | gap = 128 * 1024 * 1024; |
393 | if (gap > (task_size / 6 * 5)) | 396 | if (gap > (task_size / 6 * 5)) |
@@ -399,18 +402,6 @@ void arch_pick_mmap_layout(struct mm_struct *mm) | |||
399 | } | 402 | } |
400 | } | 403 | } |
401 | 404 | ||
402 | SYSCALL_DEFINE1(sparc_brk, unsigned long, brk) | ||
403 | { | ||
404 | /* People could try to be nasty and use ta 0x6d in 32bit programs */ | ||
405 | if (test_thread_flag(TIF_32BIT) && brk >= STACK_TOP32) | ||
406 | return current->mm->brk; | ||
407 | |||
408 | if (unlikely(straddles_64bit_va_hole(current->mm->brk, brk))) | ||
409 | return current->mm->brk; | ||
410 | |||
411 | return sys_brk(brk); | ||
412 | } | ||
413 | |||
414 | /* | 405 | /* |
415 | * sys_pipe() is the normal C calling standard for creating | 406 | * sys_pipe() is the normal C calling standard for creating |
416 | * a pipe. It's not the way unix traditionally does this, though. | 407 | * a pipe. It's not the way unix traditionally does this, though. |
@@ -435,7 +426,7 @@ out: | |||
435 | * This is really horribly ugly. | 426 | * This is really horribly ugly. |
436 | */ | 427 | */ |
437 | 428 | ||
438 | SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, | 429 | SYSCALL_DEFINE6(sparc_ipc, unsigned int, call, int, first, unsigned long, second, |
439 | unsigned long, third, void __user *, ptr, long, fifth) | 430 | unsigned long, third, void __user *, ptr, long, fifth) |
440 | { | 431 | { |
441 | long err; | 432 | long err; |
@@ -519,17 +510,6 @@ out: | |||
519 | return err; | 510 | return err; |
520 | } | 511 | } |
521 | 512 | ||
522 | SYSCALL_DEFINE1(sparc64_newuname, struct new_utsname __user *, name) | ||
523 | { | ||
524 | int ret = sys_newuname(name); | ||
525 | |||
526 | if (current->personality == PER_LINUX32 && !ret) { | ||
527 | ret = (copy_to_user(name->machine, "sparc\0\0", 8) | ||
528 | ? -EFAULT : 0); | ||
529 | } | ||
530 | return ret; | ||
531 | } | ||
532 | |||
533 | SYSCALL_DEFINE1(sparc64_personality, unsigned long, personality) | 513 | SYSCALL_DEFINE1(sparc64_personality, unsigned long, personality) |
534 | { | 514 | { |
535 | int ret; | 515 | int ret; |
@@ -568,23 +548,13 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, | |||
568 | unsigned long, prot, unsigned long, flags, unsigned long, fd, | 548 | unsigned long, prot, unsigned long, flags, unsigned long, fd, |
569 | unsigned long, off) | 549 | unsigned long, off) |
570 | { | 550 | { |
571 | struct file * file = NULL; | 551 | unsigned long retval = -EINVAL; |
572 | unsigned long retval = -EBADF; | ||
573 | 552 | ||
574 | if (!(flags & MAP_ANONYMOUS)) { | 553 | if ((off + PAGE_ALIGN(len)) < off) |
575 | file = fget(fd); | 554 | goto out; |
576 | if (!file) | 555 | if (off & ~PAGE_MASK) |
577 | goto out; | 556 | goto out; |
578 | } | 557 | retval = sys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT); |
579 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
580 | len = PAGE_ALIGN(len); | ||
581 | |||
582 | down_write(¤t->mm->mmap_sem); | ||
583 | retval = do_mmap(file, addr, len, prot, flags, off); | ||
584 | up_write(¤t->mm->mmap_sem); | ||
585 | |||
586 | if (file) | ||
587 | fput(file); | ||
588 | out: | 558 | out: |
589 | return retval; | 559 | return retval; |
590 | } | 560 | } |
@@ -614,12 +584,6 @@ SYSCALL_DEFINE5(64_mremap, unsigned long, addr, unsigned long, old_len, | |||
614 | 584 | ||
615 | if (test_thread_flag(TIF_32BIT)) | 585 | if (test_thread_flag(TIF_32BIT)) |
616 | goto out; | 586 | goto out; |
617 | if (unlikely(new_len >= VA_EXCLUDE_START)) | ||
618 | goto out; | ||
619 | if (unlikely(sparc_mmap_check(addr, old_len))) | ||
620 | goto out; | ||
621 | if (unlikely(sparc_mmap_check(new_addr, new_len))) | ||
622 | goto out; | ||
623 | 587 | ||
624 | down_write(¤t->mm->mmap_sem); | 588 | down_write(¤t->mm->mmap_sem); |
625 | ret = do_mremap(addr, old_len, new_len, flags, new_addr); | 589 | ret = do_mremap(addr, old_len, new_len, flags, new_addr); |
@@ -790,109 +754,6 @@ SYSCALL_DEFINE5(rt_sigaction, int, sig, const struct sigaction __user *, act, | |||
790 | return ret; | 754 | return ret; |
791 | } | 755 | } |
792 | 756 | ||
793 | /* Invoked by rtrap code to update performance counters in | ||
794 | * user space. | ||
795 | */ | ||
796 | asmlinkage void update_perfctrs(void) | ||
797 | { | ||
798 | unsigned long pic, tmp; | ||
799 | |||
800 | read_pic(pic); | ||
801 | tmp = (current_thread_info()->kernel_cntd0 += (unsigned int)pic); | ||
802 | __put_user(tmp, current_thread_info()->user_cntd0); | ||
803 | tmp = (current_thread_info()->kernel_cntd1 += (pic >> 32)); | ||
804 | __put_user(tmp, current_thread_info()->user_cntd1); | ||
805 | reset_pic(); | ||
806 | } | ||
807 | |||
808 | SYSCALL_DEFINE4(perfctr, int, opcode, unsigned long, arg0, | ||
809 | unsigned long, arg1, unsigned long, arg2) | ||
810 | { | ||
811 | int err = 0; | ||
812 | |||
813 | switch(opcode) { | ||
814 | case PERFCTR_ON: | ||
815 | current_thread_info()->pcr_reg = arg2; | ||
816 | current_thread_info()->user_cntd0 = (u64 __user *) arg0; | ||
817 | current_thread_info()->user_cntd1 = (u64 __user *) arg1; | ||
818 | current_thread_info()->kernel_cntd0 = | ||
819 | current_thread_info()->kernel_cntd1 = 0; | ||
820 | write_pcr(arg2); | ||
821 | reset_pic(); | ||
822 | set_thread_flag(TIF_PERFCTR); | ||
823 | break; | ||
824 | |||
825 | case PERFCTR_OFF: | ||
826 | err = -EINVAL; | ||
827 | if (test_thread_flag(TIF_PERFCTR)) { | ||
828 | current_thread_info()->user_cntd0 = | ||
829 | current_thread_info()->user_cntd1 = NULL; | ||
830 | current_thread_info()->pcr_reg = 0; | ||
831 | write_pcr(0); | ||
832 | clear_thread_flag(TIF_PERFCTR); | ||
833 | err = 0; | ||
834 | } | ||
835 | break; | ||
836 | |||
837 | case PERFCTR_READ: { | ||
838 | unsigned long pic, tmp; | ||
839 | |||
840 | if (!test_thread_flag(TIF_PERFCTR)) { | ||
841 | err = -EINVAL; | ||
842 | break; | ||
843 | } | ||
844 | read_pic(pic); | ||
845 | tmp = (current_thread_info()->kernel_cntd0 += (unsigned int)pic); | ||
846 | err |= __put_user(tmp, current_thread_info()->user_cntd0); | ||
847 | tmp = (current_thread_info()->kernel_cntd1 += (pic >> 32)); | ||
848 | err |= __put_user(tmp, current_thread_info()->user_cntd1); | ||
849 | reset_pic(); | ||
850 | break; | ||
851 | } | ||
852 | |||
853 | case PERFCTR_CLRPIC: | ||
854 | if (!test_thread_flag(TIF_PERFCTR)) { | ||
855 | err = -EINVAL; | ||
856 | break; | ||
857 | } | ||
858 | current_thread_info()->kernel_cntd0 = | ||
859 | current_thread_info()->kernel_cntd1 = 0; | ||
860 | reset_pic(); | ||
861 | break; | ||
862 | |||
863 | case PERFCTR_SETPCR: { | ||
864 | u64 __user *user_pcr = (u64 __user *)arg0; | ||
865 | |||
866 | if (!test_thread_flag(TIF_PERFCTR)) { | ||
867 | err = -EINVAL; | ||
868 | break; | ||
869 | } | ||
870 | err |= __get_user(current_thread_info()->pcr_reg, user_pcr); | ||
871 | write_pcr(current_thread_info()->pcr_reg); | ||
872 | current_thread_info()->kernel_cntd0 = | ||
873 | current_thread_info()->kernel_cntd1 = 0; | ||
874 | reset_pic(); | ||
875 | break; | ||
876 | } | ||
877 | |||
878 | case PERFCTR_GETPCR: { | ||
879 | u64 __user *user_pcr = (u64 __user *)arg0; | ||
880 | |||
881 | if (!test_thread_flag(TIF_PERFCTR)) { | ||
882 | err = -EINVAL; | ||
883 | break; | ||
884 | } | ||
885 | err |= __put_user(current_thread_info()->pcr_reg, user_pcr); | ||
886 | break; | ||
887 | } | ||
888 | |||
889 | default: | ||
890 | err = -EINVAL; | ||
891 | break; | ||
892 | }; | ||
893 | return err; | ||
894 | } | ||
895 | |||
896 | /* | 757 | /* |
897 | * Do a system call from kernel instead of calling sys_execve so we | 758 | * Do a system call from kernel instead of calling sys_execve so we |
898 | * end up with proper pt_regs. | 759 | * end up with proper pt_regs. |