From patchwork Fri Jun 9 17:41:25 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 9778983 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 1BE6360318 for ; Fri, 9 Jun 2017 17:43:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 07C99286E2 for ; Fri, 9 Jun 2017 17:43:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F077B286F5; Fri, 9 Jun 2017 17:43:53 +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 50913286E2 for ; Fri, 9 Jun 2017 17:43:53 +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 1dJNvH-0003tk-TN; Fri, 09 Jun 2017 17:42:11 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dJNvH-0003ry-5U for xen-devel@lists.xenproject.org; Fri, 09 Jun 2017 17:42:11 +0000 Received: from [85.158.137.68] by server-9.bemta-3.messagelabs.com id 17/75-26749-2FDDA395; Fri, 09 Jun 2017 17:42:10 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrOLMWRWlGSWpSXmKPExsVysyfVTff9Xat Igwt3dC2+b5nM5MDocfjDFZYAxijWzLyk/IoE1owXDR1sBcv0K87t28zSwHhNqYuRi0NIYDOj xNar95ggnOWMEo/WbGfrYuTkYBPQldhx8zUziC0iECrxdMF3ZpAiZoHrjBKnd8wHKuLgEBawl njZZwpSwyKgKjGx8Q5YPS9QeNG8bUwgtoSAnETD+ftgcU6g+LY9a8HmCwlYSbQcusw+gZF7AS PDKkaN4tSistQiXUNjvaSizPSMktzEzBxdQwNjvdzU4uLE9NScxKRiveT83E2MQA8zAMEOxm3 bPQ8xSnIwKYnyTiuwihTiS8pPqcxILM6ILyrNSS0+xCjDwaEkwdtzBygnWJSanlqRlpkDDDWY tAQHj5II74uTQGne4oLE3OLMdIjUKUZFKXFeS5A+AZBERmkeXBssvC8xykoJ8zICHSLEU5Bal JtZgir/ilGcg1FJmHcXyBSezLwSuOmvgBYzAS1e8s4CZHFJIkJKqoHx+IJ866wDqgwilxo39U hMbVl5wyH8toZQrIv9xhmzhL581Og7Nfdn4sEZXN8qVC7XzQ6M8MlPzFogHPP0kdHjgAuJRZO vT2RQmHpuPvvaGu9prc57utfo/hDwrG86tn2/9KzF2W1z8z99rkyczTX5BFN9wOyHi+8/1Clv +PHJ7sTzymlNL/UeKLEUZyQaajEXFScCAHRc0S5qAgAA X-Env-Sender: andre.przywara@arm.com X-Msg-Ref: server-11.tower-31.messagelabs.com!1497030127!74053380!1 X-Originating-IP: [217.140.101.70] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 9.4.19; banners=-,-,- X-VirusChecked: Checked Received: (qmail 53183 invoked from network); 9 Jun 2017 17:42:07 -0000 Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by server-11.tower-31.messagelabs.com with SMTP; 9 Jun 2017 17:42:07 -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 D1CE91596; Fri, 9 Jun 2017 10:42:06 -0700 (PDT) Received: from e104803-lin.lan (unknown [10.1.207.46]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 882163F578; Fri, 9 Jun 2017 10:42:05 -0700 (PDT) From: Andre Przywara To: Julien Grall , Stefano Stabellini Date: Fri, 9 Jun 2017 18:41:25 +0100 Message-Id: <20170609174141.5068-19-andre.przywara@arm.com> X-Mailer: git-send-email 2.9.0 In-Reply-To: <20170609174141.5068-1-andre.przywara@arm.com> References: <20170609174141.5068-1-andre.przywara@arm.com> Cc: xen-devel@lists.xenproject.org, Vijaya Kumar K , Vijay Kilari , Shanker Donthineni , Manish Jaggi Subject: [Xen-devel] [PATCH v11 18/34] ARM: vGIC: advertise LPI support 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 To let a guest know about the availability of virtual LPIs, set the respective bits in the virtual GIC registers and let a guest control the LPI enable bit. Only report the LPI capability if there is at least one ITS emulated for that guest (which depends on the host having an ITS at the moment). For Dom0 we report the same number of interrupts identifiers as the host, whereas DomUs get a number fixed at 10 bits for the moments, which covers all SPIs. Also we fix a slight inaccuracy here, since the number of interrupt identifier specified in GICD_TYPER depends on the stream interface and is independent from the number of actually wired SPIs. This also removes a "TBD" comment, as we now populate the processor number in the GICR_TYPER register, which will be used by the ITS emulation later on. Signed-off-by: Andre Przywara Acked-by: Julien Grall --- xen/arch/arm/vgic-v3.c | 83 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 76 insertions(+), 7 deletions(-) diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c index f32e419..296991a 100644 --- a/xen/arch/arm/vgic-v3.c +++ b/xen/arch/arm/vgic-v3.c @@ -170,8 +170,19 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info, switch ( gicr_reg ) { case VREG32(GICR_CTLR): - /* We have not implemented LPI's, read zero */ - goto read_as_zero_32; + { + unsigned long flags; + + if ( !v->domain->arch.vgic.has_its ) + goto read_as_zero_32; + if ( dabt.size != DABT_WORD ) goto bad_width; + + spin_lock_irqsave(&v->arch.vgic.lock, flags); + *r = vgic_reg32_extract(!!(v->arch.vgic.flags & VGIC_V3_LPIS_ENABLED), + info); + spin_unlock_irqrestore(&v->arch.vgic.lock, flags); + return 1; + } case VREG32(GICR_IIDR): if ( dabt.size != DABT_WORD ) goto bad_width; @@ -183,16 +194,20 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info, uint64_t typer, aff; if ( !vgic_reg64_check_access(dabt) ) goto bad_width; - /* TBD: Update processor id in [23:8] when ITS support is added */ aff = (MPIDR_AFFINITY_LEVEL(v->arch.vmpidr, 3) << 56 | MPIDR_AFFINITY_LEVEL(v->arch.vmpidr, 2) << 48 | MPIDR_AFFINITY_LEVEL(v->arch.vmpidr, 1) << 40 | MPIDR_AFFINITY_LEVEL(v->arch.vmpidr, 0) << 32); typer = aff; + /* We use the VCPU ID as the redistributor ID in bits[23:8] */ + typer |= v->vcpu_id << GICR_TYPER_PROC_NUM_SHIFT; if ( v->arch.vgic.flags & VGIC_V3_RDIST_LAST ) typer |= GICR_TYPER_LAST; + if ( v->domain->arch.vgic.has_its ) + typer |= GICR_TYPER_PLPIS; + *r = vgic_reg64_extract(typer, info); return 1; @@ -426,6 +441,40 @@ static uint64_t sanitize_pendbaser(uint64_t reg) return reg; } +static void vgic_vcpu_enable_lpis(struct vcpu *v) +{ + uint64_t reg = v->domain->arch.vgic.rdist_propbase; + unsigned int nr_lpis = BIT((reg & 0x1f) + 1); + + /* rdists_enabled is protected by the domain lock. */ + ASSERT(spin_is_locked(&v->domain->arch.vgic.lock)); + + if ( nr_lpis < LPI_OFFSET ) + nr_lpis = 0; + else + nr_lpis -= LPI_OFFSET; + + if ( !v->domain->arch.vgic.rdists_enabled ) + { + v->domain->arch.vgic.nr_lpis = nr_lpis; + /* + * Make sure nr_lpis is visible before rdists_enabled. + * We read nr_lpis (and rdist_propbase) outside of the lock in + * other functions, but guard those accesses by rdists_enabled, so + * make sure these are consistent. + */ + smp_mb(); + v->domain->arch.vgic.rdists_enabled = true; + /* + * Make sure the per-domain rdists_enabled flag has been set before + * enabling this particular redistributor. + */ + smp_mb(); + } + + v->arch.vgic.flags |= VGIC_V3_LPIS_ENABLED; +} + static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info, uint32_t gicr_reg, register_t r) @@ -436,8 +485,26 @@ static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info, switch ( gicr_reg ) { case VREG32(GICR_CTLR): - /* LPI's not implemented */ - goto write_ignore_32; + { + unsigned long flags; + + if ( !v->domain->arch.vgic.has_its ) + goto write_ignore_32; + if ( dabt.size != DABT_WORD ) goto bad_width; + + vgic_lock(v); /* protects rdists_enabled */ + spin_lock_irqsave(&v->arch.vgic.lock, flags); + + /* LPIs can only be enabled once, but never disabled again. */ + if ( (r & GICR_CTLR_ENABLE_LPIS) && + !(v->arch.vgic.flags & VGIC_V3_LPIS_ENABLED) ) + vgic_vcpu_enable_lpis(v); + + spin_unlock_irqrestore(&v->arch.vgic.lock, flags); + vgic_unlock(v); + + return 1; + } case VREG32(GICR_IIDR): /* RO */ @@ -1048,7 +1115,6 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info, * Number of interrupt identifier bits supported by the GIC * Stream Protocol Interface */ - unsigned int irq_bits = get_count_order(vgic_num_irqs(v->domain)); /* * Number of processors that may be used as interrupt targets when ARE * bit is zero. The maximum is 8. @@ -1061,7 +1127,10 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info, typer = ((ncpus - 1) << GICD_TYPE_CPUS_SHIFT | DIV_ROUND_UP(v->domain->arch.vgic.nr_spis, 32)); - typer |= (irq_bits - 1) << GICD_TYPE_ID_BITS_SHIFT; + if ( v->domain->arch.vgic.has_its ) + typer |= GICD_TYPE_LPIS; + + typer |= (v->domain->arch.vgic.intid_bits - 1) << GICD_TYPE_ID_BITS_SHIFT; *r = vgic_reg32_extract(typer, info);