diff options
Diffstat (limited to 'arch/powerpc/mm/hash_utils_64.c')
-rw-r--r-- | arch/powerpc/mm/hash_utils_64.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 1b6e1271719f..f410c3e12c1e 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c | |||
@@ -195,6 +195,11 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, | |||
195 | unsigned long vpn = hpt_vpn(vaddr, vsid, ssize); | 195 | unsigned long vpn = hpt_vpn(vaddr, vsid, ssize); |
196 | unsigned long tprot = prot; | 196 | unsigned long tprot = prot; |
197 | 197 | ||
198 | /* | ||
199 | * If we hit a bad address return error. | ||
200 | */ | ||
201 | if (!vsid) | ||
202 | return -1; | ||
198 | /* Make kernel text executable */ | 203 | /* Make kernel text executable */ |
199 | if (overlaps_kernel_text(vaddr, vaddr + step)) | 204 | if (overlaps_kernel_text(vaddr, vaddr + step)) |
200 | tprot &= ~HPTE_R_N; | 205 | tprot &= ~HPTE_R_N; |
@@ -759,6 +764,8 @@ void __init early_init_mmu(void) | |||
759 | /* Initialize stab / SLB management */ | 764 | /* Initialize stab / SLB management */ |
760 | if (mmu_has_feature(MMU_FTR_SLB)) | 765 | if (mmu_has_feature(MMU_FTR_SLB)) |
761 | slb_initialize(); | 766 | slb_initialize(); |
767 | else | ||
768 | stab_initialize(get_paca()->stab_real); | ||
762 | } | 769 | } |
763 | 770 | ||
764 | #ifdef CONFIG_SMP | 771 | #ifdef CONFIG_SMP |
@@ -922,11 +929,6 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) | |||
922 | DBG_LOW("hash_page(ea=%016lx, access=%lx, trap=%lx\n", | 929 | DBG_LOW("hash_page(ea=%016lx, access=%lx, trap=%lx\n", |
923 | ea, access, trap); | 930 | ea, access, trap); |
924 | 931 | ||
925 | if ((ea & ~REGION_MASK) >= PGTABLE_RANGE) { | ||
926 | DBG_LOW(" out of pgtable range !\n"); | ||
927 | return 1; | ||
928 | } | ||
929 | |||
930 | /* Get region & vsid */ | 932 | /* Get region & vsid */ |
931 | switch (REGION_ID(ea)) { | 933 | switch (REGION_ID(ea)) { |
932 | case USER_REGION_ID: | 934 | case USER_REGION_ID: |
@@ -957,6 +959,11 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) | |||
957 | } | 959 | } |
958 | DBG_LOW(" mm=%p, mm->pgdir=%p, vsid=%016lx\n", mm, mm->pgd, vsid); | 960 | DBG_LOW(" mm=%p, mm->pgdir=%p, vsid=%016lx\n", mm, mm->pgd, vsid); |
959 | 961 | ||
962 | /* Bad address. */ | ||
963 | if (!vsid) { | ||
964 | DBG_LOW("Bad address!\n"); | ||
965 | return 1; | ||
966 | } | ||
960 | /* Get pgdir */ | 967 | /* Get pgdir */ |
961 | pgdir = mm->pgd; | 968 | pgdir = mm->pgd; |
962 | if (pgdir == NULL) | 969 | if (pgdir == NULL) |
@@ -1126,6 +1133,8 @@ void hash_preload(struct mm_struct *mm, unsigned long ea, | |||
1126 | /* Get VSID */ | 1133 | /* Get VSID */ |
1127 | ssize = user_segment_size(ea); | 1134 | ssize = user_segment_size(ea); |
1128 | vsid = get_vsid(mm->context.id, ea, ssize); | 1135 | vsid = get_vsid(mm->context.id, ea, ssize); |
1136 | if (!vsid) | ||
1137 | return; | ||
1129 | 1138 | ||
1130 | /* Hash doesn't like irqs */ | 1139 | /* Hash doesn't like irqs */ |
1131 | local_irq_save(flags); | 1140 | local_irq_save(flags); |
@@ -1233,6 +1242,9 @@ static void kernel_map_linear_page(unsigned long vaddr, unsigned long lmi) | |||
1233 | hash = hpt_hash(vpn, PAGE_SHIFT, mmu_kernel_ssize); | 1242 | hash = hpt_hash(vpn, PAGE_SHIFT, mmu_kernel_ssize); |
1234 | hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); | 1243 | hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); |
1235 | 1244 | ||
1245 | /* Don't create HPTE entries for bad address */ | ||
1246 | if (!vsid) | ||
1247 | return; | ||
1236 | ret = ppc_md.hpte_insert(hpteg, vpn, __pa(vaddr), | 1248 | ret = ppc_md.hpte_insert(hpteg, vpn, __pa(vaddr), |
1237 | mode, HPTE_V_BOLTED, | 1249 | mode, HPTE_V_BOLTED, |
1238 | mmu_linear_psize, mmu_kernel_ssize); | 1250 | mmu_linear_psize, mmu_kernel_ssize); |