| 1 | /* |
| 2 | * AArch64 specific prctl functions for linux-user |
| 3 | * |
| 4 | * SPDX-License-Identifier: GPL-2.0-or-later |
| 5 | */ |
| 6 | #ifndef AARCH64_TARGET_PRCTL_H |
| 7 | #define AARCH64_TARGET_PRCTL_H |
| 8 | |
| 9 | #include "qemu/units.h" |
| 10 | #include "target/arm/cpu-features.h" |
| 11 | #include "mte_user_helper.h" |
| 12 | #include "gcs-internal.h" |
| 13 | |
| 14 | static abi_long do_prctl_sve_get_vl(CPUArchState *env) |
| 15 | { |
| 16 | ARMCPU *cpu = env_archcpu(env); |
| 17 | if (cpu_isar_feature(aa64_sve, cpu)) { |
| 18 | /* PSTATE.SM is always unset on syscall entry. */ |
| 19 | return sve_vq(env) * 16; |
| 20 | } |
| 21 | return -TARGET_EINVAL; |
| 22 | } |
| 23 | #define do_prctl_sve_get_vl do_prctl_sve_get_vl |
| 24 | |
| 25 | static abi_long do_prctl_sve_set_vl(CPUArchState *env, abi_long arg2) |
| 26 | { |
| 27 | /* |
| 28 | * We cannot support either PR_SVE_SET_VL_ONEXEC or PR_SVE_VL_INHERIT. |
| 29 | * Note the kernel definition of sve_vl_valid allows for VQ=512, |
| 30 | * i.e. VL=8192, even though the current architectural maximum is VQ=16. |
| 31 | */ |
| 32 | if (cpu_isar_feature(aa64_sve, env_archcpu(env)) |
| 33 | && arg2 >= 0 && arg2 <= 512 * 16 && !(arg2 & 15)) { |
| 34 | uint32_t vq, old_vq; |
| 35 | |
| 36 | /* PSTATE.SM is always unset on syscall entry. */ |
| 37 | old_vq = sve_vq(env); |
| 38 | |
| 39 | /* |
| 40 | * Bound the value of arg2, so that we know that it fits into |
| 41 | * the 4-bit field in ZCR_EL1. Rely on the hflags rebuild to |
| 42 | * sort out the length supported by the cpu. |
| 43 | */ |
| 44 | vq = MAX(arg2 / 16, 1); |
| 45 | vq = MIN(vq, ARM_MAX_VQ); |
| 46 | env->vfp.zcr_el[1] = vq - 1; |
| 47 | arm_rebuild_hflags(env); |
| 48 | |
| 49 | vq = sve_vq(env); |
| 50 | if (vq < old_vq) { |
| 51 | aarch64_sve_narrow_vq(env, vq); |
| 52 | } |
| 53 | return vq * 16; |
| 54 | } |
| 55 | return -TARGET_EINVAL; |
| 56 | } |
| 57 | #define do_prctl_sve_set_vl do_prctl_sve_set_vl |
| 58 | |
| 59 | static abi_long do_prctl_sme_get_vl(CPUArchState *env) |
| 60 | { |
| 61 | ARMCPU *cpu = env_archcpu(env); |
| 62 | if (cpu_isar_feature(aa64_sme, cpu)) { |
| 63 | return sme_vq(env) * 16; |
| 64 | } |
| 65 | return -TARGET_EINVAL; |
| 66 | } |
| 67 | #define do_prctl_sme_get_vl do_prctl_sme_get_vl |
| 68 | |
| 69 | static abi_long do_prctl_sme_set_vl(CPUArchState *env, abi_long arg2) |
| 70 | { |
| 71 | /* |
| 72 | * We cannot support either PR_SME_SET_VL_ONEXEC or PR_SME_VL_INHERIT. |
| 73 | * Note the kernel definition of sve_vl_valid allows for VQ=512, |
| 74 | * i.e. VL=8192, even though the architectural maximum is VQ=16. |
| 75 | */ |
| 76 | if (cpu_isar_feature(aa64_sme, env_archcpu(env)) |
| 77 | && arg2 >= 0 && arg2 <= 512 * 16 && !(arg2 & 15)) { |
| 78 | int vq, old_vq; |
| 79 | |
| 80 | old_vq = sme_vq(env); |
| 81 | |
| 82 | /* |
| 83 | * Bound the value of vq, so that we know that it fits into |
| 84 | * the 4-bit field in SMCR_EL1. Because PSTATE.SM is cleared |
| 85 | * on syscall entry, we are not modifying the current SVE |
| 86 | * vector length. |
| 87 | */ |
| 88 | vq = MAX(arg2 / 16, 1); |
| 89 | vq = MIN(vq, 16); |
| 90 | env->vfp.smcr_el[1] = |
| 91 | FIELD_DP64(env->vfp.smcr_el[1], SMCR, LEN, vq - 1); |
| 92 | |
| 93 | /* Delay rebuilding hflags until we know if ZA must change. */ |
| 94 | vq = sve_vqm1_for_el_sm(env, 0, true) + 1; |
| 95 | |
| 96 | if (vq != old_vq) { |
| 97 | /* |
| 98 | * PSTATE.ZA state is cleared on any change to SVL. |
| 99 | * We need not call arm_rebuild_hflags because PSTATE.SM was |
| 100 | * cleared on syscall entry, so this hasn't changed VL. |
| 101 | */ |
| 102 | env->svcr = FIELD_DP64(env->svcr, SVCR, ZA, 0); |
| 103 | arm_rebuild_hflags(env); |
| 104 | } |
| 105 | return vq * 16; |
| 106 | } |
| 107 | return -TARGET_EINVAL; |
| 108 | } |
| 109 | #define do_prctl_sme_set_vl do_prctl_sme_set_vl |
| 110 | |
| 111 | static abi_long do_prctl_reset_keys(CPUArchState *env, abi_long arg2) |
| 112 | { |
| 113 | ARMCPU *cpu = env_archcpu(env); |
| 114 | |
| 115 | if (cpu_isar_feature(aa64_pauth, cpu)) { |
| 116 | int all = (PR_PAC_APIAKEY | PR_PAC_APIBKEY | |
| 117 | PR_PAC_APDAKEY | PR_PAC_APDBKEY | PR_PAC_APGAKEY); |
| 118 | int ret = 0; |
| 119 | Error *err = NULL; |
| 120 | |
| 121 | if (arg2 == 0) { |
| 122 | arg2 = all; |
| 123 | } else if (arg2 & ~all) { |
| 124 | return -TARGET_EINVAL; |
| 125 | } |
| 126 | if (arg2 & PR_PAC_APIAKEY) { |
| 127 | ret |= qemu_guest_getrandom(&env->keys.apia, |
| 128 | sizeof(ARMPACKey), &err); |
| 129 | } |
| 130 | if (arg2 & PR_PAC_APIBKEY) { |
| 131 | ret |= qemu_guest_getrandom(&env->keys.apib, |
| 132 | sizeof(ARMPACKey), &err); |
| 133 | } |
| 134 | if (arg2 & PR_PAC_APDAKEY) { |
| 135 | ret |= qemu_guest_getrandom(&env->keys.apda, |
| 136 | sizeof(ARMPACKey), &err); |
| 137 | } |
| 138 | if (arg2 & PR_PAC_APDBKEY) { |
| 139 | ret |= qemu_guest_getrandom(&env->keys.apdb, |
| 140 | sizeof(ARMPACKey), &err); |
| 141 | } |
| 142 | if (arg2 & PR_PAC_APGAKEY) { |
| 143 | ret |= qemu_guest_getrandom(&env->keys.apga, |
| 144 | sizeof(ARMPACKey), &err); |
| 145 | } |
| 146 | if (ret != 0) { |
| 147 | /* |
| 148 | * Some unknown failure in the crypto. The best |
| 149 | * we can do is log it and fail the syscall. |
| 150 | * The real syscall cannot fail this way. |
| 151 | */ |
| 152 | qemu_log_mask(LOG_UNIMP, "PR_PAC_RESET_KEYS: Crypto failure: %s", |
| 153 | error_get_pretty(err)); |
| 154 | error_free(err); |
| 155 | return -TARGET_EIO; |
| 156 | } |
| 157 | return 0; |
| 158 | } |
| 159 | return -TARGET_EINVAL; |
| 160 | } |
| 161 | #define do_prctl_reset_keys do_prctl_reset_keys |
| 162 | |
| 163 | static abi_long do_prctl_set_tagged_addr_ctrl(CPUArchState *env, abi_long arg2) |
| 164 | { |
| 165 | abi_ulong valid_mask = PR_TAGGED_ADDR_ENABLE; |
| 166 | ARMCPU *cpu = env_archcpu(env); |
| 167 | |
| 168 | if (cpu_isar_feature(aa64_mte, cpu)) { |
| 169 | valid_mask |= PR_MTE_TCF_MASK; |
| 170 | valid_mask |= PR_MTE_TAG_MASK; |
| 171 | if (cpu_isar_feature(aa64_mte_store_only, cpu)) { |
| 172 | valid_mask |= PR_MTE_STORE_ONLY; |
| 173 | } |
| 174 | } |
| 175 | |
| 176 | if (arg2 & ~valid_mask) { |
| 177 | return -TARGET_EINVAL; |
| 178 | } |
| 179 | env->tagged_addr_enable = arg2 & PR_TAGGED_ADDR_ENABLE; |
| 180 | |
| 181 | if (cpu_isar_feature(aa64_mte, cpu)) { |
| 182 | arm_set_tagged_addr_ctrl(env, arg2); |
| 183 | |
| 184 | /* |
| 185 | * Write PR_MTE_TAG to GCR_EL1[Exclude]. |
| 186 | * Note that the syscall uses an include mask, |
| 187 | * and hardware uses an exclude mask -- invert. |
| 188 | */ |
| 189 | env->cp15.gcr_el1 = |
| 190 | deposit64(env->cp15.gcr_el1, 0, 16, ~arg2 >> PR_MTE_TAG_SHIFT); |
| 191 | |
| 192 | arm_rebuild_hflags(env); |
| 193 | } |
| 194 | return 0; |
| 195 | } |
| 196 | #define do_prctl_set_tagged_addr_ctrl do_prctl_set_tagged_addr_ctrl |
| 197 | |
| 198 | static abi_long do_prctl_get_tagged_addr_ctrl(CPUArchState *env) |
| 199 | { |
| 200 | ARMCPU *cpu = env_archcpu(env); |
| 201 | abi_long ret = 0; |
| 202 | |
| 203 | if (env->tagged_addr_enable) { |
| 204 | ret |= PR_TAGGED_ADDR_ENABLE; |
| 205 | } |
| 206 | if (cpu_isar_feature(aa64_mte, cpu)) { |
| 207 | /* See do_prctl_set_tagged_addr_ctrl. */ |
| 208 | ret |= extract64(env->cp15.sctlr_el[1], 38, 2) << PR_MTE_TCF_SHIFT; |
| 209 | ret = deposit64(ret, PR_MTE_TAG_SHIFT, 16, ~env->cp15.gcr_el1); |
| 210 | } |
| 211 | return ret; |
| 212 | } |
| 213 | #define do_prctl_get_tagged_addr_ctrl do_prctl_get_tagged_addr_ctrl |
| 214 | |
| 215 | static abi_long do_prctl_get_shadow_stack_status(CPUArchState *env, |
| 216 | abi_long arg2) |
| 217 | { |
| 218 | ARMCPU *cpu = env_archcpu(env); |
| 219 | |
| 220 | if (!cpu_isar_feature(aa64_gcs, cpu)) { |
| 221 | return -TARGET_EINVAL; |
| 222 | } |
| 223 | return put_user_ual(gcs_get_el0_mode(env), arg2); |
| 224 | } |
| 225 | #define do_prctl_get_shadow_stack_status do_prctl_get_shadow_stack_status |
| 226 | |
| 227 | static abi_long gcs_alloc(abi_ulong hint, abi_ulong size) |
| 228 | { |
| 229 | /* |
| 230 | * Without softmmu, we cannot protect GCS memory properly. |
| 231 | * Make do with normal read/write permissions. This at least allows |
| 232 | * emulation of correct programs which don't access the gcs stack |
| 233 | * with normal instructions. |
| 234 | */ |
| 235 | return target_mmap(hint, size, PROT_READ | PROT_WRITE, |
| 236 | MAP_PRIVATE | MAP_ANONYMOUS | |
| 237 | (hint ? MAP_FIXED_NOREPLACE : 0), -1, 0); |
| 238 | } |
| 239 | |
| 240 | static abi_ulong gcs_new_stack(TaskState *ts) |
| 241 | { |
| 242 | /* Use guest_stack_size as a proxy for RLIMIT_STACK. */ |
| 243 | abi_ulong size = MIN(MAX(guest_stack_size / 2, TARGET_PAGE_SIZE), 2 * GiB); |
| 244 | abi_ulong base = gcs_alloc(0, size); |
| 245 | |
| 246 | if (base == -1) { |
| 247 | return -1; |
| 248 | } |
| 249 | |
| 250 | ts->gcs_base = base; |
| 251 | ts->gcs_size = size; |
| 252 | return base + size - 8; |
| 253 | } |
| 254 | |
| 255 | static abi_long do_prctl_set_shadow_stack_status(CPUArchState *env, |
| 256 | abi_long new_mode) |
| 257 | { |
| 258 | ARMCPU *cpu = env_archcpu(env); |
| 259 | TaskState *ts = get_task_state(env_cpu(env)); |
| 260 | abi_long cur_mode; |
| 261 | |
| 262 | if (!cpu_isar_feature(aa64_gcs, cpu)) { |
| 263 | return -TARGET_EINVAL; |
| 264 | } |
| 265 | if (new_mode & ~(PR_SHADOW_STACK_ENABLE | |
| 266 | PR_SHADOW_STACK_WRITE | |
| 267 | PR_SHADOW_STACK_PUSH)) { |
| 268 | return -TARGET_EINVAL; |
| 269 | } |
| 270 | |
| 271 | cur_mode = gcs_get_el0_mode(env); |
| 272 | if ((new_mode ^ cur_mode) & ts->gcs_el0_locked) { |
| 273 | return -TARGET_EBUSY; |
| 274 | } |
| 275 | |
| 276 | if (new_mode & ~cur_mode & PR_SHADOW_STACK_ENABLE) { |
| 277 | abi_long gcspr; |
| 278 | |
| 279 | if (ts->gcs_base || env->cp15.gcspr_el[0]) { |
| 280 | return -EINVAL; |
| 281 | } |
| 282 | gcspr = gcs_new_stack(ts); |
| 283 | if (gcspr == -1) { |
| 284 | return -TARGET_ENOMEM; |
| 285 | } |
| 286 | env->cp15.gcspr_el[0] = gcspr; |
| 287 | } |
| 288 | |
| 289 | gcs_set_el0_mode(env, new_mode); |
| 290 | arm_rebuild_hflags(env); |
| 291 | return 0; |
| 292 | } |
| 293 | #define do_prctl_set_shadow_stack_status do_prctl_set_shadow_stack_status |
| 294 | |
| 295 | static abi_long do_prctl_lock_shadow_stack_status(CPUArchState *env, |
| 296 | abi_long arg2) |
| 297 | { |
| 298 | ARMCPU *cpu = env_archcpu(env); |
| 299 | TaskState *ts = get_task_state(env_cpu(env)); |
| 300 | |
| 301 | if (!cpu_isar_feature(aa64_gcs, cpu)) { |
| 302 | return -EINVAL; |
| 303 | } |
| 304 | ts->gcs_el0_locked |= arg2; |
| 305 | return 0; |
| 306 | } |
| 307 | #define do_prctl_lock_shadow_stack_status do_prctl_lock_shadow_stack_status |
| 308 | |
| 309 | #endif /* AARCH64_TARGET_PRCTL_H */ |