Commit 44ecda71 authored by Anshuman Khandual's avatar Anshuman Khandual Committed by Will Deacon
Browse files

arm64: errata: Workaround possible Cortex-A715 [ESR|FAR]_ELx corruption



If a Cortex-A715 cpu sees a page mapping permissions change from executable
to non-executable, it may corrupt the ESR_ELx and FAR_ELx registers, on the
next instruction abort caused by permission fault.

Only user-space does executable to non-executable permission transition via
mprotect() system call which calls ptep_modify_prot_start() and ptep_modify
_prot_commit() helpers, while changing the page mapping. The platform code
can override these helpers via __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION.

Work around the problem via doing a break-before-make TLB invalidation, for
all executable user space mappings, that go through mprotect() system call.
This overrides ptep_modify_prot_start() and ptep_modify_prot_commit(), via
defining HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION on the platform thus giving
an opportunity to intercept user space exec mappings, and do the necessary
TLB invalidation. Similar interceptions are also implemented for HugeTLB.

Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-doc@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: default avatarAnshuman Khandual <anshuman.khandual@arm.com>
Reviewed-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Link: https://lore.kernel.org/r/20221116140915.356601-3-anshuman.khandual@arm.com


Signed-off-by: default avatarWill Deacon <will@kernel.org>
parent 07e39e60
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -120,6 +120,8 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+
| ARM            | Cortex-A710     | #2224489        | ARM64_ERRATUM_2224489       |
+----------------+-----------------+-----------------+-----------------------------+
| ARM            | Cortex-A715     | #2645198        | ARM64_ERRATUM_2645198       |
+----------------+-----------------+-----------------+-----------------------------+
| ARM            | Cortex-X2       | #2119858        | ARM64_ERRATUM_2119858       |
+----------------+-----------------+-----------------+-----------------------------+
| ARM            | Cortex-X2       | #2224489        | ARM64_ERRATUM_2224489       |
+16 −0
Original line number Diff line number Diff line
@@ -964,6 +964,22 @@ config ARM64_ERRATUM_2457168

	  If unsure, say Y.

config ARM64_ERRATUM_2645198
	bool "Cortex-A715: 2645198: Workaround possible [ESR|FAR]_ELx corruption"
	default y
	help
	  This option adds the workaround for ARM Cortex-A715 erratum 2645198.

	  If a Cortex-A715 cpu sees a page mapping permissions change from executable
	  to non-executable, it may corrupt the ESR_ELx and FAR_ELx registers on the
	  next instruction abort caused by permission fault.

	  Only user-space does executable to non-executable permission transition via
	  mprotect() system call. Workaround the problem by doing a break-before-make
	  TLB invalidation, for all changes to executable user space mappings.

	  If unsure, say Y.

config CAVIUM_ERRATUM_22375
	bool "Cavium erratum 22375, 24313"
	default y
+9 −0
Original line number Diff line number Diff line
@@ -49,6 +49,15 @@ extern pte_t huge_ptep_get(pte_t *ptep);

void __init arm64_hugetlb_cma_reserve(void);

#define huge_ptep_modify_prot_start huge_ptep_modify_prot_start
extern pte_t huge_ptep_modify_prot_start(struct vm_area_struct *vma,
					 unsigned long addr, pte_t *ptep);

#define huge_ptep_modify_prot_commit huge_ptep_modify_prot_commit
extern void huge_ptep_modify_prot_commit(struct vm_area_struct *vma,
					 unsigned long addr, pte_t *ptep,
					 pte_t old_pte, pte_t new_pte);

#include <asm-generic/hugetlb.h>

#endif /* __ASM_HUGETLB_H */
+9 −0
Original line number Diff line number Diff line
@@ -1096,6 +1096,15 @@ static inline bool pud_sect_supported(void)
}


#define __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION
#define ptep_modify_prot_start ptep_modify_prot_start
extern pte_t ptep_modify_prot_start(struct vm_area_struct *vma,
				    unsigned long addr, pte_t *ptep);

#define ptep_modify_prot_commit ptep_modify_prot_commit
extern void ptep_modify_prot_commit(struct vm_area_struct *vma,
				    unsigned long addr, pte_t *ptep,
				    pte_t old_pte, pte_t new_pte);
#endif /* !__ASSEMBLY__ */

#endif /* __ASM_PGTABLE_H */
+7 −0
Original line number Diff line number Diff line
@@ -661,6 +661,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
		CAP_MIDR_RANGE_LIST(trbe_write_out_of_range_cpus),
	},
#endif
#ifdef CONFIG_ARM64_ERRATUM_2645198
	{
		.desc = "ARM erratum 2645198",
		.capability = ARM64_WORKAROUND_2645198,
		ERRATA_MIDR_ALL_VERSIONS(MIDR_CORTEX_A715)
	},
#endif
#ifdef CONFIG_ARM64_ERRATUM_2077057
	{
		.desc = "ARM erratum 2077057",
Loading