From nobody Mon Jun 29 23:03:57 2026 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 A69B6C433FE for ; Mon, 31 Jan 2022 18:27:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355298AbiAaS1s (ORCPT ); Mon, 31 Jan 2022 13:27:48 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35838 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355318AbiAaS1n (ORCPT ); Mon, 31 Jan 2022 13:27:43 -0500 Received: from mail-oi1-x22e.google.com (mail-oi1-x22e.google.com [IPv6:2607:f8b0:4864:20::22e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 622DFC06173D for ; Mon, 31 Jan 2022 10:27:43 -0800 (PST) Received: by mail-oi1-x22e.google.com with SMTP id t199so11734064oie.10 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=vuFM/aSM9wCp2PQkAhD8KsVoW7FE4JRdmk48Snd+FYf5QUWeq9zATnJj7V5sG935Tx 55MiT129YvlV/gHwYDndayxLB0r2hJDrLn+DjHXcCMZrzDhegqLA+G2r6mOQmjgEO/1i dODMJIjKEmQWKKg3dDeCZzBnEy8xrjxjZCsPMMUk6qy+ulrZs/RftE5HTmXl1gtrV5xv pR4Zq/+LROLxTEd/CRuIKATKpPD+sR/MtvojHBlx9+BfCvBSHhm8phV8NMRrLs3H0PAI EIkaoIQaRVpINyFL1GEIGLF0iwD8ZDvlzVx+5QhQHJgnK2erdU2qTEccQQXfjPJKHPSi TCBg== X-Gm-Message-State: AOAM533duueseuDNN9qMe862J+gq2AkfzT6Ra9VIBV8EQC/i9l8M53n6 +ukGUKSEDMIzvSVu0bPY+Us= 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) Sender: Emil Renner Berthing 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 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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/modul= e.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 =3D (struct got_entry *)(sec->shdr->sh_addr); - int i; - for (i =3D 0; i < sec->num_entries; i++) { - if (got[i].symbol_addr =3D=3D 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 =3D got_plt - plt; - u32 hi20 =3D (offset + 0x800) & 0xfffff000; - u32 lo12 =3D (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_sect= ion *sec) -{ - struct got_entry *got_plt =3D (struct got_entry *)sec->shdr->sh_addr; - int i; - for (i =3D 0; i < sec->num_entries; i++) { - if (got_plt[i].symbol_addr =3D=3D 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 =3D (struct plt_entry *)sec_plt->shdr->sh_addr; - int got_plt_idx =3D get_got_plt_idx(val, sec_got_plt); - if (got_plt_idx >=3D 0) - return plt + got_plt_idx; - else - return NULL; -} - #endif /* CONFIG_MODULE_SECTIONS */ =20 #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 =20 +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 =3D (struct got_entry *)(sec->shdr->sh_addr); + int i; + + for (i =3D 0; i < sec->num_entries; i++) { + if (got[i].symbol_addr =3D=3D val) + return &got[i]; + } + return NULL; +} + unsigned long module_emit_got_entry(struct module *mod, unsigned long val) { struct mod_section *got_sec =3D &mod->arch.got; @@ -29,6 +51,74 @@ unsigned long module_emit_got_entry(struct module *mod, = unsigned long val) return (unsigned long)&got[i]; } =20 +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 =3D got_plt - plt; + u32 hi20 =3D (offset + 0x800) & 0xfffff000; + u32 lo12 =3D (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 *se= c) +{ + struct got_entry *got_plt =3D (struct got_entry *)sec->shdr->sh_addr; + int i; + + for (i =3D 0; i < sec->num_entries; i++) { + if (got_plt[i].symbol_addr =3D=3D 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 =3D (struct plt_entry *)sec_plt->shdr->sh_addr; + int got_plt_idx =3D get_got_plt_idx(val, sec_got_plt); + + if (got_plt_idx >=3D 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 =3D &mod->arch.got_plt; --=20 2.35.1 From nobody Mon Jun 29 23:03:57 2026 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 AE06BC433EF for ; Mon, 31 Jan 2022 18:27:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1351249AbiAaS1w (ORCPT ); Mon, 31 Jan 2022 13:27:52 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35862 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355120AbiAaS1r (ORCPT ); Mon, 31 Jan 2022 13:27:47 -0500 Received: from mail-oi1-x22b.google.com (mail-oi1-x22b.google.com [IPv6:2607:f8b0:4864:20::22b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EAA1BC061401 for ; Mon, 31 Jan 2022 10:27:46 -0800 (PST) Received: by mail-oi1-x22b.google.com with SMTP id v67so28325845oie.9 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=ViOQa7jA/PeOemmKqa5KUoARehE0aotMFnMggBj1x23vDsG6SRNZDJDHl/H9pIpMFl CYEooVOo4pxXI5TZTs6DohnxNU2X4+q5geLMk9VW3MDwN+yst4TqP64uAEFNELWiucVy 7dcTkw5AZaexhPCKuLtKJgoRgkPx6hEwKM2CnxdMAdsngPPNqKAGgWFthta496tAId/k FIMXIEV/M7GfW/ouPmVwL9Xz2WOnxW3s/klDKxaXF7y0FB4VkIltksopJyCmQJkpuRxI +Hr5CZa8LWQfHr/jXEH8yWEH1domUvsgNXD9uPrHGV/kCxp4Go0BrZbX5tpamv91pVJ4 hvTA== X-Gm-Message-State: AOAM530AmoojdHQuJFDHAfA9ZJuF1IyXY/Ebu927tfnxKUSqFgCf3Jex v2G2+eapKjKLQshWuS2MaPg= 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) Sender: Emil Renner Berthing 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 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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 =20 -static int apply_r_riscv_32_rela(struct module *me, u32 *location, Elf_Add= r v) +static int riscv_insn_rmw(void *location, u32 keep, u32 set) +{ + u16 *parcel =3D location; + u32 insn =3D (u32)parcel[0] | (u32)parcel[1] << 16; + + insn &=3D keep; + insn |=3D set; + + parcel[0] =3D insn; + parcel[1] =3D insn >> 16; + return 0; +} + +static int riscv_insn_rvc_rmw(void *location, u16 keep, u16 set) +{ + u16 *parcel =3D location; + + *parcel =3D (*parcel & keep) | set; + return 0; +} + +static int apply_r_riscv_32_rela(struct module *me, void *location, Elf_Ad= dr v) { if (v !=3D (u32)v) { pr_err("%s: value %016llx out of range for 32-bit field\n", me->name, (long long)v); return -EINVAL; } - *location =3D v; + *(u32 *)location =3D v; return 0; } =20 -static int apply_r_riscv_64_rela(struct module *me, u32 *location, Elf_Add= r v) +static int apply_r_riscv_64_rela(struct module *me, void *location, Elf_Ad= dr v) { *(u64 *)location =3D v; return 0; } =20 -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 =3D (void *)v - (void *)location; + ptrdiff_t offset =3D (void *)v - location; u32 imm12 =3D (offset & 0x1000) << (31 - 12); u32 imm11 =3D (offset & 0x800) >> (11 - 7); u32 imm10_5 =3D (offset & 0x7e0) << (30 - 10); u32 imm4_1 =3D (offset & 0x1e) << (11 - 4); =20 - *location =3D (*location & 0x1fff07f) | imm12 | imm11 | imm10_5 | imm4_1; - return 0; + return riscv_insn_rmw(location, 0x1fff07f, imm12 | imm11 | imm10_5 | imm4= _1); } =20 -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 =3D (void *)v - (void *)location; + ptrdiff_t offset =3D (void *)v - location; u32 imm20 =3D (offset & 0x100000) << (31 - 20); u32 imm19_12 =3D (offset & 0xff000); u32 imm11 =3D (offset & 0x800) << (20 - 11); u32 imm10_1 =3D (offset & 0x7fe) << (30 - 10); =20 - *location =3D (*location & 0xfff) | imm20 | imm19_12 | imm11 | imm10_1; - return 0; + return riscv_insn_rmw(location, 0xfff, imm20 | imm19_12 | imm11 | imm10_1= ); } =20 -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 =3D (void *)v - (void *)location; + ptrdiff_t offset =3D (void *)v - location; u16 imm8 =3D (offset & 0x100) << (12 - 8); u16 imm7_6 =3D (offset & 0xc0) >> (6 - 5); u16 imm5 =3D (offset & 0x20) >> (5 - 2); u16 imm4_3 =3D (offset & 0x18) << (12 - 5); u16 imm2_1 =3D (offset & 0x6) << (12 - 10); =20 - *(u16 *)location =3D (*(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); } =20 -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 =3D (void *)v - (void *)location; + ptrdiff_t offset =3D (void *)v - location; u16 imm11 =3D (offset & 0x800) << (12 - 11); u16 imm10 =3D (offset & 0x400) >> (10 - 8); u16 imm9_8 =3D (offset & 0x300) << (12 - 11); @@ -84,16 +102,14 @@ static int apply_r_riscv_rvc_jump_rela(struct module *= me, u32 *location, u16 imm4 =3D (offset & 0x10) << (12 - 5); u16 imm3_1 =3D (offset & 0xe) << (12 - 10); =20 - *(u16 *)location =3D (*(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); } =20 -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 =3D (void *)v - (void *)location; - s32 hi20; + ptrdiff_t offset =3D (void *)v - location; =20 if (offset !=3D (s32)offset) { pr_err( @@ -102,23 +118,20 @@ static int apply_r_riscv_pcrel_hi20_rela(struct modul= e *me, u32 *location, return -EINVAL; } =20 - hi20 =3D (offset + 0x800) & 0xfffff000; - *location =3D (*location & 0xfff) | hi20; - return 0; + return riscv_insn_rmw(location, 0xfff, (offset + 0x800) & 0xfffff000); } =20 -static int apply_r_riscv_pcrel_lo12_i_rela(struct module *me, u32 *locatio= n, +static int apply_r_riscv_pcrel_lo12_i_rela(struct module *me, void *locati= on, Elf_Addr v) { /* * v is the lo12 value to fill. It is calculated before calling this * handler. */ - *location =3D (*location & 0xfffff) | ((v & 0xfff) << 20); - return 0; + return riscv_insn_rmw(location, 0xfffff, (v & 0xfff) << 20); } =20 -static int apply_r_riscv_pcrel_lo12_s_rela(struct module *me, u32 *locatio= n, +static int apply_r_riscv_pcrel_lo12_s_rela(struct module *me, void *locati= on, Elf_Addr v) { /* @@ -128,15 +141,12 @@ static int apply_r_riscv_pcrel_lo12_s_rela(struct mod= ule *me, u32 *location, u32 imm11_5 =3D (v & 0xfe0) << (31 - 11); u32 imm4_0 =3D (v & 0x1f) << (11 - 4); =20 - *location =3D (*location & 0x1fff07f) | imm11_5 | imm4_0; - return 0; + return riscv_insn_rmw(location, 0x1fff07f, imm11_5 | imm4_0); } =20 -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 = =3D %p\n", @@ -144,22 +154,20 @@ static int apply_r_riscv_hi20_rela(struct module *me,= u32 *location, return -EINVAL; } =20 - hi20 =3D ((s32)v + 0x800) & 0xfffff000; - *location =3D (*location & 0xfff) | hi20; - return 0; + return riscv_insn_rmw(location, 0xfff, ((s32)v + 0x800) & 0xfffff000); } =20 -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 =3D ((s32)v + 0x800) & 0xfffff000; s32 lo12 =3D ((s32)v - hi20); - *location =3D (*location & 0xfffff) | ((lo12 & 0xfff) << 20); - return 0; + + return riscv_insn_rmw(location, 0xfffff, (lo12 & 0xfff) << 20); } =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 *m= e, u32 *location, s32 lo12 =3D ((s32)v - hi20); u32 imm11_5 =3D (lo12 & 0xfe0) << (31 - 11); u32 imm4_0 =3D (lo12 & 0x1f) << (11 - 4); - *location =3D (*location & 0x1fff07f) | imm11_5 | imm4_0; - return 0; + + return riscv_insn_rmw(location, 0x1fff07f, imm11_5 | imm4_0); } =20 -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 =3D (void *)v - (void *)location; - s32 hi20; + ptrdiff_t offset =3D (void *)v - location; =20 /* Always emit the got entry */ if (IS_ENABLED(CONFIG_MODULE_SECTIONS)) { - offset =3D module_emit_got_entry(me, v); - offset =3D (void *)offset - (void *)location; + offset =3D (void *)module_emit_got_entry(me, v) - location; } else { pr_err( "%s: can not generate the GOT entry for symbol =3D %016llx from PC =3D= %p\n", @@ -188,23 +194,20 @@ static int apply_r_riscv_got_hi20_rela(struct module = *me, u32 *location, return -EINVAL; } =20 - hi20 =3D (offset + 0x800) & 0xfffff000; - *location =3D (*location & 0xfff) | hi20; - return 0; + return riscv_insn_rmw(location, 0xfff, (offset + 0x800) & 0xfffff000); } =20 -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 =3D (void *)v - (void *)location; + ptrdiff_t offset =3D (void *)v - location; s32 fill_v =3D offset; u32 hi20, lo12; =20 if (offset !=3D fill_v) { /* Only emit the plt entry if offset over 32-bit range */ if (IS_ENABLED(CONFIG_MODULE_SECTIONS)) { - offset =3D module_emit_plt_entry(me, v); - offset =3D (void *)offset - (void *)location; + offset =3D (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= =3D %p\n", @@ -215,15 +218,14 @@ static int apply_r_riscv_call_plt_rela(struct module = *me, u32 *location, =20 hi20 =3D (offset + 0x800) & 0xfffff000; lo12 =3D (offset - hi20) & 0xfff; - *location =3D (*location & 0xfff) | hi20; - *(location + 1) =3D (*(location + 1) & 0xfffff) | (lo12 << 20); - return 0; + riscv_insn_rmw(location, 0xfff, hi20); + return riscv_insn_rmw(location + 4, 0xfffff, lo12 << 20); } =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 =3D (void *)v - (void *)location; + ptrdiff_t offset =3D (void *)v - location; s32 fill_v =3D offset; u32 hi20, lo12; =20 @@ -236,18 +238,17 @@ static int apply_r_riscv_call_rela(struct module *me,= u32 *location, =20 hi20 =3D (offset + 0x800) & 0xfffff000; lo12 =3D (offset - hi20) & 0xfff; - *location =3D (*location & 0xfff) | hi20; - *(location + 1) =3D (*(location + 1) & 0xfffff) | (lo12 << 20); - return 0; + riscv_insn_rmw(location, 0xfff, hi20); + return riscv_insn_rmw(location + 4, 0xfffff, lo12 << 20); } =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; } =20 -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; } =20 -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 +=3D (u32)v; return 0; } =20 -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 +=3D (u64)v; return 0; } =20 -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 -=3D (u32)v; return 0; } =20 -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 -=3D (u64)v; return 0; } =20 -static int (*reloc_handlers_rela[]) (struct module *me, u32 *location, +static int (*reloc_handlers_rela[]) (struct module *me, void *location, Elf_Addr v) =3D { [R_RISCV_32] =3D apply_r_riscv_32_rela, [R_RISCV_64] =3D apply_r_riscv_64_rela, [R_RISCV_BRANCH] =3D apply_r_riscv_branch_rela, [R_RISCV_JAL] =3D apply_r_riscv_jal_rela, - [R_RISCV_RVC_BRANCH] =3D apply_r_riscv_rcv_branch_rela, + [R_RISCV_RVC_BRANCH] =3D apply_r_riscv_rvc_branch_rela, [R_RISCV_RVC_JUMP] =3D apply_r_riscv_rvc_jump_rela, [R_RISCV_PCREL_HI20] =3D apply_r_riscv_pcrel_hi20_rela, [R_RISCV_PCREL_LO12_I] =3D apply_r_riscv_pcrel_lo12_i_rela, @@ -314,9 +315,9 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *s= trtab, struct module *me) { Elf_Rela *rel =3D (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; --=20 2.35.1 From nobody Mon Jun 29 23:03:57 2026 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 A9AD8C433FE for ; Mon, 31 Jan 2022 18:27:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355848AbiAaS15 (ORCPT ); Mon, 31 Jan 2022 13:27:57 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35878 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355172AbiAaS1u (ORCPT ); Mon, 31 Jan 2022 13:27:50 -0500 Received: from mail-ot1-x333.google.com (mail-ot1-x333.google.com [IPv6:2607:f8b0:4864:20::333]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 70F3AC061714 for ; Mon, 31 Jan 2022 10:27:50 -0800 (PST) Received: by mail-ot1-x333.google.com with SMTP id l12-20020a0568302b0c00b005a4856ff4ceso5702827otv.13 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=Fm9G0hPhitK4Hg8WkequJEQyqZw6N76ddj+e9QDov6QHG0CaSfb0avRdnNhVwF2Ixs T0KnXcFIR8s0DsA8/shpK5sT0IXYV/5Y9QPDq4Zbkiapdk6LyMCaNLYD/EzCkuRK67El 17GPcie/Uhr+GcsCGwhqRGuwzXMxr5UEsPZzKaZQL5AqQa7AsfYfWD700tQVjXN5of30 Xu3y3zJ/WXB7sVg49rFtzo08TCR6jsjUKY8xARbCeNQsiQQACn0E8aH6/hw3pHj0w5d5 D7e3v1TCYQL/FPYtPrB0gMmoi+C8wEDmoQrScLIzSJLhFGU11ham86G2KG4vnl5B4Gu9 2V9A== X-Gm-Message-State: AOAM531vGZvnPN6DnRlTx7OFhM/TAvxUPzRZFA3FuxqamHd156gJIW69 8CgHrGB9S/Y4z9o5PZl+jn8= 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) Sender: Emil Renner Berthing 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 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" RISC-V can do PC-relative jumps with a 32bit range using the following two instructions: auipc t0, imm20 ; t0 =3D PC + imm20 * 2^12 jalr ra, t0, imm12 ; ra =3D PC + 4, PC =3D 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 =3D (offset + 0x800) >> 12 imm12 =3D 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 =20 +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)) <=3D val && val < ((1L << 31) - (1L << = 11)); +} + static int riscv_insn_rmw(void *location, u32 keep, u32 set) { u16 *parcel =3D location; @@ -111,7 +123,7 @@ static int apply_r_riscv_pcrel_hi20_rela(struct module = *me, void *location, { ptrdiff_t offset =3D (void *)v - location; =20 - if (offset !=3D (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 = =3D %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 =3D (void *)v - location; - s32 fill_v =3D offset; u32 hi20, lo12; =20 - if (offset !=3D 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 =3D (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 =3D (void *)v - location; - s32 fill_v =3D offset; u32 hi20, lo12; =20 - if (offset !=3D 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 = =3D %p\n", me->name, (long long)v, location); --=20 2.35.1 From nobody Mon Jun 29 23:03:57 2026 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 63D9BC433EF for ; Mon, 31 Jan 2022 18:28:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1356422AbiAaS2F (ORCPT ); Mon, 31 Jan 2022 13:28:05 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35910 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355177AbiAaS1y (ORCPT ); Mon, 31 Jan 2022 13:27:54 -0500 Received: from mail-oo1-xc2d.google.com (mail-oo1-xc2d.google.com [IPv6:2607:f8b0:4864:20::c2d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5A31DC06173B for ; Mon, 31 Jan 2022 10:27:54 -0800 (PST) Received: by mail-oo1-xc2d.google.com with SMTP id r128-20020a4a4e86000000b002edb589161bso3413267ooa.9 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=PhwK6muEzzlbCGuEujkwJPjOrfCjx9RcBJsh5IMRjQWf2b2N45ZzC1OF75CjG4Rjas bI+RQfF+tMpCSpBlxIzwWp3f3srLJOZC7JxV5Ay7LjYZrcJl/aR1kRw2Q6FG/xGLXH9J liwi6G+Ac3O7jB2ys0cwPpI7UuSTtoB2UyjYinKCm1H8XWDsEJ1+ck3nIbeZK0MNNLB9 Cu6jWRlpkm/kI8mgwRAzu7wTdZ05TR5BqOzoKJm7/AGcgMwHSsa59FCpyWSpe8Z98AHv 3LnCWFIKbnKefTBWlVT3WrPqrXEgMZ1r39sg78DQ8sfCnQEi4wLUzMy5cu+Y99rHAw4G aCTQ== X-Gm-Message-State: AOAM533IWlKYd76VPDq515uI4bc73pdrY43gy+D2yhF4c/v2THkLeFgE HR85E277xKZUzdii0wqBxsQ= 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) Sender: Emil Renner Berthing 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 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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) <=3D 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)) <=3D 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 --=20 2.35.1 From nobody Mon Jun 29 23:03:57 2026 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 452ECC433EF for ; Mon, 31 Jan 2022 18:28:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1351444AbiAaS2N (ORCPT ); Mon, 31 Jan 2022 13:28:13 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35930 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355874AbiAaS16 (ORCPT ); Mon, 31 Jan 2022 13:27:58 -0500 Received: from mail-oo1-xc34.google.com (mail-oo1-xc34.google.com [IPv6:2607:f8b0:4864:20::c34]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EE9F6C061714 for ; Mon, 31 Jan 2022 10:27:57 -0800 (PST) Received: by mail-oo1-xc34.google.com with SMTP id t75-20020a4a3e4e000000b002e9c0821d78so3415406oot.4 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=05Gvjz8M2mNQiNZN0upYAA/n2XiILyAt2oZYw+NPho++gdhi6PmolezPcqAs0YtSGn w72ykbliyQ9D7cd2ImPCOBhqwKndiKtESkUzuv+aD1N5oeXO2ADj4Hq0ZdqQ4QUkNSFR B4JsfhtcnjmJVuFTnvOhtVjLoz6tja8+Npwj8MeJa9RC+YDIYfS9N5dyiTkMsnRujZWi aTwhsmjl/R6+6dWuMxVGAp37lFR2B5R+6etLKcUOqphISht+z4Hdng85NIwmNZbCd8kO cDgEKnFiw0tYwooqKdyFQfnlkSrr/c7LfaITF3Xs35MCh1bSgSvskq0g7Z4uRFWr3gUZ Wzyg== X-Gm-Message-State: AOAM532SqMlYJJigB0csTxHs0oGy1CI8QMvGRdUjMbGvdOay1U35eUn2 wDzMitra6O4latuNH6y8CE0= 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) Sender: Emil Renner Berthing 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 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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 =3D (imm + 0x800) & 0xfffff000; lo12 =3D (imm - hi20) & 0xfff; This patch simplifies it to: hi20 =3D (imm + 0x800) & 0xfffff000; lo12 =3D 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 --- 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 */ =20 #include @@ -11,38 +12,27 @@ #include #include #include +#include #include =20 -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)) <=3D 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 =3D location; u32 insn =3D (u32)parcel[0] | (u32)parcel[1] << 16; =20 - insn &=3D keep; - insn |=3D set; + insn &=3D ~mask; + insn |=3D value; =20 parcel[0] =3D insn; parcel[1] =3D insn >> 16; return 0; } =20 -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 =3D location; =20 - *parcel =3D (*parcel & keep) | set; + *parcel =3D (*parcel & ~mask) | value; return 0; } =20 @@ -67,55 +57,40 @@ static int apply_r_riscv_branch_rela(struct module *me,= void *location, Elf_Addr v) { ptrdiff_t offset =3D (void *)v - location; - u32 imm12 =3D (offset & 0x1000) << (31 - 12); - u32 imm11 =3D (offset & 0x800) >> (11 - 7); - u32 imm10_5 =3D (offset & 0x7e0) << (30 - 10); - u32 imm4_1 =3D (offset & 0x1e) << (11 - 4); =20 - 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)); } =20 static int apply_r_riscv_jal_rela(struct module *me, void *location, Elf_Addr v) { ptrdiff_t offset =3D (void *)v - location; - u32 imm20 =3D (offset & 0x100000) << (31 - 20); - u32 imm19_12 =3D (offset & 0xff000); - u32 imm11 =3D (offset & 0x800) << (20 - 11); - u32 imm10_1 =3D (offset & 0x7fe) << (30 - 10); =20 - 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)); } =20 static int apply_r_riscv_rvc_branch_rela(struct module *me, void *location, Elf_Addr v) { ptrdiff_t offset =3D (void *)v - location; - u16 imm8 =3D (offset & 0x100) << (12 - 8); - u16 imm7_6 =3D (offset & 0xc0) >> (6 - 5); - u16 imm5 =3D (offset & 0x20) >> (5 - 2); - u16 imm4_3 =3D (offset & 0x18) << (12 - 5); - u16 imm2_1 =3D (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)); } =20 static int apply_r_riscv_rvc_jump_rela(struct module *me, void *location, Elf_Addr v) { ptrdiff_t offset =3D (void *)v - location; - u16 imm11 =3D (offset & 0x800) << (12 - 11); - u16 imm10 =3D (offset & 0x400) >> (10 - 8); - u16 imm9_8 =3D (offset & 0x300) << (12 - 11); - u16 imm7 =3D (offset & 0x80) >> (7 - 6); - u16 imm6 =3D (offset & 0x40) << (12 - 11); - u16 imm5 =3D (offset & 0x20) >> (5 - 2); - u16 imm4 =3D (offset & 0x10) << (12 - 5); - u16 imm3_1 =3D (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)); } =20 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 modul= e *me, void *location, return -EINVAL; } =20 - 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)); } =20 static int apply_r_riscv_pcrel_lo12_i_rela(struct module *me, void *locati= on, 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)); } =20 static int apply_r_riscv_pcrel_lo12_s_rela(struct module *me, void *locati= on, Elf_Addr v) { - /* - * v is the lo12 value to fill. It is calculated before calling this - * handler. - */ - u32 imm11_5 =3D (v & 0xfe0) << (31 - 11); - u32 imm4_0 =3D (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)); } =20 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; } =20 - 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)); } =20 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 =3D ((s32)v + 0x800) & 0xfffff000; - s32 lo12 =3D ((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)); } =20 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 =3D ((s32)v + 0x800) & 0xfffff000; - s32 lo12 =3D ((s32)v - hi20); - u32 imm11_5 =3D (lo12 & 0xfe0) << (31 - 11); - u32 imm4_0 =3D (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)); } =20 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; } =20 - 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)); } =20 static int apply_r_riscv_call_plt_rela(struct module *me, void *location, Elf_Addr v) { ptrdiff_t offset =3D (void *)v - location; - u32 hi20, lo12; =20 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, } } =20 - hi20 =3D (offset + 0x800) & 0xfffff000; - lo12 =3D (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)); } =20 static int apply_r_riscv_call_rela(struct module *me, void *location, Elf_Addr v) { ptrdiff_t offset =3D (void *)v - location; - u32 hi20, lo12; =20 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; } =20 - hi20 =3D (offset + 0x800) & 0xfffff000; - lo12 =3D (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)); } =20 static int apply_r_riscv_relax_rela(struct module *me, void *location, --=20 2.35.1 From nobody Mon Jun 29 23:03:57 2026 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 4589AC433EF for ; Mon, 31 Jan 2022 18:28:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1356323AbiAaS2Y (ORCPT ); Mon, 31 Jan 2022 13:28:24 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35978 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1356567AbiAaS2H (ORCPT ); Mon, 31 Jan 2022 13:28:07 -0500 Received: from mail-oi1-x229.google.com (mail-oi1-x229.google.com [IPv6:2607:f8b0:4864:20::229]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6FED8C061748 for ; Mon, 31 Jan 2022 10:28:01 -0800 (PST) Received: by mail-oi1-x229.google.com with SMTP id y23so28274913oia.13 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=Q0npmfwGNdV2hwGAoGdksHLd3qzFRP1i75A2w5Z1sNV+kvOqgSmSppwsNeCjMiXDgZ 1nMDwJrx32k7lfqsQDPFbZ7bxIVDiU7GPS9fuqFPPTpNzPaLtNb1hbCZLLET+oK2FrZT a0M7i5uR9b74PwXtNd0vegGKrl55NtIm3wCfn17LJPdqTIwg81cIAmc9bnqug9QU7g5K sT1I9QJ903u+fuO/UqM1QkLgu5YgRpeu7YZFFCLEnQYzhdOQgO+qZqm+0kZojHnF3rdp 9c2JAT3OSj+WHcJ8zdECu93LynmWSGfPtJyFt163A7AD6d58MIOFgBbATkkvpzFdZ7aV Raug== X-Gm-Message-State: AOAM532f8ZpsGo33wSmNt/+bcuQl5woEf2drxInjeonLvHTCnwXqSeD9 PrSqGJBjFI3lA/TAAsEVi8Q= 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) Sender: Emil Renner Berthing 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 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 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 =20 struct got_entry { unsigned long symbol_addr; /* the real variable address */ @@ -61,36 +62,16 @@ struct plt_entry { u32 insn_jr; /* jr t1 */ }; =20 -#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 =3D got_plt - plt; - u32 hi20 =3D (offset + 0x800) & 0xfffff000; - u32 lo12 =3D (offset - hi20); =20 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_i= mm(offset), + RISCV_INSN_JALR | RISCV_INSN_RS1_T1, }; } =20 --=20 2.35.1 From nobody Mon Jun 29 23:03:57 2026 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 10111C433EF for ; Mon, 31 Jan 2022 18:28:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355738AbiAaS2P (ORCPT ); Mon, 31 Jan 2022 13:28:15 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35988 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1356632AbiAaS2I (ORCPT ); Mon, 31 Jan 2022 13:28:08 -0500 Received: from mail-oi1-x232.google.com (mail-oi1-x232.google.com [IPv6:2607:f8b0:4864:20::232]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8FAF5C061755 for ; Mon, 31 Jan 2022 10:28:05 -0800 (PST) Received: by mail-oi1-x232.google.com with SMTP id v67so28327608oie.9 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=0qfBqtroBIGbrZGhyNeThP5zhfPBBnXdHxfV1oUP4FETCTVICuv8jcmuOU/anXGAPe Lf1nprbp1eyBY90BrFMqQviTCOo6jq3Vq2NY52jVBnYDKyOU4kkPa9jd4hAzMAgX8PuX UZCEwykjGYVIPQJLlVuPdt2TJ+SoShHcFOjV+WeQy+ux8hfySvgYhMGQe0kZ8IAsmdNu uazEZ19QVrASnkIZZoAc4LDG7227N84jBT4W7Hx6SuVT9zlwZZTvo1itroudatfwrNnq 57ELSMo4tIwwYcYEvaO8JzY4tesnXODso5hBzWZSkqTDXkuRqqOWSE5X/Pbn5huobNDg xoTA== X-Gm-Message-State: AOAM532GpuIxdkcK59y2SF1smcnMaS/tZRcq/h9m/22DeaHS2yT0veB2 +kKKR5FkL+6dUImzsc895Ak= 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) Sender: Emil Renner Berthing 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 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This converts kernel/jump_label.c to use asm/insn.h to generate the jump/nop instructions. Signed-off-by: Emil Renner Berthing --- 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 =20 -#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 =3D=3D JUMP_LABEL_JMP) { long offset =3D jump_entry_target(entry) - jump_entry_code(entry); =20 - if (WARN_ON(offset & 1 || offset < -524288 || offset >=3D 524288)) + if (WARN_ON(!riscv_insn_valid_20bit_offset(offset))) return; =20 - insn =3D 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 =3D RISCV_INSN_JAL | riscv_insn_j_imm(offset); } else { insn =3D RISCV_INSN_NOP; } --=20 2.35.1