From patchwork Wed Oct 7 22:08:29 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Glauber Costa X-Patchwork-Id: 35381 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 81086B7B75 for ; Thu, 8 Oct 2009 09:13:31 +1100 (EST) Received: from localhost ([127.0.0.1]:46564 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MvelE-0003Pw-Ee for incoming@patchwork.ozlabs.org; Wed, 07 Oct 2009 18:13:28 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Mvegj-0001uj-Ob for qemu-devel@nongnu.org; Wed, 07 Oct 2009 18:08:49 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Mvege-0001s8-Ky for qemu-devel@nongnu.org; Wed, 07 Oct 2009 18:08:49 -0400 Received: from [199.232.76.173] (port=51535 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Mvege-0001s2-GB for qemu-devel@nongnu.org; Wed, 07 Oct 2009 18:08:44 -0400 Received: from mx1.redhat.com ([209.132.183.28]:12399) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1Mvegd-0006sW-Su for qemu-devel@nongnu.org; Wed, 07 Oct 2009 18:08:44 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id n97M8gGj022291; Wed, 7 Oct 2009 18:08:43 -0400 Received: from localhost.localdomain (vpn-13-129.rdu.redhat.com [10.11.13.129]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id n97M8atE028337; Wed, 7 Oct 2009 18:08:41 -0400 From: Glauber Costa To: qemu-devel@nongnu.org Date: Wed, 7 Oct 2009 19:08:29 -0300 Message-Id: <1254953315-5761-4-git-send-email-glommer@redhat.com> In-Reply-To: <1254953315-5761-3-git-send-email-glommer@redhat.com> References: <1254953315-5761-1-git-send-email-glommer@redhat.com> <1254953315-5761-2-git-send-email-glommer@redhat.com> <1254953315-5761-3-git-send-email-glommer@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 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 3/9] provide in-kernel ioapic 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 kvm with an in-kernel ioapic. We are currently not enabling it. The code is heavily based on what's in qemu-kvm.git. Signed-off-by: Glauber Costa --- hw/ioapic.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- kvm-all.c | 20 ++++++++++++++ kvm.h | 4 +++ 3 files changed, 107 insertions(+), 1 deletions(-) diff --git a/hw/ioapic.c b/hw/ioapic.c index d475654..d6a9dac 100644 --- a/hw/ioapic.c +++ b/hw/ioapic.c @@ -24,6 +24,7 @@ #include "pc.h" #include "qemu-timer.h" #include "host-utils.h" +#include "kvm.h" //#define DEBUG_IOAPIC @@ -193,6 +194,79 @@ static void ioapic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t va } } +static int kvm_kernel_ioapic_load_from_user(IOAPICState *s) +{ + int r = 0; +#if defined(KVM_CAP_IRQCHIP) && defined(TARGET_I386) + struct kvm_irqchip chip; + struct kvm_ioapic_state *kioapic; + int i; + + if (!(kvm_enabled() && kvm_irqchip_in_kernel())) + return 0; + + chip.chip_id = KVM_IRQCHIP_IOAPIC; + kioapic = &chip.chip.ioapic; + + kioapic->id = s->id; + kioapic->ioregsel = s->ioregsel; + kioapic->base_address = IOAPIC_DEFAULT_BASE_ADDRESS; + kioapic->irr = s->irr; + for (i = 0; i < IOAPIC_NUM_PINS; i++) { + kioapic->redirtbl[i].bits = s->ioredtbl[i]; + } + + r = kvm_set_irqchip(&chip); +#endif + return r; +} + +static void kvm_kernel_ioapic_save_to_user(IOAPICState *s) +{ +#if defined(KVM_CAP_IRQCHIP) && defined(TARGET_I386) + struct kvm_irqchip chip; + struct kvm_ioapic_state *kioapic; + int i; + + if (!(kvm_enabled() && kvm_irqchip_in_kernel())) + return; + chip.chip_id = KVM_IRQCHIP_IOAPIC; + kvm_get_irqchip(&chip); + kioapic = &chip.chip.ioapic; + + s->id = kioapic->id; + s->ioregsel = kioapic->ioregsel; + s->irr = kioapic->irr; + for (i = 0; i < IOAPIC_NUM_PINS; i++) { + s->ioredtbl[i] = kioapic->redirtbl[i].bits; + } +#endif +} + +static void ioapic_pre_save(void *opaque) +{ + IOAPICState *s = (void *)opaque; + + kvm_kernel_ioapic_save_to_user(s); +} + +static int ioapic_pre_load(void *opaque) +{ + IOAPICState *s = opaque; + + /* in case we are doing version 1, we just set these to sane values */ + s->irr = 0; + return 0; +} + +static int ioapic_post_load(void *opaque, int version_id) +{ + IOAPICState *s = opaque; + + return kvm_kernel_ioapic_load_from_user(s); +} + + static const VMStateDescription vmstate_ioapic = { .name = "ioapic", .version_id = 2, @@ -205,7 +279,10 @@ static const VMStateDescription vmstate_ioapic = { VMSTATE_UINT32_V(irr, IOAPICState, 2), VMSTATE_UINT64_ARRAY(ioredtbl, IOAPICState, IOAPIC_NUM_PINS), VMSTATE_END_OF_LIST() - } + }, + .pre_load = ioapic_pre_load, + .post_load = ioapic_post_load, + .pre_save = ioapic_pre_save, }; static void ioapic_reset(void *opaque) @@ -217,6 +294,11 @@ static void ioapic_reset(void *opaque) s->base_address = IOAPIC_DEFAULT_BASE_ADDRESS; for(i = 0; i < IOAPIC_NUM_PINS; i++) s->ioredtbl[i] = 1 << 16; /* mask LVT */ +#ifdef KVM_CAP_IRQCHIP + if (kvm_enabled() && kvm_irqchip_in_kernel()) { + kvm_kernel_ioapic_load_from_user(s); + } +#endif } static CPUReadMemoryFunc * const ioapic_mem_read[3] = { diff --git a/kvm-all.c b/kvm-all.c index 48ae26c..d795285 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -411,6 +411,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 e7d5beb..8d4afa0 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;