For other ID registers, we only need to check that each ID field is no greater than that of host (host support corresponding feature). Signed-off-by: zhanghailiang <zhang.zhanghailiang@xxxxxxxxxx> Signed-off-by: Peng Liang <liangpeng10@xxxxxxxxxx> --- arch/arm64/kvm/sys_regs.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 1bcfaf738491..42880800941a 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -1265,10 +1265,6 @@ static int set_id_aa64zfr0_el1(struct kvm_vcpu *vcpu, /* * cpufeature ID register user accessors - * - * For now, these registers are immutable for userspace, so no values - * are stored, and for set_id_reg() we don't allow the effective value - * to be changed. */ static int __get_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, void __user *uaddr, @@ -1292,9 +1288,18 @@ static int __set_id_reg(struct kvm_vcpu *vcpu, if (err) return err; - /* This is what we mean by invariant: you can't change it. */ - if (val != read_id_reg(vcpu, rd, raz)) - return -EINVAL; + if (raz) { + if (val != 0) + return -EINVAL; + } else { + u32 reg_id = sys_reg((u32)rd->Op0, (u32)rd->Op1, (u32)rd->CRn, + (u32)rd->CRm, (u32)rd->Op2); + + err = check_features(reg_id, val); + if (err) + return err; + __vcpu_sys_reg(vcpu, ID_REG_INDEX(reg_id)) = val; + } return 0; } -- 2.26.2