From patchwork Mon Jan 31 18:21:39 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: 12730977 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 CC98EC433F5 for ; Mon, 31 Jan 2022 18:22:30 +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=fEiihrgnq0SnjG YhzuLKaB3PGP6dp7vPvap+kCB+pt2aT+wr9nYf4SJDJxmIPbY9DdLreLLgqTSBbrZEWTttZwekxqa rfKkCVj4YCGmJ10jWiVYVnL9FWGs7c5RHocM6w9J3le1KJDk50HxjMYZrUmBaD5ho08t8OPvv+WlH EPV53d22O9ZkJty5E6A/WmzYpZET9+zr908L7B/OwZR1ryx7mHov82hKkeExGb19zt52SlWs98aue 824y7JQODZlrzV4czfHyZocnHUKRCZ8u+2DpWs1ciGSOZ4PM3m5ekj1J6Yi2wzkaWexJz2CCj0mzL lbP1N8mj/FchYixt7aFQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nEbJm-00AJCx-LU; Mon, 31 Jan 2022 18:22:22 +0000 Received: from mail-ot1-x32d.google.com ([2607:f8b0:4864:20::32d]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nEbJj-00AJBI-3f for linux-riscv@lists.infradead.org; Mon, 31 Jan 2022 18:22:21 +0000 Received: by mail-ot1-x32d.google.com with SMTP id b17-20020a9d4791000000b005a17fc2dfc1so13844869otf.1 for ; Mon, 31 Jan 2022 10:22:18 -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=WLvniTzYhM9NeYF0dtC6WNBS76XiQlppBWLTN9Xa0ghStqOzExQN7OQJ94J1BVSVjc 166YNhvEQ8bgllPis68e6A/C3hTprs57V6DGL/exUnOc7rwqaW6uM13uYsK25sT6EtcL RESfBWwpfzXbl1FoBU3qcMgQWAHJ0iK7aT5LHJv1jeg0G3BmEhs1earmnOMgH2sqpBiI mkYbqlrs5FKg3s/fk4hrbdlHw53wfw9R9e4BKjc1LjpLkKX8h+fHIgl/2+LyaeUZtl02 UujMJet6NPS1RbmGwf2LMFSFAvaCexKSr3PUAJQ+DdMizao9KttdYe+ggWbmqacpklST /nuA== 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=AgIO1E8l60vI7optvYMrWZSEuxh7sv8oBLjgg3/aJ3DIsCNkiINSXrN2mugbshnxr1 XQWxdqFnSE/hul8lWx54E+bGzO21aYval7GjljcQEA/vW3uy1N2Atzq6m9sZS6TTvlh5 WxXGNWbR5nHEyVIDlzX5jBCU7CS1Ck4hsbG1n6yKftezCPwP35DQFb0UTb0UXlFnqxdm d8d/zYK4BVsFo9oaaL8/JmoA+0trP+cx9xJRpqhGVTSlli8CsY1AtpuyMktgm0yE94Y8 Aqhy6tSvzfrAYPh0x0cg4V5gCALrJFusQ+W/fpynEBhN4MsmCtj0lsldyvcSaNa+EaRX V9IQ== X-Gm-Message-State: AOAM532T1bTzJ4kv/CdquZb/a4ahVKXpqtrM5WdxSMMB9JFYRExm/hFB dnNjJJW0s9UyCV7wYG6TdGZJyRWOVAs= X-Google-Smtp-Source: ABdhPJyFq0R4ULW2tIUjtD3ct4GN8h65Mm1X240ip2g1lOacRDVoXbpbDdZ9fGex5FtvlABmrM2fPQ== X-Received: by 2002:a9d:6495:: with SMTP id g21mr12110013otl.111.1643653337841; Mon, 31 Jan 2022 10:22:17 -0800 (PST) Received: from stitch.. (80.71.140.73.ipv4.parknet.dk. [80.71.140.73]) by smtp.gmail.com with ESMTPSA id t4sm12986340oie.14.2022.01.31.10.22.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Jan 2022 10:22:17 -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 v1 1/7] riscv: Avoid unaligned access when relocating modules Date: Mon, 31 Jan 2022 19:21:39 +0100 Message-Id: <20220131182145.236005-2-kernel@esmil.dk> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220131182145.236005-1-kernel@esmil.dk> References: <20220131182145.236005-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_102219_190448_C93A5C7B X-CRM114-Status: GOOD ( 15.75 ) 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:21:40 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: 12730978 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 E1613C433FE for ; Mon, 31 Jan 2022 18:22:33 +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=FwOXtDQWoWBe+/ jPEky/oi+zOO9muMOJtu1zOOQXoR/vdwtF685To5XOwOYx2MTU85P6pznswKmbmq+SLs9BcLVQHyt twWsShZ7Iv9b4eQo46QCZqYuntd714HZ1vrzw9fBRJOJcIDywOJq/2C1hcCJEjLHb68WtEjSZBejo ABuKGhNmTXURvNGwfAzSFQihCRP0Pw2mALPQZBgXjW0n1DmtFKTRZGIhvMsr4F+EdR/DeP9T5+Btq SXrwQmW5C/upudeAyx6THkN4huO3BPjf+edZDzkdpeY2xTotH8fSr2ZogfGWxeE7gLdiBKaCltZ5f Vy98MfmX1EsKwE2sFJdw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nEbJq-00AJEm-IH; Mon, 31 Jan 2022 18:22:26 +0000 Received: from mail-oi1-x229.google.com ([2607:f8b0:4864:20::229]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nEbJn-00AJCp-MA for linux-riscv@lists.infradead.org; Mon, 31 Jan 2022 18:22:25 +0000 Received: by mail-oi1-x229.google.com with SMTP id q8so13828976oiw.7 for ; Mon, 31 Jan 2022 10:22:22 -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=X85EtuRVbP7VmY8U9w6XBemW3oyMbvOi6t+f+1/vlgaxSrZUBi++URa8FrZbl+rz9S 2DH0pSVz3TZQZk3gHUgfeS8Peq37lvCmUkXrypyeOk5hshaATlpWFccU9AVoPYWOgMu4 qqtyfAjRBnqak+I5eV5tXX+052rjOUd4oduGlu+e6KmsegV7tI9KDL2MqLP9cFD0kZIm wM/7qMBrFy3J4dPDZFxLOUZ3qadx+jQv1eAOo/p8ilxmb3YsqZdBSuEsLvg5k6u9fi8U tGR3UrhypNq5+kIdfJhrZemZ5oD8SOD3edfFIOEYJ3r5Kmr13TyKIz0VNDn3XaJBdrgD /dUQ== 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=eaVS2g+eZ4NKeDaOwp9KCRTEtuk5vYMb0tYskQtE2d3RSrzWgOZTSd+TZM+dzZN6SW N1q6QtF7iw8455+6EEQqv2tGTro2Ha9VPALcNnc2vnbSmomJ671STYXpOGhlFx9vq51t rDj0xDjGlgBSnApUwSypszYsShQprsEjblNRqkdXlhalT0J4kRx7udzZtuG7do05SkT/ 6xhomEoK7KGLMQj2Zs0qh9edW5FvRqDv7WPBZ4Yd/CaJd5+ZBKjjI0Hyak7ktdFY766c 15yu4cJ/rRr2eD5cz8m5aWagWOCYwLK6VofPqvwg4unqy1r8X55ToGCc1Sr3JQjAspHp YQCw== X-Gm-Message-State: AOAM533A3y8yqfy/yDNmRElRLK51Eh9l02ZMhS2R+RHNF9GxurSC9Mqk f9w9ZXR87QoxA+t1/kjo0tOzA0i/B9A= X-Google-Smtp-Source: ABdhPJyKFi+2vEaah3m+jVJTG6IWp7Pd6tL2mUk1usiWRVU22DVjJnMz9fCOUh2+KDMXrG6LUFUhsQ== X-Received: by 2002:a05:6808:1890:: with SMTP id bi16mr15170985oib.307.1643653341692; Mon, 31 Jan 2022 10:22:21 -0800 (PST) Received: from stitch.. (80.71.140.73.ipv4.parknet.dk. [80.71.140.73]) by smtp.gmail.com with ESMTPSA id t4sm12986340oie.14.2022.01.31.10.22.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Jan 2022 10:22:21 -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 v1 2/7] riscv: Fix auipc+jalr relocation range checks Date: Mon, 31 Jan 2022 19:21:40 +0100 Message-Id: <20220131182145.236005-3-kernel@esmil.dk> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220131182145.236005-1-kernel@esmil.dk> References: <20220131182145.236005-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_102223_735742_C2A79298 X-CRM114-Status: GOOD ( 14.80 ) 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:21:41 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: 12730979 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 87C8EC433F5 for ; Mon, 31 Jan 2022 18:22:36 +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=wuM85mo7Uhxczc m8z5QTSwiLpdMQB8k58ObLMuttkGWPGylbVCKwk0FQYVPfwMUgXK0s3TLzWlSramyRU/hxewB8hME AaWmVyW1eLbD7V5T+Wol+VilJ7lVzk/KRQLmEUd9+qkVhYxqJ771n0cEetR/ToXXY6enfBaCidSWs 9hyF1iH5vQLqlzP6cM07hzPj+DVc/Fxi/5QL1PHTcl1BI6t6JRzuL+UuU4Ne59dykzSaMixV9Y2di 88vBltZ5s5OzxYlRKDfFaLFGVK2uO6W3NtIlcOX44IIdq1gaX93wiJ1QBB5WXqQCG5eRWC8w1Ozu0 dO7hpC9+yk/9/zQHUuUg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nEbJt-00AJGb-W7; Mon, 31 Jan 2022 18:22:30 +0000 Received: from mail-oi1-x22d.google.com ([2607:f8b0:4864:20::22d]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nEbJr-00AJEh-2j for linux-riscv@lists.infradead.org; Mon, 31 Jan 2022 18:22:28 +0000 Received: by mail-oi1-x22d.google.com with SMTP id b186so22140006oif.1 for ; Mon, 31 Jan 2022 10:22:26 -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=jqH6c0jEogoSGD5Ee/FcG2bn4Odrh9BtU928Z8acx2mqhmhtMj2i8/WcMVjxlyFVPl LjznNcOAEDBZugYf0ZQAz3MJGPFR+UnWBJUZKO17LQYeiPDOe6O7wtHh66HRmdJLKxEm 4ErPJfxLCKpW/K9WiNmWVLFK0beb2RpMRDY+b7Gp39anq6HDi4y4CetGZ4GbZokIlxIp mH6scYDJviVHAav55EkZAUD3eKVKa0inS5heTSxpSDs5IgSKpIuv1Tk5fTzXARW3RqBx K5+JVru1J3yKwEWQcaAlJ/LFBfMwZe9wwW00hlrJtbWKwiRYmjwtLP1HJWzQCL3IXGvg so2w== 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=GJtdy19/n/j/KKZMJBQcIwP0nlkWPEDCq/IAXNx6amgA3cOrr/VD315lddI8VDQ9z7 iJc2G6BctEJoflNR4g+IDfSk3IwcdlO8JABQYocYiS/MuvOzKJ76aCsJnJk9NmHP0cxk tKPhJY4vyohiqBhCxnAVPW6VKdE4bFxYSOsUnP+Sl+CCjgGl+vqxRIBhP7lMx5CaI7ge NVbBcnY4vOjtn9XwhYm88Fq+1iXrBGBSgRblx68nBspE+aw4A72BnguZbTAxBdH2N7VI wv/WUGaYpxpVb9ljY37l0NdEMHMDvGXWr3bdlYLR8PnNuDptJTjHql8rxadYIXByEZIO Nwcw== X-Gm-Message-State: AOAM531oSjaev9EEoRcfWWWSyam++voWnyBOD0tnD+hcVQIZpylVHI/9 WRaG7I+tjT32hp5AcykcBFgAl8i1d1Q= X-Google-Smtp-Source: ABdhPJybuZ+l9IBa0oBBWeviE7Tlm1E07to/F3di8EpWk18bWxhozZwdNTmIkKHKqG1rE9RAGXz/Ag== X-Received: by 2002:a05:6808:8d:: with SMTP id s13mr8759735oic.227.1643653345887; Mon, 31 Jan 2022 10:22:25 -0800 (PST) Received: from stitch.. (80.71.140.73.ipv4.parknet.dk. [80.71.140.73]) by smtp.gmail.com with ESMTPSA id t4sm12986340oie.14.2022.01.31.10.22.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Jan 2022 10:22:25 -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 v1 3/7] riscv: Add asm/insn.h header Date: Mon, 31 Jan 2022 19:21:41 +0100 Message-Id: <20220131182145.236005-4-kernel@esmil.dk> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220131182145.236005-1-kernel@esmil.dk> References: <20220131182145.236005-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_102227_150941_8FD7A544 X-CRM114-Status: GOOD ( 11.44 ) 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:21:42 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: 12730980 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 974B0C433EF for ; Mon, 31 Jan 2022 18:22:40 +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=pgQ0my+0DWLWZo e34qZdneXJRyL/d2zYzYOF3wZ4in5LZV/NRtEMhk6gdvnYyqvGDTYd27f9AL3xXxJL13iDcU7kXbU zdgdVYfPSEtVR7IvSScoBQU67Esz7Ss6AxrOWFffhoVIzX2oepe3tgr0nWCqQlq8P4bbz7cjazWIl iZvpDiuO2q18fET5Bl2zDudP00stsfBfgqEGwEKxYo4cTf58fLPnTN3C7ABqYjIek7u633W4wclkO K6n+okzkkkeibZXR7U/EuALjIz9oRZZkVnvYA6UDT+IiXgC4qyOHOUjb9PfSivGEQMT9PmT0bXQzN w3FwjQc43fS21VPIAkTA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nEbJx-00AJJn-G3; Mon, 31 Jan 2022 18:22:33 +0000 Received: from mail-ot1-x32c.google.com ([2607:f8b0:4864:20::32c]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nEbJu-00AJGp-FY for linux-riscv@lists.infradead.org; Mon, 31 Jan 2022 18:22:32 +0000 Received: by mail-ot1-x32c.google.com with SMTP id i16-20020a056830011000b005a3cc8d20fbso7464270otp.9 for ; Mon, 31 Jan 2022 10:22:30 -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=oub429PueJm31LgnMD3pH3b7Ytyx8emLL41Zq6zcUa4Ac9LecCoCIisTsrdihuy+aV hysBr2RdqFqrfnv43tQCXA6nK7yE2Infe0v73ByNGRtn3aKkIrzZfKf2f2yaSFpLfLdt 5q+/rsjTVauq3CykRcCSImm/yiWRvQfczIX1QXwyLFXdPeSqAxgEq8W15840uVEEgxEK ZkSRx4RIZ+5WGqptxDB/8E/p0q7yE4qwJKiM+NpK7nDp3RPg6NkCngyDxXfyQyQmKslH gwA2zQujQX85L86XUKOSzkW5nepWOeduGU6KaafvlbD7anyWHXEREN03zQYsm5BQCGxe FrYw== 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=NsNz/dDHnbGFCohzMi0jdgnKTB7p5oTJ8SR68namrACqfeaGVy+K1IRQctPsvQvyD4 +khbPzu2HOyIrt4WW4pQjrhRETOV2piihVGX6JkQcBdkhXZJm+/i9IvWVBoZXFFW7pi8 s+kzrU7Qan9ngmigOglHNE4wIyhTh3c2sEXcz2Rp5p4EvOKyvWYmPCGNf3rScYLBnPWS ORzAo/4oFSsInhrobzy89QwvJbwU5T43hKECfwBdAY22uNJxURg94/nTXy4L5cWF5AWd fKTUtsDtrQYbPrlHxIplK6ZsbdMBx4DgupTYEOcd/yDrB99PTn9Ai/RL9SCJEeFWQIXk rkVQ== X-Gm-Message-State: AOAM530IFg9n+mSJNMjYo22A72Wi5NkNPpkGFDfwIjhctgmTPThQYFsI 6A1mThPkXpgbbZPWZb5aQF1q9AbhRsY= X-Google-Smtp-Source: ABdhPJxSvR0FJpFkc9AXRd05GifffZyOy4S9TISnMz/YVOCd3iz66E6DSDRLK6qfJAyKlhlHkidyxw== X-Received: by 2002:a05:6830:1e11:: with SMTP id s17mr12013879otr.347.1643653349881; Mon, 31 Jan 2022 10:22:29 -0800 (PST) Received: from stitch.. (80.71.140.73.ipv4.parknet.dk. [80.71.140.73]) by smtp.gmail.com with ESMTPSA id t4sm12986340oie.14.2022.01.31.10.22.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Jan 2022 10:22:29 -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 v1 4/7] riscv: Use asm/insn.h for module relocations Date: Mon, 31 Jan 2022 19:21:42 +0100 Message-Id: <20220131182145.236005-5-kernel@esmil.dk> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220131182145.236005-1-kernel@esmil.dk> References: <20220131182145.236005-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_102230_576766_A219F7CC X-CRM114-Status: GOOD ( 15.51 ) 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 --- 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:21:43 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: 12730981 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 18548C433F5 for ; Mon, 31 Jan 2022 18:22:43 +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=VfOXPmLUt+NrvY hwekKAm0U+0wMoJmFfgfFIXU2jy53/uPSiXsEPWI9JI6iTT6YPWaFGc5ki9DwKLhcvHQs0HzAGwPm sykOMcEx4B7McFEyEISk+XQJzm9GBsfb+cWpUi1svDzReamH9fEHs2zJ/XZImewS2HhxvagJnQiO/ /C70E/SnRZaR4IhTHzswJB75T4oEVtaSAIgsKy5F3dtNaC6R5PJjSR19hlDNhEwEWddA/y4upe3Tr NtUkPA877WAhgvfav+xcCKwA73bN3qfNUQl1mS0hKPEN/N0b/q1f3VSAeWL9sjnIkLsz6hjMd9uFk YDf6oYCeXTXFU8Z+EjgA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nEbK0-00AJMu-Es; Mon, 31 Jan 2022 18:22:36 +0000 Received: from mail-ot1-x32c.google.com ([2607:f8b0:4864:20::32c]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nEbJx-00AJJz-R9 for linux-riscv@lists.infradead.org; Mon, 31 Jan 2022 18:22:35 +0000 Received: by mail-ot1-x32c.google.com with SMTP id q14-20020a05683022ce00b005a6162a1620so1062872otc.0 for ; Mon, 31 Jan 2022 10:22:33 -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=iElq6TWfe6FNOYAB6SZde3+Kjyd36wOCujz4wGdkh8f0ib8i/VM4zSOvU5JoAwfW4o zkN1JFwopjcF3PEtY4QhzcFUEYgWaOP0ysi3BUVTSK1l5XghFPpcIwCmaBVcGNYgWIEM EKoMCN4Esh15vtBOBrM4RxsNzWNbnW3QG71jsAL0aMY4vMukdFYR8H+PrWlAYWiD8sdz 5fHGzfBqElGUsvpzUxdcmp4CrF0chVrPB5CeyJbGVNX0lx1bDQrY46Svkl7FnErsURbY B8hmCZMlsGEYmuI2b8Tw2YROFPQvqjkTzcs6KqptFRoIKgsSxsw8m7xWtpHdFDcnuBDb RzhA== 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=7enrrsRlEvoahg9fC2pZNvWHWQMZOP1dwd9FpkgEA3457gmwANdMJ0Yv/fMCeMd7cb 8S5teJaiS8vknqCXa1SEWS3VoxEwGRpSbuBlUx6QkhF2JlbJ6hzGJDvG/nA0agmXTnzu bXCsGtgZWkRNeblkDeASmXvd9rCotl2UJlUCJe4gCv0mteqSr877rlQjaeUsbl4lyCaG HNDsZ7VgZRUfXGt3EzhT98LbNzQrk1yNlkRR36P4Ev+xiGonQdKGw3ko1CrOWNo+aoIe OZ67FuTcID5zYYImWCKEQJ+0gej2z9L3tBlqkrzM24HQ9tiEypy5BZlP93H1YAY3EjEc CTRw== X-Gm-Message-State: AOAM5321qPdG59vvVP0Mt/m/RDo7LmOt06qQPnX4TMUI98EeDtL1eG1X Bnf+GFamqePzHA1fh0Y2iRJbaO+JF3U= X-Google-Smtp-Source: ABdhPJxqEnmembk8ZumxKkHqD6FTwsFFWHtaMX3BJpB/i4c3c3jD4OzuDZo4IZTHWs/KTnXiZk0oHg== X-Received: by 2002:a9d:12d7:: with SMTP id g81mr12118683otg.82.1643653353310; Mon, 31 Jan 2022 10:22:33 -0800 (PST) Received: from stitch.. (80.71.140.73.ipv4.parknet.dk. [80.71.140.73]) by smtp.gmail.com with ESMTPSA id t4sm12986340oie.14.2022.01.31.10.22.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Jan 2022 10:22:33 -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 v1 5/7] riscv: Use asm/insn.h to generate plt entries Date: Mon, 31 Jan 2022 19:21:43 +0100 Message-Id: <20220131182145.236005-6-kernel@esmil.dk> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220131182145.236005-1-kernel@esmil.dk> References: <20220131182145.236005-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_102233_933689_E97B1FB5 X-CRM114-Status: GOOD ( 11.19 ) 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:21:44 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: 12730982 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 533D1C433EF for ; Mon, 31 Jan 2022 18:22:48 +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=d70Nvoz9GJGB4q Cei6z04XiBsyoSstCafbQT3l7R6Ouwsh1LS5g3D0a1EmqEO2fpq5q4A5c0XRX9nPFI9FEG7f8HoT1 jjoOaDATDHrpcZdlMTGzMPpFcIpKqglySffZRoKK0JxU6Po7Odckx6GJFlcCPGKFLbWHgvfs1nPiF mA46T6R6kr9c57wciuFRg7EtxDEt7Co7jTl4+h1B7bUo2BsCf2MMwWzJ+Tgs5jI+WFT+5AkIglJLe 5LHNiRfFK0cjNLfRrKAGNPS4HsUtGZOe7SUzQB+VWB5/6uMmXWgHNpUt63a5x5Y2H9dJJAKzyjW0A pSQ7T6HrjzTShe724kyQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nEbK5-00AJQe-3g; Mon, 31 Jan 2022 18:22:41 +0000 Received: from mail-oi1-x22d.google.com ([2607:f8b0:4864:20::22d]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nEbK1-00AJNd-JF for linux-riscv@lists.infradead.org; Mon, 31 Jan 2022 18:22:38 +0000 Received: by mail-oi1-x22d.google.com with SMTP id x193so28446104oix.0 for ; Mon, 31 Jan 2022 10:22:37 -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=GrPuCF7g8wuXvMFUhWNN1mhzoghD0PNgEzngwf2WvawQ8neFtZyyWFFWbrsLyvbhN0 1YLTZW9YmEf5d2WlRFTUJdnmChTV/PIDJd5JRx0YEC94UMjmjp0/5nD+7vFXklO6KAco tziDslat9YPXq77Ksu5JtauYUyr8ws1HKtftRCGmK2u+eUDCVSuPG81jrbVMgGBA5Xcj +cyDSjShDdJ2Mq7rljU0CX8f1UDknrJW/a7DqHadutRbyD+8xDe/3tCcKAy4a1V51tqq sGB/9BvZ8JZagsG2pE2fPv00MPEWXjT48ZAbEPc8Owmp35/GlcEaBsLshIZ7l/bJIj0s wOOw== 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=RsUYCa/KqeOnP4Oevtu5xFTwv7I2RioMZonrXxgVgyi8didmNZmOjrcikC0x2f6Av6 F+dGFpZ/0hVkQz6YDopUp2fjlC1pphDGfgl7z7F8SR5N8MwxpB6OdLROdQNaM4DllWrX eYykqi2tQpCEMsbrm6C3m6rPq64SJ6a4CNZWssXNrJpbyUnVf8nLCDWy/vdtq7lgm0Ks SJgsiQyasaV55YWwgmuUb5cCKtqXH3VvRc9YTKUjvyuQ6rylKpveWXG1JopdXZPYBhdC UQOO6fpaYsg+9qmHl75u9/pP2x1+vIl2tpwtRN2Xqu36b/yciDGmoDwyh0ISB878aXTG b+Cg== X-Gm-Message-State: AOAM5327dTsbG5GdBF+wAWqePdmHCuOWClXIsJm3cggsAUpC+i0UnijL h+jaBH3F6I0CwG4ssNbOgNbHpGwZpvw= X-Google-Smtp-Source: ABdhPJyXQjVGntX1OX0ZlbDOasHZ7YutyxmQFYeM96PygHpy3m+Tr5xZApjL6EcLrg2VuspYptU/SA== X-Received: by 2002:a05:6808:1644:: with SMTP id az4mr13575526oib.214.1643653357036; Mon, 31 Jan 2022 10:22:37 -0800 (PST) Received: from stitch.. (80.71.140.73.ipv4.parknet.dk. [80.71.140.73]) by smtp.gmail.com with ESMTPSA id t4sm12986340oie.14.2022.01.31.10.22.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Jan 2022 10:22:36 -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 v1 6/7] riscv: Use asm/insn.h for jump labels Date: Mon, 31 Jan 2022 19:21:44 +0100 Message-Id: <20220131182145.236005-7-kernel@esmil.dk> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220131182145.236005-1-kernel@esmil.dk> References: <20220131182145.236005-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_102237_675553_4DDEBBB2 X-CRM114-Status: GOOD ( 10.60 ) 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 --- 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; } From patchwork Mon Jan 31 18:21:45 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: 12730983 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 A7212C433F5 for ; Mon, 31 Jan 2022 18:22:51 +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=U/yfCq7V1/90muj+b1AfhBsd3VcnvZs3Xk20V1fPV+s=; b=UzyX0iqYooOZ14 vzXWmnswiHP0XV84OaehG/uZDu/AHfry5zHoUgQv3cxCW5HZU9e/PGZdM28kX4OA9gqMPG/5klSn3 B1ka3oublXJH6tQuA6IEl9vRZXKhqqyRRrMtBOsbHvLb7GNf749legi7ix7W+PdBmkuGfL38lNSOp wEI5CPjvvASTugonzmbNO2DjvHMKl6bzdDEFcWsG5G3Hq50bDPb63TH9Sf1H4cdEqQD2GAgBQcL1C nDso7YCgs7wOiF/xwNfVrfkUq24R2WsnkqFAAqbsfv7R+SWBF16/Xbwr7YnYl7cfbZNLBWyT4WXfS yiW1vK0/7pjFnc9iYnpg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nEbK8-00AJTu-Kc; Mon, 31 Jan 2022 18:22:44 +0000 Received: from mail-ot1-x32c.google.com ([2607:f8b0:4864:20::32c]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nEbK5-00AJQn-Fg for linux-riscv@lists.infradead.org; Mon, 31 Jan 2022 18:22:43 +0000 Received: by mail-ot1-x32c.google.com with SMTP id b17-20020a9d4791000000b005a17fc2dfc1so13845976otf.1 for ; Mon, 31 Jan 2022 10:22:41 -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=CCzMOkXflHmWMxX1XPAY7nKtPtpcp9g4eQAqLH2YIns=; b=cVK8q8IqPDBCtC4ivwSc3NI0vzhHzduPJmRPfeneeNFUbDsICRd+mkaStOSPBXhwS7 Yx81OYIDDpFzjBTNOXUaGn/MCdv/wSm3v8jx2LYnh3iCrOLoYMgisLM9s0zDdt3XYU0v 2+XHQyESKt6wXm0aFMHt1OxQBc5j1k0lnSxg2K2pmNugaNF/xBDjvMtxNwe8W25DoE5N HICPrAY5HXD+8fEfd3JVjEYXTgPSLkCAZWBw5gJQVhkwuRhuCECPzoVpuJWoJjbjFfGf bCWDU4WTLWSkNE1aquajGR2doEYuqN9JQ1XvjyD3VEgq6EyAfhfFbS2mcsffA4xD6Qu4 SBsw== 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=CCzMOkXflHmWMxX1XPAY7nKtPtpcp9g4eQAqLH2YIns=; b=Dy5oTmKyndXPo/7D6Y6aI1RWdq8putrEkbt9zE815Qtoi7lmPu4zErVQc3myTmVfIV /Uga1eZNSr4dzxlpyj7IgL7QYCyAT3I22EkIVt5TP0jFi+3buNbexw7E/0GEBDkgUBAJ IyllCM2LXJoMo756FuDGGw8kGVhOaECVKMdNVsY035M2Tx94YS1kmv7XXwc2qJ7pXSdj FLGdlzvcy9yZcz9SWT8uaGkNxeOMh/KNuqKOJaoPDJ1apjm7dX+dTXWPwsPN5XAehP4L j3E9Qr8vXsT+StpmCafxJT5GYTnJGVDtt/fzE2Ki1FCFimb0Y8pZl9HruulR/0vrtCMH 84Lg== X-Gm-Message-State: AOAM532knaQGl33c5hN/rmn3MnTEkJldTOTIGniuP0ikDXIzO6BF7RuS g5qAeMxY2YUU0TmdiqxC+g9fDR46Sv4= X-Google-Smtp-Source: ABdhPJyINXPwfY18wwXLDqhZ/f1W5qGuM2/i1IID9PGprXPfceL3GeaWq/hfJyqgBqtWWKNNWrltLA== X-Received: by 2002:a05:6830:30b6:: with SMTP id g22mr12237496ots.122.1643653360912; Mon, 31 Jan 2022 10:22:40 -0800 (PST) Received: from stitch.. (80.71.140.73.ipv4.parknet.dk. [80.71.140.73]) by smtp.gmail.com with ESMTPSA id t4sm12986340oie.14.2022.01.31.10.22.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Jan 2022 10:22:40 -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 v1 7/7] riscv: kernel/modules.c simplification Date: Mon, 31 Jan 2022 19:21:45 +0100 Message-Id: <20220131182145.236005-8-kernel@esmil.dk> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220131182145.236005-1-kernel@esmil.dk> References: <20220131182145.236005-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_102241_568757_06F5427A X-CRM114-Status: GOOD ( 14.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 Signed-off-by: Emil Renner Berthing --- arch/riscv/kernel/module.c | 93 ++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 54 deletions(-) diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c index 2212d88776e0..e371977aecfd 100644 --- a/arch/riscv/kernel/module.c +++ b/arch/riscv/kernel/module.c @@ -298,24 +298,23 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, unsigned int symindex, unsigned int relsec, struct module *me) { - Elf_Rela *rel = (void *) sechdrs[relsec].sh_addr; - int (*handler)(struct module *me, void *location, Elf_Addr v); - Elf_Sym *sym; - void *location; - unsigned int i, type; - Elf_Addr v; - int res; + Elf_Rela *rel = (void *)sechdrs[relsec].sh_addr; + unsigned int entries = sechdrs[relsec].sh_size / sizeof(*rel); + unsigned int i; pr_debug("Applying relocate section %u to %u\n", relsec, sechdrs[relsec].sh_info); - for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { - /* This is where to make the change */ - location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr - + rel[i].r_offset; - /* This is the symbol it is referring to */ - sym = (Elf_Sym *)sechdrs[symindex].sh_addr + for (i = 0; i < entries; i++) { + Elf_Sym *sym = (Elf_Sym *)sechdrs[symindex].sh_addr + ELF_RISCV_R_SYM(rel[i].r_info); + Elf_Addr loc = sechdrs[sechdrs[relsec].sh_info].sh_addr + + rel[i].r_offset; + unsigned int type = ELF_RISCV_R_TYPE(rel[i].r_info); + int (*handler)(struct module *me, void *location, Elf_Addr v); + Elf_Addr v; + int res; + if (IS_ERR_VALUE(sym->st_value)) { /* Ignore unresolved weak symbol */ if (ELF_ST_BIND(sym->st_info) == STB_WEAK) @@ -325,8 +324,6 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, return -ENOENT; } - type = ELF_RISCV_R_TYPE(rel[i].r_info); - if (type < ARRAY_SIZE(reloc_handlers_rela)) handler = reloc_handlers_rela[type]; else @@ -343,48 +340,36 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, if (type == R_RISCV_PCREL_LO12_I || type == R_RISCV_PCREL_LO12_S) { unsigned int j; - for (j = 0; j < sechdrs[relsec].sh_size / sizeof(*rel); j++) { - unsigned long hi20_loc = - sechdrs[sechdrs[relsec].sh_info].sh_addr + /* find the corresponding HI20 entry */ + for (j = 0; j < entries; j++) { + Elf_Sym *hi20_sym = (Elf_Sym *)sechdrs[symindex].sh_addr + + ELF_RISCV_R_SYM(rel[j].r_info); + Elf_Addr hi20_loc = sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[j].r_offset; - u32 hi20_type = ELF_RISCV_R_TYPE(rel[j].r_info); - - /* Find the corresponding HI20 relocation entry */ - if (hi20_loc == sym->st_value - && (hi20_type == R_RISCV_PCREL_HI20 - || hi20_type == R_RISCV_GOT_HI20)) { - s32 hi20, lo12; - Elf_Sym *hi20_sym = - (Elf_Sym *)sechdrs[symindex].sh_addr - + ELF_RISCV_R_SYM(rel[j].r_info); - unsigned long hi20_sym_val = - hi20_sym->st_value - + rel[j].r_addend; - - /* Calculate lo12 */ - size_t offset = hi20_sym_val - hi20_loc; - if (IS_ENABLED(CONFIG_MODULE_SECTIONS) - && hi20_type == R_RISCV_GOT_HI20) { - offset = module_emit_got_entry( - me, hi20_sym_val); - offset = offset - hi20_loc; - } - hi20 = (offset + 0x800) & 0xfffff000; - lo12 = offset - hi20; - v = lo12; - - break; - } - } - if (j == sechdrs[relsec].sh_size / sizeof(*rel)) { - pr_err( - "%s: Can not find HI20 relocation information\n", - me->name); - return -EINVAL; + unsigned int hi20_type = ELF_RISCV_R_TYPE(rel[j].r_info); + + if (hi20_loc != sym->st_value || + (hi20_type != R_RISCV_PCREL_HI20 && + hi20_type != R_RISCV_GOT_HI20)) + continue; + + /* calculate relative offset */ + v = hi20_sym->st_value + rel[j].r_addend; + + if (IS_ENABLED(CONFIG_MODULE_SECTIONS) && + hi20_type == R_RISCV_GOT_HI20) + v = module_emit_got_entry(me, v); + + v -= hi20_loc; + goto handle_reloc; } - } - res = handler(me, location, v); + pr_err("%s: Cannot find HI20 relocation information\n", + me->name); + return -EINVAL; + } +handle_reloc: + res = handler(me, (void *)loc, v); if (res) return res; }