static const struct arm64_ftr_bits ftr_id_aa64pfr1[] = {
        ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_MPAMFRAC_SHIFT, 4, 0),
        ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_RASFRAC_SHIFT, 4, 0),
 -      ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_SSBS_SHIFT, 4, ID_AA64PFR1_SSBS_PSTATE_NI),
+       ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_MTE),
+                      FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_MTE_SHIFT, 4, ID_AA64PFR1_MTE_NI),
 +      ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR1_SSBS_SHIFT, 4, ID_AA64PFR1_SSBS_PSTATE_NI),
        ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_BTI),
                                    FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_BT_SHIFT, 4, 0),
        ARM64_FTR_END,
 
  unsigned long __icache_flags;
  
  static const char *const hwcap_str[] = {
 -      "fp",
 -      "asimd",
 -      "evtstrm",
 -      "aes",
 -      "pmull",
 -      "sha1",
 -      "sha2",
 -      "crc32",
 -      "atomics",
 -      "fphp",
 -      "asimdhp",
 -      "cpuid",
 -      "asimdrdm",
 -      "jscvt",
 -      "fcma",
 -      "lrcpc",
 -      "dcpop",
 -      "sha3",
 -      "sm3",
 -      "sm4",
 -      "asimddp",
 -      "sha512",
 -      "sve",
 -      "asimdfhm",
 -      "dit",
 -      "uscat",
 -      "ilrcpc",
 -      "flagm",
 -      "ssbs",
 -      "sb",
 -      "paca",
 -      "pacg",
 -      "dcpodp",
 -      "sve2",
 -      "sveaes",
 -      "svepmull",
 -      "svebitperm",
 -      "svesha3",
 -      "svesm4",
 -      "flagm2",
 -      "frint",
 -      "svei8mm",
 -      "svef32mm",
 -      "svef64mm",
 -      "svebf16",
 -      "i8mm",
 -      "bf16",
 -      "dgh",
 -      "rng",
 -      "bti",
 -      "mte",
 -      NULL
 +      [KERNEL_HWCAP_FP]               = "fp",
 +      [KERNEL_HWCAP_ASIMD]            = "asimd",
 +      [KERNEL_HWCAP_EVTSTRM]          = "evtstrm",
 +      [KERNEL_HWCAP_AES]              = "aes",
 +      [KERNEL_HWCAP_PMULL]            = "pmull",
 +      [KERNEL_HWCAP_SHA1]             = "sha1",
 +      [KERNEL_HWCAP_SHA2]             = "sha2",
 +      [KERNEL_HWCAP_CRC32]            = "crc32",
 +      [KERNEL_HWCAP_ATOMICS]          = "atomics",
 +      [KERNEL_HWCAP_FPHP]             = "fphp",
 +      [KERNEL_HWCAP_ASIMDHP]          = "asimdhp",
 +      [KERNEL_HWCAP_CPUID]            = "cpuid",
 +      [KERNEL_HWCAP_ASIMDRDM]         = "asimdrdm",
 +      [KERNEL_HWCAP_JSCVT]            = "jscvt",
 +      [KERNEL_HWCAP_FCMA]             = "fcma",
 +      [KERNEL_HWCAP_LRCPC]            = "lrcpc",
 +      [KERNEL_HWCAP_DCPOP]            = "dcpop",
 +      [KERNEL_HWCAP_SHA3]             = "sha3",
 +      [KERNEL_HWCAP_SM3]              = "sm3",
 +      [KERNEL_HWCAP_SM4]              = "sm4",
 +      [KERNEL_HWCAP_ASIMDDP]          = "asimddp",
 +      [KERNEL_HWCAP_SHA512]           = "sha512",
 +      [KERNEL_HWCAP_SVE]              = "sve",
 +      [KERNEL_HWCAP_ASIMDFHM]         = "asimdfhm",
 +      [KERNEL_HWCAP_DIT]              = "dit",
 +      [KERNEL_HWCAP_USCAT]            = "uscat",
 +      [KERNEL_HWCAP_ILRCPC]           = "ilrcpc",
 +      [KERNEL_HWCAP_FLAGM]            = "flagm",
 +      [KERNEL_HWCAP_SSBS]             = "ssbs",
 +      [KERNEL_HWCAP_SB]               = "sb",
 +      [KERNEL_HWCAP_PACA]             = "paca",
 +      [KERNEL_HWCAP_PACG]             = "pacg",
 +      [KERNEL_HWCAP_DCPODP]           = "dcpodp",
 +      [KERNEL_HWCAP_SVE2]             = "sve2",
 +      [KERNEL_HWCAP_SVEAES]           = "sveaes",
 +      [KERNEL_HWCAP_SVEPMULL]         = "svepmull",
 +      [KERNEL_HWCAP_SVEBITPERM]       = "svebitperm",
 +      [KERNEL_HWCAP_SVESHA3]          = "svesha3",
 +      [KERNEL_HWCAP_SVESM4]           = "svesm4",
 +      [KERNEL_HWCAP_FLAGM2]           = "flagm2",
 +      [KERNEL_HWCAP_FRINT]            = "frint",
 +      [KERNEL_HWCAP_SVEI8MM]          = "svei8mm",
 +      [KERNEL_HWCAP_SVEF32MM]         = "svef32mm",
 +      [KERNEL_HWCAP_SVEF64MM]         = "svef64mm",
 +      [KERNEL_HWCAP_SVEBF16]          = "svebf16",
 +      [KERNEL_HWCAP_I8MM]             = "i8mm",
 +      [KERNEL_HWCAP_BF16]             = "bf16",
 +      [KERNEL_HWCAP_DGH]              = "dgh",
 +      [KERNEL_HWCAP_RNG]              = "rng",
 +      [KERNEL_HWCAP_BTI]              = "bti",
++      [KERNEL_HWCAP_MTE]              = "mte",
  };
  
  #ifdef CONFIG_COMPAT
 
        nop                                     // Patched to SMC/HVC #0
  alternative_cb_end
  .L__asm_ssbd_skip\@:
 -#endif
        .endm
  
+       /* Check for MTE asynchronous tag check faults */
+       .macro check_mte_async_tcf, flgs, tmp
+ #ifdef CONFIG_ARM64_MTE
+ alternative_if_not ARM64_MTE
+       b       1f
+ alternative_else_nop_endif
+       mrs_s   \tmp, SYS_TFSRE0_EL1
+       tbz     \tmp, #SYS_TFSR_EL1_TF0_SHIFT, 1f
+       /* Asynchronous TCF occurred for TTBR0 access, set the TI flag */
+       orr     \flgs, \flgs, #_TIF_MTE_ASYNC_FAULT
+       str     \flgs, [tsk, #TSK_TI_FLAGS]
+       msr_s   SYS_TFSRE0_EL1, xzr
+ 1:
+ #endif
+       .endm
+ 
+       /* Clear the MTE asynchronous tag check faults */
+       .macro clear_mte_async_tcf
+ #ifdef CONFIG_ARM64_MTE
+ alternative_if ARM64_MTE
+       dsb     ish
+       msr_s   SYS_TFSRE0_EL1, xzr
+ alternative_else_nop_endif
+ #endif
+       .endm
+ 
        .macro  kernel_entry, el, regsize = 64
        .if     \regsize == 32
        mov     w0, w0                          // zero upper 32 bits of x0