2 * AArch64 specific prctl functions for linux-user
4 * SPDX-License-Identifier: GPL-2.0-or-later
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)) {
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
);
44 aarch64_sve_narrow_vq(env
, vq
);
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
);
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
);
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
));
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
:
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.
142 deposit64(env
->cp15
.gcr_el1
, 0, 16, ~arg2
>> PR_MTE_TAG_SHIFT
);
143 arm_rebuild_hflags(env
);
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
);
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
);
164 #define do_prctl_get_tagged_addr_ctrl do_prctl_get_tagged_addr_ctrl
166 #endif /* AARCH64_TARGET_PRCTL_H */