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]: Make use of the new fs/compat_binfmt_elf.c
[SPARC64]: Make use of compat_sys_ptrace()

Manually fixed trivial delete/modift conflict in arch/sparc64/kernel/binfmt_elf32.c

+168 -314
+1 -7
arch/sparc64/Kconfig
··· 383 383 bool 384 384 depends on SPARC32_COMPAT 385 385 default y 386 - 387 - config BINFMT_ELF32 388 - bool "Kernel support for 32-bit ELF binaries" 389 - depends on SPARC32_COMPAT 390 - help 391 - This allows you to run 32-bit Linux/ELF binaries on your Ultra. 392 - Everybody wants this; say Y. 386 + select COMPAT_BINFMT_ELF 393 387 394 388 config BINFMT_AOUT32 395 389 bool "Kernel support for 32-bit (ie. SunOS) a.out binaries"
-1
arch/sparc64/kernel/Makefile
··· 21 21 obj-$(CONFIG_PCI_MSI) += pci_msi.o 22 22 obj-$(CONFIG_SMP) += smp.o trampoline.o hvtramp.o 23 23 obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o 24 - obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o 25 24 obj-$(CONFIG_BINFMT_AOUT32) += binfmt_aout32.o 26 25 obj-$(CONFIG_MODULES) += module.o 27 26 obj-$(CONFIG_US3_FREQ) += us3_cpufreq.o
-134
arch/sparc64/kernel/binfmt_elf32.c
··· 1 - /* 2 - * binfmt_elf32.c: Support 32-bit Sparc ELF binaries on Ultra. 3 - * 4 - * Copyright (C) 1995, 1996, 1997, 1998, 2008 David S. Miller (davem@davemloft.net) 5 - * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek (jj@ultra.linux.cz) 6 - */ 7 - 8 - #define ELF_ARCH EM_SPARC 9 - #define ELF_CLASS ELFCLASS32 10 - #define ELF_DATA ELFDATA2MSB; 11 - 12 - /* Format is: 13 - * G0 --> G7 14 - * O0 --> O7 15 - * L0 --> L7 16 - * I0 --> I7 17 - * PSR, PC, nPC, Y, WIM, TBR 18 - */ 19 - typedef unsigned int elf_greg_t; 20 - #define ELF_NGREG 38 21 - typedef elf_greg_t elf_gregset_t[ELF_NGREG]; 22 - 23 - typedef struct { 24 - union { 25 - unsigned int pr_regs[32]; 26 - unsigned long pr_dregs[16]; 27 - } pr_fr; 28 - unsigned int __unused; 29 - unsigned int pr_fsr; 30 - unsigned char pr_qcnt; 31 - unsigned char pr_q_entrysize; 32 - unsigned char pr_en; 33 - unsigned int pr_q[64]; 34 - } elf_fpregset_t; 35 - 36 - /* UltraSparc extensions. Still unused, but will be eventually. */ 37 - typedef struct { 38 - unsigned int pr_type; 39 - unsigned int pr_align; 40 - union { 41 - struct { 42 - union { 43 - unsigned int pr_regs[32]; 44 - unsigned long pr_dregs[16]; 45 - long double pr_qregs[8]; 46 - } pr_xfr; 47 - } pr_v8p; 48 - unsigned int pr_xfsr; 49 - unsigned int pr_fprs; 50 - unsigned int pr_xg[8]; 51 - unsigned int pr_xo[8]; 52 - unsigned long pr_tstate; 53 - unsigned int pr_filler[8]; 54 - } pr_un; 55 - } elf_xregset_t; 56 - 57 - #define elf_check_arch(x) (((x)->e_machine == EM_SPARC) || ((x)->e_machine == EM_SPARC32PLUS)) 58 - 59 - #define ELF_ET_DYN_BASE 0x70000000 60 - 61 - 62 - #include <asm/processor.h> 63 - #include <linux/module.h> 64 - #include <linux/elfcore.h> 65 - #include <linux/compat.h> 66 - 67 - #define elf_prstatus elf_prstatus32 68 - struct elf_prstatus32 69 - { 70 - struct elf_siginfo pr_info; /* Info associated with signal */ 71 - short pr_cursig; /* Current signal */ 72 - unsigned int pr_sigpend; /* Set of pending signals */ 73 - unsigned int pr_sighold; /* Set of held signals */ 74 - pid_t pr_pid; 75 - pid_t pr_ppid; 76 - pid_t pr_pgrp; 77 - pid_t pr_sid; 78 - struct compat_timeval pr_utime; /* User time */ 79 - struct compat_timeval pr_stime; /* System time */ 80 - struct compat_timeval pr_cutime; /* Cumulative user time */ 81 - struct compat_timeval pr_cstime; /* Cumulative system time */ 82 - elf_gregset_t pr_reg; /* GP registers */ 83 - int pr_fpvalid; /* True if math co-processor being used. */ 84 - }; 85 - 86 - #define elf_prpsinfo elf_prpsinfo32 87 - struct elf_prpsinfo32 88 - { 89 - char pr_state; /* numeric process state */ 90 - char pr_sname; /* char for pr_state */ 91 - char pr_zomb; /* zombie */ 92 - char pr_nice; /* nice val */ 93 - unsigned int pr_flag; /* flags */ 94 - u16 pr_uid; 95 - u16 pr_gid; 96 - pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid; 97 - /* Lots missing */ 98 - char pr_fname[16]; /* filename of executable */ 99 - char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */ 100 - }; 101 - 102 - #include <linux/highuid.h> 103 - 104 - #undef NEW_TO_OLD_UID 105 - #undef NEW_TO_OLD_GID 106 - #define NEW_TO_OLD_UID(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid) 107 - #define NEW_TO_OLD_GID(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid) 108 - 109 - #include <linux/time.h> 110 - 111 - #undef cputime_to_timeval 112 - #define cputime_to_timeval cputime_to_compat_timeval 113 - static inline void 114 - cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value) 115 - { 116 - unsigned long jiffies = cputime_to_jiffies(cputime); 117 - value->tv_usec = (jiffies % HZ) * (1000000L / HZ); 118 - value->tv_sec = jiffies / HZ; 119 - } 120 - 121 - #undef start_thread 122 - #define start_thread start_thread32 123 - #define init_elf_binfmt init_elf32_binfmt 124 - 125 - MODULE_DESCRIPTION("Binary format loader for compatibility with 32bit SparcLinux binaries on the Ultra"); 126 - MODULE_AUTHOR("Eric Youngdale, David S. Miller, Jakub Jelinek"); 127 - 128 - #undef MODULE_DESCRIPTION 129 - #undef MODULE_AUTHOR 130 - 131 - #undef TASK_SIZE 132 - #define TASK_SIZE STACK_TOP32 133 - 134 - #include "../../../fs/binfmt_elf.c"
+113 -163
arch/sparc64/kernel/ptrace.c
··· 684 684 return &user_sparc64_view; 685 685 } 686 686 687 - long arch_ptrace(struct task_struct *child, long request, long addr, long data) 687 + struct compat_fps { 688 + unsigned int regs[32]; 689 + unsigned int fsr; 690 + unsigned int flags; 691 + unsigned int extra; 692 + unsigned int fpqd; 693 + struct compat_fq { 694 + unsigned int insnaddr; 695 + unsigned int insn; 696 + } fpq[16]; 697 + }; 698 + 699 + long compat_arch_ptrace(struct task_struct *child, compat_long_t request, 700 + compat_ulong_t caddr, compat_ulong_t cdata) 688 701 { 689 - long addr2 = task_pt_regs(current)->u_regs[UREG_I4]; 690 - const struct user_regset_view *view; 702 + const struct user_regset_view *view = task_user_regset_view(child); 703 + compat_ulong_t caddr2 = task_pt_regs(current)->u_regs[UREG_I4]; 704 + struct pt_regs32 __user *pregs; 705 + struct compat_fps __user *fps; 706 + unsigned long addr2 = caddr2; 707 + unsigned long addr = caddr; 708 + unsigned long data = cdata; 691 709 int ret; 692 710 693 - if (test_thread_flag(TIF_32BIT)) 694 - addr2 &= 0xffffffffUL; 711 + pregs = (struct pt_regs32 __user *) addr; 712 + fps = (struct compat_fps __user *) addr; 695 713 696 - view = task_user_regset_view(child); 697 - 698 - switch(request) { 714 + switch (request) { 699 715 case PTRACE_PEEKUSR: 700 716 ret = (addr != 0) ? -EIO : 0; 701 717 break; 702 718 703 - case PTRACE_PEEKTEXT: /* read word at location addr. */ 704 - case PTRACE_PEEKDATA: { 705 - unsigned long tmp64; 706 - unsigned int tmp32; 707 - int copied; 708 - 709 - ret = -EIO; 710 - if (test_thread_flag(TIF_32BIT)) { 711 - copied = access_process_vm(child, addr, 712 - &tmp32, sizeof(tmp32), 0); 713 - if (copied == sizeof(tmp32)) 714 - ret = put_user(tmp32, 715 - (unsigned int __user *) data); 716 - } else { 717 - copied = access_process_vm(child, addr, 718 - &tmp64, sizeof(tmp64), 0); 719 - if (copied == sizeof(tmp64)) 720 - ret = put_user(tmp64, 721 - (unsigned long __user *) data); 722 - } 723 - break; 724 - } 725 - 726 - case PTRACE_POKETEXT: /* write the word at location addr. */ 727 - case PTRACE_POKEDATA: { 728 - unsigned long tmp64; 729 - unsigned int tmp32; 730 - int copied; 731 - 732 - ret = -EIO; 733 - if (test_thread_flag(TIF_32BIT)) { 734 - tmp32 = data; 735 - copied = access_process_vm(child, addr, 736 - &tmp32, sizeof(tmp32), 1); 737 - if (copied == sizeof(tmp32)) 738 - ret = 0; 739 - } else { 740 - tmp64 = data; 741 - copied = access_process_vm(child, addr, 742 - &tmp64, sizeof(tmp64), 1); 743 - if (copied == sizeof(tmp64)) 744 - ret = 0; 745 - } 746 - break; 747 - } 748 - 749 - case PTRACE_GETREGS: { 750 - struct pt_regs32 __user *pregs = 751 - (struct pt_regs32 __user *) addr; 752 - 719 + case PTRACE_GETREGS: 753 720 ret = copy_regset_to_user(child, view, REGSET_GENERAL, 754 721 32 * sizeof(u32), 755 722 4 * sizeof(u32), ··· 727 760 15 * sizeof(u32), 728 761 &pregs->u_regs[0]); 729 762 break; 730 - } 731 763 732 - case PTRACE_GETREGS64: { 733 - struct pt_regs __user *pregs = (struct pt_regs __user *) addr; 734 - 735 - ret = copy_regset_to_user(child, view, REGSET_GENERAL, 736 - 1 * sizeof(u64), 737 - 15 * sizeof(u64), 738 - &pregs->u_regs[0]); 739 - if (!ret) { 740 - /* XXX doesn't handle 'y' register correctly XXX */ 741 - ret = copy_regset_to_user(child, view, REGSET_GENERAL, 742 - 32 * sizeof(u64), 743 - 4 * sizeof(u64), 744 - &pregs->tstate); 745 - } 746 - break; 747 - } 748 - 749 - case PTRACE_SETREGS: { 750 - struct pt_regs32 __user *pregs = 751 - (struct pt_regs32 __user *) addr; 752 - 764 + case PTRACE_SETREGS: 753 765 ret = copy_regset_from_user(child, view, REGSET_GENERAL, 754 766 32 * sizeof(u32), 755 767 4 * sizeof(u32), ··· 739 793 15 * sizeof(u32), 740 794 &pregs->u_regs[0]); 741 795 break; 742 - } 743 796 744 - case PTRACE_SETREGS64: { 745 - struct pt_regs __user *pregs = (struct pt_regs __user *) addr; 746 - 747 - ret = copy_regset_from_user(child, view, REGSET_GENERAL, 748 - 1 * sizeof(u64), 749 - 15 * sizeof(u64), 750 - &pregs->u_regs[0]); 751 - if (!ret) { 752 - /* XXX doesn't handle 'y' register correctly XXX */ 753 - ret = copy_regset_from_user(child, view, REGSET_GENERAL, 754 - 32 * sizeof(u64), 755 - 4 * sizeof(u64), 756 - &pregs->tstate); 757 - } 758 - break; 759 - } 760 - 761 - case PTRACE_GETFPREGS: { 762 - struct fps { 763 - unsigned int regs[32]; 764 - unsigned int fsr; 765 - unsigned int flags; 766 - unsigned int extra; 767 - unsigned int fpqd; 768 - struct fq { 769 - unsigned int insnaddr; 770 - unsigned int insn; 771 - } fpq[16]; 772 - }; 773 - struct fps __user *fps = (struct fps __user *) addr; 774 - 797 + case PTRACE_GETFPREGS: 775 798 ret = copy_regset_to_user(child, view, REGSET_FP, 776 799 0 * sizeof(u32), 777 800 32 * sizeof(u32), ··· 758 843 ret = -EFAULT; 759 844 } 760 845 break; 761 - } 762 846 763 - case PTRACE_GETFPREGS64: { 764 - struct fps { 765 - unsigned int regs[64]; 766 - unsigned long fsr; 767 - }; 768 - struct fps __user *fps = (struct fps __user *) addr; 769 - 770 - ret = copy_regset_to_user(child, view, REGSET_FP, 771 - 0 * sizeof(u64), 772 - 33 * sizeof(u64), 773 - fps); 774 - break; 775 - } 776 - 777 - case PTRACE_SETFPREGS: { 778 - struct fps { 779 - unsigned int regs[32]; 780 - unsigned int fsr; 781 - unsigned int flags; 782 - unsigned int extra; 783 - unsigned int fpqd; 784 - struct fq { 785 - unsigned int insnaddr; 786 - unsigned int insn; 787 - } fpq[16]; 788 - }; 789 - struct fps __user *fps = (struct fps __user *) addr; 790 - 847 + case PTRACE_SETFPREGS: 791 848 ret = copy_regset_from_user(child, view, REGSET_FP, 792 849 0 * sizeof(u32), 793 850 32 * sizeof(u32), ··· 770 883 1 * sizeof(u32), 771 884 &fps->fsr); 772 885 break; 773 - } 774 - 775 - case PTRACE_SETFPREGS64: { 776 - struct fps { 777 - unsigned int regs[64]; 778 - unsigned long fsr; 779 - }; 780 - struct fps __user *fps = (struct fps __user *) addr; 781 - 782 - ret = copy_regset_to_user(child, view, REGSET_FP, 783 - 0 * sizeof(u64), 784 - 33 * sizeof(u64), 785 - fps); 786 - break; 787 - } 788 886 789 887 case PTRACE_READTEXT: 790 888 case PTRACE_READDATA: ··· 791 919 ret = -EIO; 792 920 break; 793 921 794 - case PTRACE_GETEVENTMSG: { 795 - if (test_thread_flag(TIF_32BIT)) 796 - ret = put_user(child->ptrace_message, 797 - (unsigned int __user *) data); 798 - else 799 - ret = put_user(child->ptrace_message, 800 - (unsigned long __user *) data); 922 + default: 923 + ret = compat_ptrace_request(child, request, addr, data); 801 924 break; 802 925 } 926 + 927 + return ret; 928 + } 929 + 930 + struct fps { 931 + unsigned int regs[64]; 932 + unsigned long fsr; 933 + }; 934 + 935 + long arch_ptrace(struct task_struct *child, long request, long addr, long data) 936 + { 937 + const struct user_regset_view *view = task_user_regset_view(child); 938 + struct pt_regs __user *pregs = (struct pt_regs __user *) addr; 939 + unsigned long addr2 = task_pt_regs(current)->u_regs[UREG_I4]; 940 + struct fps __user *fps = (struct fps __user *) addr; 941 + int ret; 942 + 943 + switch (request) { 944 + case PTRACE_PEEKUSR: 945 + ret = (addr != 0) ? -EIO : 0; 946 + break; 947 + 948 + case PTRACE_GETREGS64: 949 + ret = copy_regset_to_user(child, view, REGSET_GENERAL, 950 + 1 * sizeof(u64), 951 + 15 * sizeof(u64), 952 + &pregs->u_regs[0]); 953 + if (!ret) { 954 + /* XXX doesn't handle 'y' register correctly XXX */ 955 + ret = copy_regset_to_user(child, view, REGSET_GENERAL, 956 + 32 * sizeof(u64), 957 + 4 * sizeof(u64), 958 + &pregs->tstate); 959 + } 960 + break; 961 + 962 + case PTRACE_SETREGS64: 963 + ret = copy_regset_from_user(child, view, REGSET_GENERAL, 964 + 1 * sizeof(u64), 965 + 15 * sizeof(u64), 966 + &pregs->u_regs[0]); 967 + if (!ret) { 968 + /* XXX doesn't handle 'y' register correctly XXX */ 969 + ret = copy_regset_from_user(child, view, REGSET_GENERAL, 970 + 32 * sizeof(u64), 971 + 4 * sizeof(u64), 972 + &pregs->tstate); 973 + } 974 + break; 975 + 976 + case PTRACE_GETFPREGS64: 977 + ret = copy_regset_to_user(child, view, REGSET_FP, 978 + 0 * sizeof(u64), 979 + 33 * sizeof(u64), 980 + fps); 981 + break; 982 + 983 + case PTRACE_SETFPREGS64: 984 + ret = copy_regset_to_user(child, view, REGSET_FP, 985 + 0 * sizeof(u64), 986 + 33 * sizeof(u64), 987 + fps); 988 + break; 989 + 990 + case PTRACE_READTEXT: 991 + case PTRACE_READDATA: 992 + ret = ptrace_readdata(child, addr, 993 + (char __user *)addr2, data); 994 + if (ret == data) 995 + ret = 0; 996 + else if (ret >= 0) 997 + ret = -EIO; 998 + break; 999 + 1000 + case PTRACE_WRITETEXT: 1001 + case PTRACE_WRITEDATA: 1002 + ret = ptrace_writedata(child, (char __user *) addr2, 1003 + addr, data); 1004 + if (ret == data) 1005 + ret = 0; 1006 + else if (ret >= 0) 1007 + ret = -EIO; 1008 + break; 803 1009 804 1010 default: 805 1011 ret = ptrace_request(child, request, addr, data);
+1 -1
arch/sparc64/kernel/systbls.S
··· 23 23 /*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys32_chown16, sys32_mknod 24 24 /*15*/ .word sys_chmod, sys32_lchown16, sparc_brk, sys32_perfctr, sys32_lseek 25 25 /*20*/ .word sys_getpid, sys_capget, sys_capset, sys32_setuid16, sys32_getuid16 26 - /*25*/ .word sys32_vmsplice, sys_ptrace, sys_alarm, sys32_sigaltstack, sys32_pause 26 + /*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, sys32_sigaltstack, sys32_pause 27 27 /*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice 28 28 .word sys_chown, sys_sync, sys32_kill, compat_sys_newstat, sys32_sendfile 29 29 /*40*/ .word compat_sys_newlstat, sys_dup, sys_pipe, compat_sys_times, sys_getuid
+51 -8
include/asm-sparc64/elf.h
··· 75 75 /* 76 76 * These are used to set parameters in the core dumps. 77 77 */ 78 - #ifndef ELF_ARCH 79 78 #define ELF_ARCH EM_SPARCV9 80 79 #define ELF_CLASS ELFCLASS64 81 80 #define ELF_DATA ELFDATA2MSB ··· 99 100 unsigned long pr_gsr; 100 101 unsigned long pr_fprs; 101 102 } elf_fpregset_t; 102 - #endif 103 + 104 + /* Format of 32-bit elf_gregset_t is: 105 + * G0 --> G7 106 + * O0 --> O7 107 + * L0 --> L7 108 + * I0 --> I7 109 + * PSR, PC, nPC, Y, WIM, TBR 110 + */ 111 + typedef unsigned int compat_elf_greg_t; 112 + #define COMPAT_ELF_NGREG 38 113 + typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG]; 114 + 115 + typedef struct { 116 + union { 117 + unsigned int pr_regs[32]; 118 + unsigned long pr_dregs[16]; 119 + } pr_fr; 120 + unsigned int __unused; 121 + unsigned int pr_fsr; 122 + unsigned char pr_qcnt; 123 + unsigned char pr_q_entrysize; 124 + unsigned char pr_en; 125 + unsigned int pr_q[64]; 126 + } compat_elf_fpregset_t; 127 + 128 + /* UltraSparc extensions. Still unused, but will be eventually. */ 129 + typedef struct { 130 + unsigned int pr_type; 131 + unsigned int pr_align; 132 + union { 133 + struct { 134 + union { 135 + unsigned int pr_regs[32]; 136 + unsigned long pr_dregs[16]; 137 + long double pr_qregs[8]; 138 + } pr_xfr; 139 + } pr_v8p; 140 + unsigned int pr_xfsr; 141 + unsigned int pr_fprs; 142 + unsigned int pr_xg[8]; 143 + unsigned int pr_xo[8]; 144 + unsigned long pr_tstate; 145 + unsigned int pr_filler[8]; 146 + } pr_un; 147 + } elf_xregset_t; 103 148 104 149 /* 105 150 * This is used to ensure we don't load something for the wrong architecture. 106 151 */ 107 - #ifndef elf_check_arch 108 - #define elf_check_arch(x) ((x)->e_machine == ELF_ARCH) /* Might be EM_SPARCV9 or EM_SPARC */ 109 - #endif 152 + #define elf_check_arch(x) ((x)->e_machine == ELF_ARCH) 153 + #define compat_elf_check_arch(x) ((x)->e_machine == EM_SPARC || \ 154 + (x)->e_machine == EM_SPARC32PLUS) 155 + #define compat_start_thread start_thread32 110 156 111 157 #define USE_ELF_CORE_DUMP 112 158 #define ELF_EXEC_PAGESIZE PAGE_SIZE ··· 161 117 the loader. We need to make sure that it is out of the way of the program 162 118 that it will "exec", and that there is sufficient room for the brk. */ 163 119 164 - #ifndef ELF_ET_DYN_BASE 165 - #define ELF_ET_DYN_BASE 0x0000010000000000UL 166 - #endif 120 + #define ELF_ET_DYN_BASE 0x0000010000000000UL 121 + #define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL 167 122 168 123 169 124 /* This yields a mask that user programs can use to figure out what
+2
include/asm-sparc64/ptrace.h
··· 95 95 96 96 #ifdef __KERNEL__ 97 97 98 + #define __ARCH_WANT_COMPAT_SYS_PTRACE 99 + 98 100 #define force_successful_syscall_return() \ 99 101 do { current_thread_info()->syscall_noerror = 1; \ 100 102 } while (0)