linux/arch/arc/kernel/troubleshoot.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License version 2 as
   6 */
   7
   8#include <linux/ptrace.h>
   9#include <linux/module.h>
  10#include <linux/mm.h>
  11#include <linux/fs.h>
  12#include <linux/kdev_t.h>
  13#include <linux/proc_fs.h>
  14#include <linux/file.h>
  15#include <linux/sched/mm.h>
  16#include <linux/sched/debug.h>
  17
  18#include <asm/arcregs.h>
  19#include <asm/irqflags.h>
  20
  21/*
  22 * Common routine to print scratch regs (r0-r12) or callee regs (r13-r25)
  23 *   -Prints 3 regs per line and a CR.
  24 *   -To continue, callee regs right after scratch, special handling of CR
  25 */
  26static noinline void print_reg_file(long *reg_rev, int start_num)
  27{
  28        unsigned int i;
  29        char buf[512];
  30        int n = 0, len = sizeof(buf);
  31
  32        for (i = start_num; i < start_num + 13; i++) {
  33                n += scnprintf(buf + n, len - n, "r%02u: 0x%08lx\t",
  34                               i, (unsigned long)*reg_rev);
  35
  36                if (((i + 1) % 3) == 0)
  37                        n += scnprintf(buf + n, len - n, "\n");
  38
  39                /* because pt_regs has regs reversed: r12..r0, r25..r13 */
  40                if (is_isa_arcv2() && start_num == 0)
  41                        reg_rev++;
  42                else
  43                        reg_rev--;
  44        }
  45
  46        if (start_num != 0)
  47                n += scnprintf(buf + n, len - n, "\n\n");
  48
  49        /* To continue printing callee regs on same line as scratch regs */
  50        if (start_num == 0)
  51                pr_info("%s", buf);
  52        else
  53                pr_cont("%s\n", buf);
  54}
  55
  56static void show_callee_regs(struct callee_regs *cregs)
  57{
  58        print_reg_file(&(cregs->r13), 13);
  59}
  60
  61static void print_task_path_n_nm(struct task_struct *tsk, char *buf)
  62{
  63        char *path_nm = NULL;
  64        struct mm_struct *mm;
  65        struct file *exe_file;
  66
  67        mm = get_task_mm(tsk);
  68        if (!mm)
  69                goto done;
  70
  71        exe_file = get_mm_exe_file(mm);
  72        mmput(mm);
  73
  74        if (exe_file) {
  75                path_nm = file_path(exe_file, buf, 255);
  76                fput(exe_file);
  77        }
  78
  79done:
  80        pr_info("Path: %s\n", !IS_ERR(path_nm) ? path_nm : "?");
  81}
  82
  83static void show_faulting_vma(unsigned long address, char *buf)
  84{
  85        struct vm_area_struct *vma;
  86        struct inode *inode;
  87        unsigned long ino = 0;
  88        dev_t dev = 0;
  89        char *nm = buf;
  90        struct mm_struct *active_mm = current->active_mm;
  91
  92        /* can't use print_vma_addr() yet as it doesn't check for
  93         * non-inclusive vma
  94         */
  95        down_read(&active_mm->mmap_sem);
  96        vma = find_vma(active_mm, address);
  97
  98        /* check against the find_vma( ) behaviour which returns the next VMA
  99         * if the container VMA is not found
 100         */
 101        if (vma && (vma->vm_start <= address)) {
 102                struct file *file = vma->vm_file;
 103                if (file) {
 104                        nm = file_path(file, buf, PAGE_SIZE - 1);
 105                        inode = file_inode(vma->vm_file);
 106                        dev = inode->i_sb->s_dev;
 107                        ino = inode->i_ino;
 108                }
 109                pr_info("    @off 0x%lx in [%s]\n"
 110                        "    VMA: 0x%08lx to 0x%08lx\n",
 111                        vma->vm_start < TASK_UNMAPPED_BASE ?
 112                                address : address - vma->vm_start,
 113                        nm, vma->vm_start, vma->vm_end);
 114        } else
 115                pr_info("    @No matching VMA found\n");
 116
 117        up_read(&active_mm->mmap_sem);
 118}
 119
 120static void show_ecr_verbose(struct pt_regs *regs)
 121{
 122        unsigned int vec, cause_code;
 123        unsigned long address;
 124
 125        pr_info("\n[ECR   ]: 0x%08lx => ", regs->event);
 126
 127        /* For Data fault, this is data address not instruction addr */
 128        address = current->thread.fault_address;
 129
 130        vec = regs->ecr_vec;
 131        cause_code = regs->ecr_cause;
 132
 133        /* For DTLB Miss or ProtV, display the memory involved too */
 134        if (vec == ECR_V_DTLB_MISS) {
 135                pr_cont("Invalid %s @ 0x%08lx by insn @ 0x%08lx\n",
 136                       (cause_code == 0x01) ? "Read" :
 137                       ((cause_code == 0x02) ? "Write" : "EX"),
 138                       address, regs->ret);
 139        } else if (vec == ECR_V_ITLB_MISS) {
 140                pr_cont("Insn could not be fetched\n");
 141        } else if (vec == ECR_V_MACH_CHK) {
 142                pr_cont("Machine Check (%s)\n", (cause_code == 0x0) ?
 143                                        "Double Fault" : "Other Fatal Err");
 144
 145        } else if (vec == ECR_V_PROTV) {
 146                if (cause_code == ECR_C_PROTV_INST_FETCH)
 147                        pr_cont("Execute from Non-exec Page\n");
 148                else if (cause_code == ECR_C_PROTV_MISALIG_DATA)
 149                        pr_cont("Misaligned r/w from 0x%08lx\n", address);
 150                else
 151                        pr_cont("%s access not allowed on page\n",
 152                                (cause_code == 0x01) ? "Read" :
 153                                ((cause_code == 0x02) ? "Write" : "EX"));
 154        } else if (vec == ECR_V_INSN_ERR) {
 155                pr_cont("Illegal Insn\n");
 156#ifdef CONFIG_ISA_ARCV2
 157        } else if (vec == ECR_V_MEM_ERR) {
 158                if (cause_code == 0x00)
 159                        pr_cont("Bus Error from Insn Mem\n");
 160                else if (cause_code == 0x10)
 161                        pr_cont("Bus Error from Data Mem\n");
 162                else
 163                        pr_cont("Bus Error, check PRM\n");
 164#endif
 165        } else if (vec == ECR_V_TRAP) {
 166                if (regs->ecr_param == 5)
 167                        pr_cont("gcc generated __builtin_trap\n");
 168        } else {
 169                pr_cont("Check Programmer's Manual\n");
 170        }
 171}
 172
 173/************************************************************************
 174 *  API called by rest of kernel
 175 ***********************************************************************/
 176
 177void show_regs(struct pt_regs *regs)
 178{
 179        struct task_struct *tsk = current;
 180        struct callee_regs *cregs;
 181        char *buf;
 182
 183        buf = (char *)__get_free_page(GFP_KERNEL);
 184        if (!buf)
 185                return;
 186
 187        print_task_path_n_nm(tsk, buf);
 188        show_regs_print_info(KERN_INFO);
 189
 190        show_ecr_verbose(regs);
 191
 192        pr_info("[EFA   ]: 0x%08lx\n[BLINK ]: %pS\n[ERET  ]: %pS\n",
 193                current->thread.fault_address,
 194                (void *)regs->blink, (void *)regs->ret);
 195
 196        if (user_mode(regs))
 197                show_faulting_vma(regs->ret, buf); /* faulting code, not data */
 198
 199        pr_info("[STAT32]: 0x%08lx", regs->status32);
 200
 201#define STS_BIT(r, bit) r->status32 & STATUS_##bit##_MASK ? #bit" " : ""
 202
 203#ifdef CONFIG_ISA_ARCOMPACT
 204        pr_cont(" : %2s%2s%2s%2s%2s%2s%2s\n",
 205                        (regs->status32 & STATUS_U_MASK) ? "U " : "K ",
 206                        STS_BIT(regs, DE), STS_BIT(regs, AE),
 207                        STS_BIT(regs, A2), STS_BIT(regs, A1),
 208                        STS_BIT(regs, E2), STS_BIT(regs, E1));
 209#else
 210        pr_cont(" : %2s%2s%2s%2s\n",
 211                        STS_BIT(regs, IE),
 212                        (regs->status32 & STATUS_U_MASK) ? "U " : "K ",
 213                        STS_BIT(regs, DE), STS_BIT(regs, AE));
 214#endif
 215        pr_info("BTA: 0x%08lx\t SP: 0x%08lx\t FP: 0x%08lx\n",
 216                regs->bta, regs->sp, regs->fp);
 217        pr_info("LPS: 0x%08lx\tLPE: 0x%08lx\tLPC: 0x%08lx\n",
 218               regs->lp_start, regs->lp_end, regs->lp_count);
 219
 220        /* print regs->r0 thru regs->r12
 221         * Sequential printing was generating horrible code
 222         */
 223        print_reg_file(&(regs->r0), 0);
 224
 225        /* If Callee regs were saved, display them too */
 226        cregs = (struct callee_regs *)current->thread.callee_reg;
 227        if (cregs)
 228                show_callee_regs(cregs);
 229
 230        free_page((unsigned long)buf);
 231}
 232
 233void show_kernel_fault_diag(const char *str, struct pt_regs *regs,
 234                            unsigned long address)
 235{
 236        current->thread.fault_address = address;
 237
 238        /* Show fault description */
 239        pr_info("\n%s\n", str);
 240
 241        /* Caller and Callee regs */
 242        show_regs(regs);
 243
 244        /* Show stack trace if this Fatality happened in kernel mode */
 245        if (!user_mode(regs))
 246                show_stacktrace(current, regs);
 247}
 248