From nobody Wed Apr 16 13:40:02 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1534273034590684.2777002959486; Tue, 14 Aug 2018 11:57:14 -0700 (PDT) Received: from localhost ([::1]:45803 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fpeVF-0007VS-GM for importer@patchew.org; Tue, 14 Aug 2018 14:57:13 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52585) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fpdvK-0004mZ-QJ for qemu-devel@nongnu.org; Tue, 14 Aug 2018 14:21:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fpdu0-0006ge-Tu for qemu-devel@nongnu.org; Tue, 14 Aug 2018 14:20:06 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:44416) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fpdu0-0006gE-JI for qemu-devel@nongnu.org; Tue, 14 Aug 2018 14:18:44 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1fpdtz-0007H6-Ee for qemu-devel@nongnu.org; Tue, 14 Aug 2018 19:18:43 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Tue, 14 Aug 2018 19:17:52 +0100 Message-Id: <20180814181815.23348-23-peter.maydell@linaro.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180814181815.23348-1-peter.maydell@linaro.org> References: <20180814181815.23348-1-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 22/45] intc/arm_gic: Implement virtualization extensions in gic_acknowledge_irq X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Luc Michel Implement virtualization extensions in the gic_acknowledge_irq() function. This function changes the state of the highest priority IRQ from pending to active. When the current CPU is a vCPU, modifying the state of an IRQ modifies the corresponding LR entry. However if we clear the pending flag before setting the active one, we lose track of the LR entry as it becomes invalid. The next call to gic_get_lr_entry() will fail. To overcome this issue, we call gic_activate_irq() before gic_clear_pending(). This does not change the general behaviour of gic_acknowledge_irq. We also move the SGI case in gic_clear_pending_sgi() to enhance code readability as the virtualization extensions support adds a if-else level. Signed-off-by: Luc Michel Reviewed-by: Peter Maydell Message-id: 20180727095421.386-12-luc.michel@greensocs.com Signed-off-by: Peter Maydell --- hw/intc/arm_gic.c | 52 ++++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index de73dc9f54b..d80acde989f 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -365,17 +365,44 @@ static void gic_drop_prio(GICState *s, int cpu, int g= roup) s->running_priority[cpu] =3D gic_get_prio_from_apr_bits(s, cpu); } =20 +static inline uint32_t gic_clear_pending_sgi(GICState *s, int irq, int cpu) +{ + int src; + uint32_t ret; + + if (!gic_is_vcpu(cpu)) { + /* Lookup the source CPU for the SGI and clear this in the + * sgi_pending map. Return the src and clear the overall pending + * state on this CPU if the SGI is not pending from any CPUs. + */ + assert(s->sgi_pending[irq][cpu] !=3D 0); + src =3D ctz32(s->sgi_pending[irq][cpu]); + s->sgi_pending[irq][cpu] &=3D ~(1 << src); + if (s->sgi_pending[irq][cpu] =3D=3D 0) { + gic_clear_pending(s, irq, cpu); + } + ret =3D irq | ((src & 0x7) << 10); + } else { + uint32_t *lr_entry =3D gic_get_lr_entry(s, irq, cpu); + src =3D GICH_LR_CPUID(*lr_entry); + + gic_clear_pending(s, irq, cpu); + ret =3D irq | (src << 10); + } + + return ret; +} + uint32_t gic_acknowledge_irq(GICState *s, int cpu, MemTxAttrs attrs) { - int ret, irq, src; - int cm =3D 1 << cpu; + int ret, irq; =20 /* gic_get_current_pending_irq() will return 1022 or 1023 appropriately * for the case where this GIC supports grouping and the pending inter= rupt * is in the wrong group. */ irq =3D gic_get_current_pending_irq(s, cpu, attrs); - trace_gic_acknowledge_irq(cpu, irq); + trace_gic_acknowledge_irq(gic_get_vcpu_real_id(cpu), irq); =20 if (irq >=3D GIC_MAXIRQ) { DPRINTF("ACK, no pending interrupt or it is hidden: %d\n", irq); @@ -387,6 +414,8 @@ uint32_t gic_acknowledge_irq(GICState *s, int cpu, MemT= xAttrs attrs) return 1023; } =20 + gic_activate_irq(s, cpu, irq); + if (s->revision =3D=3D REV_11MPCORE) { /* Clear pending flags for both level and edge triggered interrupt= s. * Level triggered IRQs will be reasserted once they become inacti= ve. @@ -395,28 +424,13 @@ uint32_t gic_acknowledge_irq(GICState *s, int cpu, Me= mTxAttrs attrs) ret =3D irq; } else { if (irq < GIC_NR_SGIS) { - /* Lookup the source CPU for the SGI and clear this in the - * sgi_pending map. Return the src and clear the overall pend= ing - * state on this CPU if the SGI is not pending from any CPUs. - */ - assert(s->sgi_pending[irq][cpu] !=3D 0); - src =3D ctz32(s->sgi_pending[irq][cpu]); - s->sgi_pending[irq][cpu] &=3D ~(1 << src); - if (s->sgi_pending[irq][cpu] =3D=3D 0) { - gic_clear_pending(s, irq, cpu); - } - ret =3D irq | ((src & 0x7) << 10); + ret =3D gic_clear_pending_sgi(s, irq, cpu); } else { - /* Clear pending state for both level and edge triggered - * interrupts. (level triggered interrupts with an active line - * remain pending, see gic_test_pending) - */ gic_clear_pending(s, irq, cpu); ret =3D irq; } } =20 - gic_activate_irq(s, cpu, irq); gic_update(s); DPRINTF("ACK %d\n", irq); return ret; --=20 2.18.0