Received: by 2002:ac0:950c:0:0:0:0:0 with SMTP id f12csp2293839imc; Tue, 12 Mar 2019 10:45:55 -0700 (PDT) X-Google-Smtp-Source: APXvYqzp7rGizJTXaUcY+ChMvAeJhn0sJrtw2TzpPd3bo6NxcdtXjA2xdq4rfP4XpevkV6L57/K2 X-Received: by 2002:a17:902:4181:: with SMTP id f1mr41470944pld.280.1552412755104; Tue, 12 Mar 2019 10:45:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1552412755; cv=none; d=google.com; s=arc-20160816; b=kGM4gn5fm7gbxtb4yf+wzRVnS6M1oZA+ZRtki6/vCqyxezIVASEB3Lqx2M9tnJY7IH CAz1V3AXY2GAxwhGBJUQqWrLPyqFjU0S3r8zlDlz8I3uFID3pqyBKM1LwM7v9U3VldsV 8YexurIDQx/npg5DCC1A9Pcmav3sLeDIo37q1UtlmDGVwRypRkM9x89age1+46/bw5qi amDBcNBVYFKZ0EHZJOcwgdHivdizItOL2IQxYbGCfdVKi8/43Y4aeNl1u4vk9pwFSWH7 OHodASIiEenJkJ1Rd2tRclT9oTJSIDtuyRUIE2ODPl239WuMFK2GDSk29C6FXhDD8xnQ R+mA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=WgVdGrrTYCPj22/1yDrjeQstR7+U3lKusq2jHv+17Wo=; b=w6TE2XcscFxTGgvSABl0z0GA56bEWvyClAIQX6iU0FQ+wk5OAd4fRsRvBM0/QS0vHM lngdvEol7kchwoB9Vn1Aec1sh7/iaYDxjM90QAYlY1i7SpafMYeYsS/ltqTYz4znT3WP n6bV4VSGYbglK86GUp+VzQx/3znbDhd3pCIw/CALZG0mvRjzjCczH5TozVYH7/BklyZh 4IQEH3ry+GxXG1FSVOkElgt3Z1VqGRgjA4X+mgZDQgguPUdjUCmNVrX2tlsaMCWLxO4b ryOtZTi4uq7VtSM9AT77C1QAwTxsD8yDPzWLgTUuOfG2IZ1ZbYgC1/IWzLN7r9eufLao p3Zw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=M2QVypm8; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id n189si7734465pga.46.2019.03.12.10.45.39; Tue, 12 Mar 2019 10:45:55 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=M2QVypm8; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728823AbfCLRPi (ORCPT + 99 others); Tue, 12 Mar 2019 13:15:38 -0400 Received: from mail.kernel.org ([198.145.29.99]:54260 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728537AbfCLROy (ORCPT ); Tue, 12 Mar 2019 13:14:54 -0400 Received: from localhost (unknown [104.133.8.98]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id BB3A1206DF; Tue, 12 Mar 2019 17:14:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1552410892; bh=VCH/G+KIXd6g5L0dzj1SnSoVgCGgYq1HLrAKiUfCrps=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=M2QVypm8I2HSahIQA3qSdPStK1juAVnQ/dsMYF1mmZiEDDhRGrJXIr9fmiMyIFKpX MnzBpYaywB7XGqmz3o4BvNhuu9cKQLClFv/Eb7cM+G1BNGILRnn1ELZ5zCsPbE3jQe fWiGivM64fGKe63atJ+tB0j10gr3GD2bmsxFYb2M= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Heyi Guo , Heyi Guo , Marc Zyngier , Sasha Levin Subject: [PATCH 4.19 082/149] irqchip/gic-v4: Fix occasional VLPI drop Date: Tue, 12 Mar 2019 10:08:20 -0700 Message-Id: <20190312170356.573944329@linuxfoundation.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190312170349.421581206@linuxfoundation.org> References: <20190312170349.421581206@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review X-Patchwork-Hint: ignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.19-stable review patch. If anyone has any objections, please let me know. ------------------ [ Upstream commit 6479450f72c1391c03f08affe0d0110f41ae7ca0 ] 1. In current implementation, every VLPI will temporarily be mapped to the first CPU in system (normally CPU0) and then moved to the real scheduled CPU later. 2. So there is a time window and a VLPI may be sent to CPU0 instead of the real scheduled vCPU, in a multi-CPU virtual machine. 3. However, CPU0 may have not been scheduled as a virtual CPU after system boots up, so the value of its GICR_VPROPBASER is unknown at that moment. 4. If the INTID of VLPI is larger than 2^(GICR_VPROPBASER.IDbits+1), while IDbits is also in unknown state, GIC will behave as if the VLPI is out of range and simply drop it, which results in interrupt missing in Guest. As no code will clear GICR_VPROPBASER at runtime, we can safely initialize the IDbits field at boot time for each CPU to get rid of this issue. We also clear Valid bit of GICR_VPENDBASER in case any ancient programming gets left in and causes memory corrupting. A new function its_clear_vpend_valid() is added to reuse the code in its_vpe_deschedule(). Fixes: e643d8034036 ("irqchip/gic-v3-its: Add VPE scheduling") Signed-off-by: Heyi Guo Signed-off-by: Heyi Guo Signed-off-by: Marc Zyngier Signed-off-by: Sasha Levin --- drivers/irqchip/irq-gic-v3-its.c | 66 ++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 17 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 4c2246fe5dbe..d9a880108315 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1951,6 +1951,29 @@ static void its_free_pending_table(struct page *pt) get_order(max_t(u32, LPI_PENDBASE_SZ, SZ_64K))); } +static u64 its_clear_vpend_valid(void __iomem *vlpi_base) +{ + u32 count = 1000000; /* 1s! */ + bool clean; + u64 val; + + val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER); + val &= ~GICR_VPENDBASER_Valid; + gits_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER); + + do { + val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER); + clean = !(val & GICR_VPENDBASER_Dirty); + if (!clean) { + count--; + cpu_relax(); + udelay(1); + } + } while (!clean && count); + + return val; +} + static void its_cpu_init_lpis(void) { void __iomem *rbase = gic_data_rdist_rd_base(); @@ -2024,6 +2047,30 @@ static void its_cpu_init_lpis(void) val |= GICR_CTLR_ENABLE_LPIS; writel_relaxed(val, rbase + GICR_CTLR); + if (gic_rdists->has_vlpis) { + void __iomem *vlpi_base = gic_data_rdist_vlpi_base(); + + /* + * It's possible for CPU to receive VLPIs before it is + * sheduled as a vPE, especially for the first CPU, and the + * VLPI with INTID larger than 2^(IDbits+1) will be considered + * as out of range and dropped by GIC. + * So we initialize IDbits to known value to avoid VLPI drop. + */ + val = (LPI_NRBITS - 1) & GICR_VPROPBASER_IDBITS_MASK; + pr_debug("GICv4: CPU%d: Init IDbits to 0x%llx for GICR_VPROPBASER\n", + smp_processor_id(), val); + gits_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER); + + /* + * Also clear Valid bit of GICR_VPENDBASER, in case some + * ancient programming gets left in and has possibility of + * corrupting memory. + */ + val = its_clear_vpend_valid(vlpi_base); + WARN_ON(val & GICR_VPENDBASER_Dirty); + } + /* Make sure the GIC has seen the above */ dsb(sy); } @@ -2644,26 +2691,11 @@ static void its_vpe_schedule(struct its_vpe *vpe) static void its_vpe_deschedule(struct its_vpe *vpe) { void __iomem *vlpi_base = gic_data_rdist_vlpi_base(); - u32 count = 1000000; /* 1s! */ - bool clean; u64 val; - /* We're being scheduled out */ - val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER); - val &= ~GICR_VPENDBASER_Valid; - gits_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER); - - do { - val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER); - clean = !(val & GICR_VPENDBASER_Dirty); - if (!clean) { - count--; - cpu_relax(); - udelay(1); - } - } while (!clean && count); + val = its_clear_vpend_valid(vlpi_base); - if (unlikely(!clean && !count)) { + if (unlikely(val & GICR_VPENDBASER_Dirty)) { pr_err_ratelimited("ITS virtual pending table not cleaning\n"); vpe->idai = false; vpe->pending_last = true; -- 2.19.1