[STRAWMAN PATCH] KVM: PPC: Add ioctl to specify interrupt controller architecture to emulate

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This adds a new ioctl, KVM_SET_IRQ_ARCHITECTURE, which is intended to
be called by userspace to specify that it wishes the kernel to emulate
a specific interrupt controller architecture.  This doesn't imply the
creation of any specific device, but does indicate that when vcpus are
created, space for per-vcpu interrupt controller state should be
allocated.  Having this ioctl enables userspace to defer creation of
the actual interrupt controller device(s) until after the vcpus are
created.

The KVM_SET_IRQ_ARCHITECTURE ioctl takes a single 32-bit unsigned int
as its parameter.  Values for this parameter will be defined in
subsequent patches.  The value of 0 means no in-kernel interrupt
controller emulation.

In order to ensure that this ioctl will fail once any vcpu has been
created, we use an arch.vcpus_created field to indicate that vcpu
creation has commenced.  We don't use the online_vcpus field because
that is only incremented after vcpu creation; if we used that there
would be a window during the first KVM_CREATE_VCPU ioctl where the
first vcpu had been created but the interrupt architecture could still
be changed.

Signed-off-by: Paul Mackerras <paulus@xxxxxxxxx>
---
So, should this all be done in generic code?

 Documentation/virtual/kvm/api.txt   |   22 ++++++++++++
 arch/powerpc/include/asm/kvm_host.h |    2 ++
 arch/powerpc/kvm/powerpc.c          |   66 +++++++++++++++++++++++++++++++++--
 include/uapi/linux/kvm.h            |    3 ++
 4 files changed, 90 insertions(+), 3 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index cce500a..d550313 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2126,6 +2126,28 @@ header; first `n_valid' valid entries with contents from the data
 written, then `n_invalid' invalid entries, invalidating any previously
 valid entries found.
 
+4.79 KVM_SET_IRQ_ARCHITECTURE
+
+Capability: KVM_CAP_IRQ_ARCH
+Architecture: powerpc
+Type: vm ioctl
+Parameters: Pointer to u32 (in)
+Returns: 0 on success, -1 on error
+
+This is called before any vcpus are created, if in-kernel interrupt
+controller emulation is desired, to specify what overall interrupt
+controller architecture should be emulated.  Having this called before
+any vcpus are created allows per-vcpu interrupt controller state to be
+allocated at vcpu creation time, and allows the creation of the actual
+interrupt controller device to be deferred until after the vcpus are
+created.
+
+The parameter is a 32-bit unsigned integer specifying the
+architecture, or the value 0 to specify that no emulation should be
+done.  If the requested architecture is not supported by the kernel,
+this ioctl returns an EINVAL error.  Otherwise, if this ioctl is
+called after any vcpus have been created, it returns an EBUSY error.
+
 
 5. The kvm_run structure
 ------------------------
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 8a72d59..e21ea1f 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -227,6 +227,8 @@ struct kvm_arch_memory_slot {
 };
 
 struct kvm_arch {
+	unsigned int irq_arch;
+	int vcpus_created;
 	unsigned int lpid;
 #ifdef CONFIG_KVM_BOOK3S_64_HV
 	unsigned long hpt_virt;
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 934413c..b681746 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -441,10 +441,21 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
 {
 	struct kvm_vcpu *vcpu;
 	vcpu = kvmppc_core_vcpu_create(kvm, id);
-	if (!IS_ERR(vcpu)) {
-		vcpu->arch.wqp = &vcpu->wq;
-		kvmppc_create_vcpu_debugfs(vcpu, id);
+	if (IS_ERR(vcpu))
+		goto out;
+
+	/* Create per-vcpu irq controller state if needed */
+	mutex_lock(&kvm->lock);
+	kvm->arch.vcpus_created = 1;
+	switch (kvm->arch.irq_arch) {
+	default:
+		break;
 	}
+	mutex_unlock(&kvm->lock);
+
+	vcpu->arch.wqp = &vcpu->wq;
+	kvmppc_create_vcpu_debugfs(vcpu, id);
+ out:
 	return vcpu;
 }
 
@@ -459,6 +470,12 @@ void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
 	hrtimer_cancel(&vcpu->arch.dec_timer);
 	tasklet_kill(&vcpu->arch.tasklet);
 
+	/* Destroy per-vcpu irq controller state */
+	switch (vcpu->kvm->arch.irq_arch) {
+	default:
+		break;
+	}
+
 	kvmppc_remove_vcpu_debugfs(vcpu);
 	kvmppc_core_vcpu_free(vcpu);
 }
@@ -996,6 +1013,49 @@ long kvm_arch_vm_ioctl(struct file *filp,
 		break;
 	}
 #endif /* CONFIG_PPC_BOOK3S_64 */
+
+	case KVM_IRQ_LINE: {
+		struct kvm *kvm = filp->private_data;
+		struct kvm_irq_level args;
+
+		r = -EFAULT;
+		if (copy_from_user(&args, argp, sizeof(args)))
+			break;
+		switch (kvm->arch.irq_arch) {
+		default:
+			r = -EINVAL;
+		}
+		break;
+	}
+
+	case KVM_SET_IRQ_ARCHITECTURE: {
+		struct kvm *kvm = filp->private_data;
+		u32 arch_id;
+
+		r = -EFAULT;
+		if (get_user(arch_id, (u32 __user *)argp))
+			break;
+		r = 0;
+		switch (arch_id) {
+		case 0:		/* no emulation */
+			break;
+		default:
+			r = -EINVAL;
+			break;
+		}
+		if (r)
+			break;
+
+		/* mutex ensures we don't race with vcpu creation */
+		mutex_lock(&kvm->lock);
+		if (!kvm->arch.vcpus_created)
+			kvm->arch.irq_arch = arch_id;
+		else
+			r = -EBUSY;
+		mutex_unlock(&kvm->lock);
+		break;
+	}
+
 	default:
 		r = -ENOTTY;
 	}
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 9a2db57..2c0ea1c 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -662,6 +662,7 @@ struct kvm_ppc_smmu_info {
 #define KVM_CAP_PPC_HTAB_FD 84
 #define KVM_CAP_S390_CSS_SUPPORT 85
 #define KVM_CAP_PPC_EPR 86
+#define KVM_CAP_IRQ_ARCH 87
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -889,6 +890,8 @@ struct kvm_s390_ucas_mapping {
 #define KVM_ALLOCATE_RMA	  _IOR(KVMIO,  0xa9, struct kvm_allocate_rma)
 /* Available with KVM_CAP_PPC_HTAB_FD */
 #define KVM_PPC_GET_HTAB_FD	  _IOW(KVMIO,  0xaa, struct kvm_get_htab_fd)
+/* Available with KVM_CAP_IRQ_ARCH */
+#define KVM_SET_IRQ_ARCHITECTURE  _IOW(KVMIO,  0xab, __u32)
 
 /*
  * ioctls for vcpu fds
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux