[PATCH RFC v3 04/12] linux-user: add MTE_STORE_ONLY to prctl

Gabriel Brookman posted 12 patches 1 month ago
Maintainers: Laurent Vivier <laurent@vivier.eu>, Peter Maydell <peter.maydell@linaro.org>
[PATCH RFC v3 04/12] linux-user: add MTE_STORE_ONLY to prctl
Posted by Gabriel Brookman 1 month ago
Linux-user processes can now control whether MTE_STORE_ONLY is enabled
using the prctl syscall.

Signed-off-by: Gabriel Brookman <brookmangabriel@gmail.com>
---
 linux-user/aarch64/mte_user_helper.h |  3 +++
 linux-user/aarch64/target_prctl.h    | 11 +++++++++++
 tests/tcg/aarch64/mte.h              |  3 +++
 3 files changed, 17 insertions(+)

diff --git a/linux-user/aarch64/mte_user_helper.h b/linux-user/aarch64/mte_user_helper.h
index 0c53abda22..afd2d6dbda 100644
--- a/linux-user/aarch64/mte_user_helper.h
+++ b/linux-user/aarch64/mte_user_helper.h
@@ -20,6 +20,9 @@
 # define PR_MTE_TAG_SHIFT       3
 # define PR_MTE_TAG_MASK        (0xffffUL << PR_MTE_TAG_SHIFT)
 #endif
+#ifndef PR_MTE_STORE_ONLY
+# define PR_MTE_STORE_ONLY      (1UL << 19)
+#endif
 
 /**
  * arm_set_mte_tcf0 - Set TCF0 field in SCTLR_EL1 register
diff --git a/linux-user/aarch64/target_prctl.h b/linux-user/aarch64/target_prctl.h
index 621be5727f..5207580c1a 100644
--- a/linux-user/aarch64/target_prctl.h
+++ b/linux-user/aarch64/target_prctl.h
@@ -168,6 +168,9 @@ static abi_long do_prctl_set_tagged_addr_ctrl(CPUArchState *env, abi_long arg2)
     if (cpu_isar_feature(aa64_mte, cpu)) {
         valid_mask |= PR_MTE_TCF_MASK;
         valid_mask |= PR_MTE_TAG_MASK;
+        if (cpu_isar_feature(aa64_mte4, cpu)) {
+            valid_mask |= PR_MTE_STORE_ONLY;
+        }
     }
 
     if (arg2 & ~valid_mask) {
@@ -185,6 +188,14 @@ static abi_long do_prctl_set_tagged_addr_ctrl(CPUArchState *env, abi_long arg2)
          */
         env->cp15.gcr_el1 =
             deposit64(env->cp15.gcr_el1, 0, 16, ~arg2 >> PR_MTE_TAG_SHIFT);
+
+        /*
+         * If MTE_STORE_ONLY is enabled, set the corresponding sctlr_el1 bit
+         */
+        if (cpu_isar_feature(aa64_mte4, cpu)) {
+            env->cp15.sctlr_el[1] =
+                deposit64(env->cp15.sctlr_el[1], 58, 1, extract64(arg2, 19, 1));
+        }
         arm_rebuild_hflags(env);
     }
     return 0;
diff --git a/tests/tcg/aarch64/mte.h b/tests/tcg/aarch64/mte.h
index 0805676b11..17b932f3f1 100644
--- a/tests/tcg/aarch64/mte.h
+++ b/tests/tcg/aarch64/mte.h
@@ -20,6 +20,9 @@
 #ifndef PR_TAGGED_ADDR_ENABLE
 # define PR_TAGGED_ADDR_ENABLE    (1UL << 0)
 #endif
+#ifndef PR_MTE_STORE_ONLY
+# define PR_MTE_STORE_ONLY        (1UL << 19)
+#endif
 #ifndef PR_MTE_TCF_SHIFT
 # define PR_MTE_TCF_SHIFT         1
 # define PR_MTE_TCF_NONE          (0UL << PR_MTE_TCF_SHIFT)

-- 
2.52.0
Re: [PATCH RFC v3 04/12] linux-user: add MTE_STORE_ONLY to prctl
Posted by Richard Henderson 1 month ago
On 1/6/26 05:14, Gabriel Brookman wrote:
> Linux-user processes can now control whether MTE_STORE_ONLY is enabled
> using the prctl syscall.
> 
> Signed-off-by: Gabriel Brookman <brookmangabriel@gmail.com>
> ---
>   linux-user/aarch64/mte_user_helper.h |  3 +++
>   linux-user/aarch64/target_prctl.h    | 11 +++++++++++
>   tests/tcg/aarch64/mte.h              |  3 +++
>   3 files changed, 17 insertions(+)
> 
> diff --git a/linux-user/aarch64/mte_user_helper.h b/linux-user/aarch64/mte_user_helper.h
> index 0c53abda22..afd2d6dbda 100644
> --- a/linux-user/aarch64/mte_user_helper.h
> +++ b/linux-user/aarch64/mte_user_helper.h
> @@ -20,6 +20,9 @@
>   # define PR_MTE_TAG_SHIFT       3
>   # define PR_MTE_TAG_MASK        (0xffffUL << PR_MTE_TAG_SHIFT)
>   #endif
> +#ifndef PR_MTE_STORE_ONLY
> +# define PR_MTE_STORE_ONLY      (1UL << 19)
> +#endif
>   
>   /**
>    * arm_set_mte_tcf0 - Set TCF0 field in SCTLR_EL1 register
> diff --git a/linux-user/aarch64/target_prctl.h b/linux-user/aarch64/target_prctl.h
> index 621be5727f..5207580c1a 100644
> --- a/linux-user/aarch64/target_prctl.h
> +++ b/linux-user/aarch64/target_prctl.h
> @@ -168,6 +168,9 @@ static abi_long do_prctl_set_tagged_addr_ctrl(CPUArchState *env, abi_long arg2)
>       if (cpu_isar_feature(aa64_mte, cpu)) {
>           valid_mask |= PR_MTE_TCF_MASK;
>           valid_mask |= PR_MTE_TAG_MASK;
> +        if (cpu_isar_feature(aa64_mte4, cpu)) {
> +            valid_mask |= PR_MTE_STORE_ONLY;
> +        }
>       }
>   
>       if (arg2 & ~valid_mask) {
> @@ -185,6 +188,14 @@ static abi_long do_prctl_set_tagged_addr_ctrl(CPUArchState *env, abi_long arg2)
>            */
>           env->cp15.gcr_el1 =
>               deposit64(env->cp15.gcr_el1, 0, 16, ~arg2 >> PR_MTE_TAG_SHIFT);
> +
> +        /*
> +         * If MTE_STORE_ONLY is enabled, set the corresponding sctlr_el1 bit
> +         */
> +        if (cpu_isar_feature(aa64_mte4, cpu)) {
> +            env->cp15.sctlr_el[1] =
> +                deposit64(env->cp15.sctlr_el[1], 58, 1, extract64(arg2, 19, 1));
> +        }

Let's not hard-code bit numbers.  There's also no need to re-check cpu_isar_feature.

So more like

	if (arg2 & PR_MTE_STORE_ONLY) {
	    env->cp15.sctlr_el[1] |= SCTLR_TCSO0;
	} else {
	    env->cp15.sctlr_el[1] &= ~SCTLR_TCSO0;
	}

In addition, should be done in arm_set_mte_tcf0, which needs to be expanded to match 
linux's set_tagged_addr_ctrl.  This code is common to the prctl and to gdbstub.  The 
function should be renamed at the same time, since it's no longer just tcf0.


r~