kvm: arm64: Only list the registers that can be touched

For partitions, this changes over the lifecycle and is always a subset.
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index fae63c3..c15942b 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -19,6 +19,7 @@
 #include <linux/vmalloc.h>
 #include <linux/fs.h>
 #include <kvm/arm_psci.h>
+#include <kvm/arm_spci.h>
 #include <asm/cputype.h>
 #include <linux/uaccess.h>
 #include <asm/fpsimd.h>
@@ -607,6 +608,10 @@
 {
 	unsigned long res = 0;
 
+	/* XXX: This whole thing is pretty nasty */
+	if (kvm_spci_vcpu_reg_list_num(vcpu, &res))
+		return res;
+
 	res += num_core_regs(vcpu);
 	res += num_sve_regs(vcpu);
 	res += kvm_arm_num_sys_reg_descs(vcpu);
@@ -625,6 +630,11 @@
 {
 	int ret;
 
+	/* XXX: This is _really_ nasty */
+	ret = kvm_spci_vcpu_reg_list(vcpu, uindices);
+	if (ret <= 0)
+		return ret;
+
 	ret = copy_core_reg_indices(vcpu, uindices);
 	if (ret < 0)
 		return ret;
diff --git a/arch/arm64/kvm/spci.c b/arch/arm64/kvm/spci.c
index 4a1d998..eb2123a 100644
--- a/arch/arm64/kvm/spci.c
+++ b/arch/arm64/kvm/spci.c
@@ -541,6 +541,46 @@
 	return 0;
 }
 
+int kvm_spci_vcpu_reg_list_num(struct kvm_vcpu *vcpu, unsigned long *num)
+{
+	const struct kvm_spci_partition *part = part_get_linked(vcpu->kvm);
+
+	if (!part)
+		return 0;
+
+	if (likely(vcpu->arch.has_run_once))
+		*num = 0;
+	else
+		*num = 8;
+
+	return 1;
+}
+
+int kvm_spci_vcpu_reg_list(struct kvm_vcpu *vcpu, u64 __user *uindices)
+{
+	const struct kvm_spci_partition *part = part_get_linked(vcpu->kvm);
+	u64 i;
+
+	if (!part)
+		return 1;
+
+	if (likely(vcpu->arch.has_run_once))
+		return 1;
+
+	for (i = 0; i < 16; i += 2) {
+		u64 reg = KVM_REG_ARM64 | KVM_REG_ARM_CORE
+			| KVM_REG_SIZE_U64 | i;
+
+		if (uindices) {
+			if (put_user(reg, uindices))
+				return -EFAULT;
+			++uindices;
+		}
+	}
+
+	return 0;
+}
+
 /*
  * Checks the registers can be accessed by user space. If the vCPU is part of an
  * SPCI partition, the only registers that can be accessed are x0-7 and,
diff --git a/include/kvm/arm_spci.h b/include/kvm/arm_spci.h
index 5bd7071..8733901 100644
--- a/include/kvm/arm_spci.h
+++ b/include/kvm/arm_spci.h
@@ -45,6 +45,8 @@
 int kvm_spci_check_vcpu_init_features(const struct kvm_vcpu *vcpu,
 				      const struct kvm_vcpu_init *init);
 int kvm_spci_vcpu_first_run_init(struct kvm_vcpu *vcpu);
+int kvm_spci_vcpu_reg_list_num(struct kvm_vcpu *vcpu, unsigned long *num);
+int kvm_spci_vcpu_reg_list(struct kvm_vcpu *vcpu, u64 __user *uindices);
 int kvm_spci_check_vcpu_access_reg(struct kvm_vcpu *vcpu,
 				   struct kvm_one_reg *reg);