linux/arch/parisc/kernel/ptrace.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Kernel support for the ptrace() and syscall tracing interfaces.
   4 *
   5 * Copyright (C) 2000 Hewlett-Packard Co, Linuxcare Inc.
   6 * Copyright (C) 2000 Matthew Wilcox <matthew@wil.cx>
   7 * Copyright (C) 2000 David Huggins-Daines <dhd@debian.org>
   8 * Copyright (C) 2008-2016 Helge Deller <deller@gmx.de>
   9 */
  10
  11#include <linux/kernel.h>
  12#include <linux/sched.h>
  13#include <linux/mm.h>
  14#include <linux/smp.h>
  15#include <linux/elf.h>
  16#include <linux/errno.h>
  17#include <linux/ptrace.h>
  18#include <linux/tracehook.h>
  19#include <linux/user.h>
  20#include <linux/personality.h>
  21#include <linux/regset.h>
  22#include <linux/security.h>
  23#include <linux/seccomp.h>
  24#include <linux/compat.h>
  25#include <linux/signal.h>
  26#include <linux/audit.h>
  27
  28#include <linux/uaccess.h>
  29#include <asm/processor.h>
  30#include <asm/asm-offsets.h>
  31
  32/* PSW bits we allow the debugger to modify */
  33#define USER_PSW_BITS   (PSW_N | PSW_B | PSW_V | PSW_CB)
  34
  35#define CREATE_TRACE_POINTS
  36#include <trace/events/syscalls.h>
  37
  38/*
  39 * These are our native regset flavors.
  40 */
  41enum parisc_regset {
  42        REGSET_GENERAL,
  43        REGSET_FP
  44};
  45
  46/*
  47 * Called by kernel/ptrace.c when detaching..
  48 *
  49 * Make sure single step bits etc are not set.
  50 */
  51void ptrace_disable(struct task_struct *task)
  52{
  53        clear_tsk_thread_flag(task, TIF_SINGLESTEP);
  54        clear_tsk_thread_flag(task, TIF_BLOCKSTEP);
  55
  56        /* make sure the trap bits are not set */
  57        pa_psw(task)->r = 0;
  58        pa_psw(task)->t = 0;
  59        pa_psw(task)->h = 0;
  60        pa_psw(task)->l = 0;
  61}
  62
  63/*
  64 * The following functions are called by ptrace_resume() when
  65 * enabling or disabling single/block tracing.
  66 */
  67void user_disable_single_step(struct task_struct *task)
  68{
  69        ptrace_disable(task);
  70}
  71
  72void user_enable_single_step(struct task_struct *task)
  73{
  74        clear_tsk_thread_flag(task, TIF_BLOCKSTEP);
  75        set_tsk_thread_flag(task, TIF_SINGLESTEP);
  76
  77        if (pa_psw(task)->n) {
  78                /* Nullified, just crank over the queue. */
  79                task_regs(task)->iaoq[0] = task_regs(task)->iaoq[1];
  80                task_regs(task)->iasq[0] = task_regs(task)->iasq[1];
  81                task_regs(task)->iaoq[1] = task_regs(task)->iaoq[0] + 4;
  82                pa_psw(task)->n = 0;
  83                pa_psw(task)->x = 0;
  84                pa_psw(task)->y = 0;
  85                pa_psw(task)->z = 0;
  86                pa_psw(task)->b = 0;
  87                ptrace_disable(task);
  88                /* Don't wake up the task, but let the
  89                   parent know something happened. */
  90                force_sig_fault_to_task(SIGTRAP, TRAP_TRACE,
  91                                        (void __user *) (task_regs(task)->iaoq[0] & ~3),
  92                                        task);
  93                /* notify_parent(task, SIGCHLD); */
  94                return;
  95        }
  96
  97        /* Enable recovery counter traps.  The recovery counter
  98         * itself will be set to zero on a task switch.  If the
  99         * task is suspended on a syscall then the syscall return
 100         * path will overwrite the recovery counter with a suitable
 101         * value such that it traps once back in user space.  We
 102         * disable interrupts in the tasks PSW here also, to avoid
 103         * interrupts while the recovery counter is decrementing.
 104         */
 105        pa_psw(task)->r = 1;
 106        pa_psw(task)->t = 0;
 107        pa_psw(task)->h = 0;
 108        pa_psw(task)->l = 0;
 109}
 110
 111void user_enable_block_step(struct task_struct *task)
 112{
 113        clear_tsk_thread_flag(task, TIF_SINGLESTEP);
 114        set_tsk_thread_flag(task, TIF_BLOCKSTEP);
 115
 116        /* Enable taken branch trap. */
 117        pa_psw(task)->r = 0;
 118        pa_psw(task)->t = 1;
 119        pa_psw(task)->h = 0;
 120        pa_psw(task)->l = 0;
 121}
 122
 123long arch_ptrace(struct task_struct *child, long request,
 124                 unsigned long addr, unsigned long data)
 125{
 126        unsigned long __user *datap = (unsigned long __user *)data;
 127        unsigned long tmp;
 128        long ret = -EIO;
 129
 130        switch (request) {
 131
 132        /* Read the word at location addr in the USER area.  For ptraced
 133           processes, the kernel saves all regs on a syscall. */
 134        case PTRACE_PEEKUSR:
 135                if ((addr & (sizeof(unsigned long)-1)) ||
 136                     addr >= sizeof(struct pt_regs))
 137                        break;
 138                tmp = *(unsigned long *) ((char *) task_regs(child) + addr);
 139                ret = put_user(tmp, datap);
 140                break;
 141
 142        /* Write the word at location addr in the USER area.  This will need
 143           to change when the kernel no longer saves all regs on a syscall.
 144           FIXME.  There is a problem at the moment in that r3-r18 are only
 145           saved if the process is ptraced on syscall entry, and even then
 146           those values are overwritten by actual register values on syscall
 147           exit. */
 148        case PTRACE_POKEUSR:
 149                /* Some register values written here may be ignored in
 150                 * entry.S:syscall_restore_rfi; e.g. iaoq is written with
 151                 * r31/r31+4, and not with the values in pt_regs.
 152                 */
 153                if (addr == PT_PSW) {
 154                        /* Allow writing to Nullify, Divide-step-correction,
 155                         * and carry/borrow bits.
 156                         * BEWARE, if you set N, and then single step, it won't
 157                         * stop on the nullified instruction.
 158                         */
 159                        data &= USER_PSW_BITS;
 160                        task_regs(child)->gr[0] &= ~USER_PSW_BITS;
 161                        task_regs(child)->gr[0] |= data;
 162                        ret = 0;
 163                        break;
 164                }
 165
 166                if ((addr & (sizeof(unsigned long)-1)) ||
 167                     addr >= sizeof(struct pt_regs))
 168                        break;
 169                if (addr == PT_IAOQ0 || addr == PT_IAOQ1) {
 170                        data |= 3; /* ensure userspace privilege */
 171                }
 172                if ((addr >= PT_GR1 && addr <= PT_GR31) ||
 173                                addr == PT_IAOQ0 || addr == PT_IAOQ1 ||
 174                                (addr >= PT_FR0 && addr <= PT_FR31 + 4) ||
 175                                addr == PT_SAR) {
 176                        *(unsigned long *) ((char *) task_regs(child) + addr) = data;
 177                        ret = 0;
 178                }
 179                break;
 180
 181        case PTRACE_GETREGS:    /* Get all gp regs from the child. */
 182                return copy_regset_to_user(child,
 183                                           task_user_regset_view(current),
 184                                           REGSET_GENERAL,
 185                                           0, sizeof(struct user_regs_struct),
 186                                           datap);
 187
 188        case PTRACE_SETREGS:    /* Set all gp regs in the child. */
 189                return copy_regset_from_user(child,
 190                                             task_user_regset_view(current),
 191                                             REGSET_GENERAL,
 192                                             0, sizeof(struct user_regs_struct),
 193                                             datap);
 194
 195        case PTRACE_GETFPREGS:  /* Get the child FPU state. */
 196                return copy_regset_to_user(child,
 197                                           task_user_regset_view(current),
 198                                           REGSET_FP,
 199                                           0, sizeof(struct user_fp_struct),
 200                                           datap);
 201
 202        case PTRACE_SETFPREGS:  /* Set the child FPU state. */
 203                return copy_regset_from_user(child,
 204                                             task_user_regset_view(current),
 205                                             REGSET_FP,
 206                                             0, sizeof(struct user_fp_struct),
 207                                             datap);
 208
 209        default:
 210                ret = ptrace_request(child, request, addr, data);
 211                break;
 212        }
 213
 214        return ret;
 215}
 216
 217
 218#ifdef CONFIG_COMPAT
 219
 220/* This function is needed to translate 32 bit pt_regs offsets in to
 221 * 64 bit pt_regs offsets.  For example, a 32 bit gdb under a 64 bit kernel
 222 * will request offset 12 if it wants gr3, but the lower 32 bits of
 223 * the 64 bit kernels view of gr3 will be at offset 28 (3*8 + 4).
 224 * This code relies on a 32 bit pt_regs being comprised of 32 bit values
 225 * except for the fp registers which (a) are 64 bits, and (b) follow
 226 * the gr registers at the start of pt_regs.  The 32 bit pt_regs should
 227 * be half the size of the 64 bit pt_regs, plus 32*4 to allow for fr[]
 228 * being 64 bit in both cases.
 229 */
 230
 231static compat_ulong_t translate_usr_offset(compat_ulong_t offset)
 232{
 233        compat_ulong_t pos;
 234
 235        if (offset < 32*4)      /* gr[0..31] */
 236                pos = offset * 2 + 4;
 237        else if (offset < 32*4+32*8)    /* fr[0] ... fr[31] */
 238                pos = (offset - 32*4) + PT_FR0;
 239        else if (offset < sizeof(struct pt_regs)/2 + 32*4) /* sr[0] ... ipsw */
 240                pos = (offset - 32*4 - 32*8) * 2 + PT_SR0 + 4;
 241        else
 242                pos = sizeof(struct pt_regs);
 243
 244        return pos;
 245}
 246
 247long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 248                        compat_ulong_t addr, compat_ulong_t data)
 249{
 250        compat_uint_t tmp;
 251        long ret = -EIO;
 252
 253        switch (request) {
 254
 255        case PTRACE_PEEKUSR:
 256                if (addr & (sizeof(compat_uint_t)-1))
 257                        break;
 258                addr = translate_usr_offset(addr);
 259                if (addr >= sizeof(struct pt_regs))
 260                        break;
 261
 262                tmp = *(compat_uint_t *) ((char *) task_regs(child) + addr);
 263                ret = put_user(tmp, (compat_uint_t *) (unsigned long) data);
 264                break;
 265
 266        /* Write the word at location addr in the USER area.  This will need
 267           to change when the kernel no longer saves all regs on a syscall.
 268           FIXME.  There is a problem at the moment in that r3-r18 are only
 269           saved if the process is ptraced on syscall entry, and even then
 270           those values are overwritten by actual register values on syscall
 271           exit. */
 272        case PTRACE_POKEUSR:
 273                /* Some register values written here may be ignored in
 274                 * entry.S:syscall_restore_rfi; e.g. iaoq is written with
 275                 * r31/r31+4, and not with the values in pt_regs.
 276                 */
 277                if (addr == PT_PSW) {
 278                        /* Since PT_PSW==0, it is valid for 32 bit processes
 279                         * under 64 bit kernels as well.
 280                         */
 281                        ret = arch_ptrace(child, request, addr, data);
 282                } else {
 283                        if (addr & (sizeof(compat_uint_t)-1))
 284                                break;
 285                        addr = translate_usr_offset(addr);
 286                        if (addr >= sizeof(struct pt_regs))
 287                                break;
 288                        if (addr == PT_IAOQ0+4 || addr == PT_IAOQ1+4) {
 289                                data |= 3; /* ensure userspace privilege */
 290                        }
 291                        if (addr >= PT_FR0 && addr <= PT_FR31 + 4) {
 292                                /* Special case, fp regs are 64 bits anyway */
 293                                *(__u32 *) ((char *) task_regs(child) + addr) = data;
 294                                ret = 0;
 295                        }
 296                        else if ((addr >= PT_GR1+4 && addr <= PT_GR31+4) ||
 297                                        addr == PT_IAOQ0+4 || addr == PT_IAOQ1+4 ||
 298                                        addr == PT_SAR+4) {
 299                                /* Zero the top 32 bits */
 300                                *(__u32 *) ((char *) task_regs(child) + addr - 4) = 0;
 301                                *(__u32 *) ((char *) task_regs(child) + addr) = data;
 302                                ret = 0;
 303                        }
 304                }
 305                break;
 306
 307        default:
 308                ret = compat_ptrace_request(child, request, addr, data);
 309                break;
 310        }
 311
 312        return ret;
 313}
 314#endif
 315
 316long do_syscall_trace_enter(struct pt_regs *regs)
 317{
 318        if (test_thread_flag(TIF_SYSCALL_TRACE)) {
 319                int rc = tracehook_report_syscall_entry(regs);
 320
 321                /*
 322                 * As tracesys_next does not set %r28 to -ENOSYS
 323                 * when %r20 is set to -1, initialize it here.
 324                 */
 325                regs->gr[28] = -ENOSYS;
 326
 327                if (rc) {
 328                        /*
 329                         * A nonzero return code from
 330                         * tracehook_report_syscall_entry() tells us
 331                         * to prevent the syscall execution.  Skip
 332                         * the syscall call and the syscall restart handling.
 333                         *
 334                         * Note that the tracer may also just change
 335                         * regs->gr[20] to an invalid syscall number,
 336                         * that is handled by tracesys_next.
 337                         */
 338                        regs->gr[20] = -1UL;
 339                        return -1;
 340                }
 341        }
 342
 343        /* Do the secure computing check after ptrace. */
 344        if (secure_computing() == -1)
 345                return -1;
 346
 347#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
 348        if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
 349                trace_sys_enter(regs, regs->gr[20]);
 350#endif
 351
 352#ifdef CONFIG_64BIT
 353        if (!is_compat_task())
 354                audit_syscall_entry(regs->gr[20], regs->gr[26], regs->gr[25],
 355                                    regs->gr[24], regs->gr[23]);
 356        else
 357#endif
 358                audit_syscall_entry(regs->gr[20] & 0xffffffff,
 359                        regs->gr[26] & 0xffffffff,
 360                        regs->gr[25] & 0xffffffff,
 361                        regs->gr[24] & 0xffffffff,
 362                        regs->gr[23] & 0xffffffff);
 363
 364        /*
 365         * Sign extend the syscall number to 64bit since it may have been
 366         * modified by a compat ptrace call
 367         */
 368        return (int) ((u32) regs->gr[20]);
 369}
 370
 371void do_syscall_trace_exit(struct pt_regs *regs)
 372{
 373        int stepping = test_thread_flag(TIF_SINGLESTEP) ||
 374                test_thread_flag(TIF_BLOCKSTEP);
 375
 376        audit_syscall_exit(regs);
 377
 378#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
 379        if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
 380                trace_sys_exit(regs, regs->gr[20]);
 381#endif
 382
 383        if (stepping || test_thread_flag(TIF_SYSCALL_TRACE))
 384                tracehook_report_syscall_exit(regs, stepping);
 385}
 386
 387
 388/*
 389 * regset functions.
 390 */
 391
 392static int fpr_get(struct task_struct *target,
 393                     const struct user_regset *regset,
 394                     struct membuf to)
 395{
 396        struct pt_regs *regs = task_regs(target);
 397
 398        return membuf_write(&to, regs->fr, ELF_NFPREG * sizeof(__u64));
 399}
 400
 401static int fpr_set(struct task_struct *target,
 402                     const struct user_regset *regset,
 403                     unsigned int pos, unsigned int count,
 404                     const void *kbuf, const void __user *ubuf)
 405{
 406        struct pt_regs *regs = task_regs(target);
 407        const __u64 *k = kbuf;
 408        const __u64 __user *u = ubuf;
 409        __u64 reg;
 410
 411        pos /= sizeof(reg);
 412        count /= sizeof(reg);
 413
 414        if (kbuf)
 415                for (; count > 0 && pos < ELF_NFPREG; --count)
 416                        regs->fr[pos++] = *k++;
 417        else
 418                for (; count > 0 && pos < ELF_NFPREG; --count) {
 419                        if (__get_user(reg, u++))
 420                                return -EFAULT;
 421                        regs->fr[pos++] = reg;
 422                }
 423
 424        kbuf = k;
 425        ubuf = u;
 426        pos *= sizeof(reg);
 427        count *= sizeof(reg);
 428        return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
 429                                         ELF_NFPREG * sizeof(reg), -1);
 430}
 431
 432#define RI(reg) (offsetof(struct user_regs_struct,reg) / sizeof(long))
 433
 434static unsigned long get_reg(struct pt_regs *regs, int num)
 435{
 436        switch (num) {
 437        case RI(gr[0]) ... RI(gr[31]):  return regs->gr[num - RI(gr[0])];
 438        case RI(sr[0]) ... RI(sr[7]):   return regs->sr[num - RI(sr[0])];
 439        case RI(iasq[0]):               return regs->iasq[0];
 440        case RI(iasq[1]):               return regs->iasq[1];
 441        case RI(iaoq[0]):               return regs->iaoq[0];
 442        case RI(iaoq[1]):               return regs->iaoq[1];
 443        case RI(sar):                   return regs->sar;
 444        case RI(iir):                   return regs->iir;
 445        case RI(isr):                   return regs->isr;
 446        case RI(ior):                   return regs->ior;
 447        case RI(ipsw):                  return regs->ipsw;
 448        case RI(cr27):                  return regs->cr27;
 449        case RI(cr0):                   return mfctl(0);
 450        case RI(cr24):                  return mfctl(24);
 451        case RI(cr25):                  return mfctl(25);
 452        case RI(cr26):                  return mfctl(26);
 453        case RI(cr28):                  return mfctl(28);
 454        case RI(cr29):                  return mfctl(29);
 455        case RI(cr30):                  return mfctl(30);
 456        case RI(cr31):                  return mfctl(31);
 457        case RI(cr8):                   return mfctl(8);
 458        case RI(cr9):                   return mfctl(9);
 459        case RI(cr12):                  return mfctl(12);
 460        case RI(cr13):                  return mfctl(13);
 461        case RI(cr10):                  return mfctl(10);
 462        case RI(cr15):                  return mfctl(15);
 463        default:                        return 0;
 464        }
 465}
 466
 467static void set_reg(struct pt_regs *regs, int num, unsigned long val)
 468{
 469        switch (num) {
 470        case RI(gr[0]): /*
 471                         * PSW is in gr[0].
 472                         * Allow writing to Nullify, Divide-step-correction,
 473                         * and carry/borrow bits.
 474                         * BEWARE, if you set N, and then single step, it won't
 475                         * stop on the nullified instruction.
 476                         */
 477                        val &= USER_PSW_BITS;
 478                        regs->gr[0] &= ~USER_PSW_BITS;
 479                        regs->gr[0] |= val;
 480                        return;
 481        case RI(gr[1]) ... RI(gr[31]):
 482                        regs->gr[num - RI(gr[0])] = val;
 483                        return;
 484        case RI(iaoq[0]):
 485        case RI(iaoq[1]):
 486                        /* set 2 lowest bits to ensure userspace privilege: */
 487                        regs->iaoq[num - RI(iaoq[0])] = val | 3;
 488                        return;
 489        case RI(sar):   regs->sar = val;
 490                        return;
 491        default:        return;
 492#if 0
 493        /* do not allow to change any of the following registers (yet) */
 494        case RI(sr[0]) ... RI(sr[7]):   return regs->sr[num - RI(sr[0])];
 495        case RI(iasq[0]):               return regs->iasq[0];
 496        case RI(iasq[1]):               return regs->iasq[1];
 497        case RI(iir):                   return regs->iir;
 498        case RI(isr):                   return regs->isr;
 499        case RI(ior):                   return regs->ior;
 500        case RI(ipsw):                  return regs->ipsw;
 501        case RI(cr27):                  return regs->cr27;
 502        case cr0, cr24, cr25, cr26, cr27, cr28, cr29, cr30, cr31;
 503        case cr8, cr9, cr12, cr13, cr10, cr15;
 504#endif
 505        }
 506}
 507
 508static int gpr_get(struct task_struct *target,
 509                     const struct user_regset *regset,
 510                     struct membuf to)
 511{
 512        struct pt_regs *regs = task_regs(target);
 513        unsigned int pos;
 514
 515        for (pos = 0; pos < ELF_NGREG; pos++)
 516                membuf_store(&to, get_reg(regs, pos));
 517        return 0;
 518}
 519
 520static int gpr_set(struct task_struct *target,
 521                     const struct user_regset *regset,
 522                     unsigned int pos, unsigned int count,
 523                     const void *kbuf, const void __user *ubuf)
 524{
 525        struct pt_regs *regs = task_regs(target);
 526        const unsigned long *k = kbuf;
 527        const unsigned long __user *u = ubuf;
 528        unsigned long reg;
 529
 530        pos /= sizeof(reg);
 531        count /= sizeof(reg);
 532
 533        if (kbuf)
 534                for (; count > 0 && pos < ELF_NGREG; --count)
 535                        set_reg(regs, pos++, *k++);
 536        else
 537                for (; count > 0 && pos < ELF_NGREG; --count) {
 538                        if (__get_user(reg, u++))
 539                                return -EFAULT;
 540                        set_reg(regs, pos++, reg);
 541                }
 542
 543        kbuf = k;
 544        ubuf = u;
 545        pos *= sizeof(reg);
 546        count *= sizeof(reg);
 547        return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
 548                                         ELF_NGREG * sizeof(reg), -1);
 549}
 550
 551static const struct user_regset native_regsets[] = {
 552        [REGSET_GENERAL] = {
 553                .core_note_type = NT_PRSTATUS, .n = ELF_NGREG,
 554                .size = sizeof(long), .align = sizeof(long),
 555                .regset_get = gpr_get, .set = gpr_set
 556        },
 557        [REGSET_FP] = {
 558                .core_note_type = NT_PRFPREG, .n = ELF_NFPREG,
 559                .size = sizeof(__u64), .align = sizeof(__u64),
 560                .regset_get = fpr_get, .set = fpr_set
 561        }
 562};
 563
 564static const struct user_regset_view user_parisc_native_view = {
 565        .name = "parisc", .e_machine = ELF_ARCH, .ei_osabi = ELFOSABI_LINUX,
 566        .regsets = native_regsets, .n = ARRAY_SIZE(native_regsets)
 567};
 568
 569#ifdef CONFIG_64BIT
 570static int gpr32_get(struct task_struct *target,
 571                     const struct user_regset *regset,
 572                     struct membuf to)
 573{
 574        struct pt_regs *regs = task_regs(target);
 575        unsigned int pos;
 576
 577        for (pos = 0; pos < ELF_NGREG; pos++)
 578                membuf_store(&to, (compat_ulong_t)get_reg(regs, pos));
 579
 580        return 0;
 581}
 582
 583static int gpr32_set(struct task_struct *target,
 584                     const struct user_regset *regset,
 585                     unsigned int pos, unsigned int count,
 586                     const void *kbuf, const void __user *ubuf)
 587{
 588        struct pt_regs *regs = task_regs(target);
 589        const compat_ulong_t *k = kbuf;
 590        const compat_ulong_t __user *u = ubuf;
 591        compat_ulong_t reg;
 592
 593        pos /= sizeof(reg);
 594        count /= sizeof(reg);
 595
 596        if (kbuf)
 597                for (; count > 0 && pos < ELF_NGREG; --count)
 598                        set_reg(regs, pos++, *k++);
 599        else
 600                for (; count > 0 && pos < ELF_NGREG; --count) {
 601                        if (__get_user(reg, u++))
 602                                return -EFAULT;
 603                        set_reg(regs, pos++, reg);
 604                }
 605
 606        kbuf = k;
 607        ubuf = u;
 608        pos *= sizeof(reg);
 609        count *= sizeof(reg);
 610        return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
 611                                         ELF_NGREG * sizeof(reg), -1);
 612}
 613
 614/*
 615 * These are the regset flavors matching the 32bit native set.
 616 */
 617static const struct user_regset compat_regsets[] = {
 618        [REGSET_GENERAL] = {
 619                .core_note_type = NT_PRSTATUS, .n = ELF_NGREG,
 620                .size = sizeof(compat_long_t), .align = sizeof(compat_long_t),
 621                .regset_get = gpr32_get, .set = gpr32_set
 622        },
 623        [REGSET_FP] = {
 624                .core_note_type = NT_PRFPREG, .n = ELF_NFPREG,
 625                .size = sizeof(__u64), .align = sizeof(__u64),
 626                .regset_get = fpr_get, .set = fpr_set
 627        }
 628};
 629
 630static const struct user_regset_view user_parisc_compat_view = {
 631        .name = "parisc", .e_machine = EM_PARISC, .ei_osabi = ELFOSABI_LINUX,
 632        .regsets = compat_regsets, .n = ARRAY_SIZE(compat_regsets)
 633};
 634#endif  /* CONFIG_64BIT */
 635
 636const struct user_regset_view *task_user_regset_view(struct task_struct *task)
 637{
 638        BUILD_BUG_ON(sizeof(struct user_regs_struct)/sizeof(long) != ELF_NGREG);
 639        BUILD_BUG_ON(sizeof(struct user_fp_struct)/sizeof(__u64) != ELF_NFPREG);
 640#ifdef CONFIG_64BIT
 641        if (is_compat_task())
 642                return &user_parisc_compat_view;
 643#endif
 644        return &user_parisc_native_view;
 645}
 646
 647
 648/* HAVE_REGS_AND_STACK_ACCESS_API feature */
 649
 650struct pt_regs_offset {
 651        const char *name;
 652        int offset;
 653};
 654
 655#define REG_OFFSET_NAME(r)    {.name = #r, .offset = offsetof(struct pt_regs, r)}
 656#define REG_OFFSET_INDEX(r,i) {.name = #r#i, .offset = offsetof(struct pt_regs, r[i])}
 657#define REG_OFFSET_END {.name = NULL, .offset = 0}
 658
 659static const struct pt_regs_offset regoffset_table[] = {
 660        REG_OFFSET_INDEX(gr,0),
 661        REG_OFFSET_INDEX(gr,1),
 662        REG_OFFSET_INDEX(gr,2),
 663        REG_OFFSET_INDEX(gr,3),
 664        REG_OFFSET_INDEX(gr,4),
 665        REG_OFFSET_INDEX(gr,5),
 666        REG_OFFSET_INDEX(gr,6),
 667        REG_OFFSET_INDEX(gr,7),
 668        REG_OFFSET_INDEX(gr,8),
 669        REG_OFFSET_INDEX(gr,9),
 670        REG_OFFSET_INDEX(gr,10),
 671        REG_OFFSET_INDEX(gr,11),
 672        REG_OFFSET_INDEX(gr,12),
 673        REG_OFFSET_INDEX(gr,13),
 674        REG_OFFSET_INDEX(gr,14),
 675        REG_OFFSET_INDEX(gr,15),
 676        REG_OFFSET_INDEX(gr,16),
 677        REG_OFFSET_INDEX(gr,17),
 678        REG_OFFSET_INDEX(gr,18),
 679        REG_OFFSET_INDEX(gr,19),
 680        REG_OFFSET_INDEX(gr,20),
 681        REG_OFFSET_INDEX(gr,21),
 682        REG_OFFSET_INDEX(gr,22),
 683        REG_OFFSET_INDEX(gr,23),
 684        REG_OFFSET_INDEX(gr,24),
 685        REG_OFFSET_INDEX(gr,25),
 686        REG_OFFSET_INDEX(gr,26),
 687        REG_OFFSET_INDEX(gr,27),
 688        REG_OFFSET_INDEX(gr,28),
 689        REG_OFFSET_INDEX(gr,29),
 690        REG_OFFSET_INDEX(gr,30),
 691        REG_OFFSET_INDEX(gr,31),
 692        REG_OFFSET_INDEX(sr,0),
 693        REG_OFFSET_INDEX(sr,1),
 694        REG_OFFSET_INDEX(sr,2),
 695        REG_OFFSET_INDEX(sr,3),
 696        REG_OFFSET_INDEX(sr,4),
 697        REG_OFFSET_INDEX(sr,5),
 698        REG_OFFSET_INDEX(sr,6),
 699        REG_OFFSET_INDEX(sr,7),
 700        REG_OFFSET_INDEX(iasq,0),
 701        REG_OFFSET_INDEX(iasq,1),
 702        REG_OFFSET_INDEX(iaoq,0),
 703        REG_OFFSET_INDEX(iaoq,1),
 704        REG_OFFSET_NAME(cr27),
 705        REG_OFFSET_NAME(ksp),
 706        REG_OFFSET_NAME(kpc),
 707        REG_OFFSET_NAME(sar),
 708        REG_OFFSET_NAME(iir),
 709        REG_OFFSET_NAME(isr),
 710        REG_OFFSET_NAME(ior),
 711        REG_OFFSET_NAME(ipsw),
 712        REG_OFFSET_END,
 713};
 714
 715/**
 716 * regs_query_register_offset() - query register offset from its name
 717 * @name:       the name of a register
 718 *
 719 * regs_query_register_offset() returns the offset of a register in struct
 720 * pt_regs from its name. If the name is invalid, this returns -EINVAL;
 721 */
 722int regs_query_register_offset(const char *name)
 723{
 724        const struct pt_regs_offset *roff;
 725        for (roff = regoffset_table; roff->name != NULL; roff++)
 726                if (!strcmp(roff->name, name))
 727                        return roff->offset;
 728        return -EINVAL;
 729}
 730
 731/**
 732 * regs_query_register_name() - query register name from its offset
 733 * @offset:     the offset of a register in struct pt_regs.
 734 *
 735 * regs_query_register_name() returns the name of a register from its
 736 * offset in struct pt_regs. If the @offset is invalid, this returns NULL;
 737 */
 738const char *regs_query_register_name(unsigned int offset)
 739{
 740        const struct pt_regs_offset *roff;
 741        for (roff = regoffset_table; roff->name != NULL; roff++)
 742                if (roff->offset == offset)
 743                        return roff->name;
 744        return NULL;
 745}
 746
 747/**
 748 * regs_within_kernel_stack() - check the address in the stack
 749 * @regs:      pt_regs which contains kernel stack pointer.
 750 * @addr:      address which is checked.
 751 *
 752 * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
 753 * If @addr is within the kernel stack, it returns true. If not, returns false.
 754 */
 755int regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr)
 756{
 757        return ((addr & ~(THREAD_SIZE - 1))  ==
 758                (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)));
 759}
 760
 761/**
 762 * regs_get_kernel_stack_nth() - get Nth entry of the stack
 763 * @regs:       pt_regs which contains kernel stack pointer.
 764 * @n:          stack entry number.
 765 *
 766 * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
 767 * is specified by @regs. If the @n th entry is NOT in the kernel stack,
 768 * this returns 0.
 769 */
 770unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n)
 771{
 772        unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
 773
 774        addr -= n;
 775
 776        if (!regs_within_kernel_stack(regs, (unsigned long)addr))
 777                return 0;
 778
 779        return *addr;
 780}
 781