From patchwork Sat Jul 14 17:15:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luc Michel X-Patchwork-Id: 10524809 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 508AB6032C for ; Sat, 14 Jul 2018 17:25:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 34FA328ACE for ; Sat, 14 Jul 2018 17:25:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 290F528AD1; Sat, 14 Jul 2018 17:25:20 +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=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 9C85D28ACE for ; Sat, 14 Jul 2018 17:25:19 +0000 (UTC) Received: from localhost ([::1]:42112 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1feOII-0004Z0-S6 for patchwork-qemu-devel@patchwork.kernel.org; Sat, 14 Jul 2018 13:25:18 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38531) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1feO9x-0005qz-47 for qemu-devel@nongnu.org; Sat, 14 Jul 2018 13:16:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1feO9u-0004fT-HB for qemu-devel@nongnu.org; Sat, 14 Jul 2018 13:16:41 -0400 Received: from greensocs.com ([193.104.36.180]:57317) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1feO9j-0004Qd-G7; Sat, 14 Jul 2018 13:16:27 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id 7B1E6C7AF0; Sat, 14 Jul 2018 19:16:26 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1531588586; bh=hjvPhdX2GCICeVw8K3GCAmxUM1WCOlflGQnWMSsw2MM=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=bKcLHemB4Cnjuf3n8LcZ3W9ajZndshxtZOBaLHIF3H7qONqOpK/TuouCnB1epJcmG bcJ3OEtK3HfAtUKQ4G64lVnPAXYFiKuaL8GYNScukpOUX11EWMnfpZuNa05EapwvqH zo03s9mOAtccKUINCKTHPTaw+5TdGME4Qm7/Q1Uo= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=ddEuQh8m; dkim=pass (1024-bit key) header.d=greensocs.com header.b=ddEuQh8m Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id PcE-qdWwXLSY; Sat, 14 Jul 2018 19:16:25 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id 914E0C7AF9; Sat, 14 Jul 2018 19:16:25 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1531588585; bh=hjvPhdX2GCICeVw8K3GCAmxUM1WCOlflGQnWMSsw2MM=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=ddEuQh8mrW50kSlfi30m5SK+z1AMLnChbgg3aM46jdClMN1nQuBYsgjVJdhx7/Aeo Vx6Xfdw1yvRhVxJGZEehX1ruCkE6K4CTccACez5ypj8xfiIIdskKmEOVFhUMZn1qYx XJ1BHeDrMimfaiZL/8NeIztPfnNoLNW3b3kT2GdQ= Received: from localhost.localdomain (unknown [105.98.38.216]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: luc.michel@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id D688AC7ADD; Sat, 14 Jul 2018 19:16:24 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1531588585; bh=hjvPhdX2GCICeVw8K3GCAmxUM1WCOlflGQnWMSsw2MM=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=ddEuQh8mrW50kSlfi30m5SK+z1AMLnChbgg3aM46jdClMN1nQuBYsgjVJdhx7/Aeo Vx6Xfdw1yvRhVxJGZEehX1ruCkE6K4CTccACez5ypj8xfiIIdskKmEOVFhUMZn1qYx XJ1BHeDrMimfaiZL/8NeIztPfnNoLNW3b3kT2GdQ= From: Luc Michel To: qemu-devel@nongnu.org Date: Sat, 14 Jul 2018 19:15:52 +0200 Message-Id: <20180714171601.5734-12-luc.michel@greensocs.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180714171601.5734-1-luc.michel@greensocs.com> References: <20180714171601.5734-1-luc.michel@greensocs.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v4 11/20] 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: , Cc: Peter Maydell , mark.burton@greensocs.com, saipava@xilinx.com, edgari@xilinx.com, qemu-arm@nongnu.org, Jan Kiszka , Luc Michel Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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 60704cabbb..be9e2594d9 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 group) s->running_priority[cpu] = gic_get_prio_from_apr_bits(s, cpu); } +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] != 0); + src = ctz32(s->sgi_pending[irq][cpu]); + s->sgi_pending[irq][cpu] &= ~(1 << src); + if (s->sgi_pending[irq][cpu] == 0) { + gic_clear_pending(s, irq, cpu); + } + ret = irq | ((src & 0x7) << 10); + } else { + uint32_t *lr_entry = gic_get_lr_entry(s, irq, cpu); + src = GICH_LR_CPUID(*lr_entry); + + gic_clear_pending(s, irq, cpu); + ret = irq | (src << 10); + } + + return ret; +} + uint32_t gic_acknowledge_irq(GICState *s, int cpu, MemTxAttrs attrs) { - int ret, irq, src; - int cm = 1 << cpu; + int ret, irq; /* gic_get_current_pending_irq() will return 1022 or 1023 appropriately * for the case where this GIC supports grouping and the pending interrupt * is in the wrong group. */ irq = 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); if (irq >= 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, MemTxAttrs attrs) return 1023; } + gic_activate_irq(s, cpu, irq); + if (s->revision == REV_11MPCORE) { /* Clear pending flags for both level and edge triggered interrupts. * Level triggered IRQs will be reasserted once they become inactive. @@ -395,28 +424,13 @@ uint32_t gic_acknowledge_irq(GICState *s, int cpu, MemTxAttrs attrs) ret = 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 pending - * state on this CPU if the SGI is not pending from any CPUs. - */ - assert(s->sgi_pending[irq][cpu] != 0); - src = ctz32(s->sgi_pending[irq][cpu]); - s->sgi_pending[irq][cpu] &= ~(1 << src); - if (s->sgi_pending[irq][cpu] == 0) { - gic_clear_pending(s, irq, cpu); - } - ret = irq | ((src & 0x7) << 10); + ret = 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 = irq; } } - gic_activate_irq(s, cpu, irq); gic_update(s); DPRINTF("ACK %d\n", irq); return ret;