aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm/fault.c
diff options
context:
space:
mode:
authorCatalin Marinas <catalin.marinas@arm.com>2011-11-22 12:30:31 -0500
committerCatalin Marinas <catalin.marinas@arm.com>2011-12-08 05:30:40 -0500
commitf7b8156d150f7383b42622a9219b230b36435b4a (patch)
treec06e0ed558f7a9e106920a9f3acbb6bed15017bf /arch/arm/mm/fault.c
parentc9f27f1026f55b543df260ad8ab84a7bdab7792f (diff)
ARM: LPAE: Add fault handling support
The DFSR and IFSR register format is different when LPAE is enabled. In addition, DFSR and IFSR have similar definitions for the fault type. This modifies the fault code to correctly handle the new format. Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm/mm/fault.c')
-rw-r--r--arch/arm/mm/fault.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 2a0271677725..eb5520fc755f 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -110,8 +110,10 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
110 110
111 pte = pte_offset_map(pmd, addr); 111 pte = pte_offset_map(pmd, addr);
112 printk(", *pte=%08llx", (long long)pte_val(*pte)); 112 printk(", *pte=%08llx", (long long)pte_val(*pte));
113#ifndef CONFIG_ARM_LPAE
113 printk(", *ppte=%08llx", 114 printk(", *ppte=%08llx",
114 (long long)pte_val(pte[PTE_HWTABLE_PTRS])); 115 (long long)pte_val(pte[PTE_HWTABLE_PTRS]));
116#endif
115 pte_unmap(pte); 117 pte_unmap(pte);
116 } while(0); 118 } while(0);
117 119
@@ -428,6 +430,12 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
428 pmd = pmd_offset(pud, addr); 430 pmd = pmd_offset(pud, addr);
429 pmd_k = pmd_offset(pud_k, addr); 431 pmd_k = pmd_offset(pud_k, addr);
430 432
433#ifdef CONFIG_ARM_LPAE
434 /*
435 * Only one hardware entry per PMD with LPAE.
436 */
437 index = 0;
438#else
431 /* 439 /*
432 * On ARM one Linux PGD entry contains two hardware entries (see page 440 * On ARM one Linux PGD entry contains two hardware entries (see page
433 * tables layout in pgtable.h). We normally guarantee that we always 441 * tables layout in pgtable.h). We normally guarantee that we always
@@ -437,6 +445,7 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
437 * for the first of pair. 445 * for the first of pair.
438 */ 446 */
439 index = (addr >> SECTION_SHIFT) & 1; 447 index = (addr >> SECTION_SHIFT) & 1;
448#endif
440 if (pmd_none(pmd_k[index])) 449 if (pmd_none(pmd_k[index]))
441 goto bad_area; 450 goto bad_area;
442 451
@@ -484,7 +493,11 @@ struct fsr_info {
484}; 493};
485 494
486/* FSR definition */ 495/* FSR definition */
496#ifdef CONFIG_ARM_LPAE
497#include "fsr-3level.c"
498#else
487#include "fsr-2level.c" 499#include "fsr-2level.c"
500#endif
488 501
489void __init 502void __init
490hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *), 503hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *),
@@ -553,6 +566,7 @@ do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
553 arm_notify_die("", regs, &info, ifsr, 0); 566 arm_notify_die("", regs, &info, ifsr, 0);
554} 567}
555 568
569#ifndef CONFIG_ARM_LPAE
556static int __init exceptions_init(void) 570static int __init exceptions_init(void)
557{ 571{
558 if (cpu_architecture() >= CPU_ARCH_ARMv6) { 572 if (cpu_architecture() >= CPU_ARCH_ARMv6) {
@@ -575,3 +589,4 @@ static int __init exceptions_init(void)
575} 589}
576 590
577arch_initcall(exceptions_init); 591arch_initcall(exceptions_init);
592#endif