Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp1992915imm; Thu, 24 May 2018 04:10:36 -0700 (PDT) X-Google-Smtp-Source: AB8JxZqCeL8ooFr5deuOrAMBMVpVsp9lrHbg8BHpHxEho0kiXVXkPzgqyqySVeyu5sYGB4dy/mVz X-Received: by 2002:a17:902:822:: with SMTP id 31-v6mr7027091plk.172.1527160236503; Thu, 24 May 2018 04:10:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527160236; cv=none; d=google.com; s=arc-20160816; b=wRHX2X7pPxjZxkDXjeQbu2O4fY8k8SU/XRsu5buHRKzoXmT422WLe3ZQzo1Tk5n/vn O/uYsVvN4LjT8kQboX8XTEK7Gfi9DkmQ7slD6XYCKNwRiyiic3ERyPKK/AK+Q2Q7pSY5 1zLih62o9ldHKGDkAyUKDYqqsc5RVZQo9+tslvjPKoraA+LX2d3v/I5mh9T6fWT3u3my 0T8Taz4qbYJnbrkqsvT5Y0iSwLVHinBMdrPsENlfcVGDq5aLlW8X9Dn/Ov3GMIf3I42b thrssI7hLFym735EJfm4aDI4l/GCnnn2fBEOH3BHiVgWCWgxanvOXVNsXtkqP6nx3X2Z /Csw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from:dkim-signature :arc-authentication-results; bh=Fi1qP1bw/NHCleySZhDU5zWuFgw3hubjH7x5OC0+RIU=; b=xnAbrbS858LiEv9+pm9s+38lzx571kaiRxE6HxF1eHI4S5h9Qmhx5df2jZrosNypD9 A53NxTjIKEDK6IWW3wL0g+T+aCiAYrAMH+9WjtS81XHhSFZkhsZPRFH9FmV2CFSvRtE8 ZMl4UxDTMPcYYYVxOhXM66jv5snxBKCXOxXHJfi7lvMTusn5zEhaEkyOTIZ9YZzMMYOD 1jC7QCSPxyN0Jn+P8F7bL4U6xiNh6PVNtsUP2PsX0mtUu57aO8N+11sXGfxOLHiEfaF8 aCXRg5HFJblUWyZhiFnhQAHz+SJiiVr8u4aT2z1HtDtcdFdsuG7mehYX23NI6ZezDVRn b6kA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=Wz2/jjaP; 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 2-v6si21309779pfk.287.2018.05.24.04.09.59; Thu, 24 May 2018 04:10:36 -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=Wz2/jjaP; 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 S1032953AbeEXLIE (ORCPT + 99 others); Thu, 24 May 2018 07:08:04 -0400 Received: from mail.kernel.org ([198.145.29.99]:34908 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S968223AbeEXJyq (ORCPT ); Thu, 24 May 2018 05:54:46 -0400 Received: from localhost (LFbn-1-12247-202.w90-92.abo.wanadoo.fr [90.92.61.202]) (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 E9A4E208A0; Thu, 24 May 2018 09:54:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1527155685; bh=7A/Eb0BswYwjSYigdAA2e1DN4PIeRbm0Z8+OlieD/yM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Wz2/jjaPU0gLF6aiQ4hhEeZaumuTsUbb+a6EvlD5OA6KMOUh+1K9wHX0ekUSOP4vN qk6HfM+RZx0KKAX1p3tQ3bneLVrG5Ad2DyFc5VwLZ54eyIHPONPfmZjFWO0YXsN5z6 plfZlWQn4ad+jO7X90vMj9X4O64YlxWi2Duf7zXw= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Greg Kroah-Hartman , Martin Schwidefsky Subject: [PATCH 4.14 044/165] s390: extend expoline to BC instructions Date: Thu, 24 May 2018 11:37:30 +0200 Message-Id: <20180524093623.805173601@linuxfoundation.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180524093621.979359379@linuxfoundation.org> References: <20180524093621.979359379@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.14-stable review patch. If anyone has any objections, please let me know. ------------------ From: Martin Schwidefsky [ Upstream commit 6deaa3bbca804b2a3627fd685f75de64da7be535 ] The BPF JIT uses a 'b (%r)' instruction in the definition of the sk_load_word and sk_load_half functions. Add support for branch-on-condition instructions contained in the thunk code of an expoline. Signed-off-by: Martin Schwidefsky Signed-off-by: Greg Kroah-Hartman --- arch/s390/include/asm/nospec-insn.h | 57 ++++++++++++++++++++++++++++++++++++ arch/s390/kernel/nospec-branch.c | 25 ++++++++++++--- 2 files changed, 77 insertions(+), 5 deletions(-) --- a/arch/s390/include/asm/nospec-insn.h +++ b/arch/s390/include/asm/nospec-insn.h @@ -34,10 +34,18 @@ _LC_BR_R1 = __LC_BR_R1 __THUNK_PROLOG_NAME __s390x_indirect_jump_r\r2\()use_r\r1 .endm + .macro __THUNK_PROLOG_BC d0,r1,r2 + __THUNK_PROLOG_NAME __s390x_indirect_branch_\d0\()_\r2\()use_\r1 + .endm + .macro __THUNK_BR r1,r2 jg __s390x_indirect_jump_r\r2\()use_r\r1 .endm + .macro __THUNK_BC d0,r1,r2 + jg __s390x_indirect_branch_\d0\()_\r2\()use_\r1 + .endm + .macro __THUNK_BRASL r1,r2,r3 brasl \r1,__s390x_indirect_jump_r\r3\()use_r\r2 .endm @@ -80,6 +88,23 @@ _LC_BR_R1 = __LC_BR_R1 .endif .endm + .macro __DECODE_DRR expand,disp,reg,ruse + .set __decode_fail,1 + .irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 + .ifc \reg,%r\r1 + .irp r2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 + .ifc \ruse,%r\r2 + \expand \disp,\r1,\r2 + .set __decode_fail,0 + .endif + .endr + .endif + .endr + .if __decode_fail == 1 + .error "__DECODE_DRR failed" + .endif + .endm + .macro __THUNK_EX_BR reg,ruse # Be very careful when adding instructions to this macro! # The ALTERNATIVE replacement code has a .+10 which targets @@ -100,12 +125,30 @@ _LC_BR_R1 = __LC_BR_R1 555: br \reg .endm + .macro __THUNK_EX_BC disp,reg,ruse +#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES + exrl 0,556f + j . +#else + larl \ruse,556f + ex 0,0(\ruse) + j . +#endif +556: b \disp(\reg) + .endm + .macro GEN_BR_THUNK reg,ruse=%r1 __DECODE_RR __THUNK_PROLOG_BR,\reg,\ruse __THUNK_EX_BR \reg,\ruse __THUNK_EPILOG .endm + .macro GEN_B_THUNK disp,reg,ruse=%r1 + __DECODE_DRR __THUNK_PROLOG_BC,\disp,\reg,\ruse + __THUNK_EX_BC \disp,\reg,\ruse + __THUNK_EPILOG + .endm + .macro BR_EX reg,ruse=%r1 557: __DECODE_RR __THUNK_BR,\reg,\ruse .pushsection .s390_indirect_branches,"a",@progbits @@ -113,6 +156,13 @@ _LC_BR_R1 = __LC_BR_R1 .popsection .endm + .macro B_EX disp,reg,ruse=%r1 +558: __DECODE_DRR __THUNK_BC,\disp,\reg,\ruse + .pushsection .s390_indirect_branches,"a",@progbits + .long 558b-. + .popsection + .endm + .macro BASR_EX rsave,rtarget,ruse=%r1 559: __DECODE_RRR __THUNK_BRASL,\rsave,\rtarget,\ruse .pushsection .s390_indirect_branches,"a",@progbits @@ -124,10 +174,17 @@ _LC_BR_R1 = __LC_BR_R1 .macro GEN_BR_THUNK reg,ruse=%r1 .endm + .macro GEN_B_THUNK disp,reg,ruse=%r1 + .endm + .macro BR_EX reg,ruse=%r1 br \reg .endm + .macro B_EX disp,reg,ruse=%r1 + b \disp(\reg) + .endm + .macro BASR_EX rsave,rtarget,ruse=%r1 basr \rsave,\rtarget .endm --- a/arch/s390/kernel/nospec-branch.c +++ b/arch/s390/kernel/nospec-branch.c @@ -94,7 +94,6 @@ static void __init_or_module __nospec_re s32 *epo; /* Second part of the instruction replace is always a nop */ - memcpy(insnbuf + 2, (char[]) { 0x47, 0x00, 0x00, 0x00 }, 4); for (epo = start; epo < end; epo++) { instr = (u8 *) epo + *epo; if (instr[0] == 0xc0 && (instr[1] & 0x0f) == 0x04) @@ -115,18 +114,34 @@ static void __init_or_module __nospec_re br = thunk + (*(int *)(thunk + 2)) * 2; else continue; - if (br[0] != 0x07 || (br[1] & 0xf0) != 0xf0) + /* Check for unconditional branch 0x07f? or 0x47f???? */ + if ((br[0] & 0xbf) != 0x07 || (br[1] & 0xf0) != 0xf0) continue; + + memcpy(insnbuf + 2, (char[]) { 0x47, 0x00, 0x07, 0x00 }, 4); switch (type) { case BRCL_EXPOLINE: - /* brcl to thunk, replace with br + nop */ insnbuf[0] = br[0]; insnbuf[1] = (instr[1] & 0xf0) | (br[1] & 0x0f); + if (br[0] == 0x47) { + /* brcl to b, replace with bc + nopr */ + insnbuf[2] = br[2]; + insnbuf[3] = br[3]; + } else { + /* brcl to br, replace with bcr + nop */ + } break; case BRASL_EXPOLINE: - /* brasl to thunk, replace with basr + nop */ - insnbuf[0] = 0x0d; insnbuf[1] = (instr[1] & 0xf0) | (br[1] & 0x0f); + if (br[0] == 0x47) { + /* brasl to b, replace with bas + nopr */ + insnbuf[0] = 0x4d; + insnbuf[2] = br[2]; + insnbuf[3] = br[3]; + } else { + /* brasl to br, replace with basr + nop */ + insnbuf[0] = 0x0d; + } break; }