diff options
-rw-r--r-- | arch/powerpc/include/asm/mmu-hash64.h | 4 | ||||
-rw-r--r-- | arch/powerpc/mm/hash_utils_64.c | 34 | ||||
-rw-r--r-- | arch/powerpc/mm/hugetlbpage-hash64.c | 2 |
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) | |||
250 | int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, | 250 | int __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 | 253 | extern 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); | ||
254 | extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend, | 256 | extern 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 | ||
874 | void 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 | ||