4343#include <linux/stacktrace.h>
4444
4545#include <asm/alternative.h>
46+ #include <asm/apple_cpufeature.h>
4647#include <asm/compat.h>
4748#include <asm/cpufeature.h>
4849#include <asm/cacheflush.h>
@@ -374,6 +375,9 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
374375 if (system_supports_tpidr2 ())
375376 p -> thread .tpidr2_el0 = read_sysreg_s (SYS_TPIDR2_EL0 );
376377
378+ if (system_has_actlr_state ())
379+ p -> thread .actlr = read_sysreg (actlr_el1 );
380+
377381 if (stack_start ) {
378382 if (is_compat_thread (task_thread_info (p )))
379383 childregs -> compat_sp = stack_start ;
@@ -516,6 +520,58 @@ void update_sctlr_el1(u64 sctlr)
516520 isb ();
517521}
518522
523+ /*
524+ * IMPDEF control register ACTLR_EL1 handling. Some CPUs use this to
525+ * expose features that can be controlled by userspace.
526+ */
527+ static void actlr_thread_switch (struct task_struct * next )
528+ {
529+ if (!system_has_actlr_state ())
530+ return ;
531+
532+ current -> thread .actlr = read_sysreg (actlr_el1 );
533+ write_sysreg (next -> thread .actlr , actlr_el1 );
534+ }
535+
536+ #ifdef CONFIG_ARM64_MEMORY_MODEL_CONTROL
537+ int arch_prctl_mem_model_get (struct task_struct * t )
538+ {
539+ if (cpus_have_const_cap (ARM64_HAS_TSO_APPLE ) &&
540+ t -> thread .actlr & ACTLR_APPLE_TSO )
541+ return PR_SET_MEM_MODEL_TSO ;
542+
543+ return PR_SET_MEM_MODEL_DEFAULT ;
544+ }
545+
546+ int arch_prctl_mem_model_set (struct task_struct * t , unsigned long val )
547+ {
548+ if (cpus_have_const_cap (ARM64_HAS_TSO_FIXED ) && val == PR_SET_MEM_MODEL_TSO )
549+ return 0 ;
550+
551+ if (cpus_have_const_cap (ARM64_HAS_TSO_APPLE )) {
552+ WARN_ON (!system_has_actlr_state ());
553+
554+ switch (val ) {
555+ case PR_SET_MEM_MODEL_TSO :
556+ t -> thread .actlr |= ACTLR_APPLE_TSO ;
557+ break ;
558+ case PR_SET_MEM_MODEL_DEFAULT :
559+ t -> thread .actlr &= ~ACTLR_APPLE_TSO ;
560+ break ;
561+ default :
562+ return - EINVAL ;
563+ }
564+ write_sysreg (t -> thread .actlr , actlr_el1 );
565+ return 0 ;
566+ }
567+
568+ if (val == PR_SET_MEM_MODEL_DEFAULT )
569+ return 0 ;
570+
571+ return - EINVAL ;
572+ }
573+ #endif
574+
519575/*
520576 * Thread switching.
521577 */
@@ -533,6 +589,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
533589 ssbs_thread_switch (next );
534590 erratum_1418040_thread_switch (next );
535591 ptrauth_thread_switch_user (next );
592+ actlr_thread_switch (next );
536593
537594 /*
538595 * Complete any pending TLB or cache maintenance on this CPU in case
@@ -654,6 +711,10 @@ void arch_setup_new_exec(void)
654711 arch_prctl_spec_ctrl_set (current , PR_SPEC_STORE_BYPASS ,
655712 PR_SPEC_ENABLE );
656713 }
714+
715+ if (IS_ENABLED (CONFIG_ARM64_MEMORY_MODEL_CONTROL )) {
716+ arch_prctl_mem_model_set (current , PR_SET_MEM_MODEL_DEFAULT );
717+ }
657718}
658719
659720#ifdef CONFIG_ARM64_TAGGED_ADDR_ABI
0 commit comments