From: "Andreas Färber" <afaerber@suse.de>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: qemu-devel@nongnu.org, Christoffer Dall <cdall@cs.columbia.edu>,
Gleb Natapov <gleb@redhat.com>,
kvm@vger.kernel.org, patches@linaro.org,
Marcelo Tosatti <mtosatti@redhat.com>,
kvmarm@lists.cs.columbia.edu, Blue Swirl <blauwirbel@gmail.com>,
Paolo Bonzini <pbonzini@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v6 7/9] hw/kvm/arm_gic: Implement support for KVM in-kernel ARM GIC
Date: Sat, 23 Feb 2013 16:29:15 +0100 [thread overview]
Message-ID: <5128E04B.1050104@suse.de> (raw)
In-Reply-To: <1361559865-22168-8-git-send-email-peter.maydell@linaro.org>
Am 22.02.2013 20:04, schrieb Peter Maydell:
> Implement support for using the KVM in-kernel GIC for ARM.
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> hw/a15mpcore.c | 8 ++-
> hw/arm/Makefile.objs | 1 +
> hw/kvm/arm_gic.c | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 177 insertions(+), 1 deletion(-)
> create mode 100644 hw/kvm/arm_gic.c
>
> diff --git a/hw/a15mpcore.c b/hw/a15mpcore.c
> index fe6c34c..97abe41 100644
> --- a/hw/a15mpcore.c
> +++ b/hw/a15mpcore.c
> @@ -19,6 +19,7 @@
> */
>
> #include "sysbus.h"
> +#include "sysemu/kvm.h"
>
> /* A15MP private memory region. */
>
> @@ -40,8 +41,13 @@ static int a15mp_priv_init(SysBusDevice *dev)
> {
> A15MPPrivState *s = FROM_SYSBUS(A15MPPrivState, dev);
> SysBusDevice *busdev;
> + const char *gictype = "arm_gic";
>
> - s->gic = qdev_create(NULL, "arm_gic");
> + if (kvm_irqchip_in_kernel()) {
> + gictype = "kvm-arm-gic";
> + }
> +
> + s->gic = qdev_create(NULL, gictype);
> qdev_prop_set_uint32(s->gic, "num-cpu", s->num_cpu);
> qdev_prop_set_uint32(s->gic, "num-irq", s->num_irq);
> qdev_prop_set_uint32(s->gic, "revision", 2);
> diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
> index 6d049e7..38b10a8 100644
> --- a/hw/arm/Makefile.objs
> +++ b/hw/arm/Makefile.objs
> @@ -31,5 +31,6 @@ obj-y += collie.o
> obj-y += imx_serial.o imx_ccm.o imx_timer.o imx_avic.o
> obj-y += kzm.o
> obj-$(CONFIG_FDT) += ../device_tree.o
> +obj-$(CONFIG_KVM) += kvm/arm_gic.o
>
> obj-y := $(addprefix ../,$(obj-y))
> diff --git a/hw/kvm/arm_gic.c b/hw/kvm/arm_gic.c
> new file mode 100644
> index 0000000..c3b73c4
> --- /dev/null
> +++ b/hw/kvm/arm_gic.c
> @@ -0,0 +1,169 @@
> +/*
> + * ARM Generic Interrupt Controller using KVM in-kernel support
> + *
> + * Copyright (c) 2012 Linaro Limited
> + * Written by Peter Maydell
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include "hw/sysbus.h"
> +#include "sysemu/kvm.h"
> +#include "kvm_arm.h"
> +#include "hw/arm_gic_internal.h"
> +
> +#define TYPE_KVM_ARM_GIC "kvm-arm-gic"
> +#define KVM_ARM_GIC(obj) \
> + OBJECT_CHECK(GICState, (obj), TYPE_KVM_ARM_GIC)
> +#define KVM_ARM_GIC_CLASS(klass) \
> + OBJECT_CLASS_CHECK(KVMARMGICClass, (klass), TYPE_KVM_ARM_GIC)
> +#define KVM_ARM_GIC_GET_CLASS(obj) \
> + OBJECT_GET_CLASS(KVMARMGICClass, (obj), TYPE_KVM_ARM_GIC)
> +
> +typedef struct KVMARMGICClass {
> + ARMGICCommonClass parent_class;
> + int (*parent_init)(SysBusDevice *dev);
> + void (*parent_reset)(DeviceState *dev);
> +} KVMARMGICClass;
> +
> +static void kvm_arm_gic_set_irq(void *opaque, int irq, int level)
> +{
> + /* Meaning of the 'irq' parameter:
> + * [0..N-1] : external interrupts
> + * [N..N+31] : PPI (internal) interrupts for CPU 0
> + * [N+32..N+63] : PPI (internal interrupts for CPU 1
> + * ...
> + * Convert this to the kernel's desired encoding, which
> + * has separate fields in the irq number for type,
> + * CPU number and interrupt number.
> + */
> + GICState *s = (GICState *)opaque;
> + int kvm_irq, irqtype, cpu;
> +
> + if (irq < (s->num_irq - GIC_INTERNAL)) {
> + /* External interrupt. The kernel numbers these like the GIC
> + * hardware, with external interrupt IDs starting after the
> + * internal ones.
> + */
> + irqtype = KVM_ARM_IRQ_TYPE_SPI;
> + cpu = 0;
> + irq += GIC_INTERNAL;
> + } else {
> + /* Internal interrupt: decode into (cpu, interrupt id) */
> + irqtype = KVM_ARM_IRQ_TYPE_PPI;
> + irq -= (s->num_irq - GIC_INTERNAL);
> + cpu = irq / GIC_INTERNAL;
> + irq %= GIC_INTERNAL;
> + }
> + kvm_irq = (irqtype << KVM_ARM_IRQ_TYPE_SHIFT)
> + | (cpu << KVM_ARM_IRQ_VCPU_SHIFT) | irq;
> +
> + kvm_set_irq(kvm_state, kvm_irq, !!level);
> +}
> +
> +static void kvm_arm_gic_put(GICState *s)
> +{
> + /* TODO: there isn't currently a kernel interface to set the GIC state */
> +}
> +
> +static void kvm_arm_gic_get(GICState *s)
> +{
> + /* TODO: there isn't currently a kernel interface to get the GIC state */
> +}
> +
> +static void kvm_arm_gic_reset(DeviceState *dev)
> +{
> + GICState *s = ARM_GIC_COMMON(dev);
> + KVMARMGICClass *kgc = KVM_ARM_GIC_GET_CLASS(s);
> + kgc->parent_reset(dev);
> + kvm_arm_gic_put(s);
> +}
> +
> +static int kvm_arm_gic_init(SysBusDevice *dev)
Please make this a realize function ...
> +{
> + /* Device instance init function for the GIC sysbus device */
> + int i;
> + GICState *s = FROM_SYSBUS(GICState, dev);
ARM_GIC_COMMON(dev)
> + KVMARMGICClass *kgc = KVM_ARM_GIC_GET_CLASS(s);
> +
> + kgc->parent_init(dev);
... and call sbc->init(dev) here as long as the base class is not updated.
> +
> + i = s->num_irq - GIC_INTERNAL;
> + /* For the GIC, also expose incoming GPIO lines for PPIs for each CPU.
> + * GPIO array layout is thus:
> + * [0..N-1] SPIs
> + * [N..N+31] PPIs for CPU 0
> + * [N+32..N+63] PPIs for CPU 1
> + * ...
> + */
> + i += (GIC_INTERNAL * s->num_cpu);
> + qdev_init_gpio_in(&s->busdev.qdev, kvm_arm_gic_set_irq, i);
DEVICE() and DeviceState *dev variable
> + /* We never use our outbound IRQ lines but provide them so that
> + * we maintain the same interface as the non-KVM GIC.
> + */
> + for (i = 0; i < s->num_cpu; i++) {
> + sysbus_init_irq(&s->busdev, &s->parent_irq[i]);
SYS_BUS_DEVICE() and SysBusDevice *d variable
> + }
> + /* Distributor */
> + memory_region_init_reservation(&s->iomem, "kvm-gic_dist", 0x1000);
> + sysbus_init_mmio(dev, &s->iomem);
-> instance_init?
> + kvm_arm_register_device(&s->iomem,
> + (KVM_ARM_DEVICE_VGIC_V2 << KVM_ARM_DEVICE_ID_SHIFT)
> + | KVM_VGIC_V2_ADDR_TYPE_DIST);
> + /* CPU interface for current core. Unlike arm_gic, we don't
> + * provide the "interface for core #N" memory regions, because
> + * cores with a VGIC don't have those.
> + */
> + memory_region_init_reservation(&s->cpuiomem[0], "kvm-gic_cpu", 0x1000);
> + sysbus_init_mmio(dev, &s->cpuiomem[0]);
-> instance_init?
> + kvm_arm_register_device(&s->cpuiomem[0],
> + (KVM_ARM_DEVICE_VGIC_V2 << KVM_ARM_DEVICE_ID_SHIFT)
> + | KVM_VGIC_V2_ADDR_TYPE_CPU);
> + /* TODO: we should tell the kernel at some point the address
> + * of the private peripheral base. However we don't currently have
> + * any convenient infrastructure to do that, and in any case the
> + * kernel doesn't yet implement an ioctl to let us tell it.
> + */
> + return 0;
> +}
> +
> +static void kvm_arm_gic_class_init(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> + SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
> + ARMGICCommonClass *agcc = ARM_GIC_COMMON_CLASS(klass);
> + KVMARMGICClass *kgc = KVM_ARM_GIC_CLASS(klass);
Please separate variable definitions and rest of block by a white line,
here and elsewhere.
> + agcc->pre_save = kvm_arm_gic_get;
> + agcc->post_load = kvm_arm_gic_put;
> + kgc->parent_init = sbc->init;
> + kgc->parent_reset = dc->reset;
> + sbc->init = kvm_arm_gic_init;
> + dc->reset = kvm_arm_gic_reset;
> + dc->no_user = 1;
> +}
> +
> +static const TypeInfo kvm_arm_gic_info = {
> + .name = TYPE_KVM_ARM_GIC,
> + .parent = TYPE_ARM_GIC_COMMON,
> + .instance_size = sizeof(GICState),
> + .class_init = kvm_arm_gic_class_init,
> + .class_size = sizeof(KVMARMGICClass),
> +};
> +
> +static void kvm_arm_gic_register_types(void)
> +{
> + type_register_static(&kvm_arm_gic_info);
> +}
> +
> +type_init(kvm_arm_gic_register_types)
Andreas
--
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
next prev parent reply other threads:[~2013-02-23 15:29 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-02-22 19:04 [PATCH v6 0/9] QEMU: Support KVM on ARM Peter Maydell
2013-02-22 19:04 ` [PATCH v6 1/9] oslib-posix: Align to permit transparent hugepages on ARM Linux Peter Maydell
2013-02-22 19:04 ` [PATCH v6 2/9] linux-headers: resync from mainline to add ARM KVM headers Peter Maydell
2013-02-22 19:04 ` [PATCH v6 3/9] ARM: KVM: Add support for KVM on ARM architecture Peter Maydell
2013-02-23 15:14 ` Andreas Färber
2013-02-26 14:50 ` Peter Maydell
2013-02-22 19:04 ` [PATCH v6 4/9] ARM KVM: save and load VFP registers from kernel Peter Maydell
2013-02-22 19:04 ` [PATCH v6 5/9] hw/arm_gic: Add presave/postload hooks Peter Maydell
2013-02-22 19:04 ` [PATCH v6 6/9] target-arm: Use MemoryListener to identify GIC base address for KVM Peter Maydell
2013-02-22 19:04 ` [PATCH v6 7/9] hw/kvm/arm_gic: Implement support for KVM in-kernel ARM GIC Peter Maydell
2013-02-23 15:29 ` Andreas Färber [this message]
2013-02-24 16:20 ` Peter Maydell
2013-02-22 19:04 ` [PATCH v6 8/9] configure: Enable KVM on ARM Peter Maydell
2013-02-22 19:04 ` [PATCH v6 9/9] MAINTAINERS: add entry for ARM KVM guest cores Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5128E04B.1050104@suse.de \
--to=afaerber@suse.de \
--cc=blauwirbel@gmail.com \
--cc=cdall@cs.columbia.edu \
--cc=gleb@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=mtosatti@redhat.com \
--cc=patches@linaro.org \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.