* [PATCH] Add IRQ status handling in libkvm and use status for RTC interrupt re-injection
@ 2009-01-21 12:37 Gleb Natapov
0 siblings, 0 replies; 2+ messages in thread
From: Gleb Natapov @ 2009-01-21 12:37 UTC (permalink / raw)
To: Avi Kivity; +Cc: kvm
Signed-off-by: Gleb Natapov <gleb@redhat.com>
diff --git a/libkvm/kvm-common.h b/libkvm/kvm-common.h
index d4fffbe..de1ada2 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 80300c9..9f15f32 100644
--- a/libkvm/libkvm.c
+++ b/libkvm/libkvm.c
@@ -435,8 +435,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");
}
@@ -646,7 +654,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;
@@ -655,9 +663,12 @@ 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");
+
+ *status = (kvm->irqchip_inject_ioctl == KVM_IRQ_LINE) ? 1 : 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);
--
Gleb.
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH] Add IRQ status handling in libkvm and use status for RTC interrupt re-injection
@ 2009-01-20 13:49 Gleb Natapov
0 siblings, 0 replies; 2+ messages in thread
From: Gleb Natapov @ 2009-01-20 13:49 UTC (permalink / raw)
To: kvm; +Cc: Avi Kivity
Signed-off-by: Gleb Natapov <gleb@redhat.com>
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);
--
Gleb.
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2009-01-21 12:39 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-01-21 12:37 [PATCH] Add IRQ status handling in libkvm and use status for RTC interrupt re-injection Gleb Natapov
-- strict thread matches above, loose matches on Subject: below --
2009-01-20 13:49 Gleb Natapov
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.