return id & ~(KVM_REG_ARCH_MASK | KVM_REG_SIZE_MASK | KVM_REG_ARM_CORE);
 }
 
-static int validate_core_offset(const struct kvm_vcpu *vcpu,
-                               const struct kvm_one_reg *reg)
+static int core_reg_size_from_offset(const struct kvm_vcpu *vcpu, u64 off)
 {
-       u64 off = core_reg_offset_from_id(reg->id);
        int size;
 
        switch (off) {
                return -EINVAL;
        }
 
-       if (KVM_REG_SIZE(reg->id) != size ||
-           !IS_ALIGNED(off, size / sizeof(__u32)))
+       if (!IS_ALIGNED(off, size / sizeof(__u32)))
                return -EINVAL;
 
        /*
        if (vcpu_has_sve(vcpu) && core_reg_offset_is_vreg(off))
                return -EINVAL;
 
+       return size;
+}
+
+static int validate_core_offset(const struct kvm_vcpu *vcpu,
+                               const struct kvm_one_reg *reg)
+{
+       u64 off = core_reg_offset_from_id(reg->id);
+       int size = core_reg_size_from_offset(vcpu, off);
+
+       if (size < 0)
+               return -EINVAL;
+
+       if (KVM_REG_SIZE(reg->id) != size)
+               return -EINVAL;
+
        return 0;
 }
 
 {
        unsigned int i;
        int n = 0;
-       const u64 core_reg = KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE;
 
        for (i = 0; i < sizeof(struct kvm_regs) / sizeof(__u32); i++) {
-               /*
-                * The KVM_REG_ARM64_SVE regs must be used instead of
-                * KVM_REG_ARM_CORE for accessing the FPSIMD V-registers on
-                * SVE-enabled vcpus:
-                */
-               if (vcpu_has_sve(vcpu) && core_reg_offset_is_vreg(i))
+               u64 reg = KVM_REG_ARM64 | KVM_REG_ARM_CORE | i;
+               int size = core_reg_size_from_offset(vcpu, i);
+
+               if (size < 0)
+                       continue;
+
+               switch (size) {
+               case sizeof(__u32):
+                       reg |= KVM_REG_SIZE_U32;
+                       break;
+
+               case sizeof(__u64):
+                       reg |= KVM_REG_SIZE_U64;
+                       break;
+
+               case sizeof(__uint128_t):
+                       reg |= KVM_REG_SIZE_U128;
+                       break;
+
+               default:
+                       WARN_ON(1);
                        continue;
+               }
 
                if (uindices) {
-                       if (put_user(core_reg | i, uindices))
+                       if (put_user(reg, uindices))
                                return -EFAULT;
                        uindices++;
                }