Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7be2d191 authored by Will Deacon's avatar Will Deacon Committed by Gerrit - the friendly Code Review server
Browse files

FROMLIST: arm64: mm: Invalidate both kernel and user ASIDs when performing TLBI



Since an mm has both a kernel and a user ASID, we need to ensure that
broadcast TLB maintenance targets both address spaces so that things
like CoW continue to work with the uaccess primitives in the kernel.

Reviewed-by: default avatarMark Rutland <mark.rutland@arm.com>
Tested-by: default avatarLaura Abbott <labbott@redhat.com>
Tested-by: default avatarShanker Donthineni <shankerd@codeaurora.org>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
(cherry picked from git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git


 commit 9b0de864b5bc298ea53005ad812f3386f81aee9c)
Signed-off-by: default avatarGreg Hackmann <ghackmann@google.com>
Change-Id: I1f665f7b609872424071ecef14d6fab2b2d721ea
Git-Commit: eed2e002
Git-repo: git://android.googlesource.com/kernel/common.git


[vinmenon@codeaurora.org: trivial merge conflicts]
Signed-off-by: default avatarVinayak Menon <vinmenon@codeaurora.org>
parent aefacd69
Loading
Loading
Loading
Loading
+14 −2
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@

#include <linux/sched.h>
#include <asm/cputype.h>
#include <asm/mmu.h>

/*
 * Raw TLBI operations.
@@ -42,6 +43,11 @@

#define __tlbi(op, ...)		__TLBI_N(op, ##__VA_ARGS__, 1, 0)

#define __tlbi_user(op, arg) do {						\
	if (arm64_kernel_unmapped_at_el0())					\
		__tlbi(op, (arg) | USER_ASID_FLAG);				\
} while (0)

/*
 *	TLB Management
 *	==============
@@ -109,6 +115,7 @@ static inline void flush_tlb_mm(struct mm_struct *mm)

	dsb(ishst);
	__tlbi(aside1is, asid);
	__tlbi_user(aside1is, asid);
	dsb(ish);
#endif
}
@@ -127,6 +134,7 @@ static inline void flush_tlb_page(struct vm_area_struct *vma,

	dsb(ishst);
	__tlbi(vale1is, addr);
	__tlbi_user(vale1is, addr);
	dsb(ish);
#endif
}
@@ -154,10 +162,13 @@ static inline void __flush_tlb_range(struct vm_area_struct *vma,

	dsb(ishst);
	for (addr = start; addr < end; addr += 1 << (PAGE_SHIFT - 12)) {
		if (last_level)
		if (last_level) {
			__tlbi(vale1is, addr);
		else
			__tlbi_user(vale1is, addr);
		} else {
			__tlbi(vae1is, addr);
			__tlbi_user(vae1is, addr);
		}
	}
	dsb(ish);
}
@@ -197,6 +208,7 @@ static inline void __flush_tlb_pgtable(struct mm_struct *mm,
	unsigned long addr = uaddr >> 12 | (ASID(mm) << 48);

	__tlbi(vae1is, addr);
	__tlbi_user(vae1is, addr);
	dsb(ish);
}