aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2010-07-22 20:31:13 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2010-07-22 22:56:56 -0400
commit4b8692c022a4b149d0c2cc3f4f7a363453fde72a (patch)
tree11e71230effaa73f24d999ed7eeacb1125c8a047 /arch
parent171aa2caaad16ed32b655d33565e112a12cb3537 (diff)
powerpc/mm: Add some debug output when hash insertion fails
This adds some debug output to our MMU hash code to print out some useful debug data if the hypervisor refuses the insertion (which should normally never happen). Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> ---
Diffstat (limited to 'arch')
-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