Except that each ID field should be not greater than that of host, SM3
and SM4 must have the same value; if the value of SHA1 is 0, then SHA2
must have the value 0, and vice versa; if the value of SHA2 is 2, then
SHA3 must have the value 1, and vice versa; if the value of SHA1 is 0,
then SHA3 must have the value 0.

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

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 3954b7a21a4b..76b39cab50b8 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1393,6 +1393,50 @@ static int set_id_aa64dfr0_el1(struct kvm_vcpu *vcpu,
        return 0;
 }
 
+static int set_id_aa64isar0_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 sm3, sm4, sha1, sha2, sha3;
+
+       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;
+
+       sm3 = cpuid_feature_extract_unsigned_field(val, ID_AA64ISAR0_SM3_SHIFT);
+       sm4 = cpuid_feature_extract_unsigned_field(val, ID_AA64ISAR0_SM4_SHIFT);
+       /*
+        * ID_AA64ISAR0_EL1.SM3 and ID_AA64ISAR0_EL1.SM4 must have the same
+        * value.
+        */
+       if (sm3 != sm4)
+               return -EINVAL;
+
+       sha1 = cpuid_feature_extract_unsigned_field(val, 
ID_AA64ISAR0_SHA1_SHIFT);
+       sha2 = cpuid_feature_extract_unsigned_field(val, 
ID_AA64ISAR0_SHA2_SHIFT);
+       sha3 = cpuid_feature_extract_unsigned_field(val, 
ID_AA64ISAR0_SHA3_SHIFT);
+       /*
+        * 1. If the value of ID_AA64ISAR0_EL1.SHA1 is 0, then
+        *    ID_AA64ISAR0_EL1.SHA2 must have the value 0, and vice versa;
+        * 2. If the value of ID_AA64ISAR0_EL1.SHA2 is 2, then
+        *    ID_AA64ISAR0_EL1.SHA3 must have the value 1, and vice versa;
+        * 3. If the value of ID_AA64ISAR0_EL1.SHA1 is 0, then
+        *    ID_AA64ISAR0_EL1.SHA3 must have the value 0;
+        */
+       if ((sha1 ^ sha2) || ((sha2 == 2) ^ (sha3 == 1)) || (!sha1 && sha3))
+               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)
 {
@@ -1607,7 +1651,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
        ID_UNALLOCATED(5,7),
 
        /* CRm=6 */
-       ID_SANITISED(ID_AA64ISAR0_EL1),
+       { 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),
        ID_UNALLOCATED(6,2),
        ID_UNALLOCATED(6,3),
-- 
2.26.2

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

Reply via email to