From nobody Mon Sep 15 18:02:41 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C9FC0C678D6 for ; Wed, 11 Jan 2023 17:21:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235681AbjAKRVE (ORCPT ); Wed, 11 Jan 2023 12:21:04 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49294 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234544AbjAKRUu (ORCPT ); Wed, 11 Jan 2023 12:20:50 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CB8E23057E; Wed, 11 Jan 2023 09:20:49 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 856EBB81C8A; Wed, 11 Jan 2023 17:20:48 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id F28B5C433EF; Wed, 11 Jan 2023 17:20:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673457647; bh=KRbUD/DoZCTDQnpByHlFlnPMc8QCP2Jn97CVBSFQEdU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KA9Tw53YhdOGsvk3g+hlq8uCbsDTYI6F7Vkf1KEVye3JmHxcYO3VNbvGpSW/ZrGfI fX28RfMxvvX3tyEPeChS/dDgFTCRjYT/hrx5SrTxlmWmS3XKZy+xoH8rvYkMtxyvbs gjZY9M2awgxNvZE0iJy2zngMzz5Np0pWUEUW63DKEi7jORdf6jFLY7Ke74G+SqiPVR WBmwKgn3mj2+ONqvOKgvJqCrP6tt0psl+8Qpw1DPkmpXvRQ97wYiIXXeRfzEJddNvI YSHK8yZCGOKatTi7ly3InyB3Lv1bKa7jHyRe9YIyknwmQ7CFMABeU/jPKIuuVFqDXI xebX0eOKIQoBA== From: Jisheng Zhang To: Paul Walmsley , Palmer Dabbelt , Albert Ou , Anup Patel , Atish Patra , Heiko Stuebner Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, kvm-riscv@lists.infradead.org, Heiko Stuebner Subject: [PATCH v3 01/13] riscv: fix jal offsets in patched alternatives Date: Thu, 12 Jan 2023 01:10:15 +0800 Message-Id: <20230111171027.2392-2-jszhang@kernel.org> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20230111171027.2392-1-jszhang@kernel.org> References: <20230111171027.2392-1-jszhang@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Alternatives live in a different section, so offsets used by jal instruction will point to wrong locations after the patch got applied. Similar to arm64, adjust the location to consider that offset. Co-developed-by: Heiko Stuebner Signed-off-by: Heiko Stuebner Signed-off-by: Jisheng Zhang Reviewed-by: Andrew Jones Reviewed-by: Conor Dooley --- arch/riscv/include/asm/insn.h | 27 +++++++++++++++++++++++++++ arch/riscv/kernel/alternative.c | 27 +++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/arch/riscv/include/asm/insn.h b/arch/riscv/include/asm/insn.h index 98453535324a..1d2df245d0bd 100644 --- a/arch/riscv/include/asm/insn.h +++ b/arch/riscv/include/asm/insn.h @@ -291,6 +291,33 @@ static __always_inline bool riscv_insn_is_branch(u32 c= ode) (RVC_X(x_, RVC_B_IMM_7_6_OPOFF, RVC_B_IMM_7_6_MASK) << RVC_B_IMM_7_6_OFF)= | \ (RVC_IMM_SIGN(x_) << RVC_B_IMM_SIGN_OFF); }) =20 +/* + * Get the immediate from a J-type instruction. + * + * @insn: instruction to process + * Return: immediate + */ +static inline s32 riscv_insn_extract_jtype_imm(u32 insn) +{ + return RV_EXTRACT_JTYPE_IMM(insn); +} + +/* + * Update a J-type instruction with an immediate value. + * + * @insn: pointer to the jtype instruction + * @imm: the immediate to insert into the instruction + */ +static inline void riscv_insn_insert_jtype_imm(u32 *insn, s32 imm) +{ + /* drop the old IMMs, all jal IMM bits sit at 31:12 */ + *insn &=3D ~GENMASK(31, 12); + *insn |=3D (RV_X(imm, RV_J_IMM_10_1_OFF, RV_J_IMM_10_1_MASK) << RV_J_IMM_= 10_1_OPOFF) | + (RV_X(imm, RV_J_IMM_11_OFF, RV_J_IMM_11_MASK) << RV_J_IMM_11_OPOFF) | + (RV_X(imm, RV_J_IMM_19_12_OFF, RV_J_IMM_19_12_MASK) << RV_J_IMM_19_12_O= POFF) | + (RV_X(imm, RV_J_IMM_SIGN_OFF, 1) << RV_J_IMM_SIGN_OPOFF); +} + /* * Put together one immediate from a U-type and I-type instruction pair. * diff --git a/arch/riscv/kernel/alternative.c b/arch/riscv/kernel/alternativ= e.c index 6212ea0eed72..3d4f1f32c7f6 100644 --- a/arch/riscv/kernel/alternative.c +++ b/arch/riscv/kernel/alternative.c @@ -79,6 +79,21 @@ static void riscv_alternative_fix_auipc_jalr(void *ptr, = u32 auipc_insn, patch_text_nosync(ptr, call, sizeof(u32) * 2); } =20 +static void riscv_alternative_fix_jal(void *ptr, u32 jal_insn, int patch_o= ffset) +{ + s32 imm; + + /* get and adjust new target address */ + imm =3D riscv_insn_extract_jtype_imm(jal_insn); + imm -=3D patch_offset; + + /* update instruction */ + riscv_insn_insert_jtype_imm(&jal_insn, imm); + + /* patch the call place again */ + patch_text_nosync(ptr, &jal_insn, sizeof(u32)); +} + void riscv_alternative_fix_offsets(void *alt_ptr, unsigned int len, int patch_offset) { @@ -106,6 +121,18 @@ void riscv_alternative_fix_offsets(void *alt_ptr, unsi= gned int len, riscv_alternative_fix_auipc_jalr(alt_ptr + i * sizeof(u32), insn, insn2, patch_offset); } + + if (riscv_insn_is_jal(insn)) { + s32 imm =3D riscv_insn_extract_jtype_imm(insn); + + /* Don't modify jumps inside the alternative block */ + if ((alt_ptr + i * sizeof(u32) + imm) >=3D alt_ptr && + (alt_ptr + i * sizeof(u32) + imm) < (alt_ptr + len)) + continue; + + riscv_alternative_fix_jal(alt_ptr + i * sizeof(u32), + insn, patch_offset); + } } } =20 --=20 2.38.1