KVM: arm64: Reorder handling of invariant sysregs from userspace
authorMarc Zyngier <maz@kernel.org>
Sun, 3 Jul 2022 14:11:50 +0000 (15:11 +0100)
committerMarc Zyngier <maz@kernel.org>
Sun, 17 Jul 2022 10:55:33 +0000 (11:55 +0100)
In order to allow some further refactor of the sysreg helpers,
move the handling of invariant sysreg to occur before we handle
all the other ones.

Reviewed-by: Reiji Watanabe <reijiw@google.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
arch/arm64/kvm/sys_regs.c

index 1f41028..9291cb9 100644 (file)
@@ -2849,6 +2849,7 @@ int kvm_arm_sys_reg_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg
 {
        const struct sys_reg_desc *r;
        void __user *uaddr = (void __user *)(unsigned long)reg->addr;
+       int err;
 
        if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_DEMUX)
                return demux_c15_get(reg->id, uaddr);
@@ -2856,12 +2857,14 @@ int kvm_arm_sys_reg_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg
        if (KVM_REG_SIZE(reg->id) != sizeof(__u64))
                return -ENOENT;
 
+       err = get_invariant_sys_reg(reg->id, uaddr);
+       if (err != -ENOENT)
+               return err;
+
        r = index_to_sys_reg_desc(vcpu, reg->id);
-       if (!r)
-               return get_invariant_sys_reg(reg->id, uaddr);
 
        /* Check for regs disabled by runtime config */
-       if (sysreg_hidden(vcpu, r))
+       if (!r || sysreg_hidden(vcpu, r))
                return -ENOENT;
 
        if (r->get_user)
@@ -2874,6 +2877,7 @@ int kvm_arm_sys_reg_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg
 {
        const struct sys_reg_desc *r;
        void __user *uaddr = (void __user *)(unsigned long)reg->addr;
+       int err;
 
        if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_DEMUX)
                return demux_c15_set(reg->id, uaddr);
@@ -2881,12 +2885,14 @@ int kvm_arm_sys_reg_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg
        if (KVM_REG_SIZE(reg->id) != sizeof(__u64))
                return -ENOENT;
 
+       err = set_invariant_sys_reg(reg->id, uaddr);
+       if (err != -ENOENT)
+               return err;
+
        r = index_to_sys_reg_desc(vcpu, reg->id);
-       if (!r)
-               return set_invariant_sys_reg(reg->id, uaddr);
 
        /* Check for regs disabled by runtime config */
-       if (sysreg_hidden(vcpu, r))
+       if (!r || sysreg_hidden(vcpu, r))
                return -ENOENT;
 
        if (r->set_user)