All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 16/16] KVM: PPC: Book3S HV: disconnect vCPU from IRQ device
@ 2018-04-23 16:43 Cédric Le Goater
  0 siblings, 0 replies; only message in thread
From: Cédric Le Goater @ 2018-04-23 16:43 UTC (permalink / raw)
  To: kvm-ppc

Before destroying a KVM device for IRQs, we need to disconnect the
VCPUs. Do that using a 'disable=1' as last argument of the
KVM_ENABLE_CAP ioctl. This is a bit hacky, we should introduce a
KVM_DISABLE_CAP ioctl most certainly.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 arch/powerpc/include/asm/kvm_ppc.h |  4 ++--
 arch/powerpc/kvm/book3s_xics.c     |  5 +++--
 arch/powerpc/kvm/book3s_xive.c     | 10 +++++++++-
 arch/powerpc/kvm/powerpc.c         | 28 +++++++++++++++++++++-------
 4 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 748518c7bf70..5c0af1cabe34 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -518,7 +518,7 @@ extern void kvmppc_alloc_host_rm_ops(void);
 extern void kvmppc_free_host_rm_ops(void);
 extern void kvmppc_free_pimap(struct kvm *kvm);
 extern int kvmppc_xics_rm_complete(struct kvm_vcpu *vcpu, u32 hcall);
-extern void kvmppc_xics_free_icp(struct kvm_vcpu *vcpu);
+extern int kvmppc_xics_free_icp(struct kvm_vcpu *vcpu);
 extern int kvmppc_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd);
 extern u64 kvmppc_xics_get_icp(struct kvm_vcpu *vcpu);
 extern int kvmppc_xics_set_icp(struct kvm_vcpu *vcpu, u64 icpval);
@@ -574,7 +574,7 @@ extern void kvmppc_xive_exit_module(void);
 
 extern int kvmppc_xive_connect_vcpu(struct kvm_device *dev,
 				    struct kvm_vcpu *vcpu, u32 cpu);
-extern void kvmppc_xive_cleanup_vcpu(struct kvm_vcpu *vcpu);
+extern int kvmppc_xive_cleanup_vcpu(struct kvm_vcpu *vcpu);
 extern int kvmppc_xive_set_mapped(struct kvm *kvm, unsigned long guest_irq,
 				  struct irq_desc *host_desc);
 extern int kvmppc_xive_clr_mapped(struct kvm *kvm, unsigned long guest_irq,
diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c
index b8356cdc0c04..b0c85525944d 100644
--- a/arch/powerpc/kvm/book3s_xics.c
+++ b/arch/powerpc/kvm/book3s_xics.c
@@ -1440,13 +1440,14 @@ int kvmppc_xics_connect_vcpu(struct kvm_device *dev, struct kvm_vcpu *vcpu,
 	return r;
 }
 
-void kvmppc_xics_free_icp(struct kvm_vcpu *vcpu)
+int kvmppc_xics_free_icp(struct kvm_vcpu *vcpu)
 {
 	if (!vcpu->arch.icp)
-		return;
+		return -ENOENT;
 	kfree(vcpu->arch.icp);
 	vcpu->arch.icp = NULL;
 	vcpu->arch.irq_type = KVMPPC_IRQ_DEFAULT;
+	return 0;
 }
 
 void kvmppc_xics_set_mapped(struct kvm *kvm, unsigned long irq,
diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c
index abb4ae5c5b91..3c66480d3304 100644
--- a/arch/powerpc/kvm/book3s_xive.c
+++ b/arch/powerpc/kvm/book3s_xive.c
@@ -1023,12 +1023,15 @@ void kvmppc_xive_disable_vcpu_interrupts(struct kvm_vcpu *vcpu)
 	}
 }
 
-void kvmppc_xive_cleanup_vcpu(struct kvm_vcpu *vcpu)
+int kvmppc_xive_cleanup_vcpu(struct kvm_vcpu *vcpu)
 {
 	struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu;
 	struct kvmppc_xive *xive = xc->xive;
 	int i;
 
+	if (!vcpu->arch.xive_vcpu)
+		return -ENOENT;
+
 	pr_devel("cleanup_vcpu(cpu=%d)\n", xc->server_num);
 
 	/* Ensure no interrupt is still routed to that VP */
@@ -1067,6 +1070,11 @@ void kvmppc_xive_cleanup_vcpu(struct kvm_vcpu *vcpu)
 	}
 	/* Free the VP */
 	kfree(xc);
+
+	/* Cleanup the vcpu */
+	vcpu->arch.irq_type = KVMPPC_IRQ_DEFAULT;
+	vcpu->arch.xive_vcpu = NULL;
+	return 0;
 }
 
 int kvmppc_xive_connect_vcpu(struct kvm_device *dev,
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 42eb75e43d6e..e0ff5e9610ee 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -1710,10 +1710,19 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
 		r = -EPERM;
 		dev = kvm_device_from_filp(f.file);
 		if (dev) {
-			if (xive_enabled())
-				r = kvmppc_xive_connect_vcpu(dev, vcpu, cap->args[1]);
-			else
-				r = kvmppc_xics_connect_vcpu(dev, vcpu, cap->args[1]);
+			if (cap->args[2]) {
+				if (xive_enabled())
+					r = kvmppc_xive_cleanup_vcpu(vcpu);
+				else
+					r = kvmppc_xics_free_icp(vcpu);
+			} else {
+				if (xive_enabled())
+					r = kvmppc_xive_connect_vcpu(dev, vcpu,
+							     cap->args[1]);
+				else
+					r = kvmppc_xics_connect_vcpu(dev, vcpu,
+							     cap->args[1]);
+			}
 		}
 
 		fdput(f);
@@ -1736,9 +1745,14 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
 
 		r = -EPERM;
 		dev = kvm_device_from_filp(f.file);
-		if (dev)
-			r = kvmppc_xive_native_connect_vcpu(dev, vcpu,
-							    cap->args[1]);
+		if (dev) {
+			if (cap->args[2]) {
+				r = kvmppc_xive_native_cleanup_vcpu(vcpu);
+			} else {
+				r = kvmppc_xive_native_connect_vcpu(dev, vcpu,
+							     cap->args[1]);
+			}
+		}
 
 		fdput(f);
 		break;
-- 
2.13.6


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2018-04-23 16:43 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-23 16:43 [RFC PATCH 16/16] KVM: PPC: Book3S HV: disconnect vCPU from IRQ device Cédric Le Goater

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.