aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/sys_sparc_64.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /arch/sparc/kernel/sys_sparc_64.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (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.c173
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:
317unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, unsigned long len, unsigned long pgoff, unsigned long flags) 316unsigned 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);
361void arch_pick_mmap_layout(struct mm_struct *mm) 364void 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
402SYSCALL_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
438SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, 429SYSCALL_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
522SYSCALL_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
533SYSCALL_DEFINE1(sparc64_personality, unsigned long, personality) 513SYSCALL_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(&current->mm->mmap_sem);
583 retval = do_mmap(file, addr, len, prot, flags, off);
584 up_write(&current->mm->mmap_sem);
585
586 if (file)
587 fput(file);
588out: 558out:
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(&current->mm->mmap_sem); 588 down_write(&current->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 */
796asmlinkage 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
808SYSCALL_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.