@@ -42,4 +42,7 @@ stable hypervisors.
| Implementor | Component | Erratum ID | Kconfig |
+----------------+-----------------+-----------------+-------------------------+
| ARM | Cortex-A15 | #766422 | N/A |
+| ARM | Cortex-A53 | #827319 | ARM64_ERRATUM_827319 |
+| ARM | Cortex-A53 | #824069 | ARM64_ERRATUM_824069 |
+| ARM | Cortex-A53 | #819472 | ARM64_ERRATUM_819472 |
| ARM | Cortex-A57 | #852523 | N/A |
@@ -53,6 +53,77 @@ config ALTERNATIVE
endmenu
+menu "ARM errata workaround via the alternative framework"
+ depends on ALTERNATIVE
+
+config ARM64_ERRATUM_827319
+ bool "Cortex-A53: 827319: Data cache clean instructions might cause overlapping transactions to the interconnect"
+ default y
+ depends on ARM_64
+ help
+ This option adds an alternative code sequence to work around ARM
+ erratum 827319 on Cortex-A53 parts up to r0p2 with an AMBA 5 CHI
+ master interface and an L2 cache.
+
+ Under certain conditions this erratum can cause a clean line eviction
+ to occur at the same time as another transaction to the same address
+ on the AMBA 5 CHI interface, which can cause data corruption if the
+ interconnect reorders the two transactions.
+
+ The workaround promotes data cache clean instructions to
+ data cache clean-and-invalidate.
+ Please note that this does not necessarily enable the workaround,
+ as it depends on the alternative framework, which will only patch
+ the kernel if an affected CPU is detected.
+
+ If unsure, say Y.
+
+config ARM64_ERRATUM_824069
+ bool "Cortex-A53: 824069: Cache line might not be marked as clean after a CleanShared snoop"
+ default y
+ depends on ARM_64
+ help
+ This option adds an alternative code sequence to work around ARM
+ erratum 824069 on Cortex-A53 parts up to r0p2 when it is connected
+ to a coherent interconnect.
+
+ If a Cortex-A53 processor is executing a store or prefetch for
+ write instruction at the same time as a processor in another
+ cluster is executing a cache maintenance operation to the same
+ address, then this erratum might cause a clean cache line to be
+ incorrectly marked as dirty.
+
+ The workaround promotes data cache clean instructions to
+ data cache clean-and-invalidate.
+ Please note that this option does not necessarily enable the
+ workaround, as it depends on the alternative framework, which will
+ only patch the kernel if an affected CPU is detected.
+
+ If unsure, say Y.
+
+config ARM64_ERRATUM_819472
+ bool "Cortex-A53: 819472: Store exclusive instructions might cause data corruption"
+ default y
+ depends on ARM_64
+ help
+ This option adds an alternative code sequence to work around ARM
+ erratum 819472 on Cortex-A53 parts up to r0p1 with an L2 cache
+ present when it is connected to a coherent interconnect.
+
+ If the processor is executing a load and store exclusive sequence at
+ the same time as a processor in another cluster is executing a cache
+ maintenance operation to the same address, then this erratum might
+ cause data corruption.
+
+ The workaround promotes data cache clean instructions to
+ data cache clean-and-invalidate.
+ Please note that this does not necessarily enable the workaround,
+ as it depends on the alternative framework, which will only patch
+ the kernel if an affected CPU is detected.
+
+ If unsure, say Y.
+endmenu
+
source "common/Kconfig"
source "drivers/Kconfig"
@@ -19,6 +19,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <asm/alternative.h>
+
/*
* dcache_line_size - get the minimum D-cache line size from the CTR register.
*/
@@ -17,6 +17,23 @@ is_affected_midr_range(const struct arm_cpu_capabilities *entry)
}
static const struct arm_cpu_capabilities arm_errata[] = {
+#if defined(CONFIG_ARM64_ERRATUM_827319) || \
+ defined(CONFIG_ARM64_ERRATUM_824069)
+ {
+ /* Cortex-A53 r0p[012] */
+ .desc = "ARM errata 827319, 824069",
+ .capability = ARM64_WORKAROUND_CLEAN_CACHE,
+ MIDR_RANGE(MIDR_CORTEX_A53, 0x00, 0x02),
+ },
+#endif
+#ifdef CONFIG_ARM64_ERRATUM_819472
+ {
+ /* Cortex-A53 r0[01] */
+ .desc = "ARM erratum 819472",
+ .capability = ARM64_WORKAROUND_CLEAN_CACHE,
+ MIDR_RANGE(MIDR_CORTEX_A53, 0x00, 0x01),
+ },
+#endif
{},
};
@@ -3,6 +3,8 @@
#ifndef __ASSEMBLY__
+#include <asm/alternative.h>
+
/* Write a pagetable entry */
static inline void write_pte(lpae_t *p, lpae_t pte)
{
@@ -18,7 +20,10 @@ static inline void write_pte(lpae_t *p, lpae_t pte)
#define __invalidate_dcache_one(R) "dc ivac, %" #R ";"
/* Inline ASM to flush dcache on register R (may be an inline asm operand) */
-#define __clean_dcache_one(R) "dc cvac, %" #R ";"
+#define __clean_dcache_one(R) \
+ ALTERNATIVE("dc cvac, %" #R ";", \
+ "dc civac, %" #R ";", \
+ ARM64_WORKAROUND_CLEAN_CACHE) \
/* Inline ASM to clean and invalidate dcache on register R (may be an
* inline asm operand) */
@@ -35,7 +35,9 @@
#endif
#define cpu_has_security (boot_cpu_feature32(security) > 0)
-#define ARM_NCAPS 0
+#define ARM64_WORKAROUND_CLEAN_CACHE 0
+
+#define ARM_NCAPS 1
#ifndef __ASSEMBLY__
@@ -44,6 +44,12 @@
_model == (model) && _rv >= (rv_min) && _rv <= (rv_max); \
})
+#define ARM_CPU_IMP_ARM 0x41
+
+#define ARM_CPU_PART_CORTEX_A53 0xD03
+
+#define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
+
/* MPIDR Multiprocessor Affinity Register */
#define _MPIDR_UP (30)
#define MPIDR_UP (_AC(1,U) << _MPIDR_UP)