From patchwork Fri Mar 27 02:34:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefano Stabellini X-Patchwork-Id: 11461569 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9F3A792A for ; Fri, 27 Mar 2020 02:35:51 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 769C82082D for ; Fri, 27 Mar 2020 02:35:51 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="JhRZQh4m" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 769C82082D Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jHepm-0007C9-2C; Fri, 27 Mar 2020 02:34:58 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jHepk-0007C4-NW for xen-devel@lists.xenproject.org; Fri, 27 Mar 2020 02:34:56 +0000 X-Inumbo-ID: 8b1a3f6e-6fd3-11ea-88df-12813bfff9fa Received: from mail.kernel.org (unknown [198.145.29.99]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 8b1a3f6e-6fd3-11ea-88df-12813bfff9fa; Fri, 27 Mar 2020 02:34:55 +0000 (UTC) Received: from sstabellini-ThinkPad-T480s.hsd1.ca.comcast.net (c-67-164-102-47.hsd1.ca.comcast.net [67.164.102.47]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 5645F20714; Fri, 27 Mar 2020 02:34:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1585276494; bh=ghsIk6lKAOlI4w0XTF3R9UmgymQHh3Y9m+ELbP7TZ64=; h=From:To:Cc:Subject:Date:From; b=JhRZQh4mbrJB3o8lU28MVcN7zjmytohCR3ptRa+nx4OHNJQZdi/vziLxwG3B04fU6 AXhxCf0Ly7sFvrVLhvfLMQuRoBR0SJzcdmvawr7KCOXknMowfnOFRV1KRHjye7Ejj3 dv3xsEieFhZuOE7I1Aou8GxBZxFu1wIyM5Wou5Aw= From: Stefano Stabellini To: julien@xen.org Date: Thu, 26 Mar 2020 19:34:51 -0700 Message-Id: <20200327023451.20271-1-sstabellini@kernel.org> X-Mailer: git-send-email 2.17.1 Subject: [Xen-devel] [PATCH v2] xen/arm: implement GICD_I[S/C]ACTIVER reads X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: xen-devel@lists.xenproject.org, Peng Fan , Stefano Stabellini , Stefano Stabellini , Wei Xu Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" This is a simple implementation of GICD_ICACTIVER / GICD_ISACTIVER reads. It doesn't take into account the latest state of interrupts on other vCPUs. Only the current vCPU is up-to-date. A full solution is not possible because it would require synchronization among all vCPUs, which would be very expensive in terms or latency. Signed-off-by: Stefano Stabellini CC: Wei Xu CC: Peng Fan Signed-off-by: Jeff Kubascik Acked-by: Julien Grall --- Changes in v2: - improve commit message - do not invert result - use 1U - use common patter with vgic_rank_offset - move implementation into a separate function called vgic_isactiver - add vgic2 implementation - tested on vgic2 by hacking the Linux gicv2 driver --- xen/arch/arm/vgic-v2.c | 13 +++++++++++-- xen/arch/arm/vgic-v3.c | 15 ++++++++++++--- xen/arch/arm/vgic.c | 20 ++++++++++++++++++++ xen/include/asm-arm/vgic.h | 1 + 4 files changed, 44 insertions(+), 5 deletions(-) diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c index 64b141fea5..454408d11d 100644 --- a/xen/arch/arm/vgic-v2.c +++ b/xen/arch/arm/vgic-v2.c @@ -245,10 +245,19 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info, case VRANGE32(GICD_ICPENDR, GICD_ICPENDRN): goto read_as_zero; - /* Read the active status of an IRQ via GICD is not supported */ case VRANGE32(GICD_ISACTIVER, GICD_ISACTIVERN): + if ( dabt.size != DABT_WORD ) goto bad_width; + rank = vgic_rank_offset(v, 1, gicd_reg - GICD_ISACTIVER, DABT_WORD); + if ( rank == NULL ) goto read_as_zero; + *r = vgic_isactiver(v, 32 * rank->index); + return 1; + case VRANGE32(GICD_ICACTIVER, GICD_ICACTIVERN): - goto read_as_zero; + if ( dabt.size != DABT_WORD ) goto bad_width; + rank = vgic_rank_offset(v, 1, gicd_reg - GICD_ICACTIVER, DABT_WORD); + if ( rank == NULL ) goto read_as_zero; + *r = vgic_isactiver(v, 32 * rank->index); + return 1; case VRANGE32(GICD_IPRIORITYR, GICD_IPRIORITYRN): { diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c index 4e60ba15cc..a2cd39c45d 100644 --- a/xen/arch/arm/vgic-v3.c +++ b/xen/arch/arm/vgic-v3.c @@ -712,10 +712,19 @@ static int __vgic_v3_distr_common_mmio_read(const char *name, struct vcpu *v, case VRANGE32(GICD_ICPENDR, GICD_ICPENDR): goto read_as_zero; - /* Read the active status of an IRQ via GICD/GICR is not supported */ - case VRANGE32(GICD_ISACTIVER, GICD_ISACTIVER): + case VRANGE32(GICD_ISACTIVER, GICD_ISACTIVERN): + if ( dabt.size != DABT_WORD ) goto bad_width; + rank = vgic_rank_offset(v, 1, reg - GICD_ISACTIVER, DABT_WORD); + if ( rank == NULL ) goto read_as_zero; + *r = vgic_isactiver(v, 32 * rank->index); + return 1; + case VRANGE32(GICD_ICACTIVER, GICD_ICACTIVERN): - goto read_as_zero; + if ( dabt.size != DABT_WORD ) goto bad_width; + rank = vgic_rank_offset(v, 1, reg - GICD_ICACTIVER, DABT_WORD); + if ( rank == NULL ) goto read_as_zero; + *r = vgic_isactiver(v, 32 * rank->index); + return 1; case VRANGE32(GICD_IPRIORITYR, GICD_IPRIORITYRN): { diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c index 82f524a35c..d491fa38a5 100644 --- a/xen/arch/arm/vgic.c +++ b/xen/arch/arm/vgic.c @@ -423,6 +423,26 @@ void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n) } } +uint32_t vgic_isactiver(struct vcpu *v, unsigned int start_irq) +{ + struct pending_irq *p; + unsigned int irq; + uint32_t r = 0; + + /* + * The following won't reflect the latest status of interrupts on + * other vcpus. + */ + for ( irq = start_irq; irq < start_irq + 32; irq++ ) + { + p = irq_to_pending(v, irq); + if ( p != NULL && test_bit(GIC_IRQ_GUEST_ACTIVE, &p->status) ) + r |= 1U << (irq - start_irq); + } + + return r; +} + bool vgic_to_sgi(struct vcpu *v, register_t sgir, enum gic_sgi_mode irqmode, int virq, const struct sgi_target *target) { diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h index ce1e3c4bbd..a9e3f2fa60 100644 --- a/xen/include/asm-arm/vgic.h +++ b/xen/include/asm-arm/vgic.h @@ -288,6 +288,7 @@ extern struct vgic_irq_rank *vgic_rank_offset(struct vcpu *v, int b, int n, int extern struct vgic_irq_rank *vgic_rank_irq(struct vcpu *v, unsigned int irq); extern void vgic_disable_irqs(struct vcpu *v, uint32_t r, int n); extern void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n); +extern uint32_t vgic_isactiver(struct vcpu *v, unsigned int start_irq); extern void register_vgic_ops(struct domain *d, const struct vgic_ops *ops); int vgic_v2_init(struct domain *d, int *mmio_count); int vgic_v3_init(struct domain *d, int *mmio_count);