From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MvrS7-0002iR-AR for qemu-devel@nongnu.org; Thu, 08 Oct 2009 07:46:35 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MvrS2-0002hA-Aj for qemu-devel@nongnu.org; Thu, 08 Oct 2009 07:46:34 -0400 Received: from [199.232.76.173] (port=48626 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MvrS2-0002h7-51 for qemu-devel@nongnu.org; Thu, 08 Oct 2009 07:46:30 -0400 Received: from thoth.sbs.de ([192.35.17.2]:15907) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1MvrS1-0003Up-8i for qemu-devel@nongnu.org; Thu, 08 Oct 2009 07:46:29 -0400 Message-ID: <4ACDD111.6050904@siemens.com> Date: Thu, 08 Oct 2009 13:46:25 +0200 From: Jan Kiszka MIME-Version: 1.0 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> <1254953315-5761-4-git-send-email-glommer@redhat.com> In-Reply-To: <1254953315-5761-4-git-send-email-glommer@redhat.com> Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 7bit Subject: [Qemu-devel] Re: [PATCH v2 3/9] provide in-kernel ioapic List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Glauber Costa Cc: aliguori@us.ibm.com, qemu-devel@nongnu.org Glauber Costa wrote: > 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) Hmm, here we additionally depend on 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 ... but here only KVM_CAP_IRQCHIP suffices? > + if (kvm_enabled() && kvm_irqchip_in_kernel()) { > + kvm_kernel_ioapic_load_from_user(s); > + } > +#endif Independent of this, both kvm_irqchip_in_kernel() and kvm_kernel_ioapic_load_from_user() should also be defined for the !KVM_CAP_IRQCHIP case to avoid #ifdefs here and in many other places this series touches. > } > > 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 Again, only KVM_CAP_IRQCHIP - what is the actually required dependency? > +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; Jan -- Siemens AG, Corporate Technology, CT SE 2 Corporate Competence Center Embedded Linux