linux-user/aarch64: Implement PR_MTE_TCF and PR_MTE_TAG
These prctl fields are required for the function of MTE. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20210212184902.1251044-24-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
16c8497848
commit
bfd0572f43
@ -33,5 +33,14 @@ struct target_pt_regs {
|
||||
#define TARGET_PR_SET_TAGGED_ADDR_CTRL 55
|
||||
#define TARGET_PR_GET_TAGGED_ADDR_CTRL 56
|
||||
# define TARGET_PR_TAGGED_ADDR_ENABLE (1UL << 0)
|
||||
/* MTE tag check fault modes */
|
||||
# define TARGET_PR_MTE_TCF_SHIFT 1
|
||||
# define TARGET_PR_MTE_TCF_NONE (0UL << TARGET_PR_MTE_TCF_SHIFT)
|
||||
# define TARGET_PR_MTE_TCF_SYNC (1UL << TARGET_PR_MTE_TCF_SHIFT)
|
||||
# define TARGET_PR_MTE_TCF_ASYNC (2UL << TARGET_PR_MTE_TCF_SHIFT)
|
||||
# define TARGET_PR_MTE_TCF_MASK (3UL << TARGET_PR_MTE_TCF_SHIFT)
|
||||
/* MTE tag inclusion mask */
|
||||
# define TARGET_PR_MTE_TAG_SHIFT 3
|
||||
# define TARGET_PR_MTE_TAG_MASK (0xffffUL << TARGET_PR_MTE_TAG_SHIFT)
|
||||
|
||||
#endif /* AARCH64_TARGET_SYSCALL_H */
|
||||
|
@ -10997,17 +10997,53 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
|
||||
{
|
||||
abi_ulong valid_mask = TARGET_PR_TAGGED_ADDR_ENABLE;
|
||||
CPUARMState *env = cpu_env;
|
||||
ARMCPU *cpu = env_archcpu(env);
|
||||
|
||||
if (cpu_isar_feature(aa64_mte, cpu)) {
|
||||
valid_mask |= TARGET_PR_MTE_TCF_MASK;
|
||||
valid_mask |= TARGET_PR_MTE_TAG_MASK;
|
||||
}
|
||||
|
||||
if ((arg2 & ~valid_mask) || arg3 || arg4 || arg5) {
|
||||
return -TARGET_EINVAL;
|
||||
}
|
||||
env->tagged_addr_enable = arg2 & TARGET_PR_TAGGED_ADDR_ENABLE;
|
||||
|
||||
if (cpu_isar_feature(aa64_mte, cpu)) {
|
||||
switch (arg2 & TARGET_PR_MTE_TCF_MASK) {
|
||||
case TARGET_PR_MTE_TCF_NONE:
|
||||
case TARGET_PR_MTE_TCF_SYNC:
|
||||
case TARGET_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.
|
||||
*/
|
||||
env->cp15.sctlr_el[1] =
|
||||
deposit64(env->cp15.sctlr_el[1], 38, 2,
|
||||
arg2 >> TARGET_PR_MTE_TCF_SHIFT);
|
||||
|
||||
/*
|
||||
* Write PR_MTE_TAG to GCR_EL1[Exclude].
|
||||
* Note that the syscall uses an include mask,
|
||||
* and hardware uses an exclude mask -- invert.
|
||||
*/
|
||||
env->cp15.gcr_el1 =
|
||||
deposit64(env->cp15.gcr_el1, 0, 16,
|
||||
~arg2 >> TARGET_PR_MTE_TAG_SHIFT);
|
||||
arm_rebuild_hflags(env);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
case TARGET_PR_GET_TAGGED_ADDR_CTRL:
|
||||
{
|
||||
abi_long ret = 0;
|
||||
CPUARMState *env = cpu_env;
|
||||
ARMCPU *cpu = env_archcpu(env);
|
||||
|
||||
if (arg2 || arg3 || arg4 || arg5) {
|
||||
return -TARGET_EINVAL;
|
||||
@ -11015,6 +11051,13 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
|
||||
if (env->tagged_addr_enable) {
|
||||
ret |= TARGET_PR_TAGGED_ADDR_ENABLE;
|
||||
}
|
||||
if (cpu_isar_feature(aa64_mte, cpu)) {
|
||||
/* See above. */
|
||||
ret |= (extract64(env->cp15.sctlr_el[1], 38, 2)
|
||||
<< TARGET_PR_MTE_TCF_SHIFT);
|
||||
ret = deposit64(ret, TARGET_PR_MTE_TAG_SHIFT, 16,
|
||||
~env->cp15.gcr_el1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif /* AARCH64 */
|
||||
|
Loading…
Reference in New Issue
Block a user