@@ -141,6 +141,30 @@ has_mismatched_cache_type(const struct arm64_cpu_capabilities *entry,
141141 return (ctr_real != sys ) && (ctr_raw != sys );
142142}
143143
144+ #ifdef CONFIG_ARM64_ERRATUM_4311569
145+ static DEFINE_STATIC_KEY_FALSE (arm_si_l1_workaround_4311569 );
146+ static int __init early_arm_si_l1_workaround_4311569_cfg (char * arg )
147+ {
148+ static_branch_enable (& arm_si_l1_workaround_4311569 );
149+ pr_info ("Enabling cache maintenance workaround for ARM SI-L1 erratum 4311569\n" );
150+
151+ return 0 ;
152+ }
153+ early_param ("arm_si_l1_workaround_4311569" , early_arm_si_l1_workaround_4311569_cfg );
154+
155+ /*
156+ * We have some earlier use cases to call cache maintenance operation functions, for example,
157+ * dcache_inval_poc() and dcache_clean_poc() in head.S, before making decision to turn on this
158+ * workaround. Since the scope of this workaround is limited to non-coherent DMA agents, its
159+ * safe to have the workaround off by default.
160+ */
161+ static bool
162+ need_arm_si_l1_workaround_4311569 (const struct arm64_cpu_capabilities * entry , int scope )
163+ {
164+ return static_branch_unlikely (& arm_si_l1_workaround_4311569 );
165+ }
166+ #endif
167+
144168static void
145169cpu_enable_trap_ctr_access (const struct arm64_cpu_capabilities * cap )
146170{
@@ -870,6 +894,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
870894 ERRATA_MIDR_RANGE_LIST (erratum_spec_ssbs_list ),
871895 },
872896#endif
897+ #ifdef CONFIG_ARM64_ERRATUM_4311569
898+ {
899+ .capability = ARM64_WORKAROUND_4311569 ,
900+ .type = ARM64_CPUCAP_SYSTEM_FEATURE ,
901+ .matches = need_arm_si_l1_workaround_4311569 ,
902+ },
903+ #endif
873904#ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD
874905 {
875906 .desc = "ARM errata 2966298, 3117295" ,
0 commit comments