aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/mmu-hash64.h4
-rw-r--r--arch/powerpc/mm/hash_utils_64.c34
-rw-r--r--arch/powerpc/mm/hugetlbpage-hash64.c2
3 files changed, 34 insertions, 6 deletions
diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h
index 2102b214a87c..0e398cfee2c8 100644
--- a/arch/powerpc/include/asm/mmu-hash64.h
+++ b/arch/powerpc/include/asm/mmu-hash64.h
@@ -250,7 +250,9 @@ extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
250int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, 250int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
251 pte_t *ptep, unsigned long trap, int local, int ssize, 251 pte_t *ptep, unsigned long trap, int local, int ssize,
252 unsigned int shift, unsigned int mmu_psize); 252 unsigned int shift, unsigned int mmu_psize);
253 253extern void hash_failure_debug(unsigned long ea, unsigned long access,
254 unsigned long vsid, unsigned long trap,
255 int ssize, int psize, unsigned long pte);
254extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend, 256extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
255 unsigned long pstart, unsigned long prot, 257 unsigned long pstart, unsigned long prot,
256 int psize, int ssize); 258 int psize, int ssize);
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 40847a9dd6db..09dffe6efa46 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -871,6 +871,18 @@ static inline int subpage_protection(struct mm_struct *mm, unsigned long ea)
871} 871}
872#endif 872#endif
873 873
874void hash_failure_debug(unsigned long ea, unsigned long access,
875 unsigned long vsid, unsigned long trap,
876 int ssize, int psize, unsigned long pte)
877{
878 if (!printk_ratelimit())
879 return;
880 pr_info("mm: Hashing failure ! EA=0x%lx access=0x%lx current=%s\n",
881 ea, access, current->comm);
882 pr_info(" trap=0x%lx vsid=0x%lx ssize=%d psize=%d pte=0x%lx\n",
883 trap, vsid, ssize, psize, pte);
884}
885
874/* Result code is: 886/* Result code is:
875 * 0 - handled 887 * 0 - handled
876 * 1 - normal page fault 888 * 1 - normal page fault
@@ -1036,6 +1048,12 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
1036 local, ssize, spp); 1048 local, ssize, spp);
1037 } 1049 }
1038 1050
1051 /* Dump some info in case of hash insertion failure, they should
1052 * never happen so it is really useful to know if/when they do
1053 */
1054 if (rc == -1)
1055 hash_failure_debug(ea, access, vsid, trap, ssize, psize,
1056 pte_val(*ptep));
1039#ifndef CONFIG_PPC_64K_PAGES 1057#ifndef CONFIG_PPC_64K_PAGES
1040 DBG_LOW(" o-pte: %016lx\n", pte_val(*ptep)); 1058 DBG_LOW(" o-pte: %016lx\n", pte_val(*ptep));
1041#else 1059#else
@@ -1054,8 +1072,7 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
1054 void *pgdir; 1072 void *pgdir;
1055 pte_t *ptep; 1073 pte_t *ptep;
1056 unsigned long flags; 1074 unsigned long flags;
1057 int local = 0; 1075 int rc, ssize, local = 0;
1058 int ssize;
1059 1076
1060 BUG_ON(REGION_ID(ea) != USER_REGION_ID); 1077 BUG_ON(REGION_ID(ea) != USER_REGION_ID);
1061 1078
@@ -1101,11 +1118,18 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
1101 /* Hash it in */ 1118 /* Hash it in */
1102#ifdef CONFIG_PPC_HAS_HASH_64K 1119#ifdef CONFIG_PPC_HAS_HASH_64K
1103 if (mm->context.user_psize == MMU_PAGE_64K) 1120 if (mm->context.user_psize == MMU_PAGE_64K)
1104 __hash_page_64K(ea, access, vsid, ptep, trap, local, ssize); 1121 rc = __hash_page_64K(ea, access, vsid, ptep, trap, local, ssize);
1105 else 1122 else
1106#endif /* CONFIG_PPC_HAS_HASH_64K */ 1123#endif /* CONFIG_PPC_HAS_HASH_64K */
1107 __hash_page_4K(ea, access, vsid, ptep, trap, local, ssize, 1124 rc = __hash_page_4K(ea, access, vsid, ptep, trap, local, ssize,
1108 subpage_protection(pgdir, ea)); 1125 subpage_protection(pgdir, ea));
1126
1127 /* Dump some info in case of hash insertion failure, they should
1128 * never happen so it is really useful to know if/when they do
1129 */
1130 if (rc == -1)
1131 hash_failure_debug(ea, access, vsid, trap, ssize,
1132 mm->context.user_psize, pte_val(*ptep));
1109 1133
1110 local_irq_restore(flags); 1134 local_irq_restore(flags);
1111} 1135}
diff --git a/arch/powerpc/mm/hugetlbpage-hash64.c b/arch/powerpc/mm/hugetlbpage-hash64.c
index faae9ec4cb04..cc5c273086cf 100644
--- a/arch/powerpc/mm/hugetlbpage-hash64.c
+++ b/arch/powerpc/mm/hugetlbpage-hash64.c
@@ -127,6 +127,8 @@ repeat:
127 */ 127 */
128 if (unlikely(slot == -2)) { 128 if (unlikely(slot == -2)) {
129 *ptep = __pte(old_pte); 129 *ptep = __pte(old_pte);
130 hash_failure_debug(ea, access, vsid, trap, ssize,
131 mmu_psize, old_pte);
130 return -1; 132 return -1;
131 } 133 }
132 134