From mboxrd@z Thu Jan 1 00:00:00 1970 From: Gleb Natapov Subject: [PATCH] Add IRQ status handling in libkvm and use status for RTC interrupt re-injection Date: Tue, 20 Jan 2009 15:49:23 +0200 Message-ID: <20090120134923.GE27675@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: Avi Kivity To: kvm@vger.kernel.org Return-path: Received: from mx2.redhat.com ([66.187.237.31]:40018 "EHLO mx2.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754776AbZATNvM (ORCPT ); Tue, 20 Jan 2009 08:51:12 -0500 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n0KDpC5e007884 for ; Tue, 20 Jan 2009 08:51:12 -0500 Content-Disposition: inline Sender: kvm-owner@vger.kernel.org List-ID: Signed-off-by: Gleb Natapov 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.