diff options
| author | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-01-06 17:31:35 -0500 |
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-01-06 17:32:03 -0500 |
| commit | 4ec3eb13634529c0bc7466658d84d0bbe3244aea (patch) | |
| tree | b491daac2ccfc7b8ca88e171a43f66888463568a /arch/tile/kernel/ptrace.c | |
| parent | 24056f525051a9e186af28904b396320e18bf9a0 (diff) | |
| parent | 15095bb0fe779c0403091bda7adce5fb3bb9ca35 (diff) | |
Merge branch 'smp' into misc
Conflicts:
arch/arm/kernel/entry-armv.S
arch/arm/mm/ioremap.c
Diffstat (limited to 'arch/tile/kernel/ptrace.c')
| -rw-r--r-- | arch/tile/kernel/ptrace.c | 39 |
1 files changed, 21 insertions, 18 deletions
diff --git a/arch/tile/kernel/ptrace.c b/arch/tile/kernel/ptrace.c index 9cd29884c09f..e92e40527d6d 100644 --- a/arch/tile/kernel/ptrace.c +++ b/arch/tile/kernel/ptrace.c | |||
| @@ -50,10 +50,10 @@ long arch_ptrace(struct task_struct *child, long request, | |||
| 50 | { | 50 | { |
| 51 | unsigned long __user *datap = (long __user __force *)data; | 51 | unsigned long __user *datap = (long __user __force *)data; |
| 52 | unsigned long tmp; | 52 | unsigned long tmp; |
| 53 | int i; | ||
| 54 | long ret = -EIO; | 53 | long ret = -EIO; |
| 55 | unsigned long *childregs; | ||
| 56 | char *childreg; | 54 | char *childreg; |
| 55 | struct pt_regs copyregs; | ||
| 56 | int ex1_offset; | ||
| 57 | 57 | ||
| 58 | switch (request) { | 58 | switch (request) { |
| 59 | 59 | ||
| @@ -80,6 +80,16 @@ long arch_ptrace(struct task_struct *child, long request, | |||
| 80 | if (addr >= PTREGS_SIZE) | 80 | if (addr >= PTREGS_SIZE) |
| 81 | break; | 81 | break; |
| 82 | childreg = (char *)task_pt_regs(child) + addr; | 82 | childreg = (char *)task_pt_regs(child) + addr; |
| 83 | |||
| 84 | /* Guard against overwrites of the privilege level. */ | ||
| 85 | ex1_offset = PTREGS_OFFSET_EX1; | ||
| 86 | #if defined(CONFIG_COMPAT) && defined(__BIG_ENDIAN) | ||
| 87 | if (is_compat_task()) /* point at low word */ | ||
| 88 | ex1_offset += sizeof(compat_long_t); | ||
| 89 | #endif | ||
| 90 | if (addr == ex1_offset) | ||
| 91 | data = PL_ICS_EX1(USER_PL, EX1_ICS(data)); | ||
| 92 | |||
| 83 | #ifdef CONFIG_COMPAT | 93 | #ifdef CONFIG_COMPAT |
| 84 | if (is_compat_task()) { | 94 | if (is_compat_task()) { |
| 85 | if (addr & (sizeof(compat_long_t)-1)) | 95 | if (addr & (sizeof(compat_long_t)-1)) |
| @@ -96,26 +106,19 @@ long arch_ptrace(struct task_struct *child, long request, | |||
| 96 | break; | 106 | break; |
| 97 | 107 | ||
| 98 | case PTRACE_GETREGS: /* Get all registers from the child. */ | 108 | case PTRACE_GETREGS: /* Get all registers from the child. */ |
| 99 | if (!access_ok(VERIFY_WRITE, datap, PTREGS_SIZE)) | 109 | if (copy_to_user(datap, task_pt_regs(child), |
| 100 | break; | 110 | sizeof(struct pt_regs)) == 0) { |
| 101 | childregs = (long *)task_pt_regs(child); | 111 | ret = 0; |
| 102 | for (i = 0; i < sizeof(struct pt_regs)/sizeof(unsigned long); | ||
| 103 | ++i) { | ||
| 104 | ret = __put_user(childregs[i], &datap[i]); | ||
| 105 | if (ret != 0) | ||
| 106 | break; | ||
| 107 | } | 112 | } |
| 108 | break; | 113 | break; |
| 109 | 114 | ||
| 110 | case PTRACE_SETREGS: /* Set all registers in the child. */ | 115 | case PTRACE_SETREGS: /* Set all registers in the child. */ |
| 111 | if (!access_ok(VERIFY_READ, datap, PTREGS_SIZE)) | 116 | if (copy_from_user(©regs, datap, |
| 112 | break; | 117 | sizeof(struct pt_regs)) == 0) { |
| 113 | childregs = (long *)task_pt_regs(child); | 118 | copyregs.ex1 = |
| 114 | for (i = 0; i < sizeof(struct pt_regs)/sizeof(unsigned long); | 119 | PL_ICS_EX1(USER_PL, EX1_ICS(copyregs.ex1)); |
| 115 | ++i) { | 120 | *task_pt_regs(child) = copyregs; |
| 116 | ret = __get_user(childregs[i], &datap[i]); | 121 | ret = 0; |
| 117 | if (ret != 0) | ||
| 118 | break; | ||
| 119 | } | 122 | } |
| 120 | break; | 123 | break; |
| 121 | 124 | ||
