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

Commit 3819dbd2 authored by Rohit Vaswani's avatar Rohit Vaswani
Browse files

arm64: mm: Add tlbi workaround for msm8994



MSM8994 v1 revision has a bug in which the bits [39:38]
of VA are tied to zero. ARM64 Linux uses these
bits for kernel and userspace maps. Due to this bug
it is possible that other processors don't see the
effect of tlb invalidation by VA or ASID and could result
in an abort or data corruption.

The workaround here is to replace the tlb invalidation
by VA and ASID with tlbiall in arm64 kernel.
This workaround is controlled through CONFIG_ARCH_MSM8994_V1_TLBI_WA.

Change-Id: Ie36c168881e61007d5d5383d989d7ee6adbd1d92
Signed-off-by: default avatarRohit Vaswani <rvaswani@codeaurora.org>
parent 62a8ead9
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -160,6 +160,15 @@ config ARCH_MSM8994
	  This enables support for the MSM8994 chipset. If you dont
	  know what do here, say N

config ARCH_MSM8994_V1_TLBI_WA
	bool "Enable MSM8994 v1 TLBI workaround"
	depends on ARCH_MSM8994
	help
	  This enables support for the MSM8994 v1 TLBI workaround. This
	  workaround is required for MSM8994 V1 revision where the
	  [39:38] bits of VA are tied to zero and due to which TLBI
	  operations with VA or ASID will not work.

config ARCH_XGENE
	bool "AppliedMicro X-Gene SOC Family"
	help
+14 −0
Original line number Diff line number Diff line
@@ -80,22 +80,36 @@ static inline void flush_tlb_all(void)

static inline void flush_tlb_mm(struct mm_struct *mm)
{
#ifdef CONFIG_ARCH_MSM8994_V1_TLBI_WA
	dsb();
	asm("tlbi	vmalle1is");
	dsb();
	isb();
#else
	unsigned long asid = (unsigned long)ASID(mm) << 48;

	dsb();
	asm("tlbi	aside1is, %0" : : "r" (asid));
	dsb();
#endif
}

static inline void flush_tlb_page(struct vm_area_struct *vma,
				  unsigned long uaddr)
{
#ifdef CONFIG_ARCH_MSM8994_V1_TLBI_WA
	dsb();
	asm("tlbi	vmalle1is");
	dsb();
	isb();
#else
	unsigned long addr = uaddr >> 12 |
		((unsigned long)ASID(vma->vm_mm) << 48);

	dsb();
	asm("tlbi	vae1is, %0" : : "r" (addr));
	dsb();
#endif
}

/*
+10 −0
Original line number Diff line number Diff line
@@ -34,6 +34,11 @@
 *	- vma   - vma_struct describing address range
 */
ENTRY(__cpu_flush_user_tlb_range)
#ifdef CONFIG_ARCH_MSM8994_V1_TLBI_WA
	tlbi    vmalle1is
	dsb	sy
	isb
#else
	vma_vm_mm x3, x2			// get vma->vm_mm
	mmid	w3, x3				// get vm_mm->context.id
	dsb	sy
@@ -46,6 +51,7 @@ ENTRY(__cpu_flush_user_tlb_range)
	cmp	x0, x1
	b.lo	1b
	dsb	sy
#endif
	ret
ENDPROC(__cpu_flush_user_tlb_range)

@@ -58,6 +64,9 @@ ENDPROC(__cpu_flush_user_tlb_range)
 *	- end   - end address (exclusive, may not be aligned)
 */
ENTRY(__cpu_flush_kern_tlb_range)
#ifdef CONFIG_ARCH_MSM8994_V1_TLBI_WA
	tlbi    vmalle1is
#else
	dsb	sy
	lsr	x0, x0, #12			// align address
	lsr	x1, x1, #12
@@ -65,6 +74,7 @@ ENTRY(__cpu_flush_kern_tlb_range)
	add	x0, x0, #1
	cmp	x0, x1
	b.lo	1b
#endif
	dsb	sy
	isb
	ret