Skip to contentSkip to conversation

KVM: PPC: Book3S HV: Provide a way for userspace to get/set per-vCPU areas

PATCH New Paul Mackerras 1 participant 1 message Aug 17, 2012

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 KVM: PPC: Book3S HV: Provide a way for userspace to get/set per-vCPU areas

The PAPR paravirtualization interface lets guests register three different types of per-vCPU buffer areas in its memory for communication with the hypervisor. These are called virtual processor areas (VPAs). Currently the hypercalls to register and unregister VPAs are handled by KVM in the kernel, and userspace has no way to know about or save and restore these registrations across a migration.

This adds get and set ioctls to allow userspace to see what addresses have been registered, and to register or unregister them. This will be needed for guest hibernation and migration, and is also needed so that userspace can unregister them on reset (otherwise we corrupt guest memory after reboot by writing to the VPAs registered by the previous kernel). We also add a capability to indicate that the ioctls are supported.

This also fixes a bug where we were calling init_vpa unconditionally, leading to an oops when unregistering the VPA.

---
 arch/powerpc/include/asm/kvm_ppc.h |    2 ++
 arch/powerpc/kvm/book3s_hv.c       |   54 +++++++++++++++++++++++++++++++++++-
 arch/powerpc/kvm/powerpc.c         |   23 +++++++++++++++
 include/linux/kvm.h                |   12 ++++++++
 4 files changed, 90 insertions(+), 1 deletion(-)
arch/powerpc/include/asm/kvm_ppc.h +2 -0
index 044c921..3d4c655 100644
@@ -194,6 +194,8 @@ int kvmppc_set_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
 
 int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg);
 int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg);
+int kvm_vcpu_get_vpa_info(struct kvm_vcpu *vcpu, struct kvm_ppc_vpa *vpa);
+int kvm_vcpu_set_vpa_info(struct kvm_vcpu *vcpu, struct kvm_ppc_vpa *vpa);
 
 void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 pid);
 
arch/powerpc/kvm/book3s_hv.c +53 -1

66 lines not on this page · raw message

arch/powerpc/kvm/powerpc.c +23 -0
index e84ba15..4c3d567 100644
@@ -263,6 +263,9 @@ int kvm_dev_ioctl_check_extension(long ext)
 	case KVM_CAP_SYNC_MMU:
 		r = cpu_has_feature(CPU_FTR_ARCH_206) ? 1 : 0;
 		break;
+	case KVM_CAP_PPC_VPA:
+		r = 1;
+		break;
 #endif
 	case KVM_CAP_NR_VCPUS:
 		/*
@@ -724,6 +727,26 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
 		break;
 	}
 #endif
+#ifdef CONFIG_KVM_BOOK3S_64_HV
+	case KVM_PPC_GET_VPA_INFO: {
+		struct kvm_ppc_vpa vpa;
+		r = kvm_vcpu_get_vpa_info(vcpu, &vpa);
+		if (r)
+			break;
+		r = -EFAULT;
+		if (copy_to_user(argp, &vpa, sizeof(vpa)))
+			break;
+		r = 0;
+	}
+	case KVM_PPC_SET_VPA_INFO: {
+		struct kvm_ppc_vpa vpa;
+		r = -EFAULT;
+		if (copy_from_user(&vpa, argp, sizeof(vpa)))
+			break;
+		r = kvm_vcpu_set_vpa_info(vcpu, &vpa);
+		break;
+	}
+#endif
 	default:
 		r = -EINVAL;
 	}
include/linux/kvm.h +12 -0
index 2ce09aa..2917f0e 100644
@@ -618,6 +618,7 @@ struct kvm_ppc_smmu_info {
 #define KVM_CAP_PPC_GET_SMMU_INFO 78
 #define KVM_CAP_S390_COW 79
 #define KVM_CAP_PPC_ALLOC_HTAB 80
+#define KVM_CAP_PPC_VPA 81
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -955,4 +956,15 @@ struct kvm_assigned_msix_entry {
 	__u16 padding[3];
 };
 
+struct kvm_ppc_vpa {
+	__u64 vpa_addr;
+	__u64 slb_shadow_addr;
+	__u64 dtl_addr;
+	__u32 slb_shadow_size;
+	__u32 dtl_size;
+};
+
+#define KVM_PPC_GET_VPA_INFO	_IOR(KVMIO, 0xae, struct kvm_ppc_vpa)
+#define KVM_PPC_SET_VPA_INFO	_IOW(KVMIO, 0xaf, struct kvm_ppc_vpa)
+
 #endif /* __LINUX_KVM_H */
Signature · 1 line
1.7.10