~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/riscv/kernel/process.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/riscv/kernel/process.c (Architecture mips) and /arch/m68k/kernel/process.c (Architecture m68k)


  1 // SPDX-License-Identifier: GPL-2.0-or-later   !!   1 // SPDX-License-Identifier: GPL-2.0
  2 /*                                                  2 /*
  3  * Copyright (C) 2009 Sunplus Core Technology  !!   3  *  linux/arch/m68k/kernel/process.c
  4  *  Chen Liqin <liqin.chen@sunplusct.com>      !!   4  *
  5  *  Lennox Wu <lennox.wu@sunplusct.com>        !!   5  *  Copyright (C) 1995  Hamish Macdonald
  6  * Copyright (C) 2012 Regents of the Universit !!   6  *
  7  * Copyright (C) 2017 SiFive                   !!   7  *  68060 fixes by Jesper Skov
  8  */                                                 8  */
  9                                                     9 
 10 #include <linux/cpu.h>                         !!  10 /*
 11 #include <linux/kernel.h>                      !!  11  * This file handles the architecture-dependent parts of process handling..
                                                   >>  12  */
                                                   >>  13 
                                                   >>  14 #include <linux/errno.h>
                                                   >>  15 #include <linux/module.h>
 12 #include <linux/sched.h>                           16 #include <linux/sched.h>
 13 #include <linux/sched/debug.h>                     17 #include <linux/sched/debug.h>
                                                   >>  18 #include <linux/sched/task.h>
 14 #include <linux/sched/task_stack.h>                19 #include <linux/sched/task_stack.h>
 15 #include <linux/tick.h>                        !!  20 #include <linux/kernel.h>
                                                   >>  21 #include <linux/mm.h>
                                                   >>  22 #include <linux/slab.h>
                                                   >>  23 #include <linux/fs.h>
                                                   >>  24 #include <linux/smp.h>
                                                   >>  25 #include <linux/stddef.h>
                                                   >>  26 #include <linux/unistd.h>
 16 #include <linux/ptrace.h>                          27 #include <linux/ptrace.h>
                                                   >>  28 #include <linux/user.h>
                                                   >>  29 #include <linux/reboot.h>
                                                   >>  30 #include <linux/init_task.h>
                                                   >>  31 #include <linux/mqueue.h>
                                                   >>  32 #include <linux/rcupdate.h>
                                                   >>  33 #include <linux/syscalls.h>
 17 #include <linux/uaccess.h>                         34 #include <linux/uaccess.h>
 18 #include <linux/personality.h>                 !!  35 #include <linux/elfcore.h>
 19                                                    36 
 20 #include <asm/unistd.h>                        !!  37 #include <asm/traps.h>
 21 #include <asm/processor.h>                     !!  38 #include <asm/machdep.h>
 22 #include <asm/csr.h>                           !!  39 #include <asm/setup.h>
 23 #include <asm/stacktrace.h>                    !!  40 
 24 #include <asm/string.h>                        !!  41 #include "process.h"
 25 #include <asm/switch_to.h>                     << 
 26 #include <asm/thread_info.h>                   << 
 27 #include <asm/cpuidle.h>                       << 
 28 #include <asm/vector.h>                        << 
 29 #include <asm/cpufeature.h>                    << 
 30 #include <asm/exec.h>                          << 
 31                                                << 
 32 #if defined(CONFIG_STACKPROTECTOR) && !defined << 
 33 #include <linux/stackprotector.h>              << 
 34 unsigned long __stack_chk_guard __read_mostly; << 
 35 EXPORT_SYMBOL(__stack_chk_guard);              << 
 36 #endif                                         << 
 37                                                    42 
 38 extern asmlinkage void ret_from_fork(void);    !!  43 asmlinkage void ret_from_fork(void);
                                                   >>  44 asmlinkage void ret_from_kernel_thread(void);
 39                                                    45 
 40 void noinstr arch_cpu_idle(void)               !!  46 void arch_cpu_idle(void)
 41 {                                                  47 {
 42         cpu_do_idle();                         !!  48 #if defined(MACH_ATARI_ONLY)
                                                   >>  49         /* block out HSYNC on the atari (falcon) */
                                                   >>  50         __asm__("stop #0x2200" : : : "cc");
                                                   >>  51 #else
                                                   >>  52         __asm__("stop #0x2000" : : : "cc");
                                                   >>  53 #endif
 43 }                                                  54 }
 44                                                    55 
 45 int set_unalign_ctl(struct task_struct *tsk, u !!  56 void machine_restart(char * __unused)
 46 {                                                  57 {
 47         if (!unaligned_ctl_available())        !!  58         if (mach_reset)
 48                 return -EINVAL;                !!  59                 mach_reset();
 49                                                !!  60         for (;;);
 50         tsk->thread.align_ctl = val;           << 
 51         return 0;                              << 
 52 }                                                  61 }
 53                                                    62 
 54 int get_unalign_ctl(struct task_struct *tsk, u !!  63 void machine_halt(void)
 55 {                                                  64 {
 56         if (!unaligned_ctl_available())        !!  65         if (mach_halt)
 57                 return -EINVAL;                !!  66                 mach_halt();
 58                                                !!  67         for (;;);
 59         return put_user(tsk->thread.align_ctl, << 
 60 }                                                  68 }
 61                                                    69 
 62 void __show_regs(struct pt_regs *regs)         !!  70 void machine_power_off(void)
 63 {                                                  71 {
 64         show_regs_print_info(KERN_DEFAULT);    !!  72         do_kernel_power_off();
 65                                                !!  73         for (;;);
 66         if (!user_mode(regs)) {                !!  74 }
 67                 pr_cont("epc : %pS\n", (void * << 
 68                 pr_cont(" ra : %pS\n", (void * << 
 69         }                                      << 
 70                                                    75 
 71         pr_cont("epc : " REG_FMT " ra : " REG_ !!  76 void (*pm_power_off)(void);
 72                 regs->epc, regs->ra, regs->sp) !!  77 EXPORT_SYMBOL(pm_power_off);
 73         pr_cont(" gp : " REG_FMT " tp : " REG_ << 
 74                 regs->gp, regs->tp, regs->t0); << 
 75         pr_cont(" t1 : " REG_FMT " t2 : " REG_ << 
 76                 regs->t1, regs->t2, regs->s0); << 
 77         pr_cont(" s1 : " REG_FMT " a0 : " REG_ << 
 78                 regs->s1, regs->a0, regs->a1); << 
 79         pr_cont(" a2 : " REG_FMT " a3 : " REG_ << 
 80                 regs->a2, regs->a3, regs->a4); << 
 81         pr_cont(" a5 : " REG_FMT " a6 : " REG_ << 
 82                 regs->a5, regs->a6, regs->a7); << 
 83         pr_cont(" s2 : " REG_FMT " s3 : " REG_ << 
 84                 regs->s2, regs->s3, regs->s4); << 
 85         pr_cont(" s5 : " REG_FMT " s6 : " REG_ << 
 86                 regs->s5, regs->s6, regs->s7); << 
 87         pr_cont(" s8 : " REG_FMT " s9 : " REG_ << 
 88                 regs->s8, regs->s9, regs->s10) << 
 89         pr_cont(" s11: " REG_FMT " t3 : " REG_ << 
 90                 regs->s11, regs->t3, regs->t4) << 
 91         pr_cont(" t5 : " REG_FMT " t6 : " REG_ << 
 92                 regs->t5, regs->t6);           << 
 93                                                    78 
 94         pr_cont("status: " REG_FMT " badaddr:  !!  79 void show_regs(struct pt_regs * regs)
 95                 regs->status, regs->badaddr, r << 
 96 }                                              << 
 97 void show_regs(struct pt_regs *regs)           << 
 98 {                                                  80 {
 99         __show_regs(regs);                     !!  81         pr_info("Format %02x  Vector: %04x  PC: %08lx  Status: %04x    %s\n",
100         if (!user_mode(regs))                  !!  82                 regs->format, regs->vector, regs->pc, regs->sr,
101                 dump_backtrace(regs, NULL, KER !!  83                 print_tainted());
                                                   >>  84         pr_info("ORIG_D0: %08lx  D0: %08lx  A2: %08lx  A1: %08lx\n",
                                                   >>  85                 regs->orig_d0, regs->d0, regs->a2, regs->a1);
                                                   >>  86         pr_info("A0: %08lx  D5: %08lx  D4: %08lx\n", regs->a0, regs->d5,
                                                   >>  87                 regs->d4);
                                                   >>  88         pr_info("D3: %08lx  D2: %08lx  D1: %08lx\n", regs->d3, regs->d2,
                                                   >>  89                 regs->d1);
                                                   >>  90         if (!(regs->sr & PS_S))
                                                   >>  91                 pr_info("USP: %08lx\n", rdusp());
102 }                                                  92 }
103                                                    93 
104 unsigned long arch_align_stack(unsigned long s !!  94 void flush_thread(void)
105 {                                                  95 {
106         if (!(current->personality & ADDR_NO_R !!  96         current->thread.fc = USER_DATA;
107                 sp -= get_random_u32_below(PAG !!  97 #ifdef CONFIG_FPU
108         return sp & ~0xf;                      !!  98         if (!FPU_IS_EMU) {
                                                   >>  99                 unsigned long zero = 0;
                                                   >> 100                 asm volatile("frestore %0": :"m" (zero));
                                                   >> 101         }
                                                   >> 102 #endif
109 }                                                 103 }
110                                                   104 
111 #ifdef CONFIG_COMPAT                           !! 105 /*
112 static bool compat_mode_supported __read_mostl !! 106  * Why not generic sys_clone, you ask?  m68k passes all arguments on stack.
113                                                !! 107  * And we need all registers saved, which means a bunch of stuff pushed
114 bool compat_elf_check_arch(Elf32_Ehdr *hdr)    !! 108  * on top of pt_regs, which means that sys_clone() arguments would be
                                                   >> 109  * buried.  We could, of course, copy them, but it's too costly for no
                                                   >> 110  * good reason - generic clone() would have to copy them *again* for
                                                   >> 111  * kernel_clone() anyway.  So in this case it's actually better to pass pt_regs *
                                                   >> 112  * and extract arguments for kernel_clone() from there.  Eventually we might
                                                   >> 113  * go for calling kernel_clone() directly from the wrapper, but only after we
                                                   >> 114  * are finished with kernel_clone() prototype conversion.
                                                   >> 115  */
                                                   >> 116 asmlinkage int m68k_clone(struct pt_regs *regs)
115 {                                                 117 {
116         return compat_mode_supported &&        !! 118         /* regs will be equal to current_pt_regs() */
117                hdr->e_machine == EM_RISCV &&   !! 119         struct kernel_clone_args args = {
118                hdr->e_ident[EI_CLASS] == ELFCL !! 120                 .flags          = (u32)(regs->d1) & ~CSIGNAL,
                                                   >> 121                 .pidfd          = (int __user *)regs->d3,
                                                   >> 122                 .child_tid      = (int __user *)regs->d4,
                                                   >> 123                 .parent_tid     = (int __user *)regs->d3,
                                                   >> 124                 .exit_signal    = regs->d1 & CSIGNAL,
                                                   >> 125                 .stack          = regs->d2,
                                                   >> 126                 .tls            = regs->d5,
                                                   >> 127         };
                                                   >> 128 
                                                   >> 129         return kernel_clone(&args);
119 }                                                 130 }
120                                                   131 
121 static int __init compat_mode_detect(void)     !! 132 /*
                                                   >> 133  * Because extra registers are saved on the stack after the sys_clone3()
                                                   >> 134  * arguments, this C wrapper extracts them from pt_regs * and then calls the
                                                   >> 135  * generic sys_clone3() implementation.
                                                   >> 136  */
                                                   >> 137 asmlinkage int m68k_clone3(struct pt_regs *regs)
122 {                                                 138 {
123         unsigned long tmp = csr_read(CSR_STATU !! 139         return sys_clone3((struct clone_args __user *)regs->d1, regs->d2);
124                                                << 
125         csr_write(CSR_STATUS, (tmp & ~SR_UXL)  << 
126         compat_mode_supported =                << 
127                         (csr_read(CSR_STATUS)  << 
128                                                << 
129         csr_write(CSR_STATUS, tmp);            << 
130                                                << 
131         pr_info("riscv: ELF compat mode %s",   << 
132                         compat_mode_supported  << 
133                                                << 
134         return 0;                              << 
135 }                                                 140 }
136 early_initcall(compat_mode_detect);            << 
137 #endif                                         << 
138                                                   141 
139 void start_thread(struct pt_regs *regs, unsign !! 142 int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
140         unsigned long sp)                      << 
141 {                                                 143 {
142         regs->status = SR_PIE;                 !! 144         unsigned long clone_flags = args->flags;
143         if (has_fpu()) {                       !! 145         unsigned long usp = args->stack;
144                 regs->status |= SR_FS_INITIAL; !! 146         unsigned long tls = args->tls;
145                 /*                             !! 147         struct fork_frame {
146                  * Restore the initial value t !! 148                 struct switch_stack sw;
147                  * before starting the user pr !! 149                 struct pt_regs regs;
148                  */                            !! 150         } *frame;
149                 fstate_restore(current, regs); << 
150         }                                      << 
151         regs->epc = pc;                        << 
152         regs->sp = sp;                         << 
153                                                   151 
154 #ifdef CONFIG_64BIT                            !! 152         frame = (struct fork_frame *) (task_stack_page(p) + THREAD_SIZE) - 1;
155         regs->status &= ~SR_UXL;               << 
156                                                   153 
157         if (is_compat_task())                  !! 154         p->thread.ksp = (unsigned long)frame;
158                 regs->status |= SR_UXL_32;     !! 155         p->thread.esp0 = (unsigned long)&frame->regs;
159         else                                   << 
160                 regs->status |= SR_UXL_64;     << 
161 #endif                                         << 
162 }                                              << 
163                                                   156 
164 void flush_thread(void)                        << 
165 {                                              << 
166 #ifdef CONFIG_FPU                              << 
167         /*                                        157         /*
168          * Reset FPU state and context         !! 158          * Must save the current SFC/DFC value, NOT the value when
169          *      frm: round to nearest, ties to !! 159          * the parent was last descheduled - RGH  10-08-96
170          *      fflags: accrued exceptions cle << 
171          */                                       160          */
172         fstate_off(current, task_pt_regs(curre !! 161         p->thread.fc = USER_DATA;
173         memset(&current->thread.fstate, 0, siz << 
174 #endif                                         << 
175 #ifdef CONFIG_RISCV_ISA_V                      << 
176         /* Reset vector state */               << 
177         riscv_v_vstate_ctrl_init(current);     << 
178         riscv_v_vstate_off(task_pt_regs(curren << 
179         kfree(current->thread.vstate.datap);   << 
180         memset(&current->thread.vstate, 0, siz << 
181         clear_tsk_thread_flag(current, TIF_RIS << 
182 #endif                                         << 
183 }                                              << 
184                                                   162 
185 void arch_release_task_struct(struct task_stru !! 163         if (unlikely(args->fn)) {
186 {                                              !! 164                 /* kernel thread */
187         /* Free the vector context of datap. * !! 165                 memset(frame, 0, sizeof(struct fork_frame));
188         if (has_vector())                      !! 166                 frame->regs.sr = PS_S;
189                 riscv_v_thread_free(tsk);      !! 167                 frame->sw.a3 = (unsigned long)args->fn;
190 }                                              !! 168                 frame->sw.d7 = (unsigned long)args->fn_arg;
                                                   >> 169                 frame->sw.retpc = (unsigned long)ret_from_kernel_thread;
                                                   >> 170                 p->thread.usp = 0;
                                                   >> 171                 return 0;
                                                   >> 172         }
                                                   >> 173         memcpy(frame, container_of(current_pt_regs(), struct fork_frame, regs),
                                                   >> 174                 sizeof(struct fork_frame));
                                                   >> 175         frame->regs.d0 = 0;
                                                   >> 176         frame->sw.retpc = (unsigned long)ret_from_fork;
                                                   >> 177         p->thread.usp = usp ?: rdusp();
191                                                   178 
192 int arch_dup_task_struct(struct task_struct *d !! 179         if (clone_flags & CLONE_SETTLS)
193 {                                              !! 180                 task_thread_info(p)->tp_value = tls;
194         fstate_save(src, task_pt_regs(src));   !! 181 
195         *dst = *src;                           !! 182 #ifdef CONFIG_FPU
196         /* clear entire V context, including d !! 183         if (!FPU_IS_EMU) {
197         memset(&dst->thread.vstate, 0, sizeof( !! 184                 /* Copy the current fpu state */
198         memset(&dst->thread.kernel_vstate, 0,  !! 185                 asm volatile ("fsave %0" : : "m" (p->thread.fpstate[0]) : "memory");
199         clear_tsk_thread_flag(dst, TIF_RISCV_V !! 186 
                                                   >> 187                 if (!CPU_IS_060 ? p->thread.fpstate[0] : p->thread.fpstate[2]) {
                                                   >> 188                         if (CPU_IS_COLDFIRE) {
                                                   >> 189                                 asm volatile ("fmovemd %/fp0-%/fp7,%0\n\t"
                                                   >> 190                                               "fmovel %/fpiar,%1\n\t"
                                                   >> 191                                               "fmovel %/fpcr,%2\n\t"
                                                   >> 192                                               "fmovel %/fpsr,%3"
                                                   >> 193                                               :
                                                   >> 194                                               : "m" (p->thread.fp[0]),
                                                   >> 195                                                 "m" (p->thread.fpcntl[0]),
                                                   >> 196                                                 "m" (p->thread.fpcntl[1]),
                                                   >> 197                                                 "m" (p->thread.fpcntl[2])
                                                   >> 198                                               : "memory");
                                                   >> 199                         } else {
                                                   >> 200                                 asm volatile ("fmovemx %/fp0-%/fp7,%0\n\t"
                                                   >> 201                                               "fmoveml %/fpiar/%/fpcr/%/fpsr,%1"
                                                   >> 202                                               :
                                                   >> 203                                               : "m" (p->thread.fp[0]),
                                                   >> 204                                                 "m" (p->thread.fpcntl[0])
                                                   >> 205                                               : "memory");
                                                   >> 206                         }
                                                   >> 207                 }
                                                   >> 208 
                                                   >> 209                 /* Restore the state in case the fpu was busy */
                                                   >> 210                 asm volatile ("frestore %0" : : "m" (p->thread.fpstate[0]));
                                                   >> 211         }
                                                   >> 212 #endif /* CONFIG_FPU */
200                                                   213 
201         return 0;                                 214         return 0;
202 }                                                 215 }
203                                                   216 
204 int copy_thread(struct task_struct *p, const s !! 217 /* Fill in the fpu structure for a core dump.  */
                                                   >> 218 int elf_core_copy_task_fpregs(struct task_struct *t, elf_fpregset_t *fpu)
205 {                                                 219 {
206         unsigned long clone_flags = args->flag !! 220         if (FPU_IS_EMU) {
207         unsigned long usp = args->stack;       !! 221                 int i;
208         unsigned long tls = args->tls;         << 
209         struct pt_regs *childregs = task_pt_re << 
210                                                   222 
211         memset(&p->thread.s, 0, sizeof(p->thre !! 223                 memcpy(fpu->fpcntl, current->thread.fpcntl, 12);
                                                   >> 224                 memcpy(fpu->fpregs, current->thread.fp, 96);
                                                   >> 225                 /* Convert internal fpu reg representation
                                                   >> 226                  * into long double format
                                                   >> 227                  */
                                                   >> 228                 for (i = 0; i < 24; i += 3)
                                                   >> 229                         fpu->fpregs[i] = ((fpu->fpregs[i] & 0xffff0000) << 15) |
                                                   >> 230                                          ((fpu->fpregs[i] & 0x0000ffff) << 16);
                                                   >> 231                 return 1;
                                                   >> 232         }
212                                                   233 
213         /* p->thread holds context to be resto !! 234         if (IS_ENABLED(CONFIG_FPU)) {
214         if (unlikely(args->fn)) {              !! 235                 char fpustate[216];
215                 /* Kernel thread */            !! 236 
216                 memset(childregs, 0, sizeof(st !! 237                 /* First dump the fpu context to avoid protocol violation.  */
217                 /* Supervisor/Machine, irqs on !! 238                 asm volatile ("fsave %0" :: "m" (fpustate[0]) : "memory");
218                 childregs->status = SR_PP | SR !! 239                 if (!CPU_IS_060 ? !fpustate[0] : !fpustate[2])
219                                                !! 240                         return 0;
220                 p->thread.s[0] = (unsigned lon !! 241 
221                 p->thread.s[1] = (unsigned lon !! 242                 if (CPU_IS_COLDFIRE) {
222         } else {                               !! 243                         asm volatile ("fmovel %/fpiar,%0\n\t"
223                 *childregs = *(current_pt_regs !! 244                                       "fmovel %/fpcr,%1\n\t"
224                 /* Turn off status.VS */       !! 245                                       "fmovel %/fpsr,%2\n\t"
225                 riscv_v_vstate_off(childregs); !! 246                                       "fmovemd %/fp0-%/fp7,%3"
226                 if (usp) /* User fork */       !! 247                                       :
227                         childregs->sp = usp;   !! 248                                       : "m" (fpu->fpcntl[0]),
228                 if (clone_flags & CLONE_SETTLS !! 249                                         "m" (fpu->fpcntl[1]),
229                         childregs->tp = tls;   !! 250                                         "m" (fpu->fpcntl[2]),
230                 childregs->a0 = 0; /* Return v !! 251                                         "m" (fpu->fpregs[0])
231                 p->thread.s[0] = 0;            !! 252                                       : "memory");
                                                   >> 253                 } else {
                                                   >> 254                         asm volatile ("fmovem %/fpiar/%/fpcr/%/fpsr,%0"
                                                   >> 255                                       :
                                                   >> 256                                       : "m" (fpu->fpcntl[0])
                                                   >> 257                                       : "memory");
                                                   >> 258                         asm volatile ("fmovemx %/fp0-%/fp7,%0"
                                                   >> 259                                       :
                                                   >> 260                                       : "m" (fpu->fpregs[0])
                                                   >> 261                                       : "memory");
                                                   >> 262                 }
232         }                                         263         }
233         p->thread.riscv_v_flags = 0;           !! 264 
234         if (has_vector())                      !! 265         return 1;
235                 riscv_v_thread_alloc(p);       << 
236         p->thread.ra = (unsigned long)ret_from << 
237         p->thread.sp = (unsigned long)childreg << 
238         return 0;                              << 
239 }                                                 266 }
240                                                   267 
241 void __init arch_task_cache_init(void)         !! 268 unsigned long __get_wchan(struct task_struct *p)
242 {                                                 269 {
243         riscv_v_setup_ctx_cache();             !! 270         unsigned long fp, pc;
                                                   >> 271         unsigned long stack_page;
                                                   >> 272         int count = 0;
                                                   >> 273 
                                                   >> 274         stack_page = (unsigned long)task_stack_page(p);
                                                   >> 275         fp = ((struct switch_stack *)p->thread.ksp)->a6;
                                                   >> 276         do {
                                                   >> 277                 if (fp < stack_page+sizeof(struct thread_info) ||
                                                   >> 278                     fp >= 8184+stack_page)
                                                   >> 279                         return 0;
                                                   >> 280                 pc = ((unsigned long *)fp)[1];
                                                   >> 281                 if (!in_sched_functions(pc))
                                                   >> 282                         return pc;
                                                   >> 283                 fp = *(unsigned long *) fp;
                                                   >> 284         } while (count++ < 16);
                                                   >> 285         return 0;
244 }                                                 286 }
245                                                   287 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php