aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2010-03-24 16:48:18 -0400
committerAvi Kivity <avi@redhat.com>2010-05-17 05:16:51 -0400
commit18978768d89f638165646718c50ced19f2a10164 (patch)
tree024cb2b334769c0526fe8bf9cc4e221ddaa8ea34
parent3eeafd7da2b0293b512abe95c86843fc4ab42add (diff)
KVM: PPC: Allow userspace to unset the IRQ line
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>
-rw-r--r--arch/powerpc/include/asm/kvm.h3
-rw-r--r--arch/powerpc/include/asm/kvm_ppc.h2
-rw-r--r--arch/powerpc/kvm/book3s.c6
-rw-r--r--arch/powerpc/kvm/powerpc.c6
-rw-r--r--include/linux/kvm.h1
5 files changed, 17 insertions, 1 deletions
diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h
index 19bae31202c..6c5547d82bb 100644
--- a/arch/powerpc/include/asm/kvm.h
+++ b/arch/powerpc/include/asm/kvm.h
@@ -84,4 +84,7 @@ struct kvm_guest_debug_arch {
84#define KVM_REG_QPR 0x0040 84#define KVM_REG_QPR 0x0040
85#define KVM_REG_FQPR 0x0060 85#define KVM_REG_FQPR 0x0060
86 86
87#define KVM_INTERRUPT_SET -1U
88#define KVM_INTERRUPT_UNSET -2U
89
87#endif /* __LINUX_KVM_POWERPC_H */ 90#endif /* __LINUX_KVM_POWERPC_H */
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index c7fcdd751f1..6a2464e4d6b 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -92,6 +92,8 @@ extern void kvmppc_core_queue_dec(struct kvm_vcpu *vcpu);
92extern void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu); 92extern void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu);
93extern void kvmppc_core_queue_external(struct kvm_vcpu *vcpu, 93extern void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
94 struct kvm_interrupt *irq); 94 struct kvm_interrupt *irq);
95extern void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu,
96 struct kvm_interrupt *irq);
95 97
96extern int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, 98extern int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
97 unsigned int op, int *advance); 99 unsigned int op, int *advance);
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index ff5a4205825..34e1a342bec 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -231,6 +231,12 @@ void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
231 kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_EXTERNAL); 231 kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_EXTERNAL);
232} 232}
233 233
234void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu,
235 struct kvm_interrupt *irq)
236{
237 kvmppc_book3s_dequeue_irqprio(vcpu, BOOK3S_INTERRUPT_EXTERNAL);
238}
239
234int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority) 240int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority)
235{ 241{
236 int deliver = 1; 242 int deliver = 1;
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 3f8677e9d8f..0bb6a7e826d 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -149,6 +149,7 @@ int kvm_dev_ioctl_check_extension(long ext)
149 switch (ext) { 149 switch (ext) {
150 case KVM_CAP_PPC_SEGSTATE: 150 case KVM_CAP_PPC_SEGSTATE:
151 case KVM_CAP_PPC_PAIRED_SINGLES: 151 case KVM_CAP_PPC_PAIRED_SINGLES:
152 case KVM_CAP_PPC_UNSET_IRQ:
152 r = 1; 153 r = 1;
153 break; 154 break;
154 case KVM_CAP_COALESCED_MMIO: 155 case KVM_CAP_COALESCED_MMIO:
@@ -451,7 +452,10 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
451 452
452int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq) 453int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq)
453{ 454{
454 kvmppc_core_queue_external(vcpu, irq); 455 if (irq->irq == KVM_INTERRUPT_UNSET)
456 kvmppc_core_dequeue_external(vcpu, irq);
457 else
458 kvmppc_core_queue_external(vcpu, irq);
455 459
456 if (waitqueue_active(&vcpu->wq)) { 460 if (waitqueue_active(&vcpu->wq)) {
457 wake_up_interruptible(&vcpu->wq); 461 wake_up_interruptible(&vcpu->wq);
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index ce2876717a8..c36d093e980 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -507,6 +507,7 @@ struct kvm_ioeventfd {
507#define KVM_CAP_DEBUGREGS 50 507#define KVM_CAP_DEBUGREGS 50
508#endif 508#endif
509#define KVM_CAP_X86_ROBUST_SINGLESTEP 51 509#define KVM_CAP_X86_ROBUST_SINGLESTEP 51
510#define KVM_CAP_PPC_UNSET_IRQ 53
510 511
511#ifdef KVM_CAP_IRQ_ROUTING 512#ifdef KVM_CAP_IRQ_ROUTING
512 513