diff options
Diffstat (limited to 'arch/arc/kernel/troubleshoot.c')
| -rw-r--r-- | arch/arc/kernel/troubleshoot.c | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/arch/arc/kernel/troubleshoot.c b/arch/arc/kernel/troubleshoot.c index e8d9fb452346..215f515442e0 100644 --- a/arch/arc/kernel/troubleshoot.c +++ b/arch/arc/kernel/troubleshoot.c | |||
| @@ -18,6 +18,8 @@ | |||
| 18 | #include <asm/arcregs.h> | 18 | #include <asm/arcregs.h> |
| 19 | #include <asm/irqflags.h> | 19 | #include <asm/irqflags.h> |
| 20 | 20 | ||
| 21 | #define ARC_PATH_MAX 256 | ||
| 22 | |||
| 21 | /* | 23 | /* |
| 22 | * Common routine to print scratch regs (r0-r12) or callee regs (r13-r25) | 24 | * Common routine to print scratch regs (r0-r12) or callee regs (r13-r25) |
| 23 | * -Prints 3 regs per line and a CR. | 25 | * -Prints 3 regs per line and a CR. |
| @@ -58,11 +60,12 @@ static void show_callee_regs(struct callee_regs *cregs) | |||
| 58 | print_reg_file(&(cregs->r13), 13); | 60 | print_reg_file(&(cregs->r13), 13); |
| 59 | } | 61 | } |
| 60 | 62 | ||
| 61 | static void print_task_path_n_nm(struct task_struct *tsk, char *buf) | 63 | static void print_task_path_n_nm(struct task_struct *tsk) |
| 62 | { | 64 | { |
| 63 | char *path_nm = NULL; | 65 | char *path_nm = NULL; |
| 64 | struct mm_struct *mm; | 66 | struct mm_struct *mm; |
| 65 | struct file *exe_file; | 67 | struct file *exe_file; |
| 68 | char buf[ARC_PATH_MAX]; | ||
| 66 | 69 | ||
| 67 | mm = get_task_mm(tsk); | 70 | mm = get_task_mm(tsk); |
| 68 | if (!mm) | 71 | if (!mm) |
| @@ -72,7 +75,7 @@ static void print_task_path_n_nm(struct task_struct *tsk, char *buf) | |||
| 72 | mmput(mm); | 75 | mmput(mm); |
| 73 | 76 | ||
| 74 | if (exe_file) { | 77 | if (exe_file) { |
| 75 | path_nm = file_path(exe_file, buf, 255); | 78 | path_nm = file_path(exe_file, buf, ARC_PATH_MAX-1); |
| 76 | fput(exe_file); | 79 | fput(exe_file); |
| 77 | } | 80 | } |
| 78 | 81 | ||
| @@ -80,10 +83,9 @@ done: | |||
| 80 | pr_info("Path: %s\n", !IS_ERR(path_nm) ? path_nm : "?"); | 83 | pr_info("Path: %s\n", !IS_ERR(path_nm) ? path_nm : "?"); |
| 81 | } | 84 | } |
| 82 | 85 | ||
| 83 | static void show_faulting_vma(unsigned long address, char *buf) | 86 | static void show_faulting_vma(unsigned long address) |
| 84 | { | 87 | { |
| 85 | struct vm_area_struct *vma; | 88 | struct vm_area_struct *vma; |
| 86 | char *nm = buf; | ||
| 87 | struct mm_struct *active_mm = current->active_mm; | 89 | struct mm_struct *active_mm = current->active_mm; |
| 88 | 90 | ||
| 89 | /* can't use print_vma_addr() yet as it doesn't check for | 91 | /* can't use print_vma_addr() yet as it doesn't check for |
| @@ -96,8 +98,11 @@ static void show_faulting_vma(unsigned long address, char *buf) | |||
| 96 | * if the container VMA is not found | 98 | * if the container VMA is not found |
| 97 | */ | 99 | */ |
| 98 | if (vma && (vma->vm_start <= address)) { | 100 | if (vma && (vma->vm_start <= address)) { |
| 101 | char buf[ARC_PATH_MAX]; | ||
| 102 | char *nm = "?"; | ||
| 103 | |||
| 99 | if (vma->vm_file) { | 104 | if (vma->vm_file) { |
| 100 | nm = file_path(vma->vm_file, buf, PAGE_SIZE - 1); | 105 | nm = file_path(vma->vm_file, buf, ARC_PATH_MAX-1); |
| 101 | if (IS_ERR(nm)) | 106 | if (IS_ERR(nm)) |
| 102 | nm = "?"; | 107 | nm = "?"; |
| 103 | } | 108 | } |
| @@ -173,13 +178,14 @@ void show_regs(struct pt_regs *regs) | |||
| 173 | { | 178 | { |
| 174 | struct task_struct *tsk = current; | 179 | struct task_struct *tsk = current; |
| 175 | struct callee_regs *cregs; | 180 | struct callee_regs *cregs; |
| 176 | char *buf; | ||
| 177 | 181 | ||
| 178 | buf = (char *)__get_free_page(GFP_KERNEL); | 182 | /* |
| 179 | if (!buf) | 183 | * generic code calls us with preemption disabled, but some calls |
| 180 | return; | 184 | * here could sleep, so re-enable to avoid lockdep splat |
| 185 | */ | ||
| 186 | preempt_enable(); | ||
| 181 | 187 | ||
| 182 | print_task_path_n_nm(tsk, buf); | 188 | print_task_path_n_nm(tsk); |
| 183 | show_regs_print_info(KERN_INFO); | 189 | show_regs_print_info(KERN_INFO); |
| 184 | 190 | ||
| 185 | show_ecr_verbose(regs); | 191 | show_ecr_verbose(regs); |
| @@ -189,7 +195,7 @@ void show_regs(struct pt_regs *regs) | |||
| 189 | (void *)regs->blink, (void *)regs->ret); | 195 | (void *)regs->blink, (void *)regs->ret); |
| 190 | 196 | ||
| 191 | if (user_mode(regs)) | 197 | if (user_mode(regs)) |
| 192 | show_faulting_vma(regs->ret, buf); /* faulting code, not data */ | 198 | show_faulting_vma(regs->ret); /* faulting code, not data */ |
| 193 | 199 | ||
| 194 | pr_info("[STAT32]: 0x%08lx", regs->status32); | 200 | pr_info("[STAT32]: 0x%08lx", regs->status32); |
| 195 | 201 | ||
| @@ -222,7 +228,7 @@ void show_regs(struct pt_regs *regs) | |||
| 222 | if (cregs) | 228 | if (cregs) |
| 223 | show_callee_regs(cregs); | 229 | show_callee_regs(cregs); |
| 224 | 230 | ||
| 225 | free_page((unsigned long)buf); | 231 | preempt_disable(); |
| 226 | } | 232 | } |
| 227 | 233 | ||
| 228 | void show_kernel_fault_diag(const char *str, struct pt_regs *regs, | 234 | void show_kernel_fault_diag(const char *str, struct pt_regs *regs, |
