diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
index 82e9099834ae..b7aa17d9a044 100644
--- a/arch/arm64/include/asm/cpucaps.h
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -60,7 +60,8 @@
 #define ARM64_HAS_ADDRESS_AUTH_IMP_DEF         39
 #define ARM64_HAS_GENERIC_AUTH_ARCH            40
 #define ARM64_HAS_GENERIC_AUTH_IMP_DEF         41
+#define ARM64_HAS_MTE                          42
 
-#define ARM64_NCAPS                            42
+#define ARM64_NCAPS                            43
 
 #endif /* __ASM_CPUCAPS_H */
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 72dc4c011014..996ab091ae99 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -451,6 +451,7 @@
 
 /* Common SCTLR_ELx flags. */
 #define SCTLR_ELx_DSSBS        (_BITUL(44))
+#define SCTLR_ELx_ATA          (_BITUL(43))
 #define SCTLR_ELx_ENIA (_BITUL(31))
 #define SCTLR_ELx_ENIB (_BITUL(30))
 #define SCTLR_ELx_ENDA (_BITUL(27))
@@ -496,6 +497,7 @@
 #endif
 
 /* SCTLR_EL1 specific flags. */
+#define SCTLR_EL1_ATA0         (_BITUL(42))
 #define SCTLR_EL1_UCI          (_BITUL(26))
 #define SCTLR_EL1_E0E          (_BITUL(24))
 #define SCTLR_EL1_SPAN         (_BITUL(23))
@@ -596,6 +598,7 @@
 
 /* id_aa64pfr1 */
 #define ID_AA64PFR1_SSBS_SHIFT         4
+#define ID_AA64PFR1_MTE_SHIFT          8
 
 #define ID_AA64PFR1_SSBS_PSTATE_NI     0
 #define ID_AA64PFR1_SSBS_PSTATE_ONLY   1
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index f6d84e2c92fe..f54c1e7f40aa 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -178,6 +178,7 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = {
 
 static const struct arm64_ftr_bits ftr_id_aa64pfr1[] = {
        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, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_MTE_SHIFT, 4, 0),
        ARM64_FTR_END,
 };
 
@@ -1203,6 +1204,11 @@ static void cpu_enable_address_auth(struct arm64_cpu_capabilities const *cap)
 }
 #endif /* CONFIG_ARM64_PTR_AUTH */
 
+static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap)
+{
+       sysreg_clear_set(sctlr_el1, 0, SCTLR_ELx_ATA | SCTLR_EL1_ATA0);
+}
+
 static const struct arm64_cpu_capabilities arm64_features[] = {
        {
                .desc = "GIC system register CPU interface",
@@ -1480,6 +1486,17 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .matches = has_cpuid_feature,
        },
 #endif /* CONFIG_ARM64_PTR_AUTH */
+       {
+               .desc = "Memory Tagging",
+               .capability = ARM64_HAS_MTE,
+               .type = ARM64_CPUCAP_SYSTEM_FEATURE,
+               .matches = has_cpuid_feature,
+               .sys_reg = SYS_ID_AA64PFR1_EL1,
+               .field_pos = ID_AA64PFR1_MTE_SHIFT,
+               .sign = FTR_UNSIGNED,
+               .min_field_value = 1,
+               .cpu_enable = cpu_enable_mte,
        {
                .desc = "GIC system register CPU interface",
@@ -1480,6 +1486,17 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
                .matches = has_cpuid_feature,
        },
 #endif /* CONFIG_ARM64_PTR_AUTH */
+       {
+               .desc = "Memory Tagging",
+               .capability = ARM64_HAS_MTE,
+               .type = ARM64_CPUCAP_SYSTEM_FEATURE,
+               .matches = has_cpuid_feature,
+               .sys_reg = SYS_ID_AA64PFR1_EL1,
+               .field_pos = ID_AA64PFR1_MTE_SHIFT,
+               .sign = FTR_UNSIGNED,
+               .min_field_value = 1,
+               .cpu_enable = cpu_enable_mte,
+       },
        {},
 };
 
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 73886a5f1f30..20ebf4a222e8 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -435,14 +435,14 @@ ENTRY(__cpu_setup)
         *   DEVICE_nGnRE       001     00000100
         *   DEVICE_GRE         010     00001100
         *   NORMAL_NC          011     01000100
-        *   NORMAL             100     11111111
+        *   NORMAL             100     11110000 (Tag)
         *   NORMAL_WT          101     10111011
         */
        ldr     x5, =MAIR(0x00, MT_DEVICE_nGnRnE) | \
                     MAIR(0x04, MT_DEVICE_nGnRE) | \
                     MAIR(0x0c, MT_DEVICE_GRE) | \
                     MAIR(0x44, MT_NORMAL_NC) | \
-                    MAIR(0xff, MT_NORMAL) | \
+                    MAIR(0xf0, MT_NORMAL) | \
                     MAIR(0xbb, MT_NORMAL_WT)
        msr     mair_el1, x5
        /*
