Except that each ID field should be not greater than that of host, if
the vCPU has not enabled Generic Pointer authentication, then GPA, GPI,
APA, and API must be 0.  Otherwise, GPA and GPI are exclusive; APA and
API are exclusive.

Signed-off-by: zhanghailiang <[email protected]>
Signed-off-by: Peng Liang <[email protected]>
---
 arch/arm64/kvm/sys_regs.c | 42 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 41 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 76b39cab50b8..2ea165d09c7b 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1437,6 +1437,46 @@ static int set_id_aa64isar0_el1(struct kvm_vcpu *vcpu,
        return 0;
 }
 
+static int set_id_aa64isar1_el1(struct kvm_vcpu *vcpu,
+               const struct sys_reg_desc *rd,
+               const struct kvm_one_reg *reg, void __user *uaddr)
+{
+       u32 reg_id = sys_reg((u32)rd->Op0, (u32)rd->Op1, (u32)rd->CRn,
+                            (u32)rd->CRm, (u32)rd->Op2);
+       int err;
+       u64 val;
+       unsigned int gpi, gpa, api, apa;
+
+       err = reg_from_user(&val, uaddr, sys_reg_to_index(rd));
+       if (err)
+               return err;
+       err = check_features(reg_id, val);
+       if (err)
+               return err;
+
+       gpi = cpuid_feature_extract_unsigned_field(val, ID_AA64ISAR1_GPI_SHIFT);
+       gpa = cpuid_feature_extract_unsigned_field(val, ID_AA64ISAR1_GPA_SHIFT);
+       api = cpuid_feature_extract_unsigned_field(val, ID_AA64ISAR1_API_SHIFT);
+       apa = cpuid_feature_extract_unsigned_field(val, ID_AA64ISAR1_APA_SHIFT);
+       if (!vcpu_has_ptrauth(vcpu) && (gpa || gpi || apa || api))
+               return -EINVAL;
+       /*
+        * 1. If the value of ID_AA64ISAR1_EL1.GPA is non-zero, then
+        *    ID_AA64ISAR1_EL1.GPI must have the value 0;
+        * 2. If the value of ID_AA64ISAR1_EL1.GPI is non-zero, then
+        *    ID_AA64ISAR1_EL1.GPA must have the value 0;
+        * 3. If the value of ID_AA64ISAR1_EL1.APA is non-zero, then
+        *    ID_AA64ISAR1_EL1.API must have the value 0;
+        * 4. If the value of ID_AA64ISAR1_EL1.API is non-zero, then
+        *    ID_AA64ISAR1_EL1.APA must have the value 0;
+        */
+       if ((gpi && gpa) || (api && apa))
+               return -EINVAL;
+
+       __vcpu_sys_reg(vcpu, ID_REG_INDEX(reg_id)) = val;
+       return 0;
+}
+
 static bool access_ctr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
                       const struct sys_reg_desc *r)
 {
@@ -1652,7 +1692,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 
        /* CRm=6 */
        { SYS_DESC(SYS_ID_AA64ISAR0_EL1), access_id_reg, .get_user = 
get_id_reg, .set_user = set_id_aa64isar0_el1 },
-       ID_SANITISED(ID_AA64ISAR1_EL1),
+       { SYS_DESC(SYS_ID_AA64ISAR1_EL1), access_id_reg, .get_user = 
get_id_reg, .set_user = set_id_aa64isar1_el1 },
        ID_UNALLOCATED(6,2),
        ID_UNALLOCATED(6,3),
        ID_UNALLOCATED(6,4),
-- 
2.26.2

_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

Reply via email to