From patchwork Mon Nov 16 17:12:00 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Glauber Costa X-Patchwork-Id: 38524 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 42087B7088 for ; Tue, 17 Nov 2009 04:24:28 +1100 (EST) Received: from localhost ([127.0.0.1]:60313 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NA5JQ-0006Sb-Vt for incoming@patchwork.ozlabs.org; Mon, 16 Nov 2009 12:24:25 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NA57j-0007bi-3p for qemu-devel@nongnu.org; Mon, 16 Nov 2009 12:12:19 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1NA57e-0007Yy-12 for qemu-devel@nongnu.org; Mon, 16 Nov 2009 12:12:18 -0500 Received: from [199.232.76.173] (port=36100 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NA57d-0007Yj-Cp for qemu-devel@nongnu.org; Mon, 16 Nov 2009 12:12:13 -0500 Received: from mx1.redhat.com ([209.132.183.28]:39483) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1NA57c-0005Ze-Rf for qemu-devel@nongnu.org; Mon, 16 Nov 2009 12:12:13 -0500 Received: from int-mx04.intmail.prod.int.phx2.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.17]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id nAGHCBtL027615 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 16 Nov 2009 12:12:12 -0500 Received: from localhost.localdomain (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx04.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id nAGHC7M6010655; Mon, 16 Nov 2009 12:12:11 -0500 From: Glauber Costa To: qemu-devel@nongnu.org Date: Mon, 16 Nov 2009 15:12:00 -0200 Message-Id: <1258391527-18840-3-git-send-email-glommer@redhat.com> In-Reply-To: <1258391527-18840-2-git-send-email-glommer@redhat.com> References: <1258391527-18840-1-git-send-email-glommer@redhat.com> <1258391527-18840-2-git-send-email-glommer@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.17 X-detected-operating-system: by monty-python.gnu.org: Genre and OS details not recognized. Cc: aliguori@us.ibm.com Subject: [Qemu-devel] [PATCH v2 2/9] Provide ioapic-kvm X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This patch provides the file ioapic-kvm.c, which implements a schim over the kvm in-kernel IO APIC. Signed-off-by: Glauber Costa --- Makefile.target | 2 + hw/ioapic-kvm.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ hw/pc.c | 7 ++++- hw/pc.h | 2 + kvm-all.c | 20 ++++++++++++ kvm.h | 4 ++ 6 files changed, 124 insertions(+), 1 deletions(-) create mode 100644 hw/ioapic-kvm.c diff --git a/Makefile.target b/Makefile.target index 7068dc5..6e97ba7 100644 --- a/Makefile.target +++ b/Makefile.target @@ -199,6 +199,8 @@ obj-i386-y += usb-uhci.o vmmouse.o vmport.o vmware_vga.o hpet.o obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o wdt_ib700.o obj-i386-y += ne2000-isa.o +obj-i386-$(CONFIG_KVM) += ioapic-kvm.o + # shared objects obj-ppc-y = ppc.o ide/core.o ide/qdev.o ide/isa.o ide/pci.o ide/macio.o obj-ppc-y += ide/cmd646.o diff --git a/hw/ioapic-kvm.c b/hw/ioapic-kvm.c new file mode 100644 index 0000000..9f3ff6a --- /dev/null +++ b/hw/ioapic-kvm.c @@ -0,0 +1,90 @@ +#include "hw.h" +#include "pc.h" +#include "qemu-timer.h" +#include "host-utils.h" +#include "kvm.h" + +#define IOAPIC_NUM_PINS 0x18 +#define IOAPIC_DEFAULT_BASE_ADDRESS 0xfec00000 + +static void ioapic_reset(void *opaque) +{ + struct kvm_ioapic_state *s = opaque; + struct kvm_irqchip *chip; + int i; + + chip = container_of(s, struct kvm_irqchip, chip.ioapic); + + chip->chip_id = KVM_IRQCHIP_IOAPIC; + + memset(s, 0, sizeof(*s)); + s->base_address = IOAPIC_DEFAULT_BASE_ADDRESS; + for(i = 0; i < IOAPIC_NUM_PINS; i++) + s->redirtbl[i].bits = 1 << 16; /* mask LVT */ + + kvm_set_irqchip(chip); +} + +static void ioapic_pre_save(void *opaque) +{ + struct kvm_ioapic_state *s = opaque; + struct kvm_irqchip *chip; + + chip = container_of(s, struct kvm_irqchip, chip.ioapic); + + kvm_get_irqchip(chip); +} + +static int ioapic_post_load(void *opaque, int version_id) +{ + struct kvm_ioapic_state *s = opaque; + struct kvm_irqchip *chip; + + chip = container_of(s, struct kvm_irqchip, chip.ioapic); + + return kvm_set_irqchip(chip); +} + +static const VMStateDescription vmstate_kvm_ioapic = { + .name = "ioapic-kvm", + .version_id = 1, + .minimum_version_id = 1, + .post_load = ioapic_post_load, + .pre_save = ioapic_pre_save, + .fields = (VMStateField []) { + /* Linux does not define __u64 the same as uint64_t */ +// VMSTATE_SINGLE(base_address, struct kvm_ioapic_state, 1, vmstate_info_uint64, __u64), + VMSTATE_U64(base_address, struct kvm_ioapic_state), + VMSTATE_UINT32(id, struct kvm_ioapic_state), + VMSTATE_UINT32(ioregsel, struct kvm_ioapic_state), + VMSTATE_UINT32(irr, struct kvm_ioapic_state), + VMSTATE_ARRAY_UNSAFE(redirtbl, struct kvm_ioapic_state, IOAPIC_NUM_PINS, 0, vmstate_info_u64, __u64), + VMSTATE_END_OF_LIST() + } +}; + + +static void kvm_ioapic_set_irq(void *opaque, int vector, int level) +{ +/* + int pic_ret; + + if (kvm_set_irq(vector, level, &pic_ret)) { + if (pic_ret != 0) + apic_set_irq_delivered(); + return; + } +*/ +} + +qemu_irq *kvm_ioapic_init(void) +{ + struct kvm_irqchip *s; + + s = qemu_mallocz(sizeof(*s)); + + vmstate_register(0, &vmstate_kvm_ioapic, &s->chip.ioapic); + qemu_register_reset(ioapic_reset, &s->chip.ioapic); + + return qemu_allocate_irqs(kvm_ioapic_set_irq, &s->chip.ioapic, IOAPIC_NUM_PINS); +} diff --git a/hw/pc.c b/hw/pc.c index bf4718e..b7a1734 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -39,6 +39,7 @@ #include "ide.h" #include "loader.h" #include "elf.h" +#include "kvm.h" /* output Bochs bios info messages */ //#define DEBUG_BIOS @@ -1200,7 +1201,11 @@ static void pc_init1(ram_addr_t ram_size, register_ioport_write(0x92, 1, 1, ioport92_write, NULL); if (pci_enabled) { - isa_irq_state->ioapic = ioapic_init(); + if (kvm_enabled() && kvm_irqchip_in_kernel()) { + isa_irq_state->ioapic = kvm_ioapic_init(); + } else { + isa_irq_state->ioapic = ioapic_init(); + } } pit = pit_init(0x40, isa_reserve_irq(0)); pcspk_init(pit); diff --git a/hw/pc.h b/hw/pc.h index 03ffc91..a3ad931 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -49,6 +49,8 @@ void ioapic_set_irq(void *opaque, int vector, int level); void apic_reset_irq_delivered(void); int apic_get_irq_delivered(void); +qemu_irq *kvm_ioapic_init(void); + /* i8254.c */ #define PIT_FREQ 1193182 diff --git a/kvm-all.c b/kvm-all.c index 1916ec6..fc542f3 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -391,6 +391,26 @@ int kvm_check_extension(KVMState *s, unsigned int extension) return ret; } +#ifdef KVM_CAP_IRQCHIP +int kvm_set_irqchip(struct kvm_irqchip *chip) +{ + if (!kvm_state->irqchip_in_kernel) { + return 0; + } + + return kvm_vm_ioctl(kvm_state, KVM_SET_IRQCHIP, chip); +} + +int kvm_get_irqchip(struct kvm_irqchip *chip) +{ + if (!kvm_state->irqchip_in_kernel) { + return 0; + } + + return kvm_vm_ioctl(kvm_state, KVM_GET_IRQCHIP, chip); +} +#endif + int kvm_init(int smp_cpus) { static const char upgrade_note[] = diff --git a/kvm.h b/kvm.h index ecac828..fa5dbb6 100644 --- a/kvm.h +++ b/kvm.h @@ -16,6 +16,7 @@ #include "config.h" #include "qemu-queue.h" +#include #ifdef CONFIG_KVM extern int kvm_allowed; @@ -63,6 +64,9 @@ int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap); int kvm_pit_in_kernel(void); int kvm_irqchip_in_kernel(void); +int kvm_set_irqchip(struct kvm_irqchip *chip); +int kvm_get_irqchip(struct kvm_irqchip *chip); + /* internal API */ struct KVMState;