@@ -173,21 +173,22 @@ static abi_long do_prctl_set_tagged_addr_ctrl(CPUArchState *env, abi_long arg2)
env->tagged_addr_enable = arg2 & PR_TAGGED_ADDR_ENABLE;
if (cpu_isar_feature(aa64_mte, cpu)) {
- switch (arg2 & PR_MTE_TCF_MASK) {
- case PR_MTE_TCF_NONE:
- case PR_MTE_TCF_SYNC:
- case PR_MTE_TCF_ASYNC:
- break;
- default:
- return -EINVAL;
- }
-
/*
* Write PR_MTE_TCF to SCTLR_EL1[TCF0].
- * Note that the syscall values are consistent with hw.
+ * Note that SYNC | ASYNC -> ASYMM with FEAT_MTE3,
+ * otherwise mte_update_sctlr_user chooses ASYNC.
*/
- env->cp15.sctlr_el[1] =
- deposit64(env->cp15.sctlr_el[1], 38, 2, arg2 >> PR_MTE_TCF_SHIFT);
+ unsigned tcf = 0;
+ if (arg2 & PR_MTE_TCF_ASYNC) {
+ if ((arg2 & PR_MTE_TCF_SYNC) && cpu_isar_feature(aa64_mte3, cpu)) {
+ tcf = 3;
+ } else {
+ tcf = 2;
+ }
+ } else if (arg2 & PR_MTE_TCF_SYNC) {
+ tcf = 1;
+ }
+ env->cp15.sctlr_el[1] = deposit64(env->cp15.sctlr_el[1], 38, 2, tcf);
/*
* Write PR_MTE_TAG to GCR_EL1[Exclude].
When MTE3 is supported, the kernel maps PR_MTE_TCF_ASYNC | PR_MTE_TCF_SYNC to MTE_CTRL_TCF_ASYMM and from there to SCTLR_EL1.TCF0 = 3 There is no error reported for setting ASYNC | SYNC when MTE3 is not supported; the kernel simply selects the ASYNC behavior of TCG0=2. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- linux-user/aarch64/target_prctl.h | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-)