summaryrefslogtreecommitdiff
path: root/libkvm
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2009-02-26 15:51:50 +0200
committerEduardo Habkost <ehabkost@redhat.com>2009-03-02 15:14:33 -0300
commitc6325fd4b856e3bc939eb754470cee4aadc9f279 (patch)
tree41c37ab6d316432aa09253f04d505ff577e2e5cb /libkvm
parentb402f31023d50343a14ff8a83d918094843d3b91 (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.h2
-rw-r--r--libkvm/libkvm.c19
-rw-r--r--libkvm/libkvm.h2
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,