From patchwork Fri Apr 7 17:33:06 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 9670023 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 C1A0160364 for ; Fri, 7 Apr 2017 17:33:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B4546262FF for ; Fri, 7 Apr 2017 17:33:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A90FF28628; Fri, 7 Apr 2017 17:33:44 +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=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 22D29262FF for ; Fri, 7 Apr 2017 17:33:41 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cwXjq-0006vT-OH; Fri, 07 Apr 2017 17:31:58 +0000 Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cwXjo-0006pQ-O2 for xen-devel@lists.xenproject.org; Fri, 07 Apr 2017 17:31:56 +0000 Received: from [85.158.139.211] by server-4.bemta-5.messagelabs.com id 2A/24-13971-C0DC7E85; Fri, 07 Apr 2017 17:31:56 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrALMWRWlGSWpSXmKPExsVysyfVTZf77PM Ig01PJSy+b5nM5MDocfjDFZYAxijWzLyk/IoE1oxLEyYyFvxRr1i2dhVjA2ObfBcjJ4eQwCZG ib2ni7oYuYDs5YwSt2Z+ZgdJsAnoSuy4+ZoZxBYRCJWY8/MRmM0sUCnx78MmJhBbWCBQYkrLN 8YuRg4OFgFViRe3U0HCvALWEmuaT4CVSwjISTScvw9mcwLFv37fwgyx10pixcaLjBMYuRcwMq xiVC9OLSpLLdI11UsqykzPKMlNzMzRNTQw1ctNLS5OTE/NSUwq1kvOz93ECPQtAxDsYPzS73y IUZKDSUmUV8HnSYQQX1J+SmVGYnFGfFFpTmrxIUYNDg6BzWtXX2CUYsnLz0tVkuBddPp5hJBg UWp6akVaZg4w+GBKJTh4lER4FUDSvMUFibnFmekQqVOMilLivI0gCQGQREZpHlwbLOAvMcpKC fMyAh0lxFOQWpSbWYIq/4pRnINRSZg3HmQKT2ZeCdz0V0CLmYAW+9x6CrK4JBEhJdXAWGLFd7 WDPSveWUVoY1Tnf+W3/568vZJ9mZHh0JzevwslPnfUlH41n6752OP0gfXH+PvSdY/3ziuYfP/ tvrRZnKtrl/+7GBKtuejUw5Ofe5+6btrc2naG719X14cZvj1zH5x/sm/DmubmP21GkY77faY+ WcmZE7r88qoTvs723pfDVipEztfnXafEUpyRaKjFXFScCACHC7wHcwIAAA== X-Env-Sender: andre.przywara@arm.com X-Msg-Ref: server-14.tower-206.messagelabs.com!1491586314!53642281!1 X-Originating-IP: [217.140.101.70] X-SpamReason: No, hits=0.5 required=7.0 tests=BODY_RANDOM_LONG X-StarScan-Received: X-StarScan-Version: 9.4.12; banners=-,-,- X-VirusChecked: Checked Received: (qmail 21594 invoked from network); 7 Apr 2017 17:31:55 -0000 Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by server-14.tower-206.messagelabs.com with SMTP; 7 Apr 2017 17:31:55 -0000 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 74609B16; Fri, 7 Apr 2017 10:31:54 -0700 (PDT) Received: from e104803-lin.lan (unknown [10.1.207.46]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 6F9843F3E1; Fri, 7 Apr 2017 10:31:53 -0700 (PDT) From: Andre Przywara To: Stefano Stabellini , Julien Grall Date: Fri, 7 Apr 2017 18:33:06 +0100 Message-Id: <20170407173307.9788-36-andre.przywara@arm.com> X-Mailer: git-send-email 2.9.0 In-Reply-To: <20170407173307.9788-1-andre.przywara@arm.com> References: <20170407173307.9788-1-andre.przywara@arm.com> Cc: xen-devel@lists.xenproject.org, Vijay Kilari , Shanker Donthineni Subject: [Xen-devel] [PATCH v6 35/36] ARM: vITS: create and initialize virtual ITSes for Dom0 X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP For each hardware ITS create and initialize a virtual ITS for Dom0. We use the same memory mapped address to keep the doorbell working. This introduces a function to initialize a virtual ITS. We maintain a list of virtual ITSes, at the moment for the only purpose of later being able to free them again. We advertise 24 bits worth of LPIs on the guest side, using the full 32 bits seems to trigger a Linux bug (to be investigated). Signed-off-by: Andre Przywara --- xen/arch/arm/vgic-v3-its.c | 72 ++++++++++++++++++++++++++++++++++++++++ xen/arch/arm/vgic-v3.c | 1 + xen/include/asm-arm/gic_v3_its.h | 4 +++ 3 files changed, 77 insertions(+) diff --git a/xen/arch/arm/vgic-v3-its.c b/xen/arch/arm/vgic-v3-its.c index ce90187..439210f 100644 --- a/xen/arch/arm/vgic-v3-its.c +++ b/xen/arch/arm/vgic-v3-its.c @@ -42,6 +42,7 @@ */ struct virt_its { struct domain *d; + struct list_head vits_list; paddr_t doorbell_address; unsigned int devid_bits; unsigned int intid_bits; @@ -74,14 +75,48 @@ struct vits_itte int vgic_v3_its_init_domain(struct domain *d) { + int ret; + + INIT_LIST_HEAD(&d->arch.vgic.vits_list); spin_lock_init(&d->arch.vgic.its_devices_lock); d->arch.vgic.its_devices = RB_ROOT; + if ( is_hardware_domain(d) ) + { + struct host_its *hw_its; + + list_for_each_entry(hw_its, &host_its_list, entry) + { + /* + * For each host ITS create a virtual ITS using the same + * base and thus doorbell address. + * Use the same number of device ID bits as the host, and + * allow 24 bits for the interrupt ID. + */ + ret = vgic_v3_its_init_virtual(d, hw_its->addr, + hw_its->devid_bits, 24); + if ( ret ) + { + vgic_v3_its_free_domain(d); + return ret; + } + else + d->arch.vgic.has_its = true; + } + } + return 0; } void vgic_v3_its_free_domain(struct domain *d) { + struct virt_its *pos, *temp; + + list_for_each_entry_safe( pos, temp, &d->arch.vgic.vits_list, vits_list ) + { + list_del(&pos->vits_list); + xfree(pos); + } ASSERT(RB_EMPTY_ROOT(&d->arch.vgic.its_devices)); } @@ -1255,6 +1290,43 @@ static const struct mmio_handler_ops vgic_its_mmio_handler = { .write = vgic_v3_its_mmio_write, }; +int vgic_v3_its_init_virtual(struct domain *d, paddr_t guest_addr, + unsigned int devid_bits, unsigned int intid_bits) +{ + struct virt_its *its; + uint64_t base_attr; + + its = xzalloc(struct virt_its); + if ( !its ) + return -ENOMEM; + + base_attr = GIC_BASER_InnerShareable << GITS_BASER_SHAREABILITY_SHIFT; + base_attr |= GIC_BASER_CACHE_SameAsInner << GITS_BASER_OUTER_CACHEABILITY_SHIFT; + base_attr |= GIC_BASER_CACHE_RaWaWb << GITS_BASER_INNER_CACHEABILITY_SHIFT; + + its->cbaser = base_attr; + base_attr |= 0ULL << GITS_BASER_PAGE_SIZE_SHIFT; /* 4K pages */ + its->baser_dev = GITS_BASER_TYPE_DEVICE << GITS_BASER_TYPE_SHIFT; + its->baser_dev |= (sizeof(uint64_t) - 1) << GITS_BASER_ENTRY_SIZE_SHIFT; + its->baser_dev |= base_attr; + its->baser_coll = GITS_BASER_TYPE_COLLECTION << GITS_BASER_TYPE_SHIFT; + its->baser_coll |= (sizeof(uint16_t) - 1) << GITS_BASER_ENTRY_SIZE_SHIFT; + its->baser_coll |= base_attr; + its->d = d; + its->doorbell_address = guest_addr + ITS_DOORBELL_OFFSET; + its->devid_bits = devid_bits; + its->intid_bits = intid_bits; + spin_lock_init(&its->vcmd_lock); + spin_lock_init(&its->its_lock); + + register_mmio_handler(d, &vgic_its_mmio_handler, guest_addr, SZ_64K, its); + + /* Register the virtual ITSes to be able to clean them up later. */ + list_add_tail(&its->vits_list, &d->arch.vgic.vits_list); + + return 0; +} + /* * Local variables: * mode: C diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c index 1c1d014..d381ce6 100644 --- a/xen/arch/arm/vgic-v3.c +++ b/xen/arch/arm/vgic-v3.c @@ -1659,6 +1659,7 @@ static int vgic_v3_domain_init(struct domain *d) first_cpu += size / d->arch.vgic.rdist_stride; } + d->arch.vgic.nr_regions = vgic_v3_hw.nr_rdist_regions; } else { diff --git a/xen/include/asm-arm/gic_v3_its.h b/xen/include/asm-arm/gic_v3_its.h index cd2b527..75ce534 100644 --- a/xen/include/asm-arm/gic_v3_its.h +++ b/xen/include/asm-arm/gic_v3_its.h @@ -156,6 +156,10 @@ int gicv3_its_setup_collection(unsigned int cpu); int vgic_v3_its_init_domain(struct domain *d); void vgic_v3_its_free_domain(struct domain *d); +/* Create and register a virtual ITS at the given guest address. */ +int vgic_v3_its_init_virtual(struct domain *d, paddr_t guest_addr, + unsigned int devid_bits, unsigned int intid_bits); + /* * Map a device on the host by allocating an ITT on the host (ITS). * "nr_event" specifies how many events (interrupts) this device will need.