static void crash_save_this_cpu(struct pt_regs *regs, int cpu) { struct elf_prstatus prstatus; u32 *buf; if ((cpu < 0) || (cpu >= NR_CPUS)) return; /* Using ELF notes here is opportunistic. * I need a well defined structure format * for the data I pass, and I need tags * on the data to indicate what information I have * squirrelled away. ELF notes happen to provide * all of that that no need to invent something new. */ buf = (u32*)per_cpu_ptr(crash_notes, cpu); if (!buf) return; memset(&prstatus, 0, sizeof(prstatus)); prstatus.pr_pid = current->pid; elf_core_copy_regs(&prstatus.pr_reg, regs); buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus, sizeof(prstatus)); final_note(buf); }
/* * Capture the user space registers if the task is not running (in user space) */ int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs) { struct pt_regs ptregs = *task_pt_regs(tsk); ptregs.xcs &= 0xffff; ptregs.xds &= 0xffff; ptregs.xes &= 0xffff; ptregs.xss &= 0xffff; elf_core_copy_regs(regs, &ptregs); return 1; }
/* * Capture the user space registers if the task is not running (in user space) */ int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs) { struct pt_regs ptregs; ptregs = *(struct pt_regs *) ((unsigned long)tsk->thread_info+THREAD_SIZE - sizeof(ptregs)); ptregs.xcs &= 0xffff; ptregs.xds &= 0xffff; ptregs.xes &= 0xffff; ptregs.xss &= 0xffff; elf_core_copy_regs(regs, &ptregs); return 1; }
/* * Return "current" if it looks plausible, or else a pointer to a dummy. * This can be helpful if we are just trying to emit a clean panic. */ struct task_struct *validate_current(void) { static struct task_struct corrupt = { .comm = "<corrupt>" }; struct task_struct *tsk = current; if (unlikely((unsigned long)tsk < PAGE_OFFSET || (void *)tsk > high_memory || ((unsigned long)tsk & (__alignof__(*tsk) - 1)) != 0)) { pr_err("Corrupt 'current' %p (sp %#lx)\n", tsk, stack_pointer); tsk = &corrupt; } return tsk; } /* Take and return the pointer to the previous task, for schedule_tail(). */ struct task_struct *sim_notify_fork(struct task_struct *prev) { struct task_struct *tsk = current; __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_OS_FORK_PARENT | (tsk->thread.creator_pid << _SIM_CONTROL_OPERATOR_BITS)); __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_OS_FORK | (tsk->pid << _SIM_CONTROL_OPERATOR_BITS)); return prev; } int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs) { struct pt_regs *ptregs = task_pt_regs(tsk); elf_core_copy_regs(regs, ptregs); return 1; } #if CHIP_HAS_TILE_DMA() /* Allow user processes to access the DMA SPRs */ void grant_dma_mpls(void) { #if CONFIG_KERNEL_PL == 2 __insn_mtspr(SPR_MPL_DMA_CPL_SET_1, 1); __insn_mtspr(SPR_MPL_DMA_NOTIFY_SET_1, 1); #else __insn_mtspr(SPR_MPL_DMA_CPL_SET_0, 1); __insn_mtspr(SPR_MPL_DMA_NOTIFY_SET_0, 1); #endif }