From patchwork Fri Jul 17 13:26:49 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Fedin X-Patchwork-Id: 497140 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 89C2914029E for ; Fri, 17 Jul 2015 23:27:38 +1000 (AEST) Received: from localhost ([::1]:44816 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZG5fs-0004YA-Ku for incoming@patchwork.ozlabs.org; Fri, 17 Jul 2015 09:27:36 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37159) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZG5fJ-0003UQ-Vz for qemu-devel@nongnu.org; Fri, 17 Jul 2015 09:27:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZG5fE-0002T1-NN for qemu-devel@nongnu.org; Fri, 17 Jul 2015 09:27:01 -0400 Received: from mailout4.w1.samsung.com ([210.118.77.14]:35616) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZG5fE-0002SG-F1 for qemu-devel@nongnu.org; Fri, 17 Jul 2015 09:26:56 -0400 Received: from eucpsbgm1.samsung.com (unknown [203.254.199.244]) by mailout4.w1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0NRM00EQBW0TVZ80@mailout4.w1.samsung.com> for qemu-devel@nongnu.org; Fri, 17 Jul 2015 14:26:53 +0100 (BST) X-AuditID: cbfec7f4-f79c56d0000012ee-fb-55a9029db8d2 Received: from eusync1.samsung.com ( [203.254.199.211]) by eucpsbgm1.samsung.com (EUCPMTA) with SMTP id 23.C5.04846.D9209A55; Fri, 17 Jul 2015 14:26:53 +0100 (BST) Received: from localhost ([106.109.131.169]) by eusync1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0NRM008LMW0TLY30@eusync1.samsung.com>; Fri, 17 Jul 2015 14:26:53 +0100 (BST) From: Pavel Fedin To: qemu-devel@nongnu.org Date: Fri, 17 Jul 2015 16:26:49 +0300 Message-id: <74184f32c47f47da52c923cf036de2803405d031.1437139165.git.p.fedin@samsung.com> X-Mailer: git-send-email 1.9.5.msysgit.0 In-reply-to: References: In-reply-to: References: X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrJLMWRmVeSWpSXmKPExsVy+t/xy7pzmVaGGpxfoWPx4vU/RotNn8+x WMzfcobVYs6ZBywWx3t3sFi0ff7ObnH39WcWB3aPf4f7mTx2zrrL7tFy5C2rx51re9g8nlzb zBTAGsVlk5Kak1mWWqRvl8CVcXvTDZaCVqOKZ1OjGhifqHcxcnBICJhILNsR28XICWSKSVy4 t54NxBYSWMoo0dxq1MXIBWR/Y5RYPO00I0iCTUBd4vTXDywgtoiApMTvrtPMIEXMAhOZJDbO bgXrFhawkNiy8A5YA4uAqsS7bw1gDbwC0RKf9n9jhNimIbHoyxw2kCM4Bcwlfm8ygVhsJnH8 93NcwhMY+RcwMqxiFE0tTS4oTkrPNdQrTswtLs1L10vOz93ECAnALzsYFx+zOsQowMGoxMPb 4LoiVIg1say4MvcQowQHs5II769/QCHelMTKqtSi/Pii0pzU4kOM0hwsSuK8c3e9DxESSE8s Sc1OTS1ILYLJMnFwSjUw8u77xz/9yfOJF+7Lv5m+am369zTzH3dMONe7TXMp33x62tKLQSoH mb2/yP/gT8q+0W5ed07uvcjv6shyuYlskx5cqWurd9b4cYm7s9KhaP25NUWHMh+XxbDMVJac ZXdNRdPFSUXqJ+/r7G0K3Oo8Owp25BbmGpVzZH+5ULRsQ33i16y6TS/2KrEUZyQaajEXFScC AHyODlM8AgAA X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 210.118.77.14 Cc: Peter Maydell , Eric Auger , Shlomo Pongratz , Shlomo Pongratz , Diana Craciun , Christoffer Dall Subject: [Qemu-devel] [PATCH v5 4/5] Initial implementation of vGICv3 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Get/put routines are missing, live migration is not possible. Signed-off-by: Pavel Fedin --- hw/intc/Makefile.objs | 3 + hw/intc/arm_gicv3_kvm.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+) create mode 100644 hw/intc/arm_gicv3_kvm.c diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs index 1317e5a..e2525a8 100644 --- a/hw/intc/Makefile.objs +++ b/hw/intc/Makefile.objs @@ -17,6 +17,9 @@ common-obj-$(CONFIG_OPENPIC) += openpic.o obj-$(CONFIG_APIC) += apic.o apic_common.o obj-$(CONFIG_ARM_GIC_KVM) += arm_gic_kvm.o +ifeq ($(ARCH), aarch64) # Only 64-bit KVM can use these +obj-$(CONFIG_ARM_GIC_KVM) += arm_gicv3_kvm.o +endif obj-$(CONFIG_STELLARIS) += armv7m_nvic.o obj-$(CONFIG_EXYNOS4) += exynos4210_gic.o exynos4210_combiner.o obj-$(CONFIG_GRLIB) += grlib_irqmp.o diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c new file mode 100644 index 0000000..e2724bc --- /dev/null +++ b/hw/intc/arm_gicv3_kvm.c @@ -0,0 +1,159 @@ +/* + * ARM Generic Interrupt Controller using KVM in-kernel support + * + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Written by Pavel Fedin + * Based on vGICv2 code 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 . + */ + +#include "hw/sysbus.h" +#include "sysemu/kvm.h" +#include "kvm_arm.h" +#include "gicv3_internal.h" +#include "vgic_common.h" + +#ifdef DEBUG_GICV3_KVM +static const int debug_gicv3_kvm = 1; +#else +static const int debug_gicv3_kvm = 0; +#endif + +#define DPRINTF(fmt, ...) do { \ + if (debug_gicv3_kvm) { \ + printf("kvm_gicv3: " fmt , ## __VA_ARGS__); \ + } \ + } while (0) + +#define TYPE_KVM_ARM_GICV3 "kvm-arm-gicv3" +#define KVM_ARM_GICV3(obj) \ + OBJECT_CHECK(GICv3State, (obj), TYPE_KVM_ARM_GICV3) +#define KVM_ARM_GICV3_CLASS(klass) \ + OBJECT_CLASS_CHECK(KVMARMGICv3Class, (klass), TYPE_KVM_ARM_GICV3) +#define KVM_ARM_GICV3_GET_CLASS(obj) \ + OBJECT_GET_CLASS(KVMARMGICv3Class, (obj), TYPE_KVM_ARM_GICV3) + +typedef struct KVMARMGICv3Class { + ARMGICv3CommonClass parent_class; + DeviceRealize parent_realize; + void (*parent_reset)(DeviceState *dev); +} KVMARMGICv3Class; + +static void kvm_arm_gicv3_set_irq(void *opaque, int irq, int level) +{ + GICv3State *s = (GICv3State *)opaque; + + kvm_arm_gic_set_irq(s->num_irq, irq, level); +} + +static void kvm_arm_gicv3_put(GICv3State *s) +{ + /* TODO */ + DPRINTF("Cannot put kernel gic state, no kernel interface\n"); +} + +static void kvm_arm_gicv3_get(GICv3State *s) +{ + /* TODO */ + DPRINTF("Cannot get kernel gic state, no kernel interface\n"); +} + +static void kvm_arm_gicv3_reset(DeviceState *dev) +{ + GICv3State *s = ARM_GICV3_COMMON(dev); + KVMARMGICv3Class *kgc = KVM_ARM_GICV3_GET_CLASS(s); + + DPRINTF("Reset\n"); + + kgc->parent_reset(dev); + kvm_arm_gicv3_put(s); +} + +static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp) +{ + GICv3State *s = KVM_ARM_GICV3(dev); + KVMARMGICv3Class *kgc = KVM_ARM_GICV3_GET_CLASS(s); + Error *local_err = NULL; + int ret; + + DPRINTF("kvm_arm_gicv3_realize\n"); + + kgc->parent_realize(dev, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + gicv3_init_irqs_and_mmio(s, kvm_arm_gicv3_set_irq, NULL, NULL); + + /* Try to create the device via the device control API */ + s->dev_fd = -1; + ret = kvm_create_device(kvm_state, KVM_DEV_TYPE_ARM_VGIC_V3, false); + if (ret >= 0) { + s->dev_fd = ret; + } else if (ret != -ENODEV && ret != -ENOTSUP) { + error_setg_errno(errp, -ret, "error creating in-kernel VGIC"); + return; + } + + if (kvm_gic_supports_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS, 0)) { + uint32_t numirqs = s->num_irq; + DPRINTF("KVM_DEV_ARM_VGIC_GRP_NR_IRQS = %u\n", numirqs); + kvm_gic_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS, + 0, 0, &numirqs, 1); + } + + /* Tell the kernel to complete VGIC initialization now */ + if (kvm_gic_supports_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL, + KVM_DEV_ARM_VGIC_CTRL_INIT)) { + DPRINTF("KVM_DEV_ARM_VGIC_CTRL_INIT\n"); + kvm_gic_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL, + KVM_DEV_ARM_VGIC_CTRL_INIT, 0, 0, 1); + } + + kvm_arm_register_device(&s->iomem_dist, -1, KVM_DEV_ARM_VGIC_GRP_ADDR, + KVM_VGIC_V3_ADDR_TYPE_DIST, s->dev_fd); + kvm_arm_register_device(&s->iomem_lpi, -1, KVM_DEV_ARM_VGIC_GRP_ADDR, + KVM_VGIC_V3_ADDR_TYPE_REDIST, s->dev_fd); +} + +static void kvm_arm_gicv3_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + ARMGICv3CommonClass *agcc = ARM_GICV3_COMMON_CLASS(klass); + KVMARMGICv3Class *kgc = KVM_ARM_GICV3_CLASS(klass); + + agcc->pre_save = kvm_arm_gicv3_get; + agcc->post_load = kvm_arm_gicv3_put; + kgc->parent_realize = dc->realize; + kgc->parent_reset = dc->reset; + dc->realize = kvm_arm_gicv3_realize; + dc->reset = kvm_arm_gicv3_reset; +} + +static const TypeInfo kvm_arm_gicv3_info = { + .name = TYPE_KVM_ARM_GICV3, + .parent = TYPE_ARM_GICV3_COMMON, + .instance_size = sizeof(GICv3State), + .class_init = kvm_arm_gicv3_class_init, + .class_size = sizeof(KVMARMGICv3Class), +}; + +static void kvm_arm_gicv3_register_types(void) +{ + type_register_static(&kvm_arm_gicv3_info); +} + +type_init(kvm_arm_gicv3_register_types)