linux/arch/sparc/kernel/process_64.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*  arch/sparc64/kernel/process.c
   3 *
   4 *  Copyright (C) 1995, 1996, 2008 David S. Miller (davem@davemloft.net)
   5 *  Copyright (C) 1996       Eddie C. Dost   (ecd@skynet.be)
   6 *  Copyright (C) 1997, 1998 Jakub Jelinek   (jj@sunsite.mff.cuni.cz)
   7 */
   8
   9/*
  10 * This file handles the architecture-dependent parts of process handling..
  11 */
  12#include <linux/errno.h>
  13#include <linux/export.h>
  14#include <linux/sched.h>
  15#include <linux/sched/debug.h>
  16#include <linux/sched/task.h>
  17#include <linux/sched/task_stack.h>
  18#include <linux/kernel.h>
  19#include <linux/mm.h>
  20#include <linux/fs.h>
  21#include <linux/smp.h>
  22#include <linux/stddef.h>
  23#include <linux/ptrace.h>
  24#include <linux/slab.h>
  25#include <linux/user.h>
  26#include <linux/delay.h>
  27#include <linux/compat.h>
  28#include <linux/tick.h>
  29#include <linux/init.h>
  30#include <linux/cpu.h>
  31#include <linux/perf_event.h>
  32#include <linux/elfcore.h>
  33#include <linux/sysrq.h>
  34#include <linux/nmi.h>
  35#include <linux/context_tracking.h>
  36#include <linux/signal.h>
  37
  38#include <linux/uaccess.h>
  39#include <asm/page.h>
  40#include <asm/pgalloc.h>
  41#include <asm/processor.h>
  42#include <asm/pstate.h>
  43#include <asm/elf.h>
  44#include <asm/fpumacro.h>
  45#include <asm/head.h>
  46#include <asm/cpudata.h>
  47#include <asm/mmu_context.h>
  48#include <asm/unistd.h>
  49#include <asm/hypervisor.h>
  50#include <asm/syscalls.h>
  51#include <asm/irq_regs.h>
  52#include <asm/smp.h>
  53#include <asm/pcr.h>
  54
  55#include "kstack.h"
  56
  57/* Idle loop support on sparc64. */
  58void arch_cpu_idle(void)
  59{
  60        if (tlb_type != hypervisor) {
  61                touch_nmi_watchdog();
  62                raw_local_irq_enable();
  63        } else {
  64                unsigned long pstate;
  65
  66                raw_local_irq_enable();
  67
  68                /* The sun4v sleeping code requires that we have PSTATE.IE cleared over
  69                 * the cpu sleep hypervisor call.
  70                 */
  71                __asm__ __volatile__(
  72                        "rdpr %%pstate, %0\n\t"
  73                        "andn %0, %1, %0\n\t"
  74                        "wrpr %0, %%g0, %%pstate"
  75                        : "=&r" (pstate)
  76                        : "i" (PSTATE_IE));
  77
  78                if (!need_resched() && !cpu_is_offline(smp_processor_id())) {
  79                        sun4v_cpu_yield();
  80                        /* If resumed by cpu_poke then we need to explicitly
  81                         * call scheduler_ipi().
  82                         */
  83                        scheduler_poke();
  84                }
  85
  86                /* Re-enable interrupts. */
  87                __asm__ __volatile__(
  88                        "rdpr %%pstate, %0\n\t"
  89                        "or %0, %1, %0\n\t"
  90                        "wrpr %0, %%g0, %%pstate"
  91                        : "=&r" (pstate)
  92                        : "i" (PSTATE_IE));
  93        }
  94}
  95
  96#ifdef CONFIG_HOTPLUG_CPU
  97void arch_cpu_idle_dead(void)
  98{
  99        sched_preempt_enable_no_resched();
 100        cpu_play_dead();
 101}
 102#endif
 103
 104#ifdef CONFIG_COMPAT
 105static void show_regwindow32(struct pt_regs *regs)
 106{
 107        struct reg_window32 __user *rw;
 108        struct reg_window32 r_w;
 109        
 110        __asm__ __volatile__ ("flushw");
 111        rw = compat_ptr((unsigned int)regs->u_regs[14]);
 112        if (copy_from_user (&r_w, rw, sizeof(r_w))) {
 113                return;
 114        }
 115
 116        printk("l0: %08x l1: %08x l2: %08x l3: %08x "
 117               "l4: %08x l5: %08x l6: %08x l7: %08x\n",
 118               r_w.locals[0], r_w.locals[1], r_w.locals[2], r_w.locals[3],
 119               r_w.locals[4], r_w.locals[5], r_w.locals[6], r_w.locals[7]);
 120        printk("i0: %08x i1: %08x i2: %08x i3: %08x "
 121               "i4: %08x i5: %08x i6: %08x i7: %08x\n",
 122               r_w.ins[0], r_w.ins[1], r_w.ins[2], r_w.ins[3],
 123               r_w.ins[4], r_w.ins[5], r_w.ins[6], r_w.ins[7]);
 124}
 125#else
 126#define show_regwindow32(regs)  do { } while (0)
 127#endif
 128
 129static void show_regwindow(struct pt_regs *regs)
 130{
 131        struct reg_window __user *rw;
 132        struct reg_window *rwk;
 133        struct reg_window r_w;
 134
 135        if ((regs->tstate & TSTATE_PRIV) || !(test_thread_flag(TIF_32BIT))) {
 136                __asm__ __volatile__ ("flushw");
 137                rw = (struct reg_window __user *)
 138                        (regs->u_regs[14] + STACK_BIAS);
 139                rwk = (struct reg_window *)
 140                        (regs->u_regs[14] + STACK_BIAS);
 141                if (!(regs->tstate & TSTATE_PRIV)) {
 142                        if (copy_from_user (&r_w, rw, sizeof(r_w))) {
 143                                return;
 144                        }
 145                        rwk = &r_w;
 146                }
 147        } else {
 148                show_regwindow32(regs);
 149                return;
 150        }
 151        printk("l0: %016lx l1: %016lx l2: %016lx l3: %016lx\n",
 152               rwk->locals[0], rwk->locals[1], rwk->locals[2], rwk->locals[3]);
 153        printk("l4: %016lx l5: %016lx l6: %016lx l7: %016lx\n",
 154               rwk->locals[4], rwk->locals[5], rwk->locals[6], rwk->locals[7]);
 155        printk("i0: %016lx i1: %016lx i2: %016lx i3: %016lx\n",
 156               rwk->ins[0], rwk->ins[1], rwk->ins[2], rwk->ins[3]);
 157        printk("i4: %016lx i5: %016lx i6: %016lx i7: %016lx\n",
 158               rwk->ins[4], rwk->ins[5], rwk->ins[6], rwk->ins[7]);
 159        if (regs->tstate & TSTATE_PRIV)
 160                printk("I7: <%pS>\n", (void *) rwk->ins[7]);
 161}
 162
 163void show_regs(struct pt_regs *regs)
 164{
 165        show_regs_print_info(KERN_DEFAULT);
 166
 167        printk("TSTATE: %016lx TPC: %016lx TNPC: %016lx Y: %08x    %s\n", regs->tstate,
 168               regs->tpc, regs->tnpc, regs->y, print_tainted());
 169        printk("TPC: <%pS>\n", (void *) regs->tpc);
 170        printk("g0: %016lx g1: %016lx g2: %016lx g3: %016lx\n",
 171               regs->u_regs[0], regs->u_regs[1], regs->u_regs[2],
 172               regs->u_regs[3]);
 173        printk("g4: %016lx g5: %016lx g6: %016lx g7: %016lx\n",
 174               regs->u_regs[4], regs->u_regs[5], regs->u_regs[6],
 175               regs->u_regs[7]);
 176        printk("o0: %016lx o1: %016lx o2: %016lx o3: %016lx\n",
 177               regs->u_regs[8], regs->u_regs[9], regs->u_regs[10],
 178               regs->u_regs[11]);
 179        printk("o4: %016lx o5: %016lx sp: %016lx ret_pc: %016lx\n",
 180               regs->u_regs[12], regs->u_regs[13], regs->u_regs[14],
 181               regs->u_regs[15]);
 182        printk("RPC: <%pS>\n", (void *) regs->u_regs[15]);
 183        show_regwindow(regs);
 184        show_stack(current, (unsigned long *)regs->u_regs[UREG_FP], KERN_DEFAULT);
 185}
 186
 187union global_cpu_snapshot global_cpu_snapshot[NR_CPUS];
 188static DEFINE_SPINLOCK(global_cpu_snapshot_lock);
 189
 190static void __global_reg_self(struct thread_info *tp, struct pt_regs *regs,
 191                              int this_cpu)
 192{
 193        struct global_reg_snapshot *rp;
 194
 195        flushw_all();
 196
 197        rp = &global_cpu_snapshot[this_cpu].reg;
 198
 199        rp->tstate = regs->tstate;
 200        rp->tpc = regs->tpc;
 201        rp->tnpc = regs->tnpc;
 202        rp->o7 = regs->u_regs[UREG_I7];
 203
 204        if (regs->tstate & TSTATE_PRIV) {
 205                struct reg_window *rw;
 206
 207                rw = (struct reg_window *)
 208                        (regs->u_regs[UREG_FP] + STACK_BIAS);
 209                if (kstack_valid(tp, (unsigned long) rw)) {
 210                        rp->i7 = rw->ins[7];
 211                        rw = (struct reg_window *)
 212                                (rw->ins[6] + STACK_BIAS);
 213                        if (kstack_valid(tp, (unsigned long) rw))
 214                                rp->rpc = rw->ins[7];
 215                }
 216        } else {
 217                rp->i7 = 0;
 218                rp->rpc = 0;
 219        }
 220        rp->thread = tp;
 221}
 222
 223/* In order to avoid hangs we do not try to synchronize with the
 224 * global register dump client cpus.  The last store they make is to
 225 * the thread pointer, so do a short poll waiting for that to become
 226 * non-NULL.
 227 */
 228static void __global_reg_poll(struct global_reg_snapshot *gp)
 229{
 230        int limit = 0;
 231
 232        while (!gp->thread && ++limit < 100) {
 233                barrier();
 234                udelay(1);
 235        }
 236}
 237
 238void arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self)
 239{
 240        struct thread_info *tp = current_thread_info();
 241        struct pt_regs *regs = get_irq_regs();
 242        unsigned long flags;
 243        int this_cpu, cpu;
 244
 245        if (!regs)
 246                regs = tp->kregs;
 247
 248        spin_lock_irqsave(&global_cpu_snapshot_lock, flags);
 249
 250        this_cpu = raw_smp_processor_id();
 251
 252        memset(global_cpu_snapshot, 0, sizeof(global_cpu_snapshot));
 253
 254        if (cpumask_test_cpu(this_cpu, mask) && !exclude_self)
 255                __global_reg_self(tp, regs, this_cpu);
 256
 257        smp_fetch_global_regs();
 258
 259        for_each_cpu(cpu, mask) {
 260                struct global_reg_snapshot *gp;
 261
 262                if (exclude_self && cpu == this_cpu)
 263                        continue;
 264
 265                gp = &global_cpu_snapshot[cpu].reg;
 266
 267                __global_reg_poll(gp);
 268
 269                tp = gp->thread;
 270                printk("%c CPU[%3d]: TSTATE[%016lx] TPC[%016lx] TNPC[%016lx] TASK[%s:%d]\n",
 271                       (cpu == this_cpu ? '*' : ' '), cpu,
 272                       gp->tstate, gp->tpc, gp->tnpc,
 273                       ((tp && tp->task) ? tp->task->comm : "NULL"),
 274                       ((tp && tp->task) ? tp->task->pid : -1));
 275
 276                if (gp->tstate & TSTATE_PRIV) {
 277                        printk("             TPC[%pS] O7[%pS] I7[%pS] RPC[%pS]\n",
 278                               (void *) gp->tpc,
 279                               (void *) gp->o7,
 280                               (void *) gp->i7,
 281                               (void *) gp->rpc);
 282                } else {
 283                        printk("             TPC[%lx] O7[%lx] I7[%lx] RPC[%lx]\n",
 284                               gp->tpc, gp->o7, gp->i7, gp->rpc);
 285                }
 286
 287                touch_nmi_watchdog();
 288        }
 289
 290        memset(global_cpu_snapshot, 0, sizeof(global_cpu_snapshot));
 291
 292        spin_unlock_irqrestore(&global_cpu_snapshot_lock, flags);
 293}
 294
 295#ifdef CONFIG_MAGIC_SYSRQ
 296
 297static void sysrq_handle_globreg(int key)
 298{
 299        trigger_all_cpu_backtrace();
 300}
 301
 302static const struct sysrq_key_op sparc_globalreg_op = {
 303        .handler        = sysrq_handle_globreg,
 304        .help_msg       = "global-regs(y)",
 305        .action_msg     = "Show Global CPU Regs",
 306};
 307
 308static void __global_pmu_self(int this_cpu)
 309{
 310        struct global_pmu_snapshot *pp;
 311        int i, num;
 312
 313        if (!pcr_ops)
 314                return;
 315
 316        pp = &global_cpu_snapshot[this_cpu].pmu;
 317
 318        num = 1;
 319        if (tlb_type == hypervisor &&
 320            sun4v_chip_type >= SUN4V_CHIP_NIAGARA4)
 321                num = 4;
 322
 323        for (i = 0; i < num; i++) {
 324                pp->pcr[i] = pcr_ops->read_pcr(i);
 325                pp->pic[i] = pcr_ops->read_pic(i);
 326        }
 327}
 328
 329static void __global_pmu_poll(struct global_pmu_snapshot *pp)
 330{
 331        int limit = 0;
 332
 333        while (!pp->pcr[0] && ++limit < 100) {
 334                barrier();
 335                udelay(1);
 336        }
 337}
 338
 339static void pmu_snapshot_all_cpus(void)
 340{
 341        unsigned long flags;
 342        int this_cpu, cpu;
 343
 344        spin_lock_irqsave(&global_cpu_snapshot_lock, flags);
 345
 346        memset(global_cpu_snapshot, 0, sizeof(global_cpu_snapshot));
 347
 348        this_cpu = raw_smp_processor_id();
 349
 350        __global_pmu_self(this_cpu);
 351
 352        smp_fetch_global_pmu();
 353
 354        for_each_online_cpu(cpu) {
 355                struct global_pmu_snapshot *pp = &global_cpu_snapshot[cpu].pmu;
 356
 357                __global_pmu_poll(pp);
 358
 359                printk("%c CPU[%3d]: PCR[%08lx:%08lx:%08lx:%08lx] PIC[%08lx:%08lx:%08lx:%08lx]\n",
 360                       (cpu == this_cpu ? '*' : ' '), cpu,
 361                       pp->pcr[0], pp->pcr[1], pp->pcr[2], pp->pcr[3],
 362                       pp->pic[0], pp->pic[1], pp->pic[2], pp->pic[3]);
 363
 364                touch_nmi_watchdog();
 365        }
 366
 367        memset(global_cpu_snapshot, 0, sizeof(global_cpu_snapshot));
 368
 369        spin_unlock_irqrestore(&global_cpu_snapshot_lock, flags);
 370}
 371
 372static void sysrq_handle_globpmu(int key)
 373{
 374        pmu_snapshot_all_cpus();
 375}
 376
 377static const struct sysrq_key_op sparc_globalpmu_op = {
 378        .handler        = sysrq_handle_globpmu,
 379        .help_msg       = "global-pmu(x)",
 380        .action_msg     = "Show Global PMU Regs",
 381};
 382
 383static int __init sparc_sysrq_init(void)
 384{
 385        int ret = register_sysrq_key('y', &sparc_globalreg_op);
 386
 387        if (!ret)
 388                ret = register_sysrq_key('x', &sparc_globalpmu_op);
 389        return ret;
 390}
 391
 392core_initcall(sparc_sysrq_init);
 393
 394#endif
 395
 396/* Free current thread data structures etc.. */
 397void exit_thread(struct task_struct *tsk)
 398{
 399        struct thread_info *t = task_thread_info(tsk);
 400
 401        if (t->utraps) {
 402                if (t->utraps[0] < 2)
 403                        kfree (t->utraps);
 404                else
 405                        t->utraps[0]--;
 406        }
 407}
 408
 409void flush_thread(void)
 410{
 411        struct thread_info *t = current_thread_info();
 412        struct mm_struct *mm;
 413
 414        mm = t->task->mm;
 415        if (mm)
 416                tsb_context_switch(mm);
 417
 418        set_thread_wsaved(0);
 419
 420        /* Clear FPU register state. */
 421        t->fpsaved[0] = 0;
 422}
 423
 424/* It's a bit more tricky when 64-bit tasks are involved... */
 425static unsigned long clone_stackframe(unsigned long csp, unsigned long psp)
 426{
 427        bool stack_64bit = test_thread_64bit_stack(psp);
 428        unsigned long fp, distance, rval;
 429
 430        if (stack_64bit) {
 431                csp += STACK_BIAS;
 432                psp += STACK_BIAS;
 433                __get_user(fp, &(((struct reg_window __user *)psp)->ins[6]));
 434                fp += STACK_BIAS;
 435                if (test_thread_flag(TIF_32BIT))
 436                        fp &= 0xffffffff;
 437        } else
 438                __get_user(fp, &(((struct reg_window32 __user *)psp)->ins[6]));
 439
 440        /* Now align the stack as this is mandatory in the Sparc ABI
 441         * due to how register windows work.  This hides the
 442         * restriction from thread libraries etc.
 443         */
 444        csp &= ~15UL;
 445
 446        distance = fp - psp;
 447        rval = (csp - distance);
 448        if (raw_copy_in_user((void __user *)rval, (void __user *)psp, distance))
 449                rval = 0;
 450        else if (!stack_64bit) {
 451                if (put_user(((u32)csp),
 452                             &(((struct reg_window32 __user *)rval)->ins[6])))
 453                        rval = 0;
 454        } else {
 455                if (put_user(((u64)csp - STACK_BIAS),
 456                             &(((struct reg_window __user *)rval)->ins[6])))
 457                        rval = 0;
 458                else
 459                        rval = rval - STACK_BIAS;
 460        }
 461
 462        return rval;
 463}
 464
 465/* Standard stuff. */
 466static inline void shift_window_buffer(int first_win, int last_win,
 467                                       struct thread_info *t)
 468{
 469        int i;
 470
 471        for (i = first_win; i < last_win; i++) {
 472                t->rwbuf_stkptrs[i] = t->rwbuf_stkptrs[i+1];
 473                memcpy(&t->reg_window[i], &t->reg_window[i+1],
 474                       sizeof(struct reg_window));
 475        }
 476}
 477
 478void synchronize_user_stack(void)
 479{
 480        struct thread_info *t = current_thread_info();
 481        unsigned long window;
 482
 483        flush_user_windows();
 484        if ((window = get_thread_wsaved()) != 0) {
 485                window -= 1;
 486                do {
 487                        struct reg_window *rwin = &t->reg_window[window];
 488                        int winsize = sizeof(struct reg_window);
 489                        unsigned long sp;
 490
 491                        sp = t->rwbuf_stkptrs[window];
 492
 493                        if (test_thread_64bit_stack(sp))
 494                                sp += STACK_BIAS;
 495                        else
 496                                winsize = sizeof(struct reg_window32);
 497
 498                        if (!copy_to_user((char __user *)sp, rwin, winsize)) {
 499                                shift_window_buffer(window, get_thread_wsaved() - 1, t);
 500                                set_thread_wsaved(get_thread_wsaved() - 1);
 501                        }
 502                } while (window--);
 503        }
 504}
 505
 506static void stack_unaligned(unsigned long sp)
 507{
 508        force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *) sp);
 509}
 510
 511static const char uwfault32[] = KERN_INFO \
 512        "%s[%d]: bad register window fault: SP %08lx (orig_sp %08lx) TPC %08lx O7 %08lx\n";
 513static const char uwfault64[] = KERN_INFO \
 514        "%s[%d]: bad register window fault: SP %016lx (orig_sp %016lx) TPC %08lx O7 %016lx\n";
 515
 516void fault_in_user_windows(struct pt_regs *regs)
 517{
 518        struct thread_info *t = current_thread_info();
 519        unsigned long window;
 520
 521        flush_user_windows();
 522        window = get_thread_wsaved();
 523
 524        if (likely(window != 0)) {
 525                window -= 1;
 526                do {
 527                        struct reg_window *rwin = &t->reg_window[window];
 528                        int winsize = sizeof(struct reg_window);
 529                        unsigned long sp, orig_sp;
 530
 531                        orig_sp = sp = t->rwbuf_stkptrs[window];
 532
 533                        if (test_thread_64bit_stack(sp))
 534                                sp += STACK_BIAS;
 535                        else
 536                                winsize = sizeof(struct reg_window32);
 537
 538                        if (unlikely(sp & 0x7UL))
 539                                stack_unaligned(sp);
 540
 541                        if (unlikely(copy_to_user((char __user *)sp,
 542                                                  rwin, winsize))) {
 543                                if (show_unhandled_signals)
 544                                        printk_ratelimited(is_compat_task() ?
 545                                                           uwfault32 : uwfault64,
 546                                                           current->comm, current->pid,
 547                                                           sp, orig_sp,
 548                                                           regs->tpc,
 549                                                           regs->u_regs[UREG_I7]);
 550                                goto barf;
 551                        }
 552                } while (window--);
 553        }
 554        set_thread_wsaved(0);
 555        return;
 556
 557barf:
 558        set_thread_wsaved(window + 1);
 559        force_sig(SIGSEGV);
 560}
 561
 562/* Copy a Sparc thread.  The fork() return value conventions
 563 * under SunOS are nothing short of bletcherous:
 564 * Parent -->  %o0 == childs  pid, %o1 == 0
 565 * Child  -->  %o0 == parents pid, %o1 == 1
 566 */
 567int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg,
 568                struct task_struct *p, unsigned long tls)
 569{
 570        struct thread_info *t = task_thread_info(p);
 571        struct pt_regs *regs = current_pt_regs();
 572        struct sparc_stackf *parent_sf;
 573        unsigned long child_stack_sz;
 574        char *child_trap_frame;
 575
 576        /* Calculate offset to stack_frame & pt_regs */
 577        child_stack_sz = (STACKFRAME_SZ + TRACEREG_SZ);
 578        child_trap_frame = (task_stack_page(p) +
 579                            (THREAD_SIZE - child_stack_sz));
 580
 581        t->new_child = 1;
 582        t->ksp = ((unsigned long) child_trap_frame) - STACK_BIAS;
 583        t->kregs = (struct pt_regs *) (child_trap_frame +
 584                                       sizeof(struct sparc_stackf));
 585        t->fpsaved[0] = 0;
 586
 587        if (unlikely(p->flags & (PF_KTHREAD | PF_IO_WORKER))) {
 588                memset(child_trap_frame, 0, child_stack_sz);
 589                __thread_flag_byte_ptr(t)[TI_FLAG_BYTE_CWP] = 
 590                        (current_pt_regs()->tstate + 1) & TSTATE_CWP;
 591                t->kregs->u_regs[UREG_G1] = sp; /* function */
 592                t->kregs->u_regs[UREG_G2] = arg;
 593                return 0;
 594        }
 595
 596        parent_sf = ((struct sparc_stackf *) regs) - 1;
 597        memcpy(child_trap_frame, parent_sf, child_stack_sz);
 598        if (t->flags & _TIF_32BIT) {
 599                sp &= 0x00000000ffffffffUL;
 600                regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
 601        }
 602        t->kregs->u_regs[UREG_FP] = sp;
 603        __thread_flag_byte_ptr(t)[TI_FLAG_BYTE_CWP] = 
 604                (regs->tstate + 1) & TSTATE_CWP;
 605        if (sp != regs->u_regs[UREG_FP]) {
 606                unsigned long csp;
 607
 608                csp = clone_stackframe(sp, regs->u_regs[UREG_FP]);
 609                if (!csp)
 610                        return -EFAULT;
 611                t->kregs->u_regs[UREG_FP] = csp;
 612        }
 613        if (t->utraps)
 614                t->utraps[0]++;
 615
 616        /* Set the return value for the child. */
 617        t->kregs->u_regs[UREG_I0] = current->pid;
 618        t->kregs->u_regs[UREG_I1] = 1;
 619
 620        /* Set the second return value for the parent. */
 621        regs->u_regs[UREG_I1] = 0;
 622
 623        if (clone_flags & CLONE_SETTLS)
 624                t->kregs->u_regs[UREG_G7] = tls;
 625
 626        return 0;
 627}
 628
 629/* TIF_MCDPER in thread info flags for current task is updated lazily upon
 630 * a context switch. Update this flag in current task's thread flags
 631 * before dup so the dup'd task will inherit the current TIF_MCDPER flag.
 632 */
 633int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
 634{
 635        if (adi_capable()) {
 636                register unsigned long tmp_mcdper;
 637
 638                __asm__ __volatile__(
 639                        ".word 0x83438000\n\t"  /* rd  %mcdper, %g1 */
 640                        "mov %%g1, %0\n\t"
 641                        : "=r" (tmp_mcdper)
 642                        :
 643                        : "g1");
 644                if (tmp_mcdper)
 645                        set_thread_flag(TIF_MCDPER);
 646                else
 647                        clear_thread_flag(TIF_MCDPER);
 648        }
 649
 650        *dst = *src;
 651        return 0;
 652}
 653
 654unsigned long __get_wchan(struct task_struct *task)
 655{
 656        unsigned long pc, fp, bias = 0;
 657        struct thread_info *tp;
 658        struct reg_window *rw;
 659        unsigned long ret = 0;
 660        int count = 0; 
 661
 662        tp = task_thread_info(task);
 663        bias = STACK_BIAS;
 664        fp = task_thread_info(task)->ksp + bias;
 665
 666        do {
 667                if (!kstack_valid(tp, fp))
 668                        break;
 669                rw = (struct reg_window *) fp;
 670                pc = rw->ins[7];
 671                if (!in_sched_functions(pc)) {
 672                        ret = pc;
 673                        goto out;
 674                }
 675                fp = rw->ins[6] + bias;
 676        } while (++count < 16);
 677
 678out:
 679        return ret;
 680}
 681