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

Commit 3c986ee7 authored by Will Deacon's avatar Will Deacon Committed by Channagoud Kadabi
Browse files

UPSTREAM: 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 commit 9b0de864b5bc298ea53005ad812f3386f81aee9c)

Change-Id: I8b50e223fc7de6f11388b8dfac705fa618b7335a
Signed-off-by: default avatarTodd Poynor <toddpoynor@google.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
Git-commit: 2053d3c3
Git-repo: https://android.googlesource.com/kernel/common/


Signed-off-by: default avatarChannagoud Kadabi <ckadabi@codeaurora.org>
parent 4c6b485d
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
 *	==============
@@ -103,6 +109,7 @@ static inline void flush_tlb_mm(struct mm_struct *mm)

	dsb(ishst);
	__tlbi(aside1is, asid);
	__tlbi_user(aside1is, asid);
	dsb(ish);
}

@@ -113,6 +120,7 @@ static inline void flush_tlb_page(struct vm_area_struct *vma,

	dsb(ishst);
	__tlbi(vale1is, addr);
	__tlbi_user(vale1is, addr);
	dsb(ish);
}

@@ -139,10 +147,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);
}
@@ -182,6 +193,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);
}