From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.2 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9CE8BC433E6 for ; Wed, 17 Mar 2021 01:06:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 75D5C64F9F for ; Wed, 17 Mar 2021 01:06:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229469AbhCQBF4 (ORCPT ); Tue, 16 Mar 2021 21:05:56 -0400 Received: from mail.kernel.org ([198.145.29.99]:40646 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232448AbhCQA7n (ORCPT ); Tue, 16 Mar 2021 20:59:43 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 3A2A264F97; Wed, 17 Mar 2021 00:59:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1615942781; bh=ittF78QUB3hFpptyQHSI/xEH/m7sTe6Ft8zrzq/Legs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MbFOAZs/xKcb9L1VPIFwe6O3jUtaYREo3DCTEK50hmHjkQAVqMTGiDUqSZdUADN4C HHHsJ/kWWn0KC6yBxrfnhuLzz0ngZvblXAQ0DtqY4KumOppXJhFQJimHcHjZEsIPXe VkIKdH6Rg9hydZmfjDa1sTb/ZW8IXyIGwUIlhVKuCY8rZ7OhoHesyeUrM3MXPrgEOP 8Y2ZRrah7EQOk0AVAdQQXdjtMAaHqg6g6LdgPOqe02vNn2ZvQO8r/wh+4gXkfWP/L3 bku4t++dAkTRtkFEJlF6jtqGYpohHX7XyDscLqOpt2DnKDHO+MQr3fVXwXyksYbUj4 vqDmRs6DNS7aQ== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Rob Gardner , Anatoly Pugachev , "David S . Miller" , Sasha Levin , sparclinux@vger.kernel.org Subject: [PATCH AUTOSEL 4.14 16/21] sparc64: Fix opcode filtering in handling of no fault loads Date: Tue, 16 Mar 2021 20:59:15 -0400 Message-Id: <20210317005920.726931-16-sashal@kernel.org> X-Mailer: git-send-email 2.30.1 In-Reply-To: <20210317005920.726931-1-sashal@kernel.org> References: <20210317005920.726931-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Rob Gardner [ Upstream commit e5e8b80d352ec999d2bba3ea584f541c83f4ca3f ] is_no_fault_exception() has two bugs which were discovered via random opcode testing with stress-ng. Both are caused by improper filtering of opcodes. The first bug can be triggered by a floating point store with a no-fault ASI, for instance "sta %f0, [%g0] #ASI_PNF", opcode C1A01040. The code first tests op3[5] (0x1000000), which denotes a floating point instruction, and then tests op3[2] (0x200000), which denotes a store instruction. But these bits are not mutually exclusive, and the above mentioned opcode has both bits set. The intent is to filter out stores, so the test for stores must be done first in order to have any effect. The second bug can be triggered by a floating point load with one of the invalid ASI values 0x8e or 0x8f, which pass this check in is_no_fault_exception(): if ((asi & 0xf2) == ASI_PNF) An example instruction is "ldqa [%l7 + %o7] #ASI 0x8f, %f38", opcode CF95D1EF. Asi values greater than 0x8b (ASI_SNFL) are fatal in handle_ldf_stq(), and is_no_fault_exception() must not allow these invalid asi values to make it that far. In both of these cases, handle_ldf_stq() reacts by calling sun4v_data_access_exception() or spitfire_data_access_exception(), which call is_no_fault_exception() and results in an infinite recursion. Signed-off-by: Rob Gardner Tested-by: Anatoly Pugachev Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- arch/sparc/kernel/traps_64.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c index 0a56dc257cb9..6ab9b87dbca8 100644 --- a/arch/sparc/kernel/traps_64.c +++ b/arch/sparc/kernel/traps_64.c @@ -290,14 +290,13 @@ bool is_no_fault_exception(struct pt_regs *regs) asi = (regs->tstate >> 24); /* saved %asi */ else asi = (insn >> 5); /* immediate asi */ - if ((asi & 0xf2) == ASI_PNF) { - if (insn & 0x1000000) { /* op3[5:4]=3 */ - handle_ldf_stq(insn, regs); - return true; - } else if (insn & 0x200000) { /* op3[2], stores */ + if ((asi & 0xf6) == ASI_PNF) { + if (insn & 0x200000) /* op3[2], stores */ return false; - } - handle_ld_nf(insn, regs); + if (insn & 0x1000000) /* op3[5:4]=3 (fp) */ + handle_ldf_stq(insn, regs); + else + handle_ld_nf(insn, regs); return true; } } -- 2.30.1