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);