linux-user: Rename sve prctls
[qemu.git] / linux-user / aarch64 / target_prctl.h
blob40481e6663542a107dc9dd49bb26b3c27d3dee6a
1 /*
2 * AArch64 specific prctl functions for linux-user
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 #ifndef AARCH64_TARGET_PRCTL_H
7 #define AARCH64_TARGET_PRCTL_H
9 static abi_long do_prctl_sve_get_vl(CPUArchState *env)
11 ARMCPU *cpu = env_archcpu(env);
12 if (cpu_isar_feature(aa64_sve, cpu)) {
13 return sve_vq(env) * 16;
15 return -TARGET_EINVAL;
17 #define do_prctl_sve_get_vl do_prctl_sve_get_vl
19 static abi_long do_prctl_sve_set_vl(CPUArchState *env, abi_long arg2)
22 * We cannot support either PR_SVE_SET_VL_ONEXEC or PR_SVE_VL_INHERIT.
23 * Note the kernel definition of sve_vl_valid allows for VQ=512,
24 * i.e. VL=8192, even though the current architectural maximum is VQ=16.
26 if (cpu_isar_feature(aa64_sve, env_archcpu(env))
27 && arg2 >= 0 && arg2 <= 512 * 16 && !(arg2 & 15)) {
28 uint32_t vq, old_vq;
30 old_vq = sve_vq(env);
33 * Bound the value of arg2, so that we know that it fits into
34 * the 4-bit field in ZCR_EL1. Rely on the hflags rebuild to
35 * sort out the length supported by the cpu.
37 vq = MAX(arg2 / 16, 1);
38 vq = MIN(vq, ARM_MAX_VQ);
39 env->vfp.zcr_el[1] = vq - 1;
40 arm_rebuild_hflags(env);
42 vq = sve_vq(env);
43 if (vq < old_vq) {
44 aarch64_sve_narrow_vq(env, vq);
46 return vq * 16;
48 return -TARGET_EINVAL;
50 #define do_prctl_sve_set_vl do_prctl_sve_set_vl
52 static abi_long do_prctl_reset_keys(CPUArchState *env, abi_long arg2)
54 ARMCPU *cpu = env_archcpu(env);
56 if (cpu_isar_feature(aa64_pauth, cpu)) {
57 int all = (PR_PAC_APIAKEY | PR_PAC_APIBKEY |
58 PR_PAC_APDAKEY | PR_PAC_APDBKEY | PR_PAC_APGAKEY);
59 int ret = 0;
60 Error *err = NULL;
62 if (arg2 == 0) {
63 arg2 = all;
64 } else if (arg2 & ~all) {
65 return -TARGET_EINVAL;
67 if (arg2 & PR_PAC_APIAKEY) {
68 ret |= qemu_guest_getrandom(&env->keys.apia,
69 sizeof(ARMPACKey), &err);
71 if (arg2 & PR_PAC_APIBKEY) {
72 ret |= qemu_guest_getrandom(&env->keys.apib,
73 sizeof(ARMPACKey), &err);
75 if (arg2 & PR_PAC_APDAKEY) {
76 ret |= qemu_guest_getrandom(&env->keys.apda,
77 sizeof(ARMPACKey), &err);
79 if (arg2 & PR_PAC_APDBKEY) {
80 ret |= qemu_guest_getrandom(&env->keys.apdb,
81 sizeof(ARMPACKey), &err);
83 if (arg2 & PR_PAC_APGAKEY) {
84 ret |= qemu_guest_getrandom(&env->keys.apga,
85 sizeof(ARMPACKey), &err);
87 if (ret != 0) {
89 * Some unknown failure in the crypto. The best
90 * we can do is log it and fail the syscall.
91 * The real syscall cannot fail this way.
93 qemu_log_mask(LOG_UNIMP, "PR_PAC_RESET_KEYS: Crypto failure: %s",
94 error_get_pretty(err));
95 error_free(err);
96 return -TARGET_EIO;
98 return 0;
100 return -TARGET_EINVAL;
102 #define do_prctl_reset_keys do_prctl_reset_keys
104 static abi_long do_prctl_set_tagged_addr_ctrl(CPUArchState *env, abi_long arg2)
106 abi_ulong valid_mask = PR_TAGGED_ADDR_ENABLE;
107 ARMCPU *cpu = env_archcpu(env);
109 if (cpu_isar_feature(aa64_mte, cpu)) {
110 valid_mask |= PR_MTE_TCF_MASK;
111 valid_mask |= PR_MTE_TAG_MASK;
114 if (arg2 & ~valid_mask) {
115 return -TARGET_EINVAL;
117 env->tagged_addr_enable = arg2 & PR_TAGGED_ADDR_ENABLE;
119 if (cpu_isar_feature(aa64_mte, cpu)) {
120 switch (arg2 & PR_MTE_TCF_MASK) {
121 case PR_MTE_TCF_NONE:
122 case PR_MTE_TCF_SYNC:
123 case PR_MTE_TCF_ASYNC:
124 break;
125 default:
126 return -EINVAL;
130 * Write PR_MTE_TCF to SCTLR_EL1[TCF0].
131 * Note that the syscall values are consistent with hw.
133 env->cp15.sctlr_el[1] =
134 deposit64(env->cp15.sctlr_el[1], 38, 2, arg2 >> PR_MTE_TCF_SHIFT);
137 * Write PR_MTE_TAG to GCR_EL1[Exclude].
138 * Note that the syscall uses an include mask,
139 * and hardware uses an exclude mask -- invert.
141 env->cp15.gcr_el1 =
142 deposit64(env->cp15.gcr_el1, 0, 16, ~arg2 >> PR_MTE_TAG_SHIFT);
143 arm_rebuild_hflags(env);
145 return 0;
147 #define do_prctl_set_tagged_addr_ctrl do_prctl_set_tagged_addr_ctrl
149 static abi_long do_prctl_get_tagged_addr_ctrl(CPUArchState *env)
151 ARMCPU *cpu = env_archcpu(env);
152 abi_long ret = 0;
154 if (env->tagged_addr_enable) {
155 ret |= PR_TAGGED_ADDR_ENABLE;
157 if (cpu_isar_feature(aa64_mte, cpu)) {
158 /* See do_prctl_set_tagged_addr_ctrl. */
159 ret |= extract64(env->cp15.sctlr_el[1], 38, 2) << PR_MTE_TCF_SHIFT;
160 ret = deposit64(ret, PR_MTE_TAG_SHIFT, 16, ~env->cp15.gcr_el1);
162 return ret;
164 #define do_prctl_get_tagged_addr_ctrl do_prctl_get_tagged_addr_ctrl
166 #endif /* AARCH64_TARGET_PRCTL_H */