From patchwork Fri Jun 29 13:29:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luc Michel X-Patchwork-Id: 936893 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=greensocs.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; secure) header.d=greensocs.com header.i=@greensocs.com header.b="koWroJbm"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=greensocs.com header.i=@greensocs.com header.b="llcfmHSa"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=greensocs.com header.i=@greensocs.com header.b="llcfmHSa"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41HHnd6ZgTz9rvt for ; Fri, 29 Jun 2018 23:39:49 +1000 (AEST) Received: from localhost ([::1]:42198 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fYtcp-0006MP-GH for incoming@patchwork.ozlabs.org; Fri, 29 Jun 2018 09:39:47 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38106) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fYtUH-0007hX-B2 for qemu-devel@nongnu.org; Fri, 29 Jun 2018 09:31:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fYtUC-0007IF-K6 for qemu-devel@nongnu.org; Fri, 29 Jun 2018 09:30:57 -0400 Received: from greensocs.com ([193.104.36.180]:58618) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fYtU2-0006mf-Aw; Fri, 29 Jun 2018 09:30:42 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id A7A8B4434B6; Fri, 29 Jun 2018 15:30:38 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1530279038; bh=QszQPZXYcFkSBsQQnLZxtmc59qcfJEbtosKMiFwaW9Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=koWroJbm3H2MhVCGPRohwFDUdV09eB/V4+YQUF/azbk87yEEMXL5Z0lm8ZLUeWETD uT6t/ilESrfWQnUuhqQn+sdT5lx17iRFSeXGBZjEaOjOxBkjP6rPd/V2JRdNlPi66O 4m4IY4tob3qzFld78qEiwOksBhl20YHVimiuJ9hQ= 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=llcfmHSa; dkim=pass (1024-bit key) header.d=greensocs.com header.b=llcfmHSa 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 oGHT2P4Ts9TY; Fri, 29 Jun 2018 15:30:37 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id 9F5354434B1; Fri, 29 Jun 2018 15:30:37 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1530279037; bh=QszQPZXYcFkSBsQQnLZxtmc59qcfJEbtosKMiFwaW9Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=llcfmHSayx1GclAFdkF/XUQBPsVWGfMs8rmH9480QJwCQ6wgRKcSUH6ehg2bUVOmF sn9K7c/2TbEerKNgecNckBmZ2W6DlK716Rf9ACfnZDIN9urvewiRspVH7MgCNTz7RN c1+ZlYK8w0X0IGMl/55ve9Gyl77LB9Aqgggrhm5U= Received: from michell-laptop.hive.antfield.fr (LFbn-LYO-1-488-36.w2-7.abo.wanadoo.fr [2.7.77.36]) (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 314144434B5; Fri, 29 Jun 2018 15:30:37 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1530279037; bh=QszQPZXYcFkSBsQQnLZxtmc59qcfJEbtosKMiFwaW9Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=llcfmHSayx1GclAFdkF/XUQBPsVWGfMs8rmH9480QJwCQ6wgRKcSUH6ehg2bUVOmF sn9K7c/2TbEerKNgecNckBmZ2W6DlK716Rf9ACfnZDIN9urvewiRspVH7MgCNTz7RN c1+ZlYK8w0X0IGMl/55ve9Gyl77LB9Aqgggrhm5U= From: Luc Michel To: qemu-devel@nongnu.org Date: Fri, 29 Jun 2018 15:29:45 +0200 Message-Id: <20180629132954.24269-12-luc.michel@greensocs.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180629132954.24269-1-luc.michel@greensocs.com> References: <20180629132954.24269-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 v3 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+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" 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 d61c2dd557..a7577ac073 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -366,17 +366,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); @@ -388,6 +415,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. @@ -396,28 +425,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;