diff mbox

Add IRQ status handling in libkvm and use status for RTC interrupt re-injection

Message ID 20090120134923.GE27675@redhat.com (mailing list archive)
State Accepted, archived
Headers show

Commit Message

Gleb Natapov Jan. 20, 2009, 1:49 p.m. UTC
Signed-off-by: Gleb Natapov <gleb@redhat.com>
--
			Gleb.
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/libkvm/libkvm.c b/libkvm/libkvm.c
index 80300c9..8fe67ef 100644
--- a/libkvm/libkvm.c
+++ b/libkvm/libkvm.c
@@ -646,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;
@@ -658,6 +658,7 @@  int kvm_set_irq_level(kvm_context_t kvm, int irq, int level)
 	r = ioctl(kvm->vm_fd, KVM_IRQ_LINE, &event);
 	if (r == -1)
 		perror("kvm_set_irq_level");
+	*status = event.status;
 	return 1;
 }
 
diff --git a/libkvm/libkvm.h b/libkvm/libkvm.h
index e79e4fd..f047086 100644
--- a/libkvm/libkvm.h
+++ b/libkvm/libkvm.h
@@ -525,7 +525,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,
diff --git a/qemu/hw/apic.c b/qemu/hw/apic.c
index 782b398..b5dd1d5 100644
--- a/qemu/hw/apic.c
+++ b/qemu/hw/apic.c
@@ -377,6 +377,11 @@  int apic_get_irq_delivered(void)
     return apic_irq_delivered;
 }
 
+int apic_set_irq_delivered(void)
+{
+    apic_irq_delivered = 1;
+}
+
 static void apic_set_irq(APICState *s, int vector_num, int trigger_mode)
 {
     apic_irq_delivered += !get_bit(s->irr, vector_num);
diff --git a/qemu/hw/i8259.c b/qemu/hw/i8259.c
index 6d41a5e..9da4360 100644
--- a/qemu/hw/i8259.c
+++ b/qemu/hw/i8259.c
@@ -186,9 +186,14 @@  static void i8259_set_irq(void *opaque, int irq, int level)
 {
     PicState2 *s = opaque;
 #ifdef KVM_CAP_IRQCHIP
-    if (kvm_enabled())
-	if (kvm_set_irq(irq, level))
-	    return;
+    if (kvm_enabled()) {
+        int pic_ret;
+        if (kvm_set_irq(irq, level, &pic_ret)) {
+            if (pic_ret != 0)
+                apic_set_irq_delivered();
+            return;
+        }
+    }
 #endif
 #if defined(DEBUG_PIC) || defined(DEBUG_IRQ_COUNT)
     if (level != irq_level[irq]) {
diff --git a/qemu/hw/pc.h b/qemu/hw/pc.h
index 54f865d..e637390 100644
--- a/qemu/hw/pc.h
+++ b/qemu/hw/pc.h
@@ -48,6 +48,7 @@  IOAPICState *ioapic_init(void);
 void ioapic_set_irq(void *opaque, int vector, int level);
 void apic_reset_irq_delivered(void);
 int apic_get_irq_delivered(void);
+int apic_set_irq_delivered(void);
 
 /* i8254.c */
 
diff --git a/qemu/qemu-kvm.c b/qemu/qemu-kvm.c
index 5ff63ad..9b2d516 100644
--- a/qemu/qemu-kvm.c
+++ b/qemu/qemu-kvm.c
@@ -1266,9 +1266,9 @@  int kvm_get_phys_ram_page_bitmap(unsigned char *bitmap)
 
 #ifdef KVM_CAP_IRQCHIP
 
-int kvm_set_irq(int irq, int level)
+int kvm_set_irq(int irq, int level, int *status)
 {
-    return kvm_set_irq_level(kvm_context, irq, level);
+    return kvm_set_irq_level(kvm_context, irq, level, status);
 }
 
 #endif
diff --git a/qemu/qemu-kvm.h b/qemu/qemu-kvm.h
index 042dd93..755b351 100644
--- a/qemu/qemu-kvm.h
+++ b/qemu/qemu-kvm.h
@@ -31,7 +31,7 @@  int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap);
 int kvm_qemu_init_env(CPUState *env);
 int kvm_qemu_check_extension(int ext);
 void kvm_apic_init(CPUState *env);
-int kvm_set_irq(int irq, int level);
+int kvm_set_irq(int irq, int level, int *status);
 
 int kvm_physical_memory_set_dirty_tracking(int enable);
 int kvm_update_dirty_pages_log(void);