aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arc/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-09 17:36:27 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-09 17:36:27 -0400
commite30f4192456971623b40c97a027346b69457ef69 (patch)
tree11a9a7ccfdc18f5e448661f65b8bbf2a1007b79a /arch/arc/kernel
parentb32729b1eeae7ef8f5709923b36b5a0906d213df (diff)
parenteacd0e950dc2100af54f2a94ae29105bf48ab921 (diff)
Merge tag 'arc-v3.10-rc1-part1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc
Pull ARC port updates from Vineet Gupta: "Support for two new platforms based on ARC700: - Abilis TB10x SoC [Chritisian/Pierrick] - Simulator only System-C Model [Mischa] ARC specific MM improvements: - Avoid full TLB flush (ASID increment) on munmap (even single page) - VIPT Cache Flushing improvements + Delayed dcache flush for non-aliasing dcache (big performance boost) + icache flush aliasing agnostic (no need to kill all possible aliases) Others: - Avoid needless rebuild of DTB files for every kernel build - Remove builtin cmdline as that is already provided by DeviceTree/bootargs - Fixing unaligned access emulation corner case - checkpatch fixes [Sachin] - Various fixlets [Noam] - Minor build failures/cleanups" * tag 'arc-v3.10-rc1-part1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc: (35 commits) ARC: [mm] Lazy D-cache flush (non aliasing VIPT) ARC: [mm] micro-optimize page size icache invalidate ARC: [mm] remove the pessimistic all-alias-invalidate icache helpers ARC: [mm] consolidate icache/dcache sync code ARC: [mm] optimise icache flush for kernel mappings ARC: [mm] optimise icache flush for user mappings ARC: [mm] optimize needless full mm TLB flush on munmap ARC: Add support for nSIM OSCI System C model ARC: [TB10x] Adapt device tree to new compatible string ARC: [TB10x] Add support for TB10x platform ARC: [TB10x] Device tree of TB100 and TB101 Development Kits ARC: Prepare interrupt code for external controllers ARC: Allow embedded arc-intc to be properly placed in DT intc hierarchy ARC: [cmdline] Don't overwrite u-boot provided bootargs ARC: [cmdline] Remove CONFIG_CMDLINE ARC: [plat-arcfpga] defconfig update ARC: unaligned access emulation broken if callee-reg dest of LD/ST ARC: unaligned access emulation error handling consolidation ARC: Debug/crash-printing Improvements ARC: fix typo with clock speed ...
Diffstat (limited to 'arch/arc/kernel')
-rw-r--r--arch/arc/kernel/asm-offsets.c2
-rw-r--r--arch/arc/kernel/clk.c2
-rw-r--r--arch/arc/kernel/disasm.c2
-rw-r--r--arch/arc/kernel/entry.S8
-rw-r--r--arch/arc/kernel/irq.c25
-rw-r--r--arch/arc/kernel/kprobes.c1
-rw-r--r--arch/arc/kernel/module.c4
-rw-r--r--arch/arc/kernel/setup.c36
-rw-r--r--arch/arc/kernel/time.c1
-rw-r--r--arch/arc/kernel/traps.c24
-rw-r--r--arch/arc/kernel/troubleshoot.c50
11 files changed, 81 insertions, 74 deletions
diff --git a/arch/arc/kernel/asm-offsets.c b/arch/arc/kernel/asm-offsets.c
index 0dc148ebce74..7dcda7025241 100644
--- a/arch/arc/kernel/asm-offsets.c
+++ b/arch/arc/kernel/asm-offsets.c
@@ -11,9 +11,9 @@
11#include <linux/interrupt.h> 11#include <linux/interrupt.h>
12#include <linux/thread_info.h> 12#include <linux/thread_info.h>
13#include <linux/kbuild.h> 13#include <linux/kbuild.h>
14#include <linux/ptrace.h>
14#include <asm/hardirq.h> 15#include <asm/hardirq.h>
15#include <asm/page.h> 16#include <asm/page.h>
16#include <asm/ptrace.h>
17 17
18int main(void) 18int main(void)
19{ 19{
diff --git a/arch/arc/kernel/clk.c b/arch/arc/kernel/clk.c
index 66ce0dc917fb..10c7b0b5a079 100644
--- a/arch/arc/kernel/clk.c
+++ b/arch/arc/kernel/clk.c
@@ -8,7 +8,7 @@
8 8
9#include <asm/clk.h> 9#include <asm/clk.h>
10 10
11unsigned long core_freq = 800000000; 11unsigned long core_freq = 80000000;
12 12
13/* 13/*
14 * As of now we default to device-tree provided clock 14 * As of now we default to device-tree provided clock
diff --git a/arch/arc/kernel/disasm.c b/arch/arc/kernel/disasm.c
index d14764ae2c60..b8a549c4f540 100644
--- a/arch/arc/kernel/disasm.c
+++ b/arch/arc/kernel/disasm.c
@@ -12,8 +12,8 @@
12#include <linux/types.h> 12#include <linux/types.h>
13#include <linux/kprobes.h> 13#include <linux/kprobes.h>
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/uaccess.h>
15#include <asm/disasm.h> 16#include <asm/disasm.h>
16#include <asm/uaccess.h>
17 17
18#if defined(CONFIG_KGDB) || defined(CONFIG_ARC_MISALIGN_ACCESS) || \ 18#if defined(CONFIG_KGDB) || defined(CONFIG_ARC_MISALIGN_ACCESS) || \
19 defined(CONFIG_KPROBES) 19 defined(CONFIG_KPROBES)
diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S
index 91eeab81f52d..0c6d664d4a83 100644
--- a/arch/arc/kernel/entry.S
+++ b/arch/arc/kernel/entry.S
@@ -393,12 +393,14 @@ ARC_ENTRY EV_TLBProtV
393#ifdef CONFIG_ARC_MISALIGN_ACCESS 393#ifdef CONFIG_ARC_MISALIGN_ACCESS
394 SAVE_CALLEE_SAVED_USER 394 SAVE_CALLEE_SAVED_USER
395 mov r3, sp ; callee_regs 395 mov r3, sp ; callee_regs
396#endif
397 396
398 bl do_misaligned_access 397 bl do_misaligned_access
399 398
400#ifdef CONFIG_ARC_MISALIGN_ACCESS 399 ; TBD: optimize - do this only if a callee reg was involved
401 DISCARD_CALLEE_SAVED_USER 400 ; either a dst of emulated LD/ST or src with address-writeback
401 RESTORE_CALLEE_SAVED_USER
402#else
403 bl do_misaligned_error
402#endif 404#endif
403 405
404 b ret_from_exception 406 b ret_from_exception
diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c
index 551c10dff481..8115fa531575 100644
--- a/arch/arc/kernel/irq.c
+++ b/arch/arc/kernel/irq.c
@@ -11,6 +11,8 @@
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/of.h> 12#include <linux/of.h>
13#include <linux/irqdomain.h> 13#include <linux/irqdomain.h>
14#include <linux/irqchip.h>
15#include "../../drivers/irqchip/irqchip.h"
14#include <asm/sections.h> 16#include <asm/sections.h>
15#include <asm/irq.h> 17#include <asm/irq.h>
16#include <asm/mach_desc.h> 18#include <asm/mach_desc.h>
@@ -26,7 +28,7 @@
26 * -Disable all IRQs (on CPU side) 28 * -Disable all IRQs (on CPU side)
27 * -Optionally, setup the High priority Interrupts as Level 2 IRQs 29 * -Optionally, setup the High priority Interrupts as Level 2 IRQs
28 */ 30 */
29void __init arc_init_IRQ(void) 31void __cpuinit arc_init_IRQ(void)
30{ 32{
31 int level_mask = 0; 33 int level_mask = 0;
32 34
@@ -97,15 +99,13 @@ static const struct irq_domain_ops arc_intc_domain_ops = {
97 99
98static struct irq_domain *root_domain; 100static struct irq_domain *root_domain;
99 101
100void __init init_onchip_IRQ(void) 102static int __init
103init_onchip_IRQ(struct device_node *intc, struct device_node *parent)
101{ 104{
102 struct device_node *intc = NULL; 105 if (parent)
106 panic("DeviceTree incore intc not a root irq controller\n");
103 107
104 intc = of_find_compatible_node(NULL, NULL, "snps,arc700-intc"); 108 root_domain = irq_domain_add_legacy(intc, NR_CPU_IRQS, 0, 0,
105 if(!intc)
106 panic("DeviceTree Missing incore intc\n");
107
108 root_domain = irq_domain_add_legacy(intc, NR_IRQS, 0, 0,
109 &arc_intc_domain_ops, NULL); 109 &arc_intc_domain_ops, NULL);
110 110
111 if (!root_domain) 111 if (!root_domain)
@@ -113,8 +113,12 @@ void __init init_onchip_IRQ(void)
113 113
114 /* with this we don't need to export root_domain */ 114 /* with this we don't need to export root_domain */
115 irq_set_default_host(root_domain); 115 irq_set_default_host(root_domain);
116
117 return 0;
116} 118}
117 119
120IRQCHIP_DECLARE(arc_intc, "snps,arc700-intc", init_onchip_IRQ);
121
118/* 122/*
119 * Late Interrupt system init called from start_kernel for Boot CPU only 123 * Late Interrupt system init called from start_kernel for Boot CPU only
120 * 124 *
@@ -123,12 +127,13 @@ void __init init_onchip_IRQ(void)
123 */ 127 */
124void __init init_IRQ(void) 128void __init init_IRQ(void)
125{ 129{
126 init_onchip_IRQ();
127
128 /* Any external intc can be setup here */ 130 /* Any external intc can be setup here */
129 if (machine_desc->init_irq) 131 if (machine_desc->init_irq)
130 machine_desc->init_irq(); 132 machine_desc->init_irq();
131 133
134 /* process the entire interrupt tree in one go */
135 irqchip_init();
136
132#ifdef CONFIG_SMP 137#ifdef CONFIG_SMP
133 /* Master CPU can initialize it's side of IPI */ 138 /* Master CPU can initialize it's side of IPI */
134 if (machine_desc->init_smp) 139 if (machine_desc->init_smp)
diff --git a/arch/arc/kernel/kprobes.c b/arch/arc/kernel/kprobes.c
index 3bfeacb674de..5a7b80e2d883 100644
--- a/arch/arc/kernel/kprobes.c
+++ b/arch/arc/kernel/kprobes.c
@@ -10,7 +10,6 @@
10#include <linux/kprobes.h> 10#include <linux/kprobes.h>
11#include <linux/slab.h> 11#include <linux/slab.h>
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/kprobes.h>
14#include <linux/kdebug.h> 13#include <linux/kdebug.h>
15#include <linux/sched.h> 14#include <linux/sched.h>
16#include <linux/uaccess.h> 15#include <linux/uaccess.h>
diff --git a/arch/arc/kernel/module.c b/arch/arc/kernel/module.c
index cdd359352c0a..376e04622962 100644
--- a/arch/arc/kernel/module.c
+++ b/arch/arc/kernel/module.c
@@ -47,7 +47,7 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
47 } 47 }
48 } 48 }
49#endif 49#endif
50 return 0; 50 return 0;
51} 51}
52 52
53void module_arch_cleanup(struct module *mod) 53void module_arch_cleanup(struct module *mod)
@@ -141,5 +141,5 @@ int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
141 mod->arch.unw_info = unw; 141 mod->arch.unw_info = unw;
142 } 142 }
143#endif 143#endif
144 return 0; 144 return 0;
145} 145}
diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
index 2d95ac07df7b..b2b3731dd1e9 100644
--- a/arch/arc/kernel/setup.c
+++ b/arch/arc/kernel/setup.c
@@ -14,14 +14,13 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/cpu.h> 15#include <linux/cpu.h>
16#include <linux/of_fdt.h> 16#include <linux/of_fdt.h>
17#include <linux/cache.h>
17#include <asm/sections.h> 18#include <asm/sections.h>
18#include <asm/arcregs.h> 19#include <asm/arcregs.h>
19#include <asm/tlb.h> 20#include <asm/tlb.h>
20#include <asm/cache.h>
21#include <asm/setup.h> 21#include <asm/setup.h>
22#include <asm/page.h> 22#include <asm/page.h>
23#include <asm/irq.h> 23#include <asm/irq.h>
24#include <asm/arcregs.h>
25#include <asm/prom.h> 24#include <asm/prom.h>
26#include <asm/unwind.h> 25#include <asm/unwind.h>
27#include <asm/clk.h> 26#include <asm/clk.h>
@@ -32,14 +31,14 @@
32int running_on_hw = 1; /* vs. on ISS */ 31int running_on_hw = 1; /* vs. on ISS */
33 32
34char __initdata command_line[COMMAND_LINE_SIZE]; 33char __initdata command_line[COMMAND_LINE_SIZE];
35struct machine_desc *machine_desc __initdata; 34struct machine_desc *machine_desc __cpuinitdata;
36 35
37struct task_struct *_current_task[NR_CPUS]; /* For stack switching */ 36struct task_struct *_current_task[NR_CPUS]; /* For stack switching */
38 37
39struct cpuinfo_arc cpuinfo_arc700[NR_CPUS]; 38struct cpuinfo_arc cpuinfo_arc700[NR_CPUS];
40 39
41 40
42void __init read_arc_build_cfg_regs(void) 41void __cpuinit read_arc_build_cfg_regs(void)
43{ 42{
44 struct bcr_perip uncached_space; 43 struct bcr_perip uncached_space;
45 struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; 44 struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
@@ -238,7 +237,7 @@ char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len)
238 return buf; 237 return buf;
239} 238}
240 239
241void __init arc_chk_ccms(void) 240void __cpuinit arc_chk_ccms(void)
242{ 241{
243#if defined(CONFIG_ARC_HAS_DCCM) || defined(CONFIG_ARC_HAS_ICCM) 242#if defined(CONFIG_ARC_HAS_DCCM) || defined(CONFIG_ARC_HAS_ICCM)
244 struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; 243 struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
@@ -273,7 +272,7 @@ void __init arc_chk_ccms(void)
273 * hardware has dedicated regs which need to be saved/restored on ctx-sw 272 * hardware has dedicated regs which need to be saved/restored on ctx-sw
274 * (Single Precision uses core regs), thus kernel is kind of oblivious to it 273 * (Single Precision uses core regs), thus kernel is kind of oblivious to it
275 */ 274 */
276void __init arc_chk_fpu(void) 275void __cpuinit arc_chk_fpu(void)
277{ 276{
278 struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; 277 struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
279 278
@@ -294,7 +293,7 @@ void __init arc_chk_fpu(void)
294 * such as only for boot CPU etc 293 * such as only for boot CPU etc
295 */ 294 */
296 295
297void __init setup_processor(void) 296void __cpuinit setup_processor(void)
298{ 297{
299 char str[512]; 298 char str[512];
300 int cpu_id = smp_processor_id(); 299 int cpu_id = smp_processor_id();
@@ -319,23 +318,20 @@ void __init setup_processor(void)
319 318
320void __init setup_arch(char **cmdline_p) 319void __init setup_arch(char **cmdline_p)
321{ 320{
321 /* This also populates @boot_command_line from /bootargs */
322 machine_desc = setup_machine_fdt(__dtb_start);
323 if (!machine_desc)
324 panic("Embedded DT invalid\n");
325
326 /* Append any u-boot provided cmdline */
322#ifdef CONFIG_CMDLINE_UBOOT 327#ifdef CONFIG_CMDLINE_UBOOT
323 /* Make sure that a whitespace is inserted before */ 328 /* Add a whitespace seperator between the 2 cmdlines */
324 strlcat(command_line, " ", sizeof(command_line)); 329 strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
330 strlcat(boot_command_line, command_line, COMMAND_LINE_SIZE);
325#endif 331#endif
326 /*
327 * Append .config cmdline to base command line, which might already
328 * contain u-boot "bootargs" (handled by head.S, if so configured)
329 */
330 strlcat(command_line, CONFIG_CMDLINE, sizeof(command_line));
331 332
332 /* Save unparsed command line copy for /proc/cmdline */ 333 /* Save unparsed command line copy for /proc/cmdline */
333 strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); 334 *cmdline_p = boot_command_line;
334 *cmdline_p = command_line;
335
336 machine_desc = setup_machine_fdt(__dtb_start);
337 if (!machine_desc)
338 panic("Embedded DT invalid\n");
339 335
340 /* To force early parsing of things like mem=xxx */ 336 /* To force early parsing of things like mem=xxx */
341 parse_early_param(); 337 parse_early_param();
diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
index f13f72807aa5..09f4309aa2c0 100644
--- a/arch/arc/kernel/time.c
+++ b/arch/arc/kernel/time.c
@@ -33,7 +33,6 @@
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/sched.h> 34#include <linux/sched.h>
35#include <linux/kernel.h> 35#include <linux/kernel.h>
36#include <linux/interrupt.h>
37#include <linux/time.h> 36#include <linux/time.h>
38#include <linux/init.h> 37#include <linux/init.h>
39#include <linux/timex.h> 38#include <linux/timex.h>
diff --git a/arch/arc/kernel/traps.c b/arch/arc/kernel/traps.c
index 7496995371e8..0471d9c9dd54 100644
--- a/arch/arc/kernel/traps.c
+++ b/arch/arc/kernel/traps.c
@@ -16,11 +16,12 @@
16#include <linux/sched.h> 16#include <linux/sched.h>
17#include <linux/kdebug.h> 17#include <linux/kdebug.h>
18#include <linux/uaccess.h> 18#include <linux/uaccess.h>
19#include <asm/ptrace.h> 19#include <linux/ptrace.h>
20#include <linux/kprobes.h>
21#include <linux/kgdb.h>
20#include <asm/setup.h> 22#include <asm/setup.h>
21#include <asm/kprobes.h>
22#include <asm/unaligned.h> 23#include <asm/unaligned.h>
23#include <asm/kgdb.h> 24#include <asm/kprobes.h>
24 25
25void __init trap_init(void) 26void __init trap_init(void)
26{ 27{
@@ -83,6 +84,7 @@ DO_ERROR_INFO(SIGILL, "Invalid Extn Insn", do_extension_fault, ILL_ILLOPC)
83DO_ERROR_INFO(SIGILL, "Illegal Insn (or Seq)", insterror_is_error, ILL_ILLOPC) 84DO_ERROR_INFO(SIGILL, "Illegal Insn (or Seq)", insterror_is_error, ILL_ILLOPC)
84DO_ERROR_INFO(SIGBUS, "Invalid Mem Access", do_memory_error, BUS_ADRERR) 85DO_ERROR_INFO(SIGBUS, "Invalid Mem Access", do_memory_error, BUS_ADRERR)
85DO_ERROR_INFO(SIGTRAP, "Breakpoint Set", trap_is_brkpt, TRAP_BRKPT) 86DO_ERROR_INFO(SIGTRAP, "Breakpoint Set", trap_is_brkpt, TRAP_BRKPT)
87DO_ERROR_INFO(SIGBUS, "Misaligned Access", do_misaligned_error, BUS_ADRALN)
86 88
87#ifdef CONFIG_ARC_MISALIGN_ACCESS 89#ifdef CONFIG_ARC_MISALIGN_ACCESS
88/* 90/*
@@ -91,21 +93,11 @@ DO_ERROR_INFO(SIGTRAP, "Breakpoint Set", trap_is_brkpt, TRAP_BRKPT)
91int do_misaligned_access(unsigned long cause, unsigned long address, 93int do_misaligned_access(unsigned long cause, unsigned long address,
92 struct pt_regs *regs, struct callee_regs *cregs) 94 struct pt_regs *regs, struct callee_regs *cregs)
93{ 95{
94 if (misaligned_fixup(address, regs, cause, cregs) != 0) { 96 if (misaligned_fixup(address, regs, cause, cregs) != 0)
95 siginfo_t info; 97 return do_misaligned_error(cause, address, regs);
96 98
97 info.si_signo = SIGBUS;
98 info.si_errno = 0;
99 info.si_code = BUS_ADRALN;
100 info.si_addr = (void __user *)address;
101 return handle_exception(cause, "Misaligned Access", regs,
102 &info);
103 }
104 return 0; 99 return 0;
105} 100}
106
107#else
108DO_ERROR_INFO(SIGSEGV, "Misaligned Access", do_misaligned_access, SEGV_ACCERR)
109#endif 101#endif
110 102
111/* 103/*
diff --git a/arch/arc/kernel/troubleshoot.c b/arch/arc/kernel/troubleshoot.c
index 0aec01985bf9..11c301b81c92 100644
--- a/arch/arc/kernel/troubleshoot.c
+++ b/arch/arc/kernel/troubleshoot.c
@@ -26,7 +26,6 @@ static noinline void print_reg_file(long *reg_rev, int start_num)
26 char buf[512]; 26 char buf[512];
27 int n = 0, len = sizeof(buf); 27 int n = 0, len = sizeof(buf);
28 28
29 /* weird loop because pt_regs regs rev r12..r0, r25..r13 */
30 for (i = start_num; i < start_num + 13; i++) { 29 for (i = start_num; i < start_num + 13; i++) {
31 n += scnprintf(buf + n, len - n, "r%02u: 0x%08lx\t", 30 n += scnprintf(buf + n, len - n, "r%02u: 0x%08lx\t",
32 i, (unsigned long)*reg_rev); 31 i, (unsigned long)*reg_rev);
@@ -34,13 +33,18 @@ static noinline void print_reg_file(long *reg_rev, int start_num)
34 if (((i + 1) % 3) == 0) 33 if (((i + 1) % 3) == 0)
35 n += scnprintf(buf + n, len - n, "\n"); 34 n += scnprintf(buf + n, len - n, "\n");
36 35
36 /* because pt_regs has regs reversed: r12..r0, r25..r13 */
37 reg_rev--; 37 reg_rev--;
38 } 38 }
39 39
40 if (start_num != 0) 40 if (start_num != 0)
41 n += scnprintf(buf + n, len - n, "\n\n"); 41 n += scnprintf(buf + n, len - n, "\n\n");
42 42
43 pr_info("%s", buf); 43 /* To continue printing callee regs on same line as scratch regs */
44 if (start_num == 0)
45 pr_info("%s", buf);
46 else
47 pr_cont("%s\n", buf);
44} 48}
45 49
46static void show_callee_regs(struct callee_regs *cregs) 50static void show_callee_regs(struct callee_regs *cregs)
@@ -83,6 +87,10 @@ static void show_faulting_vma(unsigned long address, char *buf)
83 dev_t dev = 0; 87 dev_t dev = 0;
84 char *nm = buf; 88 char *nm = buf;
85 89
90 /* can't use print_vma_addr() yet as it doesn't check for
91 * non-inclusive vma
92 */
93
86 vma = find_vma(current->active_mm, address); 94 vma = find_vma(current->active_mm, address);
87 95
88 /* check against the find_vma( ) behaviour which returns the next VMA 96 /* check against the find_vma( ) behaviour which returns the next VMA
@@ -98,10 +106,13 @@ static void show_faulting_vma(unsigned long address, char *buf)
98 ino = inode->i_ino; 106 ino = inode->i_ino;
99 } 107 }
100 pr_info(" @off 0x%lx in [%s]\n" 108 pr_info(" @off 0x%lx in [%s]\n"
101 " VMA: 0x%08lx to 0x%08lx\n\n", 109 " VMA: 0x%08lx to 0x%08lx\n",
102 address - vma->vm_start, nm, vma->vm_start, vma->vm_end); 110 vma->vm_start < TASK_UNMAPPED_BASE ?
103 } else 111 address : address - vma->vm_start,
112 nm, vma->vm_start, vma->vm_end);
113 } else {
104 pr_info(" @No matching VMA found\n"); 114 pr_info(" @No matching VMA found\n");
115 }
105} 116}
106 117
107static void show_ecr_verbose(struct pt_regs *regs) 118static void show_ecr_verbose(struct pt_regs *regs)
@@ -110,7 +121,7 @@ static void show_ecr_verbose(struct pt_regs *regs)
110 unsigned long address; 121 unsigned long address;
111 122
112 cause_reg = current->thread.cause_code; 123 cause_reg = current->thread.cause_code;
113 pr_info("\n[ECR]: 0x%08x => ", cause_reg); 124 pr_info("\n[ECR ]: 0x%08x => ", cause_reg);
114 125
115 /* For Data fault, this is data address not instruction addr */ 126 /* For Data fault, this is data address not instruction addr */
116 address = current->thread.fault_address; 127 address = current->thread.fault_address;
@@ -120,7 +131,7 @@ static void show_ecr_verbose(struct pt_regs *regs)
120 131
121 /* For DTLB Miss or ProtV, display the memory involved too */ 132 /* For DTLB Miss or ProtV, display the memory involved too */
122 if (vec == ECR_V_DTLB_MISS) { 133 if (vec == ECR_V_DTLB_MISS) {
123 pr_cont("Invalid (%s) @ 0x%08lx by insn @ 0x%08lx\n", 134 pr_cont("Invalid %s 0x%08lx by insn @ 0x%08lx\n",
124 (cause_code == 0x01) ? "Read From" : 135 (cause_code == 0x01) ? "Read From" :
125 ((cause_code == 0x02) ? "Write to" : "EX"), 136 ((cause_code == 0x02) ? "Write to" : "EX"),
126 address, regs->ret); 137 address, regs->ret);
@@ -168,20 +179,23 @@ void show_regs(struct pt_regs *regs)
168 if (current->thread.cause_code) 179 if (current->thread.cause_code)
169 show_ecr_verbose(regs); 180 show_ecr_verbose(regs);
170 181
171 pr_info("[EFA]: 0x%08lx\n", current->thread.fault_address); 182 pr_info("[EFA ]: 0x%08lx\n[BLINK ]: %pS\n[ERET ]: %pS\n",
172 pr_info("[ERET]: 0x%08lx (PC of Faulting Instr)\n", regs->ret); 183 current->thread.fault_address,
184 (void *)regs->blink, (void *)regs->ret);
173 185
174 show_faulting_vma(regs->ret, buf); /* faulting code, not data */ 186 if (user_mode(regs))
187 show_faulting_vma(regs->ret, buf); /* faulting code, not data */
175 188
176 /* can't use print_vma_addr() yet as it doesn't check for 189 pr_info("[STAT32]: 0x%08lx", regs->status32);
177 * non-inclusive vma 190
178 */ 191#define STS_BIT(r, bit) r->status32 & STATUS_##bit##_MASK ? #bit : ""
192 if (!user_mode(regs))
193 pr_cont(" : %2s %2s %2s %2s %2s\n",
194 STS_BIT(regs, AE), STS_BIT(regs, A2), STS_BIT(regs, A1),
195 STS_BIT(regs, E2), STS_BIT(regs, E1));
179 196
180 /* print special regs */ 197 pr_info("BTA: 0x%08lx\t SP: 0x%08lx\t FP: 0x%08lx\n",
181 pr_info("status32: 0x%08lx\n", regs->status32); 198 regs->bta, regs->sp, regs->fp);
182 pr_info(" SP: 0x%08lx\tFP: 0x%08lx\n", regs->sp, regs->fp);
183 pr_info("BTA: 0x%08lx\tBLINK: 0x%08lx\n",
184 regs->bta, regs->blink);
185 pr_info("LPS: 0x%08lx\tLPE: 0x%08lx\tLPC: 0x%08lx\n", 199 pr_info("LPS: 0x%08lx\tLPE: 0x%08lx\tLPC: 0x%08lx\n",
186 regs->lp_start, regs->lp_end, regs->lp_count); 200 regs->lp_start, regs->lp_end, regs->lp_count);
187 201