summaryrefslogtreecommitdiff
path: root/arch/powerpc/mm
diff options
context:
space:
mode:
authorAlex Shi <alex.shi@linaro.org>2017-07-11 14:21:20 +0800
committerAlex Shi <alex.shi@linaro.org>2017-07-11 16:22:22 +0800
commit2120557722577d8cff75a33a799ad15582dbd8ef (patch)
tree2518d0dd3038f52cc9d4a26200594132e115f829 /arch/powerpc/mm
parentafd012a6a05f426411186b5ed23c99bb0d83cbe7 (diff)
parent03a929fbcbb1f7dca3cca19eefcbc15ecc191331 (diff)
Merge branch 'linux-linaro-lsk-v4.4' into linux-linaro-lsk-v4.4-android
Conflicts: arch/arm64/kernel/armv8_deprecated.c arch/arm64/kernel/efi.c arch/arm64/kernel/entry.S arch/arm64/kernel/head.S arch/arm64/kernel/hw_breakpoint.c arch/arm64/mm/mmu.c include/linux/memblock.h mm/memblock.c
Diffstat (limited to 'arch/powerpc/mm')
-rw-r--r--arch/powerpc/mm/slb_low.S10
-rw-r--r--arch/powerpc/mm/slice.c2
2 files changed, 11 insertions, 1 deletions
diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S
index 4c48b487698c..0b48ce40d351 100644
--- a/arch/powerpc/mm/slb_low.S
+++ b/arch/powerpc/mm/slb_low.S
@@ -179,6 +179,16 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
b slb_finish_load
8: /* invalid EA */
+ /*
+ * It's possible the bad EA is too large to fit in the SLB cache, which
+ * would mean we'd fail to invalidate it on context switch. So mark the
+ * SLB cache as full so we force a full flush. We also set cr7+eq to
+ * mark the address as a kernel address, so slb_finish_load() skips
+ * trying to insert it into the SLB cache.
+ */
+ li r9,SLB_CACHE_ENTRIES + 1
+ sth r9,PACASLBCACHEPTR(r13)
+ crset 4*cr7+eq
li r10,0 /* BAD_VSID */
li r9,0 /* BAD_VSID */
li r11,SLB_VSID_USER /* flags don't much matter */
diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
index 0f432a702870..6ad12b244770 100644
--- a/arch/powerpc/mm/slice.c
+++ b/arch/powerpc/mm/slice.c
@@ -105,7 +105,7 @@ static int slice_area_is_free(struct mm_struct *mm, unsigned long addr,
if ((mm->task_size - len) < addr)
return 0;
vma = find_vma(mm, addr);
- return (!vma || (addr + len) <= vma->vm_start);
+ return (!vma || (addr + len) <= vm_start_gap(vma));
}
static int slice_low_has_vma(struct mm_struct *mm, unsigned long slice)