From patchwork Tue Apr 25 14:39:26 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 9698345 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id B0C0E6020A for ; Tue, 25 Apr 2017 14:39:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9614C28484 for ; Tue, 25 Apr 2017 14:39:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 897562857D; Tue, 25 Apr 2017 14:39:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 19D2328484 for ; Tue, 25 Apr 2017 14:39:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1948040AbdDYOjl (ORCPT ); Tue, 25 Apr 2017 10:39:41 -0400 Received: from foss.arm.com ([217.140.101.70]:42140 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1948200AbdDYOhi (ORCPT ); Tue, 25 Apr 2017 10:37:38 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id E4D4F19CC; Tue, 25 Apr 2017 07:37:37 -0700 (PDT) Received: from e104803-lin.lan (unknown [10.1.207.46]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id BD7A53F220; Tue, 25 Apr 2017 07:37:36 -0700 (PDT) From: Andre Przywara To: Will Deacon , Marc Zyngier Cc: Jean-Philippe Brucker , kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [kvmtool PATCH v10 09/15] arm: allow creation of an MSI register frame region Date: Tue, 25 Apr 2017 15:39:26 +0100 Message-Id: <20170425143932.17235-10-andre.przywara@arm.com> X-Mailer: git-send-email 2.9.0 In-Reply-To: <20170425143932.17235-1-andre.przywara@arm.com> References: <20170425143932.17235-1-andre.przywara@arm.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The GICv3 ITS expects a separate 64K page to hold ITS registers. Add a function to reserve such a page in the guest's I/O memory and use that for the ITS vGIC type. To cover the 64K page with the MSI doorbell (which directly follows the page with the register frames), we reserve this as well, although the guest is never expected to write into this. Signed-off-by: Andre Przywara --- arm/gic.c | 64 ++++++++++++++++++++++++++++++++++++++++++++ arm/include/arm-common/gic.h | 1 + 2 files changed, 65 insertions(+) diff --git a/arm/gic.c b/arm/gic.c index 8479b89..95e26a9 100644 --- a/arm/gic.c +++ b/arm/gic.c @@ -8,10 +8,13 @@ #include #include #include +#include static int gic_fd = -1; static u64 gic_redists_base; static u64 gic_redists_size; +static u64 gic_msi_base; +static u64 gic_msi_size = 0; int irqchip_parser(const struct option *opt, const char *arg, int unset) { @@ -29,6 +32,56 @@ int irqchip_parser(const struct option *opt, const char *arg, int unset) return 0; } +static int gic__create_its_frame(struct kvm *kvm, u64 its_frame_addr) +{ + struct kvm_create_device its_device = { + .type = KVM_DEV_TYPE_ARM_VGIC_ITS, + .flags = 0, + }; + struct kvm_device_attr its_attr = { + .group = KVM_DEV_ARM_VGIC_GRP_ADDR, + .attr = KVM_VGIC_ITS_ADDR_TYPE, + .addr = (u64)(unsigned long)&its_frame_addr, + }; + struct kvm_device_attr its_init_attr = { + .group = KVM_DEV_ARM_VGIC_GRP_CTRL, + .attr = KVM_DEV_ARM_VGIC_CTRL_INIT, + }; + int err; + + err = ioctl(kvm->vm_fd, KVM_CREATE_DEVICE, &its_device); + if (err) { + fprintf(stderr, + "GICv3 ITS requested, but kernel does not support it.\n"); + fprintf(stderr, "Try --irqchip=gicv3 instead\n"); + return err; + } + + err = ioctl(its_device.fd, KVM_HAS_DEVICE_ATTR, &its_attr); + if (err) { + close(its_device.fd); + its_device.fd = -1; + return err; + } + + err = ioctl(its_device.fd, KVM_SET_DEVICE_ATTR, &its_attr); + if (err) + return err; + + return ioctl(its_device.fd, KVM_SET_DEVICE_ATTR, &its_init_attr); +} + +static int gic__create_msi_frame(struct kvm *kvm, enum irqchip_type type, + u64 msi_frame_addr) +{ + switch (type) { + case IRQCHIP_GICV3_ITS: + return gic__create_its_frame(kvm, msi_frame_addr); + default: /* No MSI frame needed */ + return 0; + } +} + static int gic__create_device(struct kvm *kvm, enum irqchip_type type) { int err; @@ -58,6 +111,7 @@ static int gic__create_device(struct kvm *kvm, enum irqchip_type type) dist_attr.attr = KVM_VGIC_V2_ADDR_TYPE_DIST; break; case IRQCHIP_GICV3: + case IRQCHIP_GICV3_ITS: gic_device.type = KVM_DEV_TYPE_ARM_VGIC_V3; dist_attr.attr = KVM_VGIC_V3_ADDR_TYPE_DIST; break; @@ -73,6 +127,7 @@ static int gic__create_device(struct kvm *kvm, enum irqchip_type type) case IRQCHIP_GICV2: err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &cpu_if_attr); break; + case IRQCHIP_GICV3_ITS: case IRQCHIP_GICV3: err = ioctl(gic_fd, KVM_SET_DEVICE_ATTR, &redist_attr); break; @@ -84,6 +139,10 @@ static int gic__create_device(struct kvm *kvm, enum irqchip_type type) if (err) goto out_err; + err = gic__create_msi_frame(kvm, type, gic_msi_base); + if (err) + goto out_err; + return 0; out_err: @@ -127,9 +186,14 @@ int gic__create(struct kvm *kvm, enum irqchip_type type) switch (type) { case IRQCHIP_GICV2: break; + case IRQCHIP_GICV3_ITS: + /* We reserve the 64K page with the doorbell as well. */ + gic_msi_size = KVM_VGIC_V3_ITS_SIZE + SZ_64K; + /* fall through */ case IRQCHIP_GICV3: gic_redists_size = kvm->cfg.nrcpus * ARM_GIC_REDIST_SIZE; gic_redists_base = ARM_GIC_DIST_BASE - gic_redists_size; + gic_msi_base = gic_redists_base - gic_msi_size; break; default: return -ENODEV; diff --git a/arm/include/arm-common/gic.h b/arm/include/arm-common/gic.h index b43a180..433dd23 100644 --- a/arm/include/arm-common/gic.h +++ b/arm/include/arm-common/gic.h @@ -24,6 +24,7 @@ enum irqchip_type { IRQCHIP_GICV2, IRQCHIP_GICV3, + IRQCHIP_GICV3_ITS, }; struct kvm;