From patchwork Mon Jan 31 18:27:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Emil Renner Berthing X-Patchwork-Id: 12730999 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id DDF4FC433FE for ; Mon, 31 Jan 2022 18:27:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=938o1FKkVKcLU8bJEDvvqKZVS62MxhkyktqsmCLGqk8=; b=jngyO/cptCGgCR YxhlR/PGf6lxIUadgOpgPhsq977h1L4WDy75o8YIY5LMSYzxSamdXG8xb+ILsOSubdJvMAbkZZRjQ iNSclagxWGV9MxGgl7nW13Ez0fI5E3rL6sojoL9jqtpRTTpWNuyGHE+/kOhSh1NNlgORVTnmapFQp sO2jqy7UPedrceJUURfXcNIq/cS4ESLj7j2j1/v0CydvXFEhekSuR6qdz/hM4rEZgPBNs9q3Cchfd hf6ErvlB9+EoswSTbctw2ZUNl6qgfYGD0sAHGyr4enQC/hkwEoOxR4O4gOl5ndXG9Z1r3cgvif2Bh vB5Kz0k5b3pAqO0A+wig==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nEbP2-00ALBn-JP; Mon, 31 Jan 2022 18:27:48 +0000 Received: from mail-oi1-x22f.google.com ([2607:f8b0:4864:20::22f]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nEbOy-00AL96-PG for linux-riscv@lists.infradead.org; Mon, 31 Jan 2022 18:27:46 +0000 Received: by mail-oi1-x22f.google.com with SMTP id m9so28297262oia.12 for ; Mon, 31 Jan 2022 10:27:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=YCCLljOzkZTWVhp4UcnxVmYpwCgumhAeXuk5FTxJkB0=; b=HZ220OEWLABp3aSXvxPQNJay8YMq8judO11CWtgvZ1gyUaqL8ZYaudw7PMHX1V580g GnLIYZLGx8ohGTmZqFeiMGuxWkyzqIYWKO1yOdgweCylB5F7apPKMWg+2jbdBj1QBL4f QRhAFMHIY6iKV5heV2a92ydHpDNOqeSWaiLm1Rw/Mw+ukfv/7L3FRcS7lYzFLjERFhJ2 iwY3FA4Yw55OFcZFnoAy7FkSGZz0yWbw9ooKFwXbqENn1d5FC/MZQPlQIf3P/WEEWmMf 1luCJH36Asqiac3lcfPC1Ta9PpPS9elHcNxDORDJZqlYkNzvcx1CgAKYpKMrGE4XjEYo mcRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=YCCLljOzkZTWVhp4UcnxVmYpwCgumhAeXuk5FTxJkB0=; b=svjxieJhTSPJHzOd0luE4x5tnclrPSRjn7SJ88/UWEAqmEi84F6W03meHR6P9xzMFI J68sLqjHyj//tG4CkZ6cj39P0FTTYV5zmGgcEhTZZGlf9EV0CtZ4ss8j5vAEoUb5gQn9 tXiOnicLzRxQsMcdhRftJhtcb0upNMhsxGRD5W3QGr2/VhLUB5jsjyrzwPqPWYOF6LyJ 6H38hgqX3fNrbzgQ3iJ3ZizZvLtwLObmio/Jz3jyEF5wtZE6WHFmaXUbwGp7yMMJTq5x uDM+hDDyNCGxtvHAFV0oTxGUYgme678pU4pVMTu68lpbBLmj/5dsLiO54r1sQDLH0uSh yMXw== X-Gm-Message-State: AOAM530KN8m3NK/9DnSWjGaAjVQdiLjWqWi6vqIFxvhMN36NVjToRJEV Yv32Em3ozRMUjhMvUllrUuX5BuxipVsc9Q== X-Google-Smtp-Source: ABdhPJwKrM5CvEkYXnzGhb6PF6RnsL6qpETWKpCPSqV4wqkW4E6AQWHPesBXyiHuVEjJ+So+Z8fShg== X-Received: by 2002:a05:6808:1897:: with SMTP id bi23mr6779955oib.217.1643653662815; Mon, 31 Jan 2022 10:27:42 -0800 (PST) Received: from stitch.. (80.71.140.73.ipv4.parknet.dk. [80.71.140.73]) by smtp.gmail.com with ESMTPSA id a26sm16041676oiy.26.2022.01.31.10.27.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Jan 2022 10:27:42 -0800 (PST) From: Emil Renner Berthing To: linux-riscv@lists.infradead.org Cc: Emil Renner Berthing , Paul Walmsley , Palmer Dabbelt , Albert Ou , Peter Zijlstra , Josh Poimboeuf , Jason Baron , Steven Rostedt , Ard Biesheuvel , Alexandre Ghiti , Jisheng Zhang , linux-kernel@vger.kernel.org Subject: [PATCH v2 1/7] riscv: Remove unneeded definitions from asm/module.h Date: Mon, 31 Jan 2022 19:27:14 +0100 Message-Id: <20220131182720.236065-2-kernel@esmil.dk> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220131182720.236065-1-kernel@esmil.dk> References: <20220131182720.236065-1-kernel@esmil.dk> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220131_102744_853156_768A6120 X-CRM114-Status: GOOD ( 19.58 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org The inline functions previously defined here are only ever used in kernel/module-sections.c, so there is no need to include them in every user of asm/module.h. Through linux/module.h this is just about every driver. Now that these functions are static in a single file remove the inline marker to allow the compiler to make its own decisions. Signed-off-by: Emil Renner Berthing --- arch/riscv/include/asm/module.h | 87 ---------------------------- arch/riscv/kernel/module-sections.c | 90 +++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 87 deletions(-) diff --git a/arch/riscv/include/asm/module.h b/arch/riscv/include/asm/module.h index 76aa96a9fc08..570cd025f220 100644 --- a/arch/riscv/include/asm/module.h +++ b/arch/riscv/include/asm/module.h @@ -22,93 +22,6 @@ struct mod_arch_specific { struct mod_section plt; struct mod_section got_plt; }; - -struct got_entry { - unsigned long symbol_addr; /* the real variable address */ -}; - -static inline struct got_entry emit_got_entry(unsigned long val) -{ - return (struct got_entry) {val}; -} - -static inline struct got_entry *get_got_entry(unsigned long val, - const struct mod_section *sec) -{ - struct got_entry *got = (struct got_entry *)(sec->shdr->sh_addr); - int i; - for (i = 0; i < sec->num_entries; i++) { - if (got[i].symbol_addr == val) - return &got[i]; - } - return NULL; -} - -struct plt_entry { - /* - * Trampoline code to real target address. The return address - * should be the original (pc+4) before entring plt entry. - */ - u32 insn_auipc; /* auipc t0, 0x0 */ - u32 insn_ld; /* ld t1, 0x10(t0) */ - u32 insn_jr; /* jr t1 */ -}; - -#define OPC_AUIPC 0x0017 -#define OPC_LD 0x3003 -#define OPC_JALR 0x0067 -#define REG_T0 0x5 -#define REG_T1 0x6 - -static inline struct plt_entry emit_plt_entry(unsigned long val, - unsigned long plt, - unsigned long got_plt) -{ - /* - * U-Type encoding: - * +------------+----------+----------+ - * | imm[31:12] | rd[11:7] | opc[6:0] | - * +------------+----------+----------+ - * - * I-Type encoding: - * +------------+------------+--------+----------+----------+ - * | imm[31:20] | rs1[19:15] | funct3 | rd[11:7] | opc[6:0] | - * +------------+------------+--------+----------+----------+ - * - */ - unsigned long offset = got_plt - plt; - u32 hi20 = (offset + 0x800) & 0xfffff000; - u32 lo12 = (offset - hi20); - return (struct plt_entry) { - OPC_AUIPC | (REG_T0 << 7) | hi20, - OPC_LD | (lo12 << 20) | (REG_T0 << 15) | (REG_T1 << 7), - OPC_JALR | (REG_T1 << 15) - }; -} - -static inline int get_got_plt_idx(unsigned long val, const struct mod_section *sec) -{ - struct got_entry *got_plt = (struct got_entry *)sec->shdr->sh_addr; - int i; - for (i = 0; i < sec->num_entries; i++) { - if (got_plt[i].symbol_addr == val) - return i; - } - return -1; -} - -static inline struct plt_entry *get_plt_entry(unsigned long val, - const struct mod_section *sec_plt, - const struct mod_section *sec_got_plt) -{ - struct plt_entry *plt = (struct plt_entry *)sec_plt->shdr->sh_addr; - int got_plt_idx = get_got_plt_idx(val, sec_got_plt); - if (got_plt_idx >= 0) - return plt + got_plt_idx; - else - return NULL; -} - #endif /* CONFIG_MODULE_SECTIONS */ #endif /* _ASM_RISCV_MODULE_H */ diff --git a/arch/riscv/kernel/module-sections.c b/arch/riscv/kernel/module-sections.c index e264e59e596e..39d4ac681c2a 100644 --- a/arch/riscv/kernel/module-sections.c +++ b/arch/riscv/kernel/module-sections.c @@ -10,6 +10,28 @@ #include #include +struct got_entry { + unsigned long symbol_addr; /* the real variable address */ +}; + +static struct got_entry emit_got_entry(unsigned long val) +{ + return (struct got_entry) {val}; +} + +static struct got_entry *get_got_entry(unsigned long val, + const struct mod_section *sec) +{ + struct got_entry *got = (struct got_entry *)(sec->shdr->sh_addr); + int i; + + for (i = 0; i < sec->num_entries; i++) { + if (got[i].symbol_addr == val) + return &got[i]; + } + return NULL; +} + unsigned long module_emit_got_entry(struct module *mod, unsigned long val) { struct mod_section *got_sec = &mod->arch.got; @@ -29,6 +51,74 @@ unsigned long module_emit_got_entry(struct module *mod, unsigned long val) return (unsigned long)&got[i]; } +struct plt_entry { + /* + * Trampoline code to real target address. The return address + * should be the original (pc+4) before entring plt entry. + */ + u32 insn_auipc; /* auipc t0, 0x0 */ + u32 insn_ld; /* ld t1, 0x10(t0) */ + u32 insn_jr; /* jr t1 */ +}; + +#define OPC_AUIPC 0x0017 +#define OPC_LD 0x3003 +#define OPC_JALR 0x0067 +#define REG_T0 0x5 +#define REG_T1 0x6 + +static struct plt_entry emit_plt_entry(unsigned long val, + unsigned long plt, + unsigned long got_plt) +{ + /* + * U-Type encoding: + * +------------+----------+----------+ + * | imm[31:12] | rd[11:7] | opc[6:0] | + * +------------+----------+----------+ + * + * I-Type encoding: + * +------------+------------+--------+----------+----------+ + * | imm[31:20] | rs1[19:15] | funct3 | rd[11:7] | opc[6:0] | + * +------------+------------+--------+----------+----------+ + * + */ + unsigned long offset = got_plt - plt; + u32 hi20 = (offset + 0x800) & 0xfffff000; + u32 lo12 = (offset - hi20); + + return (struct plt_entry) { + OPC_AUIPC | (REG_T0 << 7) | hi20, + OPC_LD | (lo12 << 20) | (REG_T0 << 15) | (REG_T1 << 7), + OPC_JALR | (REG_T1 << 15) + }; +} + +static int get_got_plt_idx(unsigned long val, const struct mod_section *sec) +{ + struct got_entry *got_plt = (struct got_entry *)sec->shdr->sh_addr; + int i; + + for (i = 0; i < sec->num_entries; i++) { + if (got_plt[i].symbol_addr == val) + return i; + } + return -1; +} + +static struct plt_entry *get_plt_entry(unsigned long val, + const struct mod_section *sec_plt, + const struct mod_section *sec_got_plt) +{ + struct plt_entry *plt = (struct plt_entry *)sec_plt->shdr->sh_addr; + int got_plt_idx = get_got_plt_idx(val, sec_got_plt); + + if (got_plt_idx >= 0) + return plt + got_plt_idx; + else + return NULL; +} + unsigned long module_emit_plt_entry(struct module *mod, unsigned long val) { struct mod_section *got_plt_sec = &mod->arch.got_plt; From patchwork Mon Jan 31 18:27:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Emil Renner Berthing X-Patchwork-Id: 12731000 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 22C36C433F5 for ; Mon, 31 Jan 2022 18:27:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=SQt01d7UvhSa/xk0wMEHWbTX6tObiaXNolYpcTxcrXw=; b=tvh8sUIDTUKBNk xIEoZTQkJiBUnuAU2URJ4gCuhB0NxhGOpZbDcHK5zm7hnsKug1/ihUEWLwPpHE1JyxlUY7VTtd+MG ldHdI5wvXi56jXt6lB7VNOPC2n4IZxxyV67GZAm2fslO5SeDZ7qGrmvIuDWAwvEYW18DIrHXGCZ5k F1xdvxQ5r3EVOIX/zg20Cq2LzDk18GvcKWt9MFyi6ga7s1LUWBeMb6/IfBXlY+LOpHStl4y2hjYVm ArvAsoS908HWSCYbVl8waigqKEApyogDCB5xos+l8Kympe4YpqfDR1c5Kra+RVu0KuHc3HjL7hBHN MHmCB+gQYU7ridF+4r5w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nEbP4-00ALD9-S5; Mon, 31 Jan 2022 18:27:50 +0000 Received: from mail-oi1-x236.google.com ([2607:f8b0:4864:20::236]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nEbP1-00ALAe-Fd for linux-riscv@lists.infradead.org; Mon, 31 Jan 2022 18:27:49 +0000 Received: by mail-oi1-x236.google.com with SMTP id u13so12149468oie.5 for ; Mon, 31 Jan 2022 10:27:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=du1Y7EMk87RkBVDbWmaUJHf7VmzL/EHA98mqnBTL1m8=; b=og5vAQIkW5rwK4FcgqUejbZe5BvHJp7z5dWrFIctJpiqbcWlsF7qDqbm8g03q9I9tC n7mjd7N+e9+5dr9FQ+2D998SNzyeqqweHFgLLgQGuZJWo8cIMxzXfja8f39jrl91NMv/ JDjbaH49mr2lXGZO4/NDc14t5wM2LY0XYsMmHL6I1AgiVv1yj7XcI1bclZSRPmlLGlq4 X6j4SKdUxabPcqxZvK7v9aLxLBNjCgIa64imttiUf4lAw4uxCbR0bWtblayv7sZ4sdrs 2z/dICXwRgTAyYfXFPahkblvSrhTDqTNPROEIzcG5svI0OIgiyMPUHMy4OCUZM9NodiG eq6w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=du1Y7EMk87RkBVDbWmaUJHf7VmzL/EHA98mqnBTL1m8=; b=uvn4SizDH5kQQEWEFV62/o+5j0ojNoiNtLQ4nU4tpb0Eehl07KEWlZhdbQwcVmwV5Z O5csbhkPcU9U+hDo3xiO5sn2gF2YPZz2VBFz4vPwGZhsT50JYOiRTi1kU9VyJ+MpR/zK g64cQJJzh0T2rnq6gx4htvHkNM15ygexkOqUS/Qf02Z2HkBiCCgUGYzVJsB36NgzFYI0 wHOPlp3BAgAH0K9c3NFZEfqkAQv0l/sDFu8uKtOTzQRvol1kiCkIKfInvCoO4/R5Ss1P 4YJngEBCoFANWM4l+RjlzfVCMOjrMdsnJu8pURp0dGcUh5Qsz0w+qzuZOkO3vmSK5yVQ NLaA== X-Gm-Message-State: AOAM532/Jf0cEUDQU6QFkhMMnBgw733ebEbEcanDuYFVxXVgLkr6dFu+ O5PVdqGhDta6ijuFXM/LY/yJi9GInQgrLA== X-Google-Smtp-Source: ABdhPJzmVwVaBHBeVjzYqlgwPLhys193gC9c7mnDoam6RNxuZlsOqvSxnUe8uPQriZgfLaYiA3E0qA== X-Received: by 2002:a05:6808:228b:: with SMTP id bo11mr14614704oib.113.1643653666269; Mon, 31 Jan 2022 10:27:46 -0800 (PST) Received: from stitch.. (80.71.140.73.ipv4.parknet.dk. [80.71.140.73]) by smtp.gmail.com with ESMTPSA id a26sm16041676oiy.26.2022.01.31.10.27.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Jan 2022 10:27:45 -0800 (PST) From: Emil Renner Berthing To: linux-riscv@lists.infradead.org Cc: Emil Renner Berthing , Paul Walmsley , Palmer Dabbelt , Albert Ou , Peter Zijlstra , Josh Poimboeuf , Jason Baron , Steven Rostedt , Ard Biesheuvel , Alexandre Ghiti , Jisheng Zhang , linux-kernel@vger.kernel.org Subject: [PATCH v2 2/7] riscv: Avoid unaligned access when relocating modules Date: Mon, 31 Jan 2022 19:27:15 +0100 Message-Id: <20220131182720.236065-3-kernel@esmil.dk> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220131182720.236065-1-kernel@esmil.dk> References: <20220131182720.236065-1-kernel@esmil.dk> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220131_102747_549345_F117B94A X-CRM114-Status: GOOD ( 15.95 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org With the C-extension regular 32bit instructions are not necessarily aligned on 4-byte boundaries. RISC-V instructions are in fact an ordered list of 16bit native-endian "parcels", so access the instruction as such. This should also make the code work in case someone builds a big-endian RISC-V machine. Fix rcv -> rvc typo while we're at it. Signed-off-by: Emil Renner Berthing --- arch/riscv/kernel/module.c | 151 +++++++++++++++++++------------------ 1 file changed, 76 insertions(+), 75 deletions(-) diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c index 68a9e3d1fe16..3d33442226e7 100644 --- a/arch/riscv/kernel/module.c +++ b/arch/riscv/kernel/module.c @@ -13,68 +13,86 @@ #include #include -static int apply_r_riscv_32_rela(struct module *me, u32 *location, Elf_Addr v) +static int riscv_insn_rmw(void *location, u32 keep, u32 set) +{ + u16 *parcel = location; + u32 insn = (u32)parcel[0] | (u32)parcel[1] << 16; + + insn &= keep; + insn |= set; + + parcel[0] = insn; + parcel[1] = insn >> 16; + return 0; +} + +static int riscv_insn_rvc_rmw(void *location, u16 keep, u16 set) +{ + u16 *parcel = location; + + *parcel = (*parcel & keep) | set; + return 0; +} + +static int apply_r_riscv_32_rela(struct module *me, void *location, Elf_Addr v) { if (v != (u32)v) { pr_err("%s: value %016llx out of range for 32-bit field\n", me->name, (long long)v); return -EINVAL; } - *location = v; + *(u32 *)location = v; return 0; } -static int apply_r_riscv_64_rela(struct module *me, u32 *location, Elf_Addr v) +static int apply_r_riscv_64_rela(struct module *me, void *location, Elf_Addr v) { *(u64 *)location = v; return 0; } -static int apply_r_riscv_branch_rela(struct module *me, u32 *location, +static int apply_r_riscv_branch_rela(struct module *me, void *location, Elf_Addr v) { - ptrdiff_t offset = (void *)v - (void *)location; + ptrdiff_t offset = (void *)v - location; u32 imm12 = (offset & 0x1000) << (31 - 12); u32 imm11 = (offset & 0x800) >> (11 - 7); u32 imm10_5 = (offset & 0x7e0) << (30 - 10); u32 imm4_1 = (offset & 0x1e) << (11 - 4); - *location = (*location & 0x1fff07f) | imm12 | imm11 | imm10_5 | imm4_1; - return 0; + return riscv_insn_rmw(location, 0x1fff07f, imm12 | imm11 | imm10_5 | imm4_1); } -static int apply_r_riscv_jal_rela(struct module *me, u32 *location, +static int apply_r_riscv_jal_rela(struct module *me, void *location, Elf_Addr v) { - ptrdiff_t offset = (void *)v - (void *)location; + ptrdiff_t offset = (void *)v - location; u32 imm20 = (offset & 0x100000) << (31 - 20); u32 imm19_12 = (offset & 0xff000); u32 imm11 = (offset & 0x800) << (20 - 11); u32 imm10_1 = (offset & 0x7fe) << (30 - 10); - *location = (*location & 0xfff) | imm20 | imm19_12 | imm11 | imm10_1; - return 0; + return riscv_insn_rmw(location, 0xfff, imm20 | imm19_12 | imm11 | imm10_1); } -static int apply_r_riscv_rcv_branch_rela(struct module *me, u32 *location, +static int apply_r_riscv_rvc_branch_rela(struct module *me, void *location, Elf_Addr v) { - ptrdiff_t offset = (void *)v - (void *)location; + ptrdiff_t offset = (void *)v - location; u16 imm8 = (offset & 0x100) << (12 - 8); u16 imm7_6 = (offset & 0xc0) >> (6 - 5); u16 imm5 = (offset & 0x20) >> (5 - 2); u16 imm4_3 = (offset & 0x18) << (12 - 5); u16 imm2_1 = (offset & 0x6) << (12 - 10); - *(u16 *)location = (*(u16 *)location & 0xe383) | - imm8 | imm7_6 | imm5 | imm4_3 | imm2_1; - return 0; + return riscv_insn_rvc_rmw(location, 0xe383, + imm8 | imm7_6 | imm5 | imm4_3 | imm2_1); } -static int apply_r_riscv_rvc_jump_rela(struct module *me, u32 *location, +static int apply_r_riscv_rvc_jump_rela(struct module *me, void *location, Elf_Addr v) { - ptrdiff_t offset = (void *)v - (void *)location; + ptrdiff_t offset = (void *)v - location; u16 imm11 = (offset & 0x800) << (12 - 11); u16 imm10 = (offset & 0x400) >> (10 - 8); u16 imm9_8 = (offset & 0x300) << (12 - 11); @@ -84,16 +102,14 @@ static int apply_r_riscv_rvc_jump_rela(struct module *me, u32 *location, u16 imm4 = (offset & 0x10) << (12 - 5); u16 imm3_1 = (offset & 0xe) << (12 - 10); - *(u16 *)location = (*(u16 *)location & 0xe003) | - imm11 | imm10 | imm9_8 | imm7 | imm6 | imm5 | imm4 | imm3_1; - return 0; + return riscv_insn_rvc_rmw(location, 0xe003, + imm11 | imm10 | imm9_8 | imm7 | imm6 | imm5 | imm4 | imm3_1); } -static int apply_r_riscv_pcrel_hi20_rela(struct module *me, u32 *location, +static int apply_r_riscv_pcrel_hi20_rela(struct module *me, void *location, Elf_Addr v) { - ptrdiff_t offset = (void *)v - (void *)location; - s32 hi20; + ptrdiff_t offset = (void *)v - location; if (offset != (s32)offset) { pr_err( @@ -102,23 +118,20 @@ static int apply_r_riscv_pcrel_hi20_rela(struct module *me, u32 *location, return -EINVAL; } - hi20 = (offset + 0x800) & 0xfffff000; - *location = (*location & 0xfff) | hi20; - return 0; + return riscv_insn_rmw(location, 0xfff, (offset + 0x800) & 0xfffff000); } -static int apply_r_riscv_pcrel_lo12_i_rela(struct module *me, u32 *location, +static int apply_r_riscv_pcrel_lo12_i_rela(struct module *me, void *location, Elf_Addr v) { /* * v is the lo12 value to fill. It is calculated before calling this * handler. */ - *location = (*location & 0xfffff) | ((v & 0xfff) << 20); - return 0; + return riscv_insn_rmw(location, 0xfffff, (v & 0xfff) << 20); } -static int apply_r_riscv_pcrel_lo12_s_rela(struct module *me, u32 *location, +static int apply_r_riscv_pcrel_lo12_s_rela(struct module *me, void *location, Elf_Addr v) { /* @@ -128,15 +141,12 @@ static int apply_r_riscv_pcrel_lo12_s_rela(struct module *me, u32 *location, u32 imm11_5 = (v & 0xfe0) << (31 - 11); u32 imm4_0 = (v & 0x1f) << (11 - 4); - *location = (*location & 0x1fff07f) | imm11_5 | imm4_0; - return 0; + return riscv_insn_rmw(location, 0x1fff07f, imm11_5 | imm4_0); } -static int apply_r_riscv_hi20_rela(struct module *me, u32 *location, +static int apply_r_riscv_hi20_rela(struct module *me, void *location, Elf_Addr v) { - s32 hi20; - if (IS_ENABLED(CONFIG_CMODEL_MEDLOW)) { pr_err( "%s: target %016llx can not be addressed by the 32-bit offset from PC = %p\n", @@ -144,22 +154,20 @@ static int apply_r_riscv_hi20_rela(struct module *me, u32 *location, return -EINVAL; } - hi20 = ((s32)v + 0x800) & 0xfffff000; - *location = (*location & 0xfff) | hi20; - return 0; + return riscv_insn_rmw(location, 0xfff, ((s32)v + 0x800) & 0xfffff000); } -static int apply_r_riscv_lo12_i_rela(struct module *me, u32 *location, +static int apply_r_riscv_lo12_i_rela(struct module *me, void *location, Elf_Addr v) { /* Skip medlow checking because of filtering by HI20 already */ s32 hi20 = ((s32)v + 0x800) & 0xfffff000; s32 lo12 = ((s32)v - hi20); - *location = (*location & 0xfffff) | ((lo12 & 0xfff) << 20); - return 0; + + return riscv_insn_rmw(location, 0xfffff, (lo12 & 0xfff) << 20); } -static int apply_r_riscv_lo12_s_rela(struct module *me, u32 *location, +static int apply_r_riscv_lo12_s_rela(struct module *me, void *location, Elf_Addr v) { /* Skip medlow checking because of filtering by HI20 already */ @@ -167,20 +175,18 @@ static int apply_r_riscv_lo12_s_rela(struct module *me, u32 *location, s32 lo12 = ((s32)v - hi20); u32 imm11_5 = (lo12 & 0xfe0) << (31 - 11); u32 imm4_0 = (lo12 & 0x1f) << (11 - 4); - *location = (*location & 0x1fff07f) | imm11_5 | imm4_0; - return 0; + + return riscv_insn_rmw(location, 0x1fff07f, imm11_5 | imm4_0); } -static int apply_r_riscv_got_hi20_rela(struct module *me, u32 *location, +static int apply_r_riscv_got_hi20_rela(struct module *me, void *location, Elf_Addr v) { - ptrdiff_t offset = (void *)v - (void *)location; - s32 hi20; + ptrdiff_t offset = (void *)v - location; /* Always emit the got entry */ if (IS_ENABLED(CONFIG_MODULE_SECTIONS)) { - offset = module_emit_got_entry(me, v); - offset = (void *)offset - (void *)location; + offset = (void *)module_emit_got_entry(me, v) - location; } else { pr_err( "%s: can not generate the GOT entry for symbol = %016llx from PC = %p\n", @@ -188,23 +194,20 @@ static int apply_r_riscv_got_hi20_rela(struct module *me, u32 *location, return -EINVAL; } - hi20 = (offset + 0x800) & 0xfffff000; - *location = (*location & 0xfff) | hi20; - return 0; + return riscv_insn_rmw(location, 0xfff, (offset + 0x800) & 0xfffff000); } -static int apply_r_riscv_call_plt_rela(struct module *me, u32 *location, +static int apply_r_riscv_call_plt_rela(struct module *me, void *location, Elf_Addr v) { - ptrdiff_t offset = (void *)v - (void *)location; + ptrdiff_t offset = (void *)v - location; s32 fill_v = offset; u32 hi20, lo12; if (offset != fill_v) { /* Only emit the plt entry if offset over 32-bit range */ if (IS_ENABLED(CONFIG_MODULE_SECTIONS)) { - offset = module_emit_plt_entry(me, v); - offset = (void *)offset - (void *)location; + offset = (void *)module_emit_plt_entry(me, v) - location; } else { pr_err( "%s: target %016llx can not be addressed by the 32-bit offset from PC = %p\n", @@ -215,15 +218,14 @@ static int apply_r_riscv_call_plt_rela(struct module *me, u32 *location, hi20 = (offset + 0x800) & 0xfffff000; lo12 = (offset - hi20) & 0xfff; - *location = (*location & 0xfff) | hi20; - *(location + 1) = (*(location + 1) & 0xfffff) | (lo12 << 20); - return 0; + riscv_insn_rmw(location, 0xfff, hi20); + return riscv_insn_rmw(location + 4, 0xfffff, lo12 << 20); } -static int apply_r_riscv_call_rela(struct module *me, u32 *location, +static int apply_r_riscv_call_rela(struct module *me, void *location, Elf_Addr v) { - ptrdiff_t offset = (void *)v - (void *)location; + ptrdiff_t offset = (void *)v - location; s32 fill_v = offset; u32 hi20, lo12; @@ -236,18 +238,17 @@ static int apply_r_riscv_call_rela(struct module *me, u32 *location, hi20 = (offset + 0x800) & 0xfffff000; lo12 = (offset - hi20) & 0xfff; - *location = (*location & 0xfff) | hi20; - *(location + 1) = (*(location + 1) & 0xfffff) | (lo12 << 20); - return 0; + riscv_insn_rmw(location, 0xfff, hi20); + return riscv_insn_rmw(location + 4, 0xfffff, lo12 << 20); } -static int apply_r_riscv_relax_rela(struct module *me, u32 *location, +static int apply_r_riscv_relax_rela(struct module *me, void *location, Elf_Addr v) { return 0; } -static int apply_r_riscv_align_rela(struct module *me, u32 *location, +static int apply_r_riscv_align_rela(struct module *me, void *location, Elf_Addr v) { pr_err( @@ -256,41 +257,41 @@ static int apply_r_riscv_align_rela(struct module *me, u32 *location, return -EINVAL; } -static int apply_r_riscv_add32_rela(struct module *me, u32 *location, +static int apply_r_riscv_add32_rela(struct module *me, void *location, Elf_Addr v) { *(u32 *)location += (u32)v; return 0; } -static int apply_r_riscv_add64_rela(struct module *me, u32 *location, +static int apply_r_riscv_add64_rela(struct module *me, void *location, Elf_Addr v) { *(u64 *)location += (u64)v; return 0; } -static int apply_r_riscv_sub32_rela(struct module *me, u32 *location, +static int apply_r_riscv_sub32_rela(struct module *me, void *location, Elf_Addr v) { *(u32 *)location -= (u32)v; return 0; } -static int apply_r_riscv_sub64_rela(struct module *me, u32 *location, +static int apply_r_riscv_sub64_rela(struct module *me, void *location, Elf_Addr v) { *(u64 *)location -= (u64)v; return 0; } -static int (*reloc_handlers_rela[]) (struct module *me, u32 *location, +static int (*reloc_handlers_rela[]) (struct module *me, void *location, Elf_Addr v) = { [R_RISCV_32] = apply_r_riscv_32_rela, [R_RISCV_64] = apply_r_riscv_64_rela, [R_RISCV_BRANCH] = apply_r_riscv_branch_rela, [R_RISCV_JAL] = apply_r_riscv_jal_rela, - [R_RISCV_RVC_BRANCH] = apply_r_riscv_rcv_branch_rela, + [R_RISCV_RVC_BRANCH] = apply_r_riscv_rvc_branch_rela, [R_RISCV_RVC_JUMP] = apply_r_riscv_rvc_jump_rela, [R_RISCV_PCREL_HI20] = apply_r_riscv_pcrel_hi20_rela, [R_RISCV_PCREL_LO12_I] = apply_r_riscv_pcrel_lo12_i_rela, @@ -314,9 +315,9 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, struct module *me) { Elf_Rela *rel = (void *) sechdrs[relsec].sh_addr; - int (*handler)(struct module *me, u32 *location, Elf_Addr v); + int (*handler)(struct module *me, void *location, Elf_Addr v); Elf_Sym *sym; - u32 *location; + void *location; unsigned int i, type; Elf_Addr v; int res; From patchwork Mon Jan 31 18:27:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Emil Renner Berthing X-Patchwork-Id: 12731001 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3F9DBC433F5 for ; Mon, 31 Jan 2022 18:28:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=ADEpjhhpnWooiSDL4nXYtMKcweKRiHZeuz9Syaia/Wo=; b=WlKA4jfC73Ej6d 75E/R0WV3PmO2Xzj8DR1pWa2nN7zuP8aQDIoDFpt0+PVkQLnbWtv3JoemnkC2Y/Sq5zAGBa8zMqMJ VNozPamar/2tl9X4RdvOwew2wPVDsnhopQTRjFpCVA5SOhswuuvcm1bjzSZ5/b4RzqelDRlwmO3Qr WIaIjeeLg+SwqJIpqoMOl8BCm9YMBtWCYWYrqgcAtY/DLweGo70D+0V3SHgCUHhR3Yy+JMiJUQzY9 8uwcSVaZ4PgWVKzYMf/TnX2rixaRY1oK7o3kL/cgQvBmmZExE0Q8D8dU5RALpscg4NwVTg0o3FZFp 4/uqWEUK/yByB5zPhzTQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nEbPP-00ALRX-Bi; Mon, 31 Jan 2022 18:28:11 +0000 Received: from mail-ot1-x329.google.com ([2607:f8b0:4864:20::329]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nEbP5-00ALCv-SQ for linux-riscv@lists.infradead.org; Mon, 31 Jan 2022 18:27:53 +0000 Received: by mail-ot1-x329.google.com with SMTP id d18-20020a9d51d2000000b005a09728a8c2so13835125oth.3 for ; Mon, 31 Jan 2022 10:27:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=pFasC+wyxSnpAZ2usTdBEAt8b8vmkJCatL6gaFi2YnA=; b=jpvQ12JqsAmFiYXikZczOVDw5Kt0XfkhYMBMzN6tcJTC0FJYu+eD55ciJJi5xu+xHK oVgSpKYqmmNFXvxtbjYbM7q1joXuoE3Rbh1bNsWsWRSdTybFgvZr7/NQfmMG4HtfKIKG /5rSVurc0tNqeuZZTrKFzuZb0N6M2N5YH3LWhKryCYuun0JxbvgkTp/58CgzctLUQ9B6 3PeZ6hWRPyRORzvu2gB3By23xMKcv31tvbkcvFSp3LTWHOwTX6X9iFBc8vTyMnTaC4nW qDessmj1nBnuYWhbzRkklIq6ewo0Aih4AFMR1V3VMexgtpaNoequZrxlCHp2bLOm+J49 5AzA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=pFasC+wyxSnpAZ2usTdBEAt8b8vmkJCatL6gaFi2YnA=; b=6W0RseTrdw5niMlzu/WqYANpy8Sr6vTMGRwrHMBYCNg/Kngv4nK0rraYAazeu21gDP ftU8J+BXYFk/jq2dxXfMuCwEReHApCBWflg4rIAdXgnlPyZ/WrgI7W+wJaFZFevkQIp3 cAc13WJ7pFOzhiMJOTDNnJ48xWCWsOudmIUKTUFQAHfAqqT1YM+s5PRPgK7Mp3CtgRgS hQXtiaFf2jdDWoeoG3hWEZ+W/rwWW3VhritssGcuzmeMam0uotJeqa2BVBlUqkQOdxYi L4PIYoauEYyYLo08ktTZi3/gXwJzgFAFbAjuqdjQ/fOJSLOrWIbDLApnESNztjLKfJEb KWrQ== X-Gm-Message-State: AOAM531dcx3+1ZHk000BOiw8Jb5QGlnV0TjKyYmUIjBa3OUHM8We4ybS L/tvbwsm+NlA6Ywg3yu+P75tYxWE20LBVg== X-Google-Smtp-Source: ABdhPJzBTaqANAdPoa+FjV2Ik3Mc6tUBsaq3/j7JGk9sEd6q1zJXozM9fiU3Tnt/9CFg85fhURwygA== X-Received: by 2002:a9d:4e89:: with SMTP id v9mr12038860otk.177.1643653669852; Mon, 31 Jan 2022 10:27:49 -0800 (PST) Received: from stitch.. (80.71.140.73.ipv4.parknet.dk. [80.71.140.73]) by smtp.gmail.com with ESMTPSA id a26sm16041676oiy.26.2022.01.31.10.27.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Jan 2022 10:27:49 -0800 (PST) From: Emil Renner Berthing To: linux-riscv@lists.infradead.org Cc: Emil Renner Berthing , Paul Walmsley , Palmer Dabbelt , Albert Ou , Peter Zijlstra , Josh Poimboeuf , Jason Baron , Steven Rostedt , Ard Biesheuvel , Alexandre Ghiti , Jisheng Zhang , linux-kernel@vger.kernel.org Subject: [PATCH v2 3/7] riscv: Fix auipc+jalr relocation range checks Date: Mon, 31 Jan 2022 19:27:16 +0100 Message-Id: <20220131182720.236065-4-kernel@esmil.dk> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220131182720.236065-1-kernel@esmil.dk> References: <20220131182720.236065-1-kernel@esmil.dk> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220131_102751_934439_9F0D7076 X-CRM114-Status: GOOD ( 15.00 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org RISC-V can do PC-relative jumps with a 32bit range using the following two instructions: auipc t0, imm20 ; t0 = PC + imm20 * 2^12 jalr ra, t0, imm12 ; ra = PC + 4, PC = t0 + imm12, Crucially both the 20bit immediate imm20 and the 12bit immediate imm12 are treated as two's-complement signed values. For this reason the immediates are usually calculated like this: imm20 = (offset + 0x800) >> 12 imm12 = offset & 0xfff ..where offset is the signed offset from the auipc instruction. When the 11th bit of offset is 0 the addition of 0x800 doesn't change the top 20 bits and imm12 considered positive. When the 11th bit is 1 the carry of the addition by 0x800 means imm20 is one higher, but since imm12 is then considered negative the two's complement representation means it all cancels out nicely. However, this addition by 0x800 (2^11) means an offset greater than or equal to 2^31 - 2^11 would overflow so imm20 is considered negative and result in a backwards jump. Similarly the lower range of offset is also moved down by 2^11 and hence the true 32bit range is [-2^31 - 2^11, 2^31 - 2^11) Signed-off-by: Emil Renner Berthing --- arch/riscv/kernel/module.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c index 3d33442226e7..a75ccf3a6ce8 100644 --- a/arch/riscv/kernel/module.c +++ b/arch/riscv/kernel/module.c @@ -13,6 +13,18 @@ #include #include +static inline bool riscv_insn_valid_32bit_offset(ptrdiff_t val) +{ + if (IS_ENABLED(CONFIG_32BIT)) + return true; + + /* + * auipc+jalr can reach any PC-relative offset in the range + * [-2^31 - 2^11, 2^31 - 2^11) + */ + return (-(1L << 31) - (1L << 11)) <= val && val < ((1L << 31) - (1L << 11)); +} + static int riscv_insn_rmw(void *location, u32 keep, u32 set) { u16 *parcel = location; @@ -111,7 +123,7 @@ static int apply_r_riscv_pcrel_hi20_rela(struct module *me, void *location, { ptrdiff_t offset = (void *)v - location; - if (offset != (s32)offset) { + if (!riscv_insn_valid_32bit_offset(offset)) { pr_err( "%s: target %016llx can not be addressed by the 32-bit offset from PC = %p\n", me->name, (long long)v, location); @@ -201,10 +213,9 @@ static int apply_r_riscv_call_plt_rela(struct module *me, void *location, Elf_Addr v) { ptrdiff_t offset = (void *)v - location; - s32 fill_v = offset; u32 hi20, lo12; - if (offset != fill_v) { + if (!riscv_insn_valid_32bit_offset(offset)) { /* Only emit the plt entry if offset over 32-bit range */ if (IS_ENABLED(CONFIG_MODULE_SECTIONS)) { offset = (void *)module_emit_plt_entry(me, v) - location; @@ -226,10 +237,9 @@ static int apply_r_riscv_call_rela(struct module *me, void *location, Elf_Addr v) { ptrdiff_t offset = (void *)v - location; - s32 fill_v = offset; u32 hi20, lo12; - if (offset != fill_v) { + if (!riscv_insn_valid_32bit_offset(offset)) { pr_err( "%s: target %016llx can not be addressed by the 32-bit offset from PC = %p\n", me->name, (long long)v, location); From patchwork Mon Jan 31 18:27:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Emil Renner Berthing X-Patchwork-Id: 12731002 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 48A0FC433F5 for ; Mon, 31 Jan 2022 18:28:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=R0oU9Oy2dTltzsD7t3l8xek7TsFUBk4so14zbhCgQ7o=; b=bD4W0vY1mnq7ff UCyQQdWVinW5KK3MKs/KTmg2fnGnhcFMaDfTapFMLmq9/J8FoiH/fjFiwaegaJt6w+YklqIbsTb9M QOmvQBRNjVWRk4EZS0Ib1Ac77s2rSBY7n6oA+AxQcOGVO0QSFLPUgmhLRfwupt19AGRmaPBueM7XT YI65XLQ4egICt769BGoMrKkf5qbQDy4TjwcbCXgARyZPtPSxaQK/iZsaQM5Pk/9iezT1Ui2WwTWUB HcdoLX1rbxKEZFpFySYangClLknURW7lvPWraeS+jO91Uv3GAQ2du90YVTcQ/01HWU7PTVChog8mR hk60mrr/kkqCSaio15uw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nEbPS-00ALSs-0s; Mon, 31 Jan 2022 18:28:14 +0000 Received: from mail-oo1-xc35.google.com ([2607:f8b0:4864:20::c35]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nEbP8-00ALFe-Vx for linux-riscv@lists.infradead.org; Mon, 31 Jan 2022 18:27:56 +0000 Received: by mail-oo1-xc35.google.com with SMTP id b15-20020a4a878f000000b002dccc412166so3408908ooi.11 for ; Mon, 31 Jan 2022 10:27:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=6eMWCVmEcwxhKWA4X00yoLIXiWrdcmbrlYXjWFueDp8=; b=fECWMfmSx7xi9TWXcSID08QPIXmifjyjSOyTWkkpZydwLb+0iGj2OVdfTN9kqGxnL4 ZwisFQHbTkiIWRmmRUN7aMJZI2ypu0HlXEf0Yxa3pHBQ2yvrs1+n0KrImqtU7sugMlUm ffUSKi1p5GDz4iIQP2YUCLcYEPiUeqhBW3rRLNtKs84i9snx3IXPZWHPSNJ4FWJjzcGV 0Bo5NhsjO+dmTKFPGzTMTMyJCUDSCoXnXR/b3FC6yvpRx5C2KGu1Tr31tkYor3KHO3JI h9FjxKDNy1QLGUjEx7qo5L/Uyzc1xJpbvX231oOTZvr+j9JuiPcDG4yk7twyf9IgFd5s 3yVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=6eMWCVmEcwxhKWA4X00yoLIXiWrdcmbrlYXjWFueDp8=; b=wDXKRIM7esE29vWQx0/OYUBBq7f7/ZqW4v0MAAiD3WWnO+hvpkeONGiBCoUcHhN1ZZ MrK9ZDWT3Z8xRPb5OmaC+hSRwF4lEqYjWPeuaRdObWtAM8bv9TQB0X4NIDy7UceHBNzF 2mgfQArviCUW/QvZtttram2GqzZheFT7CQlcn70po4eul3Q6/DSKYB83mEeE/KKrRLx1 OkDoCTmrW6ZckidqxSYzVjgy8qTFr9cqZ4tbQLnb4P8MUglMihGUaOgCVjTPqRdhdJEB ifSXV9CwajpzWMyayg9g3xGSvlnAOwk5MRkJHS5swfaaEG0HBxTQV+VtV+GMXBEgqCme iAeg== X-Gm-Message-State: AOAM533wYMXNvgA1Futu0xsmkJdFA598gjgnhUIsQ6K5B4l+VjjXca7I Jb3W9hUnnrV993uFMKYBf6NLlcuPSojznA== X-Google-Smtp-Source: ABdhPJxf60k7BXEd9jZi8bgw6CW7udffRwf/L9FTLY5jFqF6Lj+OoBEEtJufFm1rQ2GdCrSmPEMeKA== X-Received: by 2002:a4a:e0d8:: with SMTP id e24mr10794943oot.56.1643653673746; Mon, 31 Jan 2022 10:27:53 -0800 (PST) Received: from stitch.. (80.71.140.73.ipv4.parknet.dk. [80.71.140.73]) by smtp.gmail.com with ESMTPSA id a26sm16041676oiy.26.2022.01.31.10.27.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Jan 2022 10:27:53 -0800 (PST) From: Emil Renner Berthing To: linux-riscv@lists.infradead.org Cc: Emil Renner Berthing , Paul Walmsley , Palmer Dabbelt , Albert Ou , Peter Zijlstra , Josh Poimboeuf , Jason Baron , Steven Rostedt , Ard Biesheuvel , Alexandre Ghiti , Jisheng Zhang , linux-kernel@vger.kernel.org Subject: [PATCH v2 4/7] riscv: Add asm/insn.h header Date: Mon, 31 Jan 2022 19:27:17 +0100 Message-Id: <20220131182720.236065-5-kernel@esmil.dk> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220131182720.236065-1-kernel@esmil.dk> References: <20220131182720.236065-1-kernel@esmil.dk> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220131_102755_067858_BCC930CC X-CRM114-Status: GOOD ( 11.68 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org Add new asm/insn.h header to consolidate RISC-V instruction constants and inline helper functions. Signed-off-by: Emil Renner Berthing --- arch/riscv/include/asm/insn.h | 121 ++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 arch/riscv/include/asm/insn.h diff --git a/arch/riscv/include/asm/insn.h b/arch/riscv/include/asm/insn.h new file mode 100644 index 000000000000..2bdb089390f0 --- /dev/null +++ b/arch/riscv/include/asm/insn.h @@ -0,0 +1,121 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Emil Renner Berthing + */ +#ifndef __ASM_RISCV_INSN_H +#define __ASM_RISCV_INSN_H + +#include + +#define RISCV_INSN_LD _AC(0x00003003, U) +#define RISCV_INSN_ADDI _AC(0x00000013, U) +#define RISCV_INSN_NOP RISCV_INSN_ADDI +#define RISCV_INSN_AUIPC _AC(0x00000017, U) +#define RISCV_INSN_LUI _AC(0x00000037, U) +#define RISCV_INSN_JALR _AC(0x00000067, U) +#define RISCV_INSN_JAL _AC(0x0000006f, U) + +#define RISCV_INSN_RA _AC(0x1, U) +#define RISCV_INSN_T0 _AC(0x5, U) +#define RISCV_INSN_T1 _AC(0x6, U) + +#define RISCV_INSN_RD_POS 7 +#define RISCV_INSN_RD_RA (RISCV_INSN_RA << RISCV_INSN_RD_POS) +#define RISCV_INSN_RD_T0 (RISCV_INSN_T0 << RISCV_INSN_RD_POS) +#define RISCV_INSN_RD_T1 (RISCV_INSN_T1 << RISCV_INSN_RD_POS) + +#define RISCV_INSN_RS1_POS 15 +#define RISCV_INSN_RS1_RA (RISCV_INSN_RA << RISCV_INSN_RS1_POS) +#define RISCV_INSN_RS1_T0 (RISCV_INSN_T0 << RISCV_INSN_RS1_POS) +#define RISCV_INSN_RS1_T1 (RISCV_INSN_T1 << RISCV_INSN_RS1_POS) + +#define RISCV_INSN_I_IMM_MASK _AC(0xfff00000, U) +#define RISCV_INSN_S_IMM_MASK _AC(0xfe000f80, U) +#define RISCV_INSN_B_IMM_MASK _AC(0xfe000f80, U) +#define RISCV_INSN_U_IMM_MASK _AC(0xfffff000, U) +#define RISCV_INSN_J_IMM_MASK _AC(0xfffff000, U) + +#define RISCV_INSN_CI_IMM_MASK _AC(0x107c, U) +#define RISCV_INSN_CSS_IMM_MASK _AC(0x1f80, U) +#define RISCV_INSN_CIW_IMM_MASK _AC(0x1fe0, U) +#define RISCV_INSN_CL_IMM_MASK _AC(0x1c60, U) +#define RISCV_INSN_CS_IMM_MASK _AC(0x1c60, U) +#define RISCV_INSN_CB_IMM_MASK _AC(0x1c7c, U) +#define RISCV_INSN_CJ_IMM_MASK _AC(0x1ffc, U) + +#ifndef __ASSEMBLY__ +#include +#include + +static inline bool riscv_insn_valid_20bit_offset(ptrdiff_t val) +{ + return !(val & 1) && -(1L << 19) <= val && val < (1L << 19); +} + +static inline bool riscv_insn_valid_32bit_offset(ptrdiff_t val) +{ + if (IS_ENABLED(CONFIG_32BIT)) + return true; + + /* + * auipc+jalr can reach any PC-relative offset in the range + * [-2^31 - 2^11, 2^31 - 2^11) + */ + return (-(1L << 31) - (1L << 11)) <= val && val < ((1L << 31) - (1L << 11)); +} + +static inline u32 riscv_insn_i_imm(u32 imm) +{ + return (imm & GENMASK(11, 0)) << 20; +} + +static inline u32 riscv_insn_s_imm(u32 imm) +{ + return (imm & GENMASK( 4, 0)) << ( 7 - 0) | + (imm & GENMASK(11, 5)) << (25 - 5); +} + +static inline u32 riscv_insn_b_imm(u32 imm) +{ + return (imm & GENMASK(11, 11)) >> (11 - 7) | + (imm & GENMASK( 4, 1)) << ( 8 - 1) | + (imm & GENMASK(10, 5)) << (25 - 5) | + (imm & GENMASK(12, 12)) << (31 - 12); +} + +static inline u32 riscv_insn_u_imm(u32 imm) +{ + return imm & GENMASK(31, 12); +} + +static inline u32 riscv_insn_j_imm(u32 imm) +{ + return (imm & GENMASK(19, 12)) << (12 - 12) | + (imm & GENMASK(11, 11)) << (20 - 11) | + (imm & GENMASK(10, 1)) << (21 - 1) | + (imm & GENMASK(20, 20)) << (31 - 20); +} + +static inline u16 riscv_insn_rvc_branch_imm(u16 imm) +{ + return (imm & GENMASK(5, 5)) >> ( 5 - 2) | + (imm & GENMASK(2, 1)) << ( 3 - 1) | + (imm & GENMASK(7, 6)) >> ( 6 - 5) | + (imm & GENMASK(4, 3)) << (10 - 3) | + (imm & GENMASK(8, 8)) << (12 - 8); +} + +static inline u16 riscv_insn_rvc_jump_imm(u16 imm) +{ + return (imm & GENMASK( 5, 5)) >> ( 5 - 2) | + (imm & GENMASK( 3, 1)) << ( 3 - 1) | + (imm & GENMASK( 7, 7)) >> ( 7 - 6) | + (imm & GENMASK( 6, 6)) << ( 7 - 6) | + (imm & GENMASK(10, 10)) >> (10 - 8) | + (imm & GENMASK( 9, 8)) << ( 9 - 8) | + (imm & GENMASK( 4, 4)) << (11 - 4) | + (imm & GENMASK(11, 11)) << (12 - 11); +} + +#endif +#endif From patchwork Mon Jan 31 18:27:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Emil Renner Berthing X-Patchwork-Id: 12731003 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6797AC433F5 for ; Mon, 31 Jan 2022 18:28:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=uxJ989v/GT/qqoN2Zfref2FBvgbsYB5S7PBlguMt99M=; b=0Nx4i4SOEwAzBO fb1TOntJI8b650zEhLfzDlrZ7iCRrXPpVdcK53J2r2gOrHm0iqhyrWeNChpbUtvpSl8Lbz6+u+i+E 05Vuhan5FOZ58diHWm/YrQ6RKckkSnUzK0xi/mfDNef8p8cVSLN37JyMvpsn64L/ryXDXJDpb9O/p z2eERlG8tml61rwDlAT6vA+yNrOSC2elHZkO7ftvET4GLIyiwuZLF7zgZMZ8C+N9S4ciW1ws41cyK s0nETkQGi3XbAQ2ZBaEdU2VgzPtdh267VUJSxMKsQjeCW+Q16SaZlUKvk2zEMqefhxK40WC3+rR46 WQP8dIXMTK+JRUa0LTNg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nEbPV-00ALVC-W7; Mon, 31 Jan 2022 18:28:18 +0000 Received: from mail-oo1-xc2c.google.com ([2607:f8b0:4864:20::c2c]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nEbPC-00ALIP-7K for linux-riscv@lists.infradead.org; Mon, 31 Jan 2022 18:28:00 +0000 Received: by mail-oo1-xc2c.google.com with SMTP id q145-20020a4a3397000000b002e85c7234b1so3421165ooq.8 for ; Mon, 31 Jan 2022 10:27:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=VzUOBCF2GRIbP/r2774p/6cI7x5/0EzMdeh+yBNP7rI=; b=W/MZ1pMibpaaH/NEFmtpq4FZh2hmJ/5ZDneTaK6q29s4W0wzELdHifv4kJ5gUwl371 8beImFnShdYyg++HyKF4sM4UdzDWOA+L13Jo+AlKteTrLguBzu0HQaAMBX+ergX3wD/X 0gCfRrxsOo7T7Wzapmz6vRyEdqmCH7T5mYNXncQZZcRiR+rulbDiX7rppD/l3QJ/ijd4 +9k+zR1Qn8tmK6Fd4faX/u4mp1KKiZW/GcIbwh+uFRKqDYAIznlZBBthnsNjxKh/fuPi Pkw585pkzeu3EQUFSE6aYYBfqJsFi7Z6m5VsWORfZcWjNjXVaQ6lJWPAaB0am/Y7dPGZ JuHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=VzUOBCF2GRIbP/r2774p/6cI7x5/0EzMdeh+yBNP7rI=; b=yjeqp7Mm+awVOAgasLiqbAAfFgvBz8lEnO0AWqz/4bJJ/LrQ6YsKEElPfI9kdV6H4s 2ZRHTB4DhXifS9qFSymfWikn8OpOfOvXZNqpIWQIVEBVt+bYAmMHlgpjg29zbx5uEZeD AoLWMtKUg1tkrE/j7XuxDZrl77QNs1fLjfpLx2RsZn1yfWGMGDn0gTP7BNRwdQRKcpec IVn9r2M91yCYMh9eHGOrbYqE+ttzBUY8kv++0R379VWzGHorBY1m/GE2jEqx1jjozZVA Chj+S8/kPJnRcP2Qb1L1ro6MUTqXucbnjThhkRk2yXcX0dTpThfsMw7VeBNfLUxhfioa DG/A== X-Gm-Message-State: AOAM531e76jh97O4KR5IhSA8GqArtnh2otiHYVclowUBIm0l+/5WkHdF 2fVkIGiu+MKSzyVZUoSk470hcy5Ww3AjTQ== X-Google-Smtp-Source: ABdhPJyopLmiqXJePWRxpLpjaT4YVXQthxB0f67V867ujjyucDDfJYsQoZ/Op1IiA7vf4hq5oJ/wJg== X-Received: by 2002:a4a:c606:: with SMTP id l6mr11026387ooq.27.1643653677285; Mon, 31 Jan 2022 10:27:57 -0800 (PST) Received: from stitch.. (80.71.140.73.ipv4.parknet.dk. [80.71.140.73]) by smtp.gmail.com with ESMTPSA id a26sm16041676oiy.26.2022.01.31.10.27.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Jan 2022 10:27:56 -0800 (PST) From: Emil Renner Berthing To: linux-riscv@lists.infradead.org Cc: Emil Renner Berthing , Paul Walmsley , Palmer Dabbelt , Albert Ou , Peter Zijlstra , Josh Poimboeuf , Jason Baron , Steven Rostedt , Ard Biesheuvel , Alexandre Ghiti , Jisheng Zhang , linux-kernel@vger.kernel.org Subject: [PATCH v2 5/7] riscv: Use asm/insn.h for module relocations Date: Mon, 31 Jan 2022 19:27:18 +0100 Message-Id: <20220131182720.236065-6-kernel@esmil.dk> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220131182720.236065-1-kernel@esmil.dk> References: <20220131182720.236065-1-kernel@esmil.dk> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220131_102758_305095_D3C53B0B X-CRM114-Status: GOOD ( 15.52 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org This converts the module relocations in kernel/module.c to use asm/insn.h for instruction manipulation. Also RISC-V has a number of instruction pairs to generate 32bit immediates or jump/call offsets. Eg.: lui rd, hi20 addi rd, rd, lo12 ..where hi20 is the upper 20bits to load into register rd and lo12 is the lower 12bits. However both immediates are interpreted as two's complement signed values. Hence the old code calculates hi20 and lo12 for 32bit immediates imm like this: hi20 = (imm + 0x800) & 0xfffff000; lo12 = (imm - hi20) & 0xfff; This patch simplifies it to: hi20 = (imm + 0x800) & 0xfffff000; lo12 = imm & 0xfff; ..which amounts to the same: imm - hi20 may be become negative/underflow, but it doesn't change the lower 12 bits. Signed-off-by: Emil Renner Berthing Reported-by: kernel test robot --- arch/riscv/kernel/module.c | 138 +++++++++++++++---------------------- 1 file changed, 56 insertions(+), 82 deletions(-) diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c index a75ccf3a6ce8..2212d88776e0 100644 --- a/arch/riscv/kernel/module.c +++ b/arch/riscv/kernel/module.c @@ -2,6 +2,7 @@ /* * * Copyright (C) 2017 Zihao Yu + * Copyright (C) 2020 Emil Renner Berthing */ #include @@ -11,38 +12,27 @@ #include #include #include +#include #include -static inline bool riscv_insn_valid_32bit_offset(ptrdiff_t val) -{ - if (IS_ENABLED(CONFIG_32BIT)) - return true; - - /* - * auipc+jalr can reach any PC-relative offset in the range - * [-2^31 - 2^11, 2^31 - 2^11) - */ - return (-(1L << 31) - (1L << 11)) <= val && val < ((1L << 31) - (1L << 11)); -} - -static int riscv_insn_rmw(void *location, u32 keep, u32 set) +static int riscv_insn_rmw(void *location, u32 mask, u32 value) { u16 *parcel = location; u32 insn = (u32)parcel[0] | (u32)parcel[1] << 16; - insn &= keep; - insn |= set; + insn &= ~mask; + insn |= value; parcel[0] = insn; parcel[1] = insn >> 16; return 0; } -static int riscv_insn_rvc_rmw(void *location, u16 keep, u16 set) +static int riscv_insn_rvc_rmw(void *location, u16 mask, u16 value) { u16 *parcel = location; - *parcel = (*parcel & keep) | set; + *parcel = (*parcel & ~mask) | value; return 0; } @@ -67,55 +57,40 @@ static int apply_r_riscv_branch_rela(struct module *me, void *location, Elf_Addr v) { ptrdiff_t offset = (void *)v - location; - u32 imm12 = (offset & 0x1000) << (31 - 12); - u32 imm11 = (offset & 0x800) >> (11 - 7); - u32 imm10_5 = (offset & 0x7e0) << (30 - 10); - u32 imm4_1 = (offset & 0x1e) << (11 - 4); - return riscv_insn_rmw(location, 0x1fff07f, imm12 | imm11 | imm10_5 | imm4_1); + return riscv_insn_rmw(location, + RISCV_INSN_B_IMM_MASK, + riscv_insn_b_imm(offset)); } static int apply_r_riscv_jal_rela(struct module *me, void *location, Elf_Addr v) { ptrdiff_t offset = (void *)v - location; - u32 imm20 = (offset & 0x100000) << (31 - 20); - u32 imm19_12 = (offset & 0xff000); - u32 imm11 = (offset & 0x800) << (20 - 11); - u32 imm10_1 = (offset & 0x7fe) << (30 - 10); - return riscv_insn_rmw(location, 0xfff, imm20 | imm19_12 | imm11 | imm10_1); + return riscv_insn_rmw(location, + RISCV_INSN_J_IMM_MASK, + riscv_insn_j_imm(offset)); } static int apply_r_riscv_rvc_branch_rela(struct module *me, void *location, Elf_Addr v) { ptrdiff_t offset = (void *)v - location; - u16 imm8 = (offset & 0x100) << (12 - 8); - u16 imm7_6 = (offset & 0xc0) >> (6 - 5); - u16 imm5 = (offset & 0x20) >> (5 - 2); - u16 imm4_3 = (offset & 0x18) << (12 - 5); - u16 imm2_1 = (offset & 0x6) << (12 - 10); - - return riscv_insn_rvc_rmw(location, 0xe383, - imm8 | imm7_6 | imm5 | imm4_3 | imm2_1); + + return riscv_insn_rvc_rmw(location, + RISCV_INSN_CB_IMM_MASK, + riscv_insn_rvc_branch_imm(offset)); } static int apply_r_riscv_rvc_jump_rela(struct module *me, void *location, Elf_Addr v) { ptrdiff_t offset = (void *)v - location; - u16 imm11 = (offset & 0x800) << (12 - 11); - u16 imm10 = (offset & 0x400) >> (10 - 8); - u16 imm9_8 = (offset & 0x300) << (12 - 11); - u16 imm7 = (offset & 0x80) >> (7 - 6); - u16 imm6 = (offset & 0x40) << (12 - 11); - u16 imm5 = (offset & 0x20) >> (5 - 2); - u16 imm4 = (offset & 0x10) << (12 - 5); - u16 imm3_1 = (offset & 0xe) << (12 - 10); - - return riscv_insn_rvc_rmw(location, 0xe003, - imm11 | imm10 | imm9_8 | imm7 | imm6 | imm5 | imm4 | imm3_1); + + return riscv_insn_rvc_rmw(location, + RISCV_INSN_CJ_IMM_MASK, + riscv_insn_rvc_jump_imm(offset)); } static int apply_r_riscv_pcrel_hi20_rela(struct module *me, void *location, @@ -130,30 +105,27 @@ static int apply_r_riscv_pcrel_hi20_rela(struct module *me, void *location, return -EINVAL; } - return riscv_insn_rmw(location, 0xfff, (offset + 0x800) & 0xfffff000); + return riscv_insn_rmw(location, + RISCV_INSN_U_IMM_MASK, + riscv_insn_u_imm(offset + 0x800)); } static int apply_r_riscv_pcrel_lo12_i_rela(struct module *me, void *location, Elf_Addr v) { - /* - * v is the lo12 value to fill. It is calculated before calling this - * handler. - */ - return riscv_insn_rmw(location, 0xfffff, (v & 0xfff) << 20); + /* v is already the relative offset */ + return riscv_insn_rmw(location, + RISCV_INSN_I_IMM_MASK, + riscv_insn_i_imm(v)); } static int apply_r_riscv_pcrel_lo12_s_rela(struct module *me, void *location, Elf_Addr v) { - /* - * v is the lo12 value to fill. It is calculated before calling this - * handler. - */ - u32 imm11_5 = (v & 0xfe0) << (31 - 11); - u32 imm4_0 = (v & 0x1f) << (11 - 4); - - return riscv_insn_rmw(location, 0x1fff07f, imm11_5 | imm4_0); + /* v is already the relative offset */ + return riscv_insn_rmw(location, + RISCV_INSN_S_IMM_MASK, + riscv_insn_s_imm(v)); } static int apply_r_riscv_hi20_rela(struct module *me, void *location, @@ -166,29 +138,27 @@ static int apply_r_riscv_hi20_rela(struct module *me, void *location, return -EINVAL; } - return riscv_insn_rmw(location, 0xfff, ((s32)v + 0x800) & 0xfffff000); + return riscv_insn_rmw(location, + RISCV_INSN_U_IMM_MASK, + riscv_insn_u_imm(v + 0x800)); } static int apply_r_riscv_lo12_i_rela(struct module *me, void *location, Elf_Addr v) { /* Skip medlow checking because of filtering by HI20 already */ - s32 hi20 = ((s32)v + 0x800) & 0xfffff000; - s32 lo12 = ((s32)v - hi20); - - return riscv_insn_rmw(location, 0xfffff, (lo12 & 0xfff) << 20); + return riscv_insn_rmw(location, + RISCV_INSN_I_IMM_MASK, + riscv_insn_i_imm(v)); } static int apply_r_riscv_lo12_s_rela(struct module *me, void *location, Elf_Addr v) { /* Skip medlow checking because of filtering by HI20 already */ - s32 hi20 = ((s32)v + 0x800) & 0xfffff000; - s32 lo12 = ((s32)v - hi20); - u32 imm11_5 = (lo12 & 0xfe0) << (31 - 11); - u32 imm4_0 = (lo12 & 0x1f) << (11 - 4); - - return riscv_insn_rmw(location, 0x1fff07f, imm11_5 | imm4_0); + return riscv_insn_rmw(location, + RISCV_INSN_S_IMM_MASK, + riscv_insn_s_imm(v)); } static int apply_r_riscv_got_hi20_rela(struct module *me, void *location, @@ -206,14 +176,15 @@ static int apply_r_riscv_got_hi20_rela(struct module *me, void *location, return -EINVAL; } - return riscv_insn_rmw(location, 0xfff, (offset + 0x800) & 0xfffff000); + return riscv_insn_rmw(location, + RISCV_INSN_U_IMM_MASK, + riscv_insn_u_imm(offset + 0x800)); } static int apply_r_riscv_call_plt_rela(struct module *me, void *location, Elf_Addr v) { ptrdiff_t offset = (void *)v - location; - u32 hi20, lo12; if (!riscv_insn_valid_32bit_offset(offset)) { /* Only emit the plt entry if offset over 32-bit range */ @@ -227,17 +198,18 @@ static int apply_r_riscv_call_plt_rela(struct module *me, void *location, } } - hi20 = (offset + 0x800) & 0xfffff000; - lo12 = (offset - hi20) & 0xfff; - riscv_insn_rmw(location, 0xfff, hi20); - return riscv_insn_rmw(location + 4, 0xfffff, lo12 << 20); + riscv_insn_rmw(location, + RISCV_INSN_U_IMM_MASK, + riscv_insn_u_imm(offset + 0x800)); + return riscv_insn_rmw(location + 4, + RISCV_INSN_I_IMM_MASK, + riscv_insn_i_imm(offset)); } static int apply_r_riscv_call_rela(struct module *me, void *location, Elf_Addr v) { ptrdiff_t offset = (void *)v - location; - u32 hi20, lo12; if (!riscv_insn_valid_32bit_offset(offset)) { pr_err( @@ -246,10 +218,12 @@ static int apply_r_riscv_call_rela(struct module *me, void *location, return -EINVAL; } - hi20 = (offset + 0x800) & 0xfffff000; - lo12 = (offset - hi20) & 0xfff; - riscv_insn_rmw(location, 0xfff, hi20); - return riscv_insn_rmw(location + 4, 0xfffff, lo12 << 20); + riscv_insn_rmw(location, + RISCV_INSN_U_IMM_MASK, + riscv_insn_u_imm(offset + 0x800)); + return riscv_insn_rmw(location + 4, + RISCV_INSN_I_IMM_MASK, + riscv_insn_i_imm(offset)); } static int apply_r_riscv_relax_rela(struct module *me, void *location, From patchwork Mon Jan 31 18:27:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Emil Renner Berthing X-Patchwork-Id: 12731004 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3ED72C433EF for ; Mon, 31 Jan 2022 18:28:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=VGGEGMpYvPKEvnedgucXcLRWaBv7IyN5uKFnsxCjmLw=; b=mNAxpYSz1Slhrh gibEJ2UpnngIT9y4vDeTji+UyoaJMDH58yUUhDV0i6qFpbDhvCgbQjkL6H4Qxc8fb0SG3YpT1/Bpa FZ/kKy7oqLFsYccPea4cxc60rRIBPwpkzk+w3TAHeWaI7cUgwwIBD8Oklqk2RvM8VPkTrZMRw+hP/ R7C9tKQI5vkVKNEDsb/TqReE88FTy4eqDnccSH/8MkWCoOxBSr2xzpSWs2Lx9J8m0S5fmiZvsDFvm W276YQCwo95Mt/GfaxVUiu431APiUEACXLyHEFLNzmlbvyCuvXQk9+LpCrlDc7RPBYkP7k673O9fo Stxs6eWZAjMXciXrSp8g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nEbPY-00ALXK-A4; Mon, 31 Jan 2022 18:28:20 +0000 Received: from mail-oi1-x233.google.com ([2607:f8b0:4864:20::233]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nEbPF-00ALKu-GB for linux-riscv@lists.infradead.org; Mon, 31 Jan 2022 18:28:03 +0000 Received: by mail-oi1-x233.google.com with SMTP id e81so28361841oia.6 for ; Mon, 31 Jan 2022 10:28:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Uv9kZcj+SYuMKmc2v8qVWQoeoD1xbOxuZhUO9LDOn7M=; b=ae2tEWK0mabJWBmBgb5+OPbZ4b4jy14di2q6CL9US53w3IQdvYKiJqQL97T2G1wDVb M50JwRAHj1f5EZbC/U8JiRH/KACoNyG/uqmAO3x6eKrJkOmt9gJi9U0ifS3seocUEW9r hyaY3Xg6rvhtptwS5T0dGbJAKZaAMebQ/Qc53ybw5n+gqM9uxnLXV6hHOkYDR5yGHFS7 Z3ORY6td/UaqX8Ax1lYM1IDFFab8WZtPvgutSSoaqW4g7/FDPZPYTid+YrJa62DTXZUi MhsD7QtoIZwz6MtZUjbgf5vaNl0O/132oNzAS1fkOSz9QfYHQC+Lv79GFuYie5OG218Q wjZg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=Uv9kZcj+SYuMKmc2v8qVWQoeoD1xbOxuZhUO9LDOn7M=; b=k3I6V+76nOlcbYuIpY4qlZzIk+fkYRBujjno2PsoueHWmAsRzRjD9gThugYsHEc2Mq bdu0ldSXKNpakQtriDHFmePFOcsD6LEIL0ViriQgrNN2hYcMvPFAScHRM5DBVtyqtRtT HvvU69mjQvaqdOaYXEHJ5QbdgiFvmZj7E+px5CsU2kAZXBEktCjikO53TBPpvFSQPZZq 51Pgcc4QagVVJMVIOYALmW9G7oJK5Xd1ypgf4BVeVlOTgeTcfH3H8bGwujtnQ10ZBb2w jPCKTWsK9YO94HE5IrQ8gNlOxEJ6nnRva3YzuKkmJnKqXDz6W5JxKuUOlXW+FFhZJt0U kWow== X-Gm-Message-State: AOAM532g7FrpaBuQmujWk7ZTKAkrn7GMFGQc3AnuzXpFuaw+DfktNwPC cU8o/CAY3DW9oyrQRoO3XpNjHehC1i6eAg== X-Google-Smtp-Source: ABdhPJw/C4So3Aq1Zja1WakK5TxhFMU6yk7ULAS3F55FaGH/rIbSkWXxwvjmSKICqrUp4l6kNQa84Q== X-Received: by 2002:aca:aa86:: with SMTP id t128mr13285285oie.169.1643653680913; Mon, 31 Jan 2022 10:28:00 -0800 (PST) Received: from stitch.. (80.71.140.73.ipv4.parknet.dk. [80.71.140.73]) by smtp.gmail.com with ESMTPSA id a26sm16041676oiy.26.2022.01.31.10.27.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Jan 2022 10:28:00 -0800 (PST) From: Emil Renner Berthing To: linux-riscv@lists.infradead.org Cc: Emil Renner Berthing , Paul Walmsley , Palmer Dabbelt , Albert Ou , Peter Zijlstra , Josh Poimboeuf , Jason Baron , Steven Rostedt , Ard Biesheuvel , Alexandre Ghiti , Jisheng Zhang , linux-kernel@vger.kernel.org Subject: [PATCH v2 6/7] riscv: Use asm/insn.h to generate plt entries Date: Mon, 31 Jan 2022 19:27:19 +0100 Message-Id: <20220131182720.236065-7-kernel@esmil.dk> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220131182720.236065-1-kernel@esmil.dk> References: <20220131182720.236065-1-kernel@esmil.dk> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220131_102801_561911_44C7D2AF X-CRM114-Status: GOOD ( 11.14 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org This converts kernel/module-sections.c to use asm/insn.h to generate the instructions in the plt entries. Signed-off-by: Emil Renner Berthing --- arch/riscv/kernel/module-sections.c | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/arch/riscv/kernel/module-sections.c b/arch/riscv/kernel/module-sections.c index 39d4ac681c2a..cb73399c3603 100644 --- a/arch/riscv/kernel/module-sections.c +++ b/arch/riscv/kernel/module-sections.c @@ -9,6 +9,7 @@ #include #include #include +#include struct got_entry { unsigned long symbol_addr; /* the real variable address */ @@ -61,36 +62,16 @@ struct plt_entry { u32 insn_jr; /* jr t1 */ }; -#define OPC_AUIPC 0x0017 -#define OPC_LD 0x3003 -#define OPC_JALR 0x0067 -#define REG_T0 0x5 -#define REG_T1 0x6 - static struct plt_entry emit_plt_entry(unsigned long val, unsigned long plt, unsigned long got_plt) { - /* - * U-Type encoding: - * +------------+----------+----------+ - * | imm[31:12] | rd[11:7] | opc[6:0] | - * +------------+----------+----------+ - * - * I-Type encoding: - * +------------+------------+--------+----------+----------+ - * | imm[31:20] | rs1[19:15] | funct3 | rd[11:7] | opc[6:0] | - * +------------+------------+--------+----------+----------+ - * - */ unsigned long offset = got_plt - plt; - u32 hi20 = (offset + 0x800) & 0xfffff000; - u32 lo12 = (offset - hi20); return (struct plt_entry) { - OPC_AUIPC | (REG_T0 << 7) | hi20, - OPC_LD | (lo12 << 20) | (REG_T0 << 15) | (REG_T1 << 7), - OPC_JALR | (REG_T1 << 15) + RISCV_INSN_AUIPC | RISCV_INSN_RD_T0 | riscv_insn_u_imm(offset + 0x800), + RISCV_INSN_LD | RISCV_INSN_RD_T1 | RISCV_INSN_RS1_T0 | riscv_insn_i_imm(offset), + RISCV_INSN_JALR | RISCV_INSN_RS1_T1, }; } From patchwork Mon Jan 31 18:27:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Emil Renner Berthing X-Patchwork-Id: 12731005 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 82C51C433EF for ; Mon, 31 Jan 2022 18:28:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=GW96CPND3IDXIlCjq1GQtuFX2I0NC7pyVKjt8cUvO/g=; b=QOBknT8R4TpeQ9 Mf+H6UkOsK4b8+/MwcQKI4DKWG/cd+NPY/EHxxzVdPeQX18dMFF/H1qyXwRWWQl6QDkdEYPAUWkDu XCw1Xf6b5XMpJ+nOXjBGClf7MBomcHUMHLQaptO1Jlw2+Dsodw63JBiT5cle1YWF3XCgskCkEgAI8 VwLQQvqwwQXbigD8Lfqa7VERzd2SrwMGKPHY61jb0yNzKaqaFP4/AXo/yc7q9R5JzmYS2IkarJjYe yFoWG8xy8GNmLdT4RlhMxP/wUOWRHZLM8l02+8xQEn1z6/vRGWsiieJiWOiYDoHNaH15qBEatWCi7 CYs8vKs/7+8nCw/XCjQw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nEbPb-00ALZl-Fd; Mon, 31 Jan 2022 18:28:23 +0000 Received: from mail-oi1-x22a.google.com ([2607:f8b0:4864:20::22a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nEbPJ-00ALNr-QT for linux-riscv@lists.infradead.org; Mon, 31 Jan 2022 18:28:07 +0000 Received: by mail-oi1-x22a.google.com with SMTP id r27so6176384oiw.4 for ; Mon, 31 Jan 2022 10:28:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=U2McVQuv53c33dZYwtuytrfr7zhfRHKf5OwpDdiji0Q=; b=jXncjUEe1a2gGcfncdsQNKvZ5vzVDf3n4UUs/6i0J6Jovf2zn5tkf9YNbcUhJRIhg4 iiP5AXss/MrSWrwT2nrnFSCUKqo4LurylYJQzQBtUTR9mq/aUdlu8wO44IdVDCaCW+6L NNlbkLNAO8/ve9RpEP9HFYPbHdeae7zd3RRsmMTaWG1PkZn6hZS9N36KpE42yE+L/UKN yQ/jom03GwNzQ2o0lmB0vxoraJkSvOmzNF21tzteuYplOQJot9C6Jn/yGqc7MRnHmTta eABYEarwMVl+7m0KRcJ2VcS4VNXOomnltMSl4Kyvtjt5bCCCZT9xPD97gTjLHPmtSJCI tnQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=U2McVQuv53c33dZYwtuytrfr7zhfRHKf5OwpDdiji0Q=; b=2RHUguA1kE0ugqDAaC1htZnUNVoDpL+tE8wIL98IR/Iz77PTQ2WZS/2PBuSzSFaK1a BSt/nykEDsnyRWA6VltXiPunMUTiHp+V3Z+5uszjiTn1FpVyVNUmeb5QBMSDZM9cHQk0 84BFYx/3Oh7xWwKJHivXROyXgODoxQyV/ycioAGoWPJsK0+QEscRUt2U2eD5NEKAbFTX NzLiCrvGCYkKeutJ9sK4OL1MUHmYUPHSBiiWwBpKDcCofm7CRUOufgCNMac3B51Ym8Tp QzTi4A2XYuShVuUpJWPbKj6CBa51cUXb7f2B+YJyVtOHSgrCdT6IsKcICueIsY/MveG5 7c5g== X-Gm-Message-State: AOAM533AJM8i4WtJfE/xETFPCVFelY4fEG0ceRecjPG29dB6pkAJ4Kgz xjDRyplbQr+SwNy8P/e6SECY2sZ2PuQ5rQ== X-Google-Smtp-Source: ABdhPJykrjHso1HeIEehNxkQa/Hvgme48EycTjUAdgXHfcYLHtwx65a013NI9+o+UcHqFs6xlO//5w== X-Received: by 2002:aca:1e1a:: with SMTP id m26mr14036052oic.208.1643653684887; Mon, 31 Jan 2022 10:28:04 -0800 (PST) Received: from stitch.. (80.71.140.73.ipv4.parknet.dk. [80.71.140.73]) by smtp.gmail.com with ESMTPSA id a26sm16041676oiy.26.2022.01.31.10.28.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Jan 2022 10:28:04 -0800 (PST) From: Emil Renner Berthing To: linux-riscv@lists.infradead.org Cc: Emil Renner Berthing , Paul Walmsley , Palmer Dabbelt , Albert Ou , Peter Zijlstra , Josh Poimboeuf , Jason Baron , Steven Rostedt , Ard Biesheuvel , Alexandre Ghiti , Jisheng Zhang , linux-kernel@vger.kernel.org Subject: [PATCH v2 7/7] riscv: Use asm/insn.h for jump labels Date: Mon, 31 Jan 2022 19:27:20 +0100 Message-Id: <20220131182720.236065-8-kernel@esmil.dk> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220131182720.236065-1-kernel@esmil.dk> References: <20220131182720.236065-1-kernel@esmil.dk> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220131_102805_871903_1917199D X-CRM114-Status: GOOD ( 10.71 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org This converts kernel/jump_label.c to use asm/insn.h to generate the jump/nop instructions. Signed-off-by: Emil Renner Berthing Reported-by: kernel test robot Reported-by: kernel test robot --- arch/riscv/kernel/jump_label.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/arch/riscv/kernel/jump_label.c b/arch/riscv/kernel/jump_label.c index 20e09056d141..b5b4892c3e9e 100644 --- a/arch/riscv/kernel/jump_label.c +++ b/arch/riscv/kernel/jump_label.c @@ -9,11 +9,9 @@ #include #include #include +#include #include -#define RISCV_INSN_NOP 0x00000013U -#define RISCV_INSN_JAL 0x0000006fU - void arch_jump_label_transform(struct jump_entry *entry, enum jump_label_type type) { @@ -23,14 +21,10 @@ void arch_jump_label_transform(struct jump_entry *entry, if (type == JUMP_LABEL_JMP) { long offset = jump_entry_target(entry) - jump_entry_code(entry); - if (WARN_ON(offset & 1 || offset < -524288 || offset >= 524288)) + if (WARN_ON(!riscv_insn_valid_20bit_offset(offset))) return; - insn = RISCV_INSN_JAL | - (((u32)offset & GENMASK(19, 12)) << (12 - 12)) | - (((u32)offset & GENMASK(11, 11)) << (20 - 11)) | - (((u32)offset & GENMASK(10, 1)) << (21 - 1)) | - (((u32)offset & GENMASK(20, 20)) << (31 - 20)); + insn = RISCV_INSN_JAL | riscv_insn_j_imm(offset); } else { insn = RISCV_INSN_NOP; }