From patchwork Sun Jan 15 15:49:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jisheng Zhang X-Patchwork-Id: 43861 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp799861wrn; Sun, 15 Jan 2023 08:01:47 -0800 (PST) X-Google-Smtp-Source: AMrXdXtQsr1cPn5TLTDzwY4MEIe82t56yE+SgRxdIanWWrx6BYmaucfxzHZ1xGNNLSRQgmNafI4T X-Received: by 2002:a17:907:c98a:b0:85f:5d72:183f with SMTP id uj10-20020a170907c98a00b0085f5d72183fmr13199056ejc.56.1673798507806; Sun, 15 Jan 2023 08:01:47 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1673798507; cv=none; d=google.com; s=arc-20160816; b=0+f9FNLtcnVocfba4TrbMVzx5yJLUXLdwY9fQ8p/eSmDFLLS839jpZcrIs1p4b8PXz +Ga/HK5R5fUKMf2bY5UPid/SJc34qiZeZn9n95p81XJaMk5m/rNhg9KdH9fNhFK48TYS ED9iIjHjeSSAEVZ7vnpahGDzHLo0H1YrTe5ZVK0zLW91lP/1czmw7e331s3SbzwPokGQ HM7Oca+FbYEvA+kMSgdadFEVRSK7Hr3KPCCKtz3bVAWSJlWDEMv6nho6XAHGPYw5g/vg dhJhEpegIeOcAmcgu6SFECjkrTcC77IcjOrepHqjiKpMhxgS1495a1sds54J9lVWFfIo 3zBw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=3GFUD4izrqwdBDc7hm7Ep2Bxw43o9R/H8xeY+PNCM4w=; b=RMXHyK/k/cpvGUygc1SMyNSm/LBJzagNS1mkzvc8oebMzqX5ES5mpcYo230DWYicAR MtQbfnUNkvSuML1gE7I600u45oxp8huI9IfxPMTeAYI/QvMf9GBNEjrDdqSVQRgsETH5 lNGKVZ8oO4lcV/VtdYnYXeWon9Gr/r0VSGcpfgDhCCR9MlOsGle7QHA2fdjXDZiLehIz rw3sN+jNL3WT0tTsymUheAucerBWpBRW51gpC/fzsWlkerKf3pyrTP2qVETPpco3VK2f Ux+YyPWlDdxHC9OMHc/bDuEKXd3X24EA7TXbrxYapEOHVXG7oGagzML9fE5wr8hCteFi 1oLg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=LFfsE9CB; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id ww2-20020a170907084200b007c01839ded7si4748565ejb.993.2023.01.15.08.01.22; Sun, 15 Jan 2023 08:01:47 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=LFfsE9CB; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230411AbjAOQAZ (ORCPT + 99 others); Sun, 15 Jan 2023 11:00:25 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59456 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231280AbjAOQAU (ORCPT ); Sun, 15 Jan 2023 11:00:20 -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 9CFBDF76D; Sun, 15 Jan 2023 08:00:17 -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 57775B80B8B; Sun, 15 Jan 2023 16:00:16 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2E175C43396; Sun, 15 Jan 2023 16:00:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673798415; bh=2ZvtCqdxiDchWM0Oyh/DWI5647npO3T45GiQr8L+r6g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LFfsE9CBDHd3YOK8zdlabXUtrCKcFABxQwEOHlgaYrk2pq623BiWt0sQXAPJYIqJ5 ZN7+IbsAG02xc8m7muJU178BhU1TMJ00LsN+i0DwGm/5Tj+RMl0yuukJ6InVN/xZVT Yxx2lD8qSWZWAqCG4z2jQ7QKenEefd92MQQtSBGuKK20ojPQeyhvWuZTbuZR5qiBVE BuCxoS3uwnqWFBKoR7Ec3+QokDtJzDXRgPHf7W7lJwj2C8F6rNQMdD5zJGBQAhB0bK oIHba+eZ904+FEw4BEwUP+rGdqURhQ8+ZGDCOFRqqjZpLRyedp4Oi07+uCSGILsJK7 oIL5lL8hbCuIA== From: Jisheng Zhang To: Paul Walmsley , Palmer Dabbelt , Albert Ou , Anup Patel , Atish Patra , Heiko Stuebner , Conor Dooley , Andrew Jones Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, kvm-riscv@lists.infradead.org, Heiko Stuebner Subject: [PATCH v4 01/13] riscv: fix jal offsets in patched alternatives Date: Sun, 15 Jan 2023 23:49:41 +0800 Message-Id: <20230115154953.831-2-jszhang@kernel.org> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20230115154953.831-1-jszhang@kernel.org> References: <20230115154953.831-1-jszhang@kernel.org> MIME-Version: 1.0 X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1755104943937965149?= X-GMAIL-MSGID: =?utf-8?q?1755104943937965149?= 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..25ef9c0b19e7 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 code) (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); }) +/* + * 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 &= ~GENMASK(31, 12); + *insn |= (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_OPOFF) | + (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/alternative.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); } +static void riscv_alternative_fix_jal(void *ptr, u32 jal_insn, int patch_offset) +{ + s32 imm; + + /* get and adjust new target address */ + imm = riscv_insn_extract_jtype_imm(jal_insn); + imm -= 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, unsigned int len, riscv_alternative_fix_auipc_jalr(alt_ptr + i * sizeof(u32), insn, insn2, patch_offset); } + + if (riscv_insn_is_jal(insn)) { + s32 imm = riscv_insn_extract_jtype_imm(insn); + + /* Don't modify jumps inside the alternative block */ + if ((alt_ptr + i * sizeof(u32) + imm) >= alt_ptr && + (alt_ptr + i * sizeof(u32) + imm) < (alt_ptr + len)) + continue; + + riscv_alternative_fix_jal(alt_ptr + i * sizeof(u32), + insn, patch_offset); + } } }