* set bits and map into register values determines our
         * default order.
         */
-       if (resolved_mte_tcf & MTE_CTRL_TCF_ASYNC)
+       if (resolved_mte_tcf & MTE_CTRL_TCF_ASYMM)
+               sctlr |= SCTLR_EL1_TCF0_ASYMM;
+       else if (resolved_mte_tcf & MTE_CTRL_TCF_ASYNC)
                sctlr |= SCTLR_EL1_TCF0_ASYNC;
        else if (resolved_mte_tcf & MTE_CTRL_TCF_SYNC)
                sctlr |= SCTLR_EL1_TCF0_SYNC;
                mte_ctrl |= MTE_CTRL_TCF_ASYNC;
        if (arg & PR_MTE_TCF_SYNC)
                mte_ctrl |= MTE_CTRL_TCF_SYNC;
+       if (arg & PR_MTE_TCF_ASYMM)
+               mte_ctrl |= MTE_CTRL_TCF_ASYMM;
 
        task->thread.mte_ctrl = mte_ctrl;
        if (task == current) {
                ret |= PR_MTE_TCF_ASYNC;
        if (mte_ctrl & MTE_CTRL_TCF_SYNC)
                ret |= PR_MTE_TCF_SYNC;
+       if (mte_ctrl & MTE_CTRL_TCF_ASYMM)
+               ret |= PR_MTE_TCF_ASYMM;
 
        return ret;
 }
                return sysfs_emit(buf, "async\n");
        case MTE_CTRL_TCF_SYNC:
                return sysfs_emit(buf, "sync\n");
+       case MTE_CTRL_TCF_ASYMM:
+               return sysfs_emit(buf, "asymm\n");
        default:
                return sysfs_emit(buf, "???\n");
        }
                tcf = MTE_CTRL_TCF_ASYNC;
        else if (sysfs_streq(buf, "sync"))
                tcf = MTE_CTRL_TCF_SYNC;
+       else if (cpus_have_cap(ARM64_MTE_ASYMM) && sysfs_streq(buf, "asymm"))
+               tcf = MTE_CTRL_TCF_ASYMM;
        else
                return -EINVAL;
 
 
                return -EINVAL;
 
        if (system_supports_mte())
-               valid_mask |= PR_MTE_TCF_MASK | PR_MTE_TAG_MASK;
+               valid_mask |= PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC \
+                       | PR_MTE_TAG_MASK;
+       if (cpus_have_cap(ARM64_MTE_ASYMM))
+               valid_mask |= PR_MTE_TCF_ASYMM;
 
        if (arg & ~valid_mask)
                return -EINVAL;
 
 # define PR_MTE_TCF_NONE               0UL
 # define PR_MTE_TCF_SYNC               (1UL << 1)
 # define PR_MTE_TCF_ASYNC              (1UL << 2)
-# define PR_MTE_TCF_MASK               (PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC)
+# define PR_MTE_TCF_ASYMM              (1UL << 19)
+# define PR_MTE_TCF_MASK               (PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC | \
+                                        PR_MTE_TCF_ASYMM)
 /* MTE tag inclusion mask */
 # define PR_MTE_TAG_SHIFT              3
 # define PR_MTE_TAG_MASK               (0xffffUL << PR_MTE_TAG_SHIFT)