diff options
author | Gleb Natapov <gleb@redhat.com> | 2009-02-26 15:51:50 +0200 |
---|---|---|
committer | Eduardo Habkost <ehabkost@redhat.com> | 2009-03-02 15:14:33 -0300 |
commit | c6325fd4b856e3bc939eb754470cee4aadc9f279 (patch) | |
tree | 41c37ab6d316432aa09253f04d505ff577e2e5cb /libkvm | |
parent | b402f31023d50343a14ff8a83d918094843d3b91 (diff) |
handle IRQ status injection in userspace
This allows timers to keep track of injected and coalesced interrupts.
upstrem commit: ea1b668e7684dc43e9d198ba0b25fe47a0b2acd2
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
RH-Upstream-status: applied(kvm/master)
Bugzilla: 487595
Acked-by: Eduardo Habkost <ehabkost@redhat.com>
Acked-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'libkvm')
-rw-r--r-- | libkvm/kvm-common.h | 2 | ||||
-rw-r--r-- | libkvm/libkvm.c | 19 | ||||
-rw-r--r-- | libkvm/libkvm.h | 2 |
3 files changed, 19 insertions, 4 deletions
diff --git a/libkvm/kvm-common.h b/libkvm/kvm-common.h index c5beacc3..ee010fbe 100644 --- a/libkvm/kvm-common.h +++ b/libkvm/kvm-common.h @@ -55,6 +55,8 @@ struct kvm_context { int no_irqchip_creation; /// in-kernel irqchip status int irqchip_in_kernel; + /// ioctl to use to inject interrupts + int irqchip_inject_ioctl; /// do not create in-kernel pit if set int no_pit_creation; /// in-kernel pit status diff --git a/libkvm/libkvm.c b/libkvm/libkvm.c index 0408fdb2..25494bef 100644 --- a/libkvm/libkvm.c +++ b/libkvm/libkvm.c @@ -427,8 +427,16 @@ void kvm_create_irqchip(kvm_context_t kvm) r = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_IRQCHIP); if (r > 0) { /* kernel irqchip supported */ r = ioctl(kvm->vm_fd, KVM_CREATE_IRQCHIP); - if (r >= 0) + if (r >= 0) { + kvm->irqchip_inject_ioctl = KVM_IRQ_LINE; +#if defined(KVM_CAP_IRQ_INJECT_STATUS) && defined(KVM_IRQ_LINE_STATUS) + r = ioctl(kvm->fd, KVM_CHECK_EXTENSION, + KVM_CAP_IRQ_INJECT_STATUS); + if (r > 0) + kvm->irqchip_inject_ioctl = KVM_IRQ_LINE_STATUS; +#endif kvm->irqchip_in_kernel = 1; + } else fprintf(stderr, "Create kernel PIC irqchip failed\n"); } @@ -638,7 +646,7 @@ int kvm_get_dirty_pages_range(kvm_context_t kvm, unsigned long phys_addr, #ifdef KVM_CAP_IRQCHIP -int kvm_set_irq_level(kvm_context_t kvm, int irq, int level) +int kvm_set_irq_level(kvm_context_t kvm, int irq, int level, int *status) { struct kvm_irq_level event; int r; @@ -647,9 +655,14 @@ int kvm_set_irq_level(kvm_context_t kvm, int irq, int level) return 0; event.level = level; event.irq = irq; - r = ioctl(kvm->vm_fd, KVM_IRQ_LINE, &event); + r = ioctl(kvm->vm_fd, kvm->irqchip_inject_ioctl, &event); if (r == -1) perror("kvm_set_irq_level"); + + if (status) + *status = (kvm->irqchip_inject_ioctl == KVM_IRQ_LINE) ? + 1 : event.status; + return 1; } diff --git a/libkvm/libkvm.h b/libkvm/libkvm.h index ee1ba68f..b24b655c 100644 --- a/libkvm/libkvm.h +++ b/libkvm/libkvm.h @@ -509,7 +509,7 @@ int kvm_get_mem_map_range(kvm_context_t kvm, unsigned long phys_addr, unsigned long len, void *buf, void *opaque, int (*cb)(unsigned long start,unsigned long len, void* bitmap, void* opaque)); -int kvm_set_irq_level(kvm_context_t kvm, int irq, int level); +int kvm_set_irq_level(kvm_context_t kvm, int irq, int level, int *status); int kvm_dirty_pages_log_enable_slot(kvm_context_t kvm, uint64_t phys_start, |