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); |
