KVM: PPC: Allow userspace to unset the IRQ line
authorAlexander Graf <agraf@suse.de>
Wed, 24 Mar 2010 20:48:18 +0000 (21:48 +0100)
committerAvi Kivity <avi@redhat.com>
Mon, 17 May 2010 09:16:51 +0000 (12:16 +0300)
Userspace can tell us that it wants to trigger an interrupt. But
so far it can't tell us that it wants to stop triggering one.

So let's interpret the parameter to the ioctl that we have anyways
to tell us if we want to raise or lower the interrupt line.

Signed-off-by: Alexander Graf <agraf@suse.de>
v2 -> v3:

 - Add CAP for unset irq
Signed-off-by: Avi Kivity <avi@redhat.com>
arch/powerpc/include/asm/kvm.h
arch/powerpc/include/asm/kvm_ppc.h
arch/powerpc/kvm/book3s.c
arch/powerpc/kvm/powerpc.c
include/linux/kvm.h

index 19bae31202ce5e60d7949ff2dbdcfbfd24d41be3..6c5547d82bbe7dc5283dec2fc6ddf437fe2e76e0 100644 (file)
@@ -84,4 +84,7 @@ struct kvm_guest_debug_arch {
 #define KVM_REG_QPR            0x0040
 #define KVM_REG_FQPR           0x0060
 
+#define KVM_INTERRUPT_SET      -1U
+#define KVM_INTERRUPT_UNSET    -2U
+
 #endif /* __LINUX_KVM_POWERPC_H */
index c7fcdd751f14fa4d0df1a2f6fb1c12f929f8868d..6a2464e4d6b9d851c7bf990be4d0ae623048fe65 100644 (file)
@@ -92,6 +92,8 @@ extern void kvmppc_core_queue_dec(struct kvm_vcpu *vcpu);
 extern void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu);
 extern void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
                                        struct kvm_interrupt *irq);
+extern void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu,
+                                         struct kvm_interrupt *irq);
 
 extern int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
                                   unsigned int op, int *advance);
index ff5a420582574f5776eb285d17d115a8e75065b4..34e1a342bec834794ada56894743d029f9194033 100644 (file)
@@ -231,6 +231,12 @@ void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
        kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_EXTERNAL);
 }
 
+void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu,
+                                  struct kvm_interrupt *irq)
+{
+       kvmppc_book3s_dequeue_irqprio(vcpu, BOOK3S_INTERRUPT_EXTERNAL);
+}
+
 int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
 {
        int deliver = 1;
index 3f8677e9d8f90a3dbdbd4458151c3e08302f1817..0bb6a7e826d1dbec22db80c76cb279c6865807a8 100644 (file)
@@ -149,6 +149,7 @@ int kvm_dev_ioctl_check_extension(long ext)
        switch (ext) {
        case KVM_CAP_PPC_SEGSTATE:
        case KVM_CAP_PPC_PAIRED_SINGLES:
+       case KVM_CAP_PPC_UNSET_IRQ:
                r = 1;
                break;
        case KVM_CAP_COALESCED_MMIO:
@@ -451,7 +452,10 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 
 int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq)
 {
-       kvmppc_core_queue_external(vcpu, irq);
+       if (irq->irq == KVM_INTERRUPT_UNSET)
+               kvmppc_core_dequeue_external(vcpu, irq);
+       else
+               kvmppc_core_queue_external(vcpu, irq);
 
        if (waitqueue_active(&vcpu->wq)) {
                wake_up_interruptible(&vcpu->wq);
index ce2876717a8b1dafc45e5d534e764d3f748eebcf..c36d093e980617eef3119395302df4ff0109a58b 100644 (file)
@@ -507,6 +507,7 @@ struct kvm_ioeventfd {
 #define KVM_CAP_DEBUGREGS 50
 #endif
 #define KVM_CAP_X86_ROBUST_SINGLESTEP 51
+#define KVM_CAP_PPC_UNSET_IRQ 53
 
 #ifdef KVM_CAP_IRQ_ROUTING