Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arm64: mte: move register initialization to C

If FEAT_MTE2 is disabled via the arm64.nomte command line argument on a
CPU that claims to support FEAT_MTE2, the kernel will use Tagged Normal
in the MAIR. If we interpret arm64.nomte to mean that the CPU does not
in fact implement FEAT_MTE2, setting the system register like this may
lead to UNSPECIFIED behavior. Fix it by arranging for MAIR to be set
in the C function cpu_enable_mte which is called based on the sanitized
version of the system register.

There is no need for the rest of the MTE-related system register
initialization to happen from assembly, with the exception of TCR_EL1,
which must be set to include at least TBI1 because the secondary CPUs
access KASan-allocated data structures early. Therefore, make the TCR_EL1
initialization unconditional and move the rest of the initialization to
cpu_enable_mte so that we no longer have a dependency on the unsanitized
ID register value.

Co-developed-by: Evgenii Stepanov <eugenis@google.com>
Signed-off-by: Peter Collingbourne <pcc@google.com>
Signed-off-by: Evgenii Stepanov <eugenis@google.com>
Suggested-by: Catalin Marinas <catalin.marinas@arm.com>
Reported-by: kernel test robot <lkp@intel.com>
Fixes: 3b714d24ef17 ("arm64: mte: CPU feature detection and initial sysreg configuration")
Cc: <stable@vger.kernel.org> # 5.10.x
Link: https://lore.kernel.org/r/20220915222053.3484231-1-eugenis@google.com
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>

authored by

Peter Collingbourne and committed by
Catalin Marinas
973b9e37 739e49e0

+65 -42
+5
arch/arm64/include/asm/mte.h
··· 42 42 void mte_copy_page_tags(void *kto, const void *kfrom); 43 43 void mte_thread_init_user(void); 44 44 void mte_thread_switch(struct task_struct *next); 45 + void mte_cpu_setup(void); 45 46 void mte_suspend_enter(void); 47 + void mte_suspend_exit(void); 46 48 long set_mte_ctrl(struct task_struct *task, unsigned long arg); 47 49 long get_mte_ctrl(struct task_struct *task); 48 50 int mte_ptrace_copy_tags(struct task_struct *child, long request, ··· 72 70 { 73 71 } 74 72 static inline void mte_suspend_enter(void) 73 + { 74 + } 75 + static inline void mte_suspend_exit(void) 75 76 { 76 77 } 77 78 static inline long set_mte_ctrl(struct task_struct *task, unsigned long arg)
+2 -1
arch/arm64/kernel/cpufeature.c
··· 2034 2034 static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap) 2035 2035 { 2036 2036 sysreg_clear_set(sctlr_el1, 0, SCTLR_ELx_ATA | SCTLR_EL1_ATA0); 2037 - isb(); 2037 + 2038 + mte_cpu_setup(); 2038 2039 2039 2040 /* 2040 2041 * Clear the tags in the zero page. This needs to be done via the
+51
arch/arm64/kernel/mte.c
··· 285 285 mte_check_tfsr_el1(); 286 286 } 287 287 288 + void mte_cpu_setup(void) 289 + { 290 + u64 rgsr; 291 + 292 + /* 293 + * CnP must be enabled only after the MAIR_EL1 register has been set 294 + * up. Inconsistent MAIR_EL1 between CPUs sharing the same TLB may 295 + * lead to the wrong memory type being used for a brief window during 296 + * CPU power-up. 297 + * 298 + * CnP is not a boot feature so MTE gets enabled before CnP, but let's 299 + * make sure that is the case. 300 + */ 301 + BUG_ON(read_sysreg(ttbr0_el1) & TTBR_CNP_BIT); 302 + BUG_ON(read_sysreg(ttbr1_el1) & TTBR_CNP_BIT); 303 + 304 + /* Normal Tagged memory type at the corresponding MAIR index */ 305 + sysreg_clear_set(mair_el1, 306 + MAIR_ATTRIDX(MAIR_ATTR_MASK, MT_NORMAL_TAGGED), 307 + MAIR_ATTRIDX(MAIR_ATTR_NORMAL_TAGGED, 308 + MT_NORMAL_TAGGED)); 309 + 310 + write_sysreg_s(KERNEL_GCR_EL1, SYS_GCR_EL1); 311 + 312 + /* 313 + * If GCR_EL1.RRND=1 is implemented the same way as RRND=0, then 314 + * RGSR_EL1.SEED must be non-zero for IRG to produce 315 + * pseudorandom numbers. As RGSR_EL1 is UNKNOWN out of reset, we 316 + * must initialize it. 317 + */ 318 + rgsr = (read_sysreg(CNTVCT_EL0) & SYS_RGSR_EL1_SEED_MASK) << 319 + SYS_RGSR_EL1_SEED_SHIFT; 320 + if (rgsr == 0) 321 + rgsr = 1 << SYS_RGSR_EL1_SEED_SHIFT; 322 + write_sysreg_s(rgsr, SYS_RGSR_EL1); 323 + 324 + /* clear any pending tag check faults in TFSR*_EL1 */ 325 + write_sysreg_s(0, SYS_TFSR_EL1); 326 + write_sysreg_s(0, SYS_TFSRE0_EL1); 327 + 328 + local_flush_tlb_all(); 329 + } 330 + 288 331 void mte_suspend_enter(void) 289 332 { 290 333 if (!system_supports_mte()) ··· 342 299 343 300 /* Report SYS_TFSR_EL1 before suspend entry */ 344 301 mte_check_tfsr_el1(); 302 + } 303 + 304 + void mte_suspend_exit(void) 305 + { 306 + if (!system_supports_mte()) 307 + return; 308 + 309 + mte_cpu_setup(); 345 310 } 346 311 347 312 long set_mte_ctrl(struct task_struct *task, unsigned long arg)
+2
arch/arm64/kernel/suspend.c
··· 43 43 { 44 44 unsigned int cpu = smp_processor_id(); 45 45 46 + mte_suspend_exit(); 47 + 46 48 /* 47 49 * We are resuming from reset with the idmap active in TTBR0_EL1. 48 50 * We must uninstall the idmap and restore the expected MMU
+5 -41
arch/arm64/mm/proc.S
··· 48 48 49 49 #ifdef CONFIG_KASAN_HW_TAGS 50 50 #define TCR_MTE_FLAGS TCR_TCMA1 | TCR_TBI1 | TCR_TBID1 51 - #else 51 + #elif defined(CONFIG_ARM64_MTE) 52 52 /* 53 53 * The mte_zero_clear_page_tags() implementation uses DC GZVA, which relies on 54 54 * TBI being enabled at EL1. 55 55 */ 56 56 #define TCR_MTE_FLAGS TCR_TBI1 | TCR_TBID1 57 + #else 58 + #define TCR_MTE_FLAGS 0 57 59 #endif 58 60 59 61 /* 60 62 * Default MAIR_EL1. MT_NORMAL_TAGGED is initially mapped as Normal memory and 61 - * changed during __cpu_setup to Normal Tagged if the system supports MTE. 63 + * changed during mte_cpu_setup to Normal Tagged if the system supports MTE. 62 64 */ 63 65 #define MAIR_EL1_SET \ 64 66 (MAIR_ATTRIDX(MAIR_ATTR_DEVICE_nGnRnE, MT_DEVICE_nGnRnE) | \ ··· 428 426 mov_q mair, MAIR_EL1_SET 429 427 mov_q tcr, TCR_TxSZ(VA_BITS) | TCR_CACHE_FLAGS | TCR_SMP_FLAGS | \ 430 428 TCR_TG_FLAGS | TCR_KASLR_FLAGS | TCR_ASID16 | \ 431 - TCR_TBI0 | TCR_A1 | TCR_KASAN_SW_FLAGS 429 + TCR_TBI0 | TCR_A1 | TCR_KASAN_SW_FLAGS | TCR_MTE_FLAGS 432 430 433 - #ifdef CONFIG_ARM64_MTE 434 - /* 435 - * Update MAIR_EL1, GCR_EL1 and TFSR*_EL1 if MTE is supported 436 - * (ID_AA64PFR1_EL1[11:8] > 1). 437 - */ 438 - mrs x10, ID_AA64PFR1_EL1 439 - ubfx x10, x10, #ID_AA64PFR1_MTE_SHIFT, #4 440 - cmp x10, #ID_AA64PFR1_MTE 441 - b.lt 1f 442 - 443 - /* Normal Tagged memory type at the corresponding MAIR index */ 444 - mov x10, #MAIR_ATTR_NORMAL_TAGGED 445 - bfi mair, x10, #(8 * MT_NORMAL_TAGGED), #8 446 - 447 - mov x10, #KERNEL_GCR_EL1 448 - msr_s SYS_GCR_EL1, x10 449 - 450 - /* 451 - * If GCR_EL1.RRND=1 is implemented the same way as RRND=0, then 452 - * RGSR_EL1.SEED must be non-zero for IRG to produce 453 - * pseudorandom numbers. As RGSR_EL1 is UNKNOWN out of reset, we 454 - * must initialize it. 455 - */ 456 - mrs x10, CNTVCT_EL0 457 - ands x10, x10, #SYS_RGSR_EL1_SEED_MASK 458 - csinc x10, x10, xzr, ne 459 - lsl x10, x10, #SYS_RGSR_EL1_SEED_SHIFT 460 - msr_s SYS_RGSR_EL1, x10 461 - 462 - /* clear any pending tag check faults in TFSR*_EL1 */ 463 - msr_s SYS_TFSR_EL1, xzr 464 - msr_s SYS_TFSRE0_EL1, xzr 465 - 466 - /* set the TCR_EL1 bits */ 467 - mov_q x10, TCR_MTE_FLAGS 468 - orr tcr, tcr, x10 469 - 1: 470 - #endif 471 431 tcr_clear_errata_bits tcr, x9, x5 472 432 473 433 #ifdef CONFIG_ARM64_VA_BITS_52