linux/arch/mips/kernel/ptrace.c
<<
>>
Prefs
   1/*
   2 * This file is subject to the terms and conditions of the GNU General Public
   3 * License.  See the file "COPYING" in the main directory of this archive
   4 * for more details.
   5 *
   6 * Copyright (C) 1992 Ross Biro
   7 * Copyright (C) Linus Torvalds
   8 * Copyright (C) 1994, 95, 96, 97, 98, 2000 Ralf Baechle
   9 * Copyright (C) 1996 David S. Miller
  10 * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
  11 * Copyright (C) 1999 MIPS Technologies, Inc.
  12 * Copyright (C) 2000 Ulf Carlsson
  13 *
  14 * At this time Linux/MIPS64 only supports syscall tracing, even for 32-bit
  15 * binaries.
  16 */
  17#include <linux/compiler.h>
  18#include <linux/context_tracking.h>
  19#include <linux/elf.h>
  20#include <linux/kernel.h>
  21#include <linux/sched.h>
  22#include <linux/mm.h>
  23#include <linux/errno.h>
  24#include <linux/ptrace.h>
  25#include <linux/regset.h>
  26#include <linux/smp.h>
  27#include <linux/security.h>
  28#include <linux/stddef.h>
  29#include <linux/tracehook.h>
  30#include <linux/audit.h>
  31#include <linux/seccomp.h>
  32#include <linux/ftrace.h>
  33
  34#include <asm/byteorder.h>
  35#include <asm/cpu.h>
  36#include <asm/cpu-info.h>
  37#include <asm/dsp.h>
  38#include <asm/fpu.h>
  39#include <asm/mipsregs.h>
  40#include <asm/mipsmtregs.h>
  41#include <asm/pgtable.h>
  42#include <asm/page.h>
  43#include <asm/syscall.h>
  44#include <asm/uaccess.h>
  45#include <asm/bootinfo.h>
  46#include <asm/reg.h>
  47
  48#define CREATE_TRACE_POINTS
  49#include <trace/events/syscalls.h>
  50
  51static void init_fp_ctx(struct task_struct *target)
  52{
  53        /* If FP has been used then the target already has context */
  54        if (tsk_used_math(target))
  55                return;
  56
  57        /* Begin with data registers set to all 1s... */
  58        memset(&target->thread.fpu.fpr, ~0, sizeof(target->thread.fpu.fpr));
  59
  60        /* ...and FCSR zeroed */
  61        target->thread.fpu.fcr31 = 0;
  62
  63        /*
  64         * Record that the target has "used" math, such that the context
  65         * just initialised, and any modifications made by the caller,
  66         * aren't discarded.
  67         */
  68        set_stopped_child_used_math(target);
  69}
  70
  71/*
  72 * Called by kernel/ptrace.c when detaching..
  73 *
  74 * Make sure single step bits etc are not set.
  75 */
  76void ptrace_disable(struct task_struct *child)
  77{
  78        /* Don't load the watchpoint registers for the ex-child. */
  79        clear_tsk_thread_flag(child, TIF_LOAD_WATCH);
  80}
  81
  82/*
  83 * Read a general register set.  We always use the 64-bit format, even
  84 * for 32-bit kernels and for 32-bit processes on a 64-bit kernel.
  85 * Registers are sign extended to fill the available space.
  86 */
  87int ptrace_getregs(struct task_struct *child, struct user_pt_regs __user *data)
  88{
  89        struct pt_regs *regs;
  90        int i;
  91
  92        if (!access_ok(VERIFY_WRITE, data, 38 * 8))
  93                return -EIO;
  94
  95        regs = task_pt_regs(child);
  96
  97        for (i = 0; i < 32; i++)
  98                __put_user((long)regs->regs[i], (__s64 __user *)&data->regs[i]);
  99        __put_user((long)regs->lo, (__s64 __user *)&data->lo);
 100        __put_user((long)regs->hi, (__s64 __user *)&data->hi);
 101        __put_user((long)regs->cp0_epc, (__s64 __user *)&data->cp0_epc);
 102        __put_user((long)regs->cp0_badvaddr, (__s64 __user *)&data->cp0_badvaddr);
 103        __put_user((long)regs->cp0_status, (__s64 __user *)&data->cp0_status);
 104        __put_user((long)regs->cp0_cause, (__s64 __user *)&data->cp0_cause);
 105
 106        return 0;
 107}
 108
 109/*
 110 * Write a general register set.  As for PTRACE_GETREGS, we always use
 111 * the 64-bit format.  On a 32-bit kernel only the lower order half
 112 * (according to endianness) will be used.
 113 */
 114int ptrace_setregs(struct task_struct *child, struct user_pt_regs __user *data)
 115{
 116        struct pt_regs *regs;
 117        int i;
 118
 119        if (!access_ok(VERIFY_READ, data, 38 * 8))
 120                return -EIO;
 121
 122        regs = task_pt_regs(child);
 123
 124        for (i = 0; i < 32; i++)
 125                __get_user(regs->regs[i], (__s64 __user *)&data->regs[i]);
 126        __get_user(regs->lo, (__s64 __user *)&data->lo);
 127        __get_user(regs->hi, (__s64 __user *)&data->hi);
 128        __get_user(regs->cp0_epc, (__s64 __user *)&data->cp0_epc);
 129
 130        /* badvaddr, status, and cause may not be written.  */
 131
 132        return 0;
 133}
 134
 135int ptrace_getfpregs(struct task_struct *child, __u32 __user *data)
 136{
 137        int i;
 138
 139        if (!access_ok(VERIFY_WRITE, data, 33 * 8))
 140                return -EIO;
 141
 142        if (tsk_used_math(child)) {
 143                union fpureg *fregs = get_fpu_regs(child);
 144                for (i = 0; i < 32; i++)
 145                        __put_user(get_fpr64(&fregs[i], 0),
 146                                   i + (__u64 __user *)data);
 147        } else {
 148                for (i = 0; i < 32; i++)
 149                        __put_user((__u64) -1, i + (__u64 __user *) data);
 150        }
 151
 152        __put_user(child->thread.fpu.fcr31, data + 64);
 153        __put_user(boot_cpu_data.fpu_id, data + 65);
 154
 155        return 0;
 156}
 157
 158int ptrace_setfpregs(struct task_struct *child, __u32 __user *data)
 159{
 160        union fpureg *fregs;
 161        u64 fpr_val;
 162        u32 fcr31;
 163        u32 value;
 164        u32 mask;
 165        int i;
 166
 167        if (!access_ok(VERIFY_READ, data, 33 * 8))
 168                return -EIO;
 169
 170        init_fp_ctx(child);
 171        fregs = get_fpu_regs(child);
 172
 173        for (i = 0; i < 32; i++) {
 174                __get_user(fpr_val, i + (__u64 __user *)data);
 175                set_fpr64(&fregs[i], 0, fpr_val);
 176        }
 177
 178        __get_user(value, data + 64);
 179        fcr31 = child->thread.fpu.fcr31;
 180        mask = boot_cpu_data.fpu_msk31;
 181        child->thread.fpu.fcr31 = (value & ~mask) | (fcr31 & mask);
 182
 183        /* FIR may not be written.  */
 184
 185        return 0;
 186}
 187
 188int ptrace_get_watch_regs(struct task_struct *child,
 189                          struct pt_watch_regs __user *addr)
 190{
 191        enum pt_watch_style style;
 192        int i;
 193
 194        if (!cpu_has_watch || boot_cpu_data.watch_reg_use_cnt == 0)
 195                return -EIO;
 196        if (!access_ok(VERIFY_WRITE, addr, sizeof(struct pt_watch_regs)))
 197                return -EIO;
 198
 199#ifdef CONFIG_32BIT
 200        style = pt_watch_style_mips32;
 201#define WATCH_STYLE mips32
 202#else
 203        style = pt_watch_style_mips64;
 204#define WATCH_STYLE mips64
 205#endif
 206
 207        __put_user(style, &addr->style);
 208        __put_user(boot_cpu_data.watch_reg_use_cnt,
 209                   &addr->WATCH_STYLE.num_valid);
 210        for (i = 0; i < boot_cpu_data.watch_reg_use_cnt; i++) {
 211                __put_user(child->thread.watch.mips3264.watchlo[i],
 212                           &addr->WATCH_STYLE.watchlo[i]);
 213                __put_user(child->thread.watch.mips3264.watchhi[i] & 0xfff,
 214                           &addr->WATCH_STYLE.watchhi[i]);
 215                __put_user(boot_cpu_data.watch_reg_masks[i],
 216                           &addr->WATCH_STYLE.watch_masks[i]);
 217        }
 218        for (; i < 8; i++) {
 219                __put_user(0, &addr->WATCH_STYLE.watchlo[i]);
 220                __put_user(0, &addr->WATCH_STYLE.watchhi[i]);
 221                __put_user(0, &addr->WATCH_STYLE.watch_masks[i]);
 222        }
 223
 224        return 0;
 225}
 226
 227int ptrace_set_watch_regs(struct task_struct *child,
 228                          struct pt_watch_regs __user *addr)
 229{
 230        int i;
 231        int watch_active = 0;
 232        unsigned long lt[NUM_WATCH_REGS];
 233        u16 ht[NUM_WATCH_REGS];
 234
 235        if (!cpu_has_watch || boot_cpu_data.watch_reg_use_cnt == 0)
 236                return -EIO;
 237        if (!access_ok(VERIFY_READ, addr, sizeof(struct pt_watch_regs)))
 238                return -EIO;
 239        /* Check the values. */
 240        for (i = 0; i < boot_cpu_data.watch_reg_use_cnt; i++) {
 241                __get_user(lt[i], &addr->WATCH_STYLE.watchlo[i]);
 242#ifdef CONFIG_32BIT
 243                if (lt[i] & __UA_LIMIT)
 244                        return -EINVAL;
 245#else
 246                if (test_tsk_thread_flag(child, TIF_32BIT_ADDR)) {
 247                        if (lt[i] & 0xffffffff80000000UL)
 248                                return -EINVAL;
 249                } else {
 250                        if (lt[i] & __UA_LIMIT)
 251                                return -EINVAL;
 252                }
 253#endif
 254                __get_user(ht[i], &addr->WATCH_STYLE.watchhi[i]);
 255                if (ht[i] & ~0xff8)
 256                        return -EINVAL;
 257        }
 258        /* Install them. */
 259        for (i = 0; i < boot_cpu_data.watch_reg_use_cnt; i++) {
 260                if (lt[i] & 7)
 261                        watch_active = 1;
 262                child->thread.watch.mips3264.watchlo[i] = lt[i];
 263                /* Set the G bit. */
 264                child->thread.watch.mips3264.watchhi[i] = ht[i];
 265        }
 266
 267        if (watch_active)
 268                set_tsk_thread_flag(child, TIF_LOAD_WATCH);
 269        else
 270                clear_tsk_thread_flag(child, TIF_LOAD_WATCH);
 271
 272        return 0;
 273}
 274
 275/* regset get/set implementations */
 276
 277#if defined(CONFIG_32BIT) || defined(CONFIG_MIPS32_O32)
 278
 279static int gpr32_get(struct task_struct *target,
 280                     const struct user_regset *regset,
 281                     unsigned int pos, unsigned int count,
 282                     void *kbuf, void __user *ubuf)
 283{
 284        struct pt_regs *regs = task_pt_regs(target);
 285        u32 uregs[ELF_NGREG] = {};
 286        unsigned i;
 287
 288        for (i = MIPS32_EF_R1; i <= MIPS32_EF_R31; i++) {
 289                /* k0/k1 are copied as zero. */
 290                if (i == MIPS32_EF_R26 || i == MIPS32_EF_R27)
 291                        continue;
 292
 293                uregs[i] = regs->regs[i - MIPS32_EF_R0];
 294        }
 295
 296        uregs[MIPS32_EF_LO] = regs->lo;
 297        uregs[MIPS32_EF_HI] = regs->hi;
 298        uregs[MIPS32_EF_CP0_EPC] = regs->cp0_epc;
 299        uregs[MIPS32_EF_CP0_BADVADDR] = regs->cp0_badvaddr;
 300        uregs[MIPS32_EF_CP0_STATUS] = regs->cp0_status;
 301        uregs[MIPS32_EF_CP0_CAUSE] = regs->cp0_cause;
 302
 303        return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, 0,
 304                                   sizeof(uregs));
 305}
 306
 307static int gpr32_set(struct task_struct *target,
 308                     const struct user_regset *regset,
 309                     unsigned int pos, unsigned int count,
 310                     const void *kbuf, const void __user *ubuf)
 311{
 312        struct pt_regs *regs = task_pt_regs(target);
 313        u32 uregs[ELF_NGREG];
 314        unsigned start, num_regs, i;
 315        int err;
 316
 317        start = pos / sizeof(u32);
 318        num_regs = count / sizeof(u32);
 319
 320        if (start + num_regs > ELF_NGREG)
 321                return -EIO;
 322
 323        err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, uregs, 0,
 324                                 sizeof(uregs));
 325        if (err)
 326                return err;
 327
 328        for (i = start; i < num_regs; i++) {
 329                /*
 330                 * Cast all values to signed here so that if this is a 64-bit
 331                 * kernel, the supplied 32-bit values will be sign extended.
 332                 */
 333                switch (i) {
 334                case MIPS32_EF_R1 ... MIPS32_EF_R25:
 335                        /* k0/k1 are ignored. */
 336                case MIPS32_EF_R28 ... MIPS32_EF_R31:
 337                        regs->regs[i - MIPS32_EF_R0] = (s32)uregs[i];
 338                        break;
 339                case MIPS32_EF_LO:
 340                        regs->lo = (s32)uregs[i];
 341                        break;
 342                case MIPS32_EF_HI:
 343                        regs->hi = (s32)uregs[i];
 344                        break;
 345                case MIPS32_EF_CP0_EPC:
 346                        regs->cp0_epc = (s32)uregs[i];
 347                        break;
 348                }
 349        }
 350
 351        return 0;
 352}
 353
 354#endif /* CONFIG_32BIT || CONFIG_MIPS32_O32 */
 355
 356#ifdef CONFIG_64BIT
 357
 358static int gpr64_get(struct task_struct *target,
 359                     const struct user_regset *regset,
 360                     unsigned int pos, unsigned int count,
 361                     void *kbuf, void __user *ubuf)
 362{
 363        struct pt_regs *regs = task_pt_regs(target);
 364        u64 uregs[ELF_NGREG] = {};
 365        unsigned i;
 366
 367        for (i = MIPS64_EF_R1; i <= MIPS64_EF_R31; i++) {
 368                /* k0/k1 are copied as zero. */
 369                if (i == MIPS64_EF_R26 || i == MIPS64_EF_R27)
 370                        continue;
 371
 372                uregs[i] = regs->regs[i - MIPS64_EF_R0];
 373        }
 374
 375        uregs[MIPS64_EF_LO] = regs->lo;
 376        uregs[MIPS64_EF_HI] = regs->hi;
 377        uregs[MIPS64_EF_CP0_EPC] = regs->cp0_epc;
 378        uregs[MIPS64_EF_CP0_BADVADDR] = regs->cp0_badvaddr;
 379        uregs[MIPS64_EF_CP0_STATUS] = regs->cp0_status;
 380        uregs[MIPS64_EF_CP0_CAUSE] = regs->cp0_cause;
 381
 382        return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, 0,
 383                                   sizeof(uregs));
 384}
 385
 386static int gpr64_set(struct task_struct *target,
 387                     const struct user_regset *regset,
 388                     unsigned int pos, unsigned int count,
 389                     const void *kbuf, const void __user *ubuf)
 390{
 391        struct pt_regs *regs = task_pt_regs(target);
 392        u64 uregs[ELF_NGREG];
 393        unsigned start, num_regs, i;
 394        int err;
 395
 396        start = pos / sizeof(u64);
 397        num_regs = count / sizeof(u64);
 398
 399        if (start + num_regs > ELF_NGREG)
 400                return -EIO;
 401
 402        err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, uregs, 0,
 403                                 sizeof(uregs));
 404        if (err)
 405                return err;
 406
 407        for (i = start; i < num_regs; i++) {
 408                switch (i) {
 409                case MIPS64_EF_R1 ... MIPS64_EF_R25:
 410                        /* k0/k1 are ignored. */
 411                case MIPS64_EF_R28 ... MIPS64_EF_R31:
 412                        regs->regs[i - MIPS64_EF_R0] = uregs[i];
 413                        break;
 414                case MIPS64_EF_LO:
 415                        regs->lo = uregs[i];
 416                        break;
 417                case MIPS64_EF_HI:
 418                        regs->hi = uregs[i];
 419                        break;
 420                case MIPS64_EF_CP0_EPC:
 421                        regs->cp0_epc = uregs[i];
 422                        break;
 423                }
 424        }
 425
 426        return 0;
 427}
 428
 429#endif /* CONFIG_64BIT */
 430
 431static int fpr_get(struct task_struct *target,
 432                   const struct user_regset *regset,
 433                   unsigned int pos, unsigned int count,
 434                   void *kbuf, void __user *ubuf)
 435{
 436        unsigned i;
 437        int err;
 438        u64 fpr_val;
 439
 440        /* XXX fcr31  */
 441
 442        if (sizeof(target->thread.fpu.fpr[i]) == sizeof(elf_fpreg_t))
 443                return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
 444                                           &target->thread.fpu,
 445                                           0, sizeof(elf_fpregset_t));
 446
 447        for (i = 0; i < NUM_FPU_REGS; i++) {
 448                fpr_val = get_fpr64(&target->thread.fpu.fpr[i], 0);
 449                err = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
 450                                          &fpr_val, i * sizeof(elf_fpreg_t),
 451                                          (i + 1) * sizeof(elf_fpreg_t));
 452                if (err)
 453                        return err;
 454        }
 455
 456        return 0;
 457}
 458
 459static int fpr_set(struct task_struct *target,
 460                   const struct user_regset *regset,
 461                   unsigned int pos, unsigned int count,
 462                   const void *kbuf, const void __user *ubuf)
 463{
 464        unsigned i;
 465        int err;
 466        u64 fpr_val;
 467
 468        /* XXX fcr31  */
 469
 470        init_fp_ctx(target);
 471
 472        if (sizeof(target->thread.fpu.fpr[i]) == sizeof(elf_fpreg_t))
 473                return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
 474                                          &target->thread.fpu,
 475                                          0, sizeof(elf_fpregset_t));
 476
 477        for (i = 0; i < NUM_FPU_REGS; i++) {
 478                err = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
 479                                         &fpr_val, i * sizeof(elf_fpreg_t),
 480                                         (i + 1) * sizeof(elf_fpreg_t));
 481                if (err)
 482                        return err;
 483                set_fpr64(&target->thread.fpu.fpr[i], 0, fpr_val);
 484        }
 485
 486        return 0;
 487}
 488
 489enum mips_regset {
 490        REGSET_GPR,
 491        REGSET_FPR,
 492};
 493
 494struct pt_regs_offset {
 495        const char *name;
 496        int offset;
 497};
 498
 499#define REG_OFFSET_NAME(reg, r) {                                       \
 500        .name = #reg,                                                   \
 501        .offset = offsetof(struct pt_regs, r)                           \
 502}
 503
 504#define REG_OFFSET_END {                                                \
 505        .name = NULL,                                                   \
 506        .offset = 0                                                     \
 507}
 508
 509static const struct pt_regs_offset regoffset_table[] = {
 510        REG_OFFSET_NAME(r0, regs[0]),
 511        REG_OFFSET_NAME(r1, regs[1]),
 512        REG_OFFSET_NAME(r2, regs[2]),
 513        REG_OFFSET_NAME(r3, regs[3]),
 514        REG_OFFSET_NAME(r4, regs[4]),
 515        REG_OFFSET_NAME(r5, regs[5]),
 516        REG_OFFSET_NAME(r6, regs[6]),
 517        REG_OFFSET_NAME(r7, regs[7]),
 518        REG_OFFSET_NAME(r8, regs[8]),
 519        REG_OFFSET_NAME(r9, regs[9]),
 520        REG_OFFSET_NAME(r10, regs[10]),
 521        REG_OFFSET_NAME(r11, regs[11]),
 522        REG_OFFSET_NAME(r12, regs[12]),
 523        REG_OFFSET_NAME(r13, regs[13]),
 524        REG_OFFSET_NAME(r14, regs[14]),
 525        REG_OFFSET_NAME(r15, regs[15]),
 526        REG_OFFSET_NAME(r16, regs[16]),
 527        REG_OFFSET_NAME(r17, regs[17]),
 528        REG_OFFSET_NAME(r18, regs[18]),
 529        REG_OFFSET_NAME(r19, regs[19]),
 530        REG_OFFSET_NAME(r20, regs[20]),
 531        REG_OFFSET_NAME(r21, regs[21]),
 532        REG_OFFSET_NAME(r22, regs[22]),
 533        REG_OFFSET_NAME(r23, regs[23]),
 534        REG_OFFSET_NAME(r24, regs[24]),
 535        REG_OFFSET_NAME(r25, regs[25]),
 536        REG_OFFSET_NAME(r26, regs[26]),
 537        REG_OFFSET_NAME(r27, regs[27]),
 538        REG_OFFSET_NAME(r28, regs[28]),
 539        REG_OFFSET_NAME(r29, regs[29]),
 540        REG_OFFSET_NAME(r30, regs[30]),
 541        REG_OFFSET_NAME(r31, regs[31]),
 542        REG_OFFSET_NAME(c0_status, cp0_status),
 543        REG_OFFSET_NAME(hi, hi),
 544        REG_OFFSET_NAME(lo, lo),
 545#ifdef CONFIG_CPU_HAS_SMARTMIPS
 546        REG_OFFSET_NAME(acx, acx),
 547#endif
 548        REG_OFFSET_NAME(c0_badvaddr, cp0_badvaddr),
 549        REG_OFFSET_NAME(c0_cause, cp0_cause),
 550        REG_OFFSET_NAME(c0_epc, cp0_epc),
 551#ifdef CONFIG_CPU_CAVIUM_OCTEON
 552        REG_OFFSET_NAME(mpl0, mpl[0]),
 553        REG_OFFSET_NAME(mpl1, mpl[1]),
 554        REG_OFFSET_NAME(mpl2, mpl[2]),
 555        REG_OFFSET_NAME(mtp0, mtp[0]),
 556        REG_OFFSET_NAME(mtp1, mtp[1]),
 557        REG_OFFSET_NAME(mtp2, mtp[2]),
 558#endif
 559        REG_OFFSET_END,
 560};
 561
 562/**
 563 * regs_query_register_offset() - query register offset from its name
 564 * @name:       the name of a register
 565 *
 566 * regs_query_register_offset() returns the offset of a register in struct
 567 * pt_regs from its name. If the name is invalid, this returns -EINVAL;
 568 */
 569int regs_query_register_offset(const char *name)
 570{
 571        const struct pt_regs_offset *roff;
 572        for (roff = regoffset_table; roff->name != NULL; roff++)
 573                if (!strcmp(roff->name, name))
 574                        return roff->offset;
 575        return -EINVAL;
 576}
 577
 578#if defined(CONFIG_32BIT) || defined(CONFIG_MIPS32_O32)
 579
 580static const struct user_regset mips_regsets[] = {
 581        [REGSET_GPR] = {
 582                .core_note_type = NT_PRSTATUS,
 583                .n              = ELF_NGREG,
 584                .size           = sizeof(unsigned int),
 585                .align          = sizeof(unsigned int),
 586                .get            = gpr32_get,
 587                .set            = gpr32_set,
 588        },
 589        [REGSET_FPR] = {
 590                .core_note_type = NT_PRFPREG,
 591                .n              = ELF_NFPREG,
 592                .size           = sizeof(elf_fpreg_t),
 593                .align          = sizeof(elf_fpreg_t),
 594                .get            = fpr_get,
 595                .set            = fpr_set,
 596        },
 597};
 598
 599static const struct user_regset_view user_mips_view = {
 600        .name           = "mips",
 601        .e_machine      = ELF_ARCH,
 602        .ei_osabi       = ELF_OSABI,
 603        .regsets        = mips_regsets,
 604        .n              = ARRAY_SIZE(mips_regsets),
 605};
 606
 607#endif /* CONFIG_32BIT || CONFIG_MIPS32_O32 */
 608
 609#ifdef CONFIG_64BIT
 610
 611static const struct user_regset mips64_regsets[] = {
 612        [REGSET_GPR] = {
 613                .core_note_type = NT_PRSTATUS,
 614                .n              = ELF_NGREG,
 615                .size           = sizeof(unsigned long),
 616                .align          = sizeof(unsigned long),
 617                .get            = gpr64_get,
 618                .set            = gpr64_set,
 619        },
 620        [REGSET_FPR] = {
 621                .core_note_type = NT_PRFPREG,
 622                .n              = ELF_NFPREG,
 623                .size           = sizeof(elf_fpreg_t),
 624                .align          = sizeof(elf_fpreg_t),
 625                .get            = fpr_get,
 626                .set            = fpr_set,
 627        },
 628};
 629
 630static const struct user_regset_view user_mips64_view = {
 631        .name           = "mips64",
 632        .e_machine      = ELF_ARCH,
 633        .ei_osabi       = ELF_OSABI,
 634        .regsets        = mips64_regsets,
 635        .n              = ARRAY_SIZE(mips64_regsets),
 636};
 637
 638#endif /* CONFIG_64BIT */
 639
 640const struct user_regset_view *task_user_regset_view(struct task_struct *task)
 641{
 642#ifdef CONFIG_32BIT
 643        return &user_mips_view;
 644#else
 645#ifdef CONFIG_MIPS32_O32
 646        if (test_tsk_thread_flag(task, TIF_32BIT_REGS))
 647                return &user_mips_view;
 648#endif
 649        return &user_mips64_view;
 650#endif
 651}
 652
 653long arch_ptrace(struct task_struct *child, long request,
 654                 unsigned long addr, unsigned long data)
 655{
 656        int ret;
 657        void __user *addrp = (void __user *) addr;
 658        void __user *datavp = (void __user *) data;
 659        unsigned long __user *datalp = (void __user *) data;
 660
 661        switch (request) {
 662        /* when I and D space are separate, these will need to be fixed. */
 663        case PTRACE_PEEKTEXT: /* read word at location addr. */
 664        case PTRACE_PEEKDATA:
 665                ret = generic_ptrace_peekdata(child, addr, data);
 666                break;
 667
 668        /* Read the word at location addr in the USER area. */
 669        case PTRACE_PEEKUSR: {
 670                struct pt_regs *regs;
 671                union fpureg *fregs;
 672                unsigned long tmp = 0;
 673
 674                regs = task_pt_regs(child);
 675                ret = 0;  /* Default return value. */
 676
 677                switch (addr) {
 678                case 0 ... 31:
 679                        tmp = regs->regs[addr];
 680                        break;
 681                case FPR_BASE ... FPR_BASE + 31:
 682                        if (!tsk_used_math(child)) {
 683                                /* FP not yet used */
 684                                tmp = -1;
 685                                break;
 686                        }
 687                        fregs = get_fpu_regs(child);
 688
 689#ifdef CONFIG_32BIT
 690                        if (test_thread_flag(TIF_32BIT_FPREGS)) {
 691                                /*
 692                                 * The odd registers are actually the high
 693                                 * order bits of the values stored in the even
 694                                 * registers - unless we're using r2k_switch.S.
 695                                 */
 696                                tmp = get_fpr32(&fregs[(addr & ~1) - FPR_BASE],
 697                                                addr & 1);
 698                                break;
 699                        }
 700#endif
 701                        tmp = get_fpr32(&fregs[addr - FPR_BASE], 0);
 702                        break;
 703                case PC:
 704                        tmp = regs->cp0_epc;
 705                        break;
 706                case CAUSE:
 707                        tmp = regs->cp0_cause;
 708                        break;
 709                case BADVADDR:
 710                        tmp = regs->cp0_badvaddr;
 711                        break;
 712                case MMHI:
 713                        tmp = regs->hi;
 714                        break;
 715                case MMLO:
 716                        tmp = regs->lo;
 717                        break;
 718#ifdef CONFIG_CPU_HAS_SMARTMIPS
 719                case ACX:
 720                        tmp = regs->acx;
 721                        break;
 722#endif
 723                case FPC_CSR:
 724                        tmp = child->thread.fpu.fcr31;
 725                        break;
 726                case FPC_EIR:
 727                        /* implementation / version register */
 728                        tmp = boot_cpu_data.fpu_id;
 729                        break;
 730                case DSP_BASE ... DSP_BASE + 5: {
 731                        dspreg_t *dregs;
 732
 733                        if (!cpu_has_dsp) {
 734                                tmp = 0;
 735                                ret = -EIO;
 736                                goto out;
 737                        }
 738                        dregs = __get_dsp_regs(child);
 739                        tmp = (unsigned long) (dregs[addr - DSP_BASE]);
 740                        break;
 741                }
 742                case DSP_CONTROL:
 743                        if (!cpu_has_dsp) {
 744                                tmp = 0;
 745                                ret = -EIO;
 746                                goto out;
 747                        }
 748                        tmp = child->thread.dsp.dspcontrol;
 749                        break;
 750                default:
 751                        tmp = 0;
 752                        ret = -EIO;
 753                        goto out;
 754                }
 755                ret = put_user(tmp, datalp);
 756                break;
 757        }
 758
 759        /* when I and D space are separate, this will have to be fixed. */
 760        case PTRACE_POKETEXT: /* write the word at location addr. */
 761        case PTRACE_POKEDATA:
 762                ret = generic_ptrace_pokedata(child, addr, data);
 763                break;
 764
 765        case PTRACE_POKEUSR: {
 766                struct pt_regs *regs;
 767                ret = 0;
 768                regs = task_pt_regs(child);
 769
 770                switch (addr) {
 771                case 0 ... 31:
 772                        regs->regs[addr] = data;
 773                        break;
 774                case FPR_BASE ... FPR_BASE + 31: {
 775                        union fpureg *fregs = get_fpu_regs(child);
 776
 777                        init_fp_ctx(child);
 778#ifdef CONFIG_32BIT
 779                        if (test_thread_flag(TIF_32BIT_FPREGS)) {
 780                                /*
 781                                 * The odd registers are actually the high
 782                                 * order bits of the values stored in the even
 783                                 * registers - unless we're using r2k_switch.S.
 784                                 */
 785                                set_fpr32(&fregs[(addr & ~1) - FPR_BASE],
 786                                          addr & 1, data);
 787                                break;
 788                        }
 789#endif
 790                        set_fpr64(&fregs[addr - FPR_BASE], 0, data);
 791                        break;
 792                }
 793                case PC:
 794                        regs->cp0_epc = data;
 795                        break;
 796                case MMHI:
 797                        regs->hi = data;
 798                        break;
 799                case MMLO:
 800                        regs->lo = data;
 801                        break;
 802#ifdef CONFIG_CPU_HAS_SMARTMIPS
 803                case ACX:
 804                        regs->acx = data;
 805                        break;
 806#endif
 807                case FPC_CSR:
 808                        child->thread.fpu.fcr31 = data & ~FPU_CSR_ALL_X;
 809                        break;
 810                case DSP_BASE ... DSP_BASE + 5: {
 811                        dspreg_t *dregs;
 812
 813                        if (!cpu_has_dsp) {
 814                                ret = -EIO;
 815                                break;
 816                        }
 817
 818                        dregs = __get_dsp_regs(child);
 819                        dregs[addr - DSP_BASE] = data;
 820                        break;
 821                }
 822                case DSP_CONTROL:
 823                        if (!cpu_has_dsp) {
 824                                ret = -EIO;
 825                                break;
 826                        }
 827                        child->thread.dsp.dspcontrol = data;
 828                        break;
 829                default:
 830                        /* The rest are not allowed. */
 831                        ret = -EIO;
 832                        break;
 833                }
 834                break;
 835                }
 836
 837        case PTRACE_GETREGS:
 838                ret = ptrace_getregs(child, datavp);
 839                break;
 840
 841        case PTRACE_SETREGS:
 842                ret = ptrace_setregs(child, datavp);
 843                break;
 844
 845        case PTRACE_GETFPREGS:
 846                ret = ptrace_getfpregs(child, datavp);
 847                break;
 848
 849        case PTRACE_SETFPREGS:
 850                ret = ptrace_setfpregs(child, datavp);
 851                break;
 852
 853        case PTRACE_GET_THREAD_AREA:
 854                ret = put_user(task_thread_info(child)->tp_value, datalp);
 855                break;
 856
 857        case PTRACE_GET_WATCH_REGS:
 858                ret = ptrace_get_watch_regs(child, addrp);
 859                break;
 860
 861        case PTRACE_SET_WATCH_REGS:
 862                ret = ptrace_set_watch_regs(child, addrp);
 863                break;
 864
 865        default:
 866                ret = ptrace_request(child, request, addr, data);
 867                break;
 868        }
 869 out:
 870        return ret;
 871}
 872
 873/*
 874 * Notification of system call entry/exit
 875 * - triggered by current->work.syscall_trace
 876 */
 877asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall)
 878{
 879        long ret = 0;
 880        user_exit();
 881
 882        current_thread_info()->syscall = syscall;
 883
 884        if (secure_computing() == -1)
 885                return -1;
 886
 887        if (test_thread_flag(TIF_SYSCALL_TRACE) &&
 888            tracehook_report_syscall_entry(regs))
 889                ret = -1;
 890
 891        if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
 892                trace_sys_enter(regs, regs->regs[2]);
 893
 894        audit_syscall_entry(syscall, regs->regs[4], regs->regs[5],
 895                            regs->regs[6], regs->regs[7]);
 896        return syscall;
 897}
 898
 899/*
 900 * Notification of system call entry/exit
 901 * - triggered by current->work.syscall_trace
 902 */
 903asmlinkage void syscall_trace_leave(struct pt_regs *regs)
 904{
 905        /*
 906         * We may come here right after calling schedule_user()
 907         * or do_notify_resume(), in which case we can be in RCU
 908         * user mode.
 909         */
 910        user_exit();
 911
 912        audit_syscall_exit(regs);
 913
 914        if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
 915                trace_sys_exit(regs, regs->regs[2]);
 916
 917        if (test_thread_flag(TIF_SYSCALL_TRACE))
 918                tracehook_report_syscall_exit(regs, 0);
 919
 920        user_enter();
 921}
 922