From patchwork Tue Feb 7 14:28:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xi Ruoyao X-Patchwork-Id: 53935 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:2388:b0:96:219d:e725 with SMTP id i8csp4043608dyf; Tue, 7 Feb 2023 06:32:14 -0800 (PST) X-Google-Smtp-Source: AK7set+0d9QscmHm5veb3gBoBbGrx7Qv456DUSezryTB9aS32REwxdzfOBXOmJJUkP2wxyLrginI X-Received: by 2002:a50:aa9b:0:b0:4aa:c680:c703 with SMTP id q27-20020a50aa9b000000b004aac680c703mr3955411edc.36.1675780334213; Tue, 07 Feb 2023 06:32:14 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1675780334; cv=none; d=google.com; s=arc-20160816; b=L3qxvmIyvnEnV8p93FXSLhNZOs6dYD9CwNT+7Qx32nhmORtWdQLeX8ij6E4SPTNjuQ KxUa3jLN8uKWMvasJthsyt1xPo6+obwXHZqGH4z2zOG9p0t0puW2tKFRqASJxdmhsvTD s8YtgYDMrv24DEnG3NEAnscHglMYMoEbslCPie/7Kvij30bO4e/Y6CJDGJHzPw4LXu1G TNxZDj6CUtDAlsjups+xZeDrczcuJ7m1zuW7xoItCFyG5gKN8SRpws9u9QrLu4oQVM2f nG0a1SO4dzM1hZyll3UNmwPK83X8eJFxbpAJ6TCVgOj1BCWp47VX92Hdj8oK6dePIWSk TDFQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=lw7LryyT4KqlU4iEt1of33N218ph7x4pF/sA7UW0f94=; b=ry1YlcxokXT+ijAUu4JAPNXfrzyH5PvlTwsx8J7+x+ZAWFs9XnV0+J/NXsGyJU73BS 4LtapiezzMWOBHl2PSHPQ4oCSSfWv/kfUzVio/NX7U62M0+NWUp7ApVPXAgPRn+QqEM8 VVLh5G5E8jMgreCuXZUsMZL5ycLYCQ55Qq1Y3eMAKWnYMWctaHn9Z6j83PvVc8Oc5Yf7 No6dQc/qKkHJawYAqA8CyqIXE3in03p5vXx9mcxyAA/GPP2oThj1HFglLjTe2gl4cVHB V81ND6SWqjPY4yrSGYIwyU2qqn0nsDOHPuvwRcxJiSazsRLFzYYQL3bsROQblsjglMgI tdkQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@xry111.site header.s=default header.b="HVJNsBr/"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=xry111.site Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id h5-20020a50ed85000000b004aaa3ed634asi10232497edr.19.2023.02.07.06.31.50; Tue, 07 Feb 2023 06:32:14 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@xry111.site header.s=default header.b="HVJNsBr/"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=xry111.site Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232996AbjBGOam (ORCPT + 99 others); Tue, 7 Feb 2023 09:30:42 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44440 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232782AbjBGOaG (ORCPT ); Tue, 7 Feb 2023 09:30:06 -0500 Received: from xry111.site (xry111.site [89.208.246.23]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6190AA260 for ; Tue, 7 Feb 2023 06:29:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1675780177; bh=oMzyttSCKaIX1gPfNc0f7aOnWiUj9GW0I5ny0MzusMc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HVJNsBr/mdPdpYfYD51lhUfOZI7ELx9OI7hsDmCZoR3EOe8j019LXTKpD82OS7sYv gNKnSaZXWuI27czfBah/Rv0SaxYbbOyXR1nZ+e67XjLzbylsIPYgjLzzoFhfyJE0N3 VKOwwaHCskNZfohwMZ9i2rnvf+dbwLc/hN73Br8s= Received: from xry111-x57s1.. (unknown [IPv6:240e:358:11cc:4100:dc73:854d:832e:2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) (Authenticated sender: xry111@xry111.site) by xry111.site (Postfix) with ESMTPSA id 264FA65DC8; Tue, 7 Feb 2023 09:29:30 -0500 (EST) From: Xi Ruoyao To: Youling Tang , Huacai Chen , Jinyang He Cc: Xuerui Wang , loongarch@lists.linux.dev, linux-kernel@vger.kernel.org, Xi Ruoyao Subject: [PATCH v2 1/5] LoongArch: Use la.pcrel instead of la.abs when it's trivially possible Date: Tue, 7 Feb 2023 22:28:18 +0800 Message-Id: <20230207142822.52172-2-xry111@xry111.site> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230207142822.52172-1-xry111@xry111.site> References: <20230207142822.52172-1-xry111@xry111.site> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_PASS,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1757183039742745160?= X-GMAIL-MSGID: =?utf-8?q?1757183039742745160?= Let's start to kill la.abs inpreparation for the subsequent support of the PIE kernel. Signed-off-by: Xi Ruoyao --- arch/loongarch/include/asm/stackframe.h | 2 +- arch/loongarch/include/asm/uaccess.h | 1 - arch/loongarch/kernel/entry.S | 2 +- arch/loongarch/kernel/head.S | 2 +- arch/loongarch/mm/tlbex.S | 3 +-- 5 files changed, 4 insertions(+), 6 deletions(-) diff --git a/arch/loongarch/include/asm/stackframe.h b/arch/loongarch/include/asm/stackframe.h index 4ca953062b5b..7deb043ce387 100644 --- a/arch/loongarch/include/asm/stackframe.h +++ b/arch/loongarch/include/asm/stackframe.h @@ -90,7 +90,7 @@ .endm .macro set_saved_sp stackp temp temp2 - la.abs \temp, kernelsp + la.pcrel \temp, kernelsp #ifdef CONFIG_SMP LONG_ADD \temp, \temp, u0 #endif diff --git a/arch/loongarch/include/asm/uaccess.h b/arch/loongarch/include/asm/uaccess.h index 255899d4a7c3..0d22991ae430 100644 --- a/arch/loongarch/include/asm/uaccess.h +++ b/arch/loongarch/include/asm/uaccess.h @@ -22,7 +22,6 @@ extern u64 __ua_limit; #define __UA_ADDR ".dword" -#define __UA_LA "la.abs" #define __UA_LIMIT __ua_limit /* diff --git a/arch/loongarch/kernel/entry.S b/arch/loongarch/kernel/entry.S index d53b631c9022..2566977f2f68 100644 --- a/arch/loongarch/kernel/entry.S +++ b/arch/loongarch/kernel/entry.S @@ -20,7 +20,7 @@ .align 5 SYM_FUNC_START(handle_syscall) csrrd t0, PERCPU_BASE_KS - la.abs t1, kernelsp + la.pcrel t1, kernelsp add.d t1, t1, t0 move t2, sp ld.d sp, t1, 0 diff --git a/arch/loongarch/kernel/head.S b/arch/loongarch/kernel/head.S index 57bada6b4e93..aa6181714ec3 100644 --- a/arch/loongarch/kernel/head.S +++ b/arch/loongarch/kernel/head.S @@ -117,7 +117,7 @@ SYM_CODE_START(smpboot_entry) li.w t0, 0x00 # FPE=0, SXE=0, ASXE=0, BTE=0 csrwr t0, LOONGARCH_CSR_EUEN - la.abs t0, cpuboot_data + la.pcrel t0, cpuboot_data ld.d sp, t0, CPU_BOOT_STACK ld.d tp, t0, CPU_BOOT_TINFO diff --git a/arch/loongarch/mm/tlbex.S b/arch/loongarch/mm/tlbex.S index 58781c6e4191..3dd2a9615cd9 100644 --- a/arch/loongarch/mm/tlbex.S +++ b/arch/loongarch/mm/tlbex.S @@ -24,8 +24,7 @@ move a0, sp REG_S a2, sp, PT_BVADDR li.w a1, \write - la.abs t0, do_page_fault - jirl ra, t0, 0 + bl do_page_fault RESTORE_ALL_AND_RET SYM_FUNC_END(tlb_do_page_fault_\write) .endm From patchwork Tue Feb 7 14:28:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xi Ruoyao X-Patchwork-Id: 53939 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:2388:b0:96:219d:e725 with SMTP id i8csp4044060dyf; Tue, 7 Feb 2023 06:32:45 -0800 (PST) X-Google-Smtp-Source: AK7set/1FmnZ/bwqSaAYe2tSMUzB9Myj63yo5/mw/wcFMHOuTQ/8KNIEh4ig86XW0ga/kurSt/si X-Received: by 2002:a17:902:f14d:b0:198:fb24:95f7 with SMTP id d13-20020a170902f14d00b00198fb2495f7mr2648366plb.29.1675780364950; Tue, 07 Feb 2023 06:32:44 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1675780364; cv=none; d=google.com; s=arc-20160816; b=eFmaMrLPfnna/kpu4vvHOW54/vEN1WhlcDSLOOW3Q3eMDUFOjeCquAZvdkI3gSNCpJ T/JiuQ8FmWOxLJAbQGOZGPeH5HcK+Q3vvaY6I1D4QgwrTlWdeOIxIWmhOfYFDBoYstJN Td/L6yxZw+bOsfkfQHRN7IalWLxVhDum7mKWAmILKsDoJ6oXoz69q5O1/bpJT1nZfoa6 b9eWZNO4AIjt44LeCt+T5TmEmcdw8sTHc6D7/+xwTljHTK14lBvOmQWt22TlfjPWz9Xg tRcm3glVfAz65qAfPUdXZ5lQv2BWo16CFZaWMNdZgrUY+llBdDNFOmRwomwPuu49WV79 Qo7Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=hgZD6XGjUDKOr592CtYuBl2bC5iOq+TKrqaQoW4LMbI=; b=zpH6/AKKda+M2vQqmwHguxyB7fxpP8O4s4xu9nKQ1vhnRWH3AGBMiDckHT1W9n23mm r0EhmGk9US3u1SJAz/AkpstbPlUyX1Gkh4jpXnfm2oFUbt5zgheZburqPmGW7VF75A3U yqXaDKTm8OCWyY9x0evoJkE48MEDD6Xj1WUXpKrMQnrx0tDNiBeCwE6W250IaU9oj8Z1 1cYCuGKKv6nutZTQjuqjd9QLjMpwFv6o8ceOIqsEhyvGGx2t215S0VfHzDImyvTsKFmn hdWO1VSR9/RjHBps6pIA/f4B6a3vsb8wOCqLh0X0sL7oFzVIR5/GrxI5Gd40LRMw/c9i TiUQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@xry111.site header.s=default header.b=lfQjViy2; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=xry111.site Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id ij14-20020a170902ab4e00b0019609a4f16dsi5618908plb.461.2023.02.07.06.32.30; Tue, 07 Feb 2023 06:32:44 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@xry111.site header.s=default header.b=lfQjViy2; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=xry111.site Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233046AbjBGObj (ORCPT + 99 others); Tue, 7 Feb 2023 09:31:39 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44628 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232930AbjBGOaY (ORCPT ); Tue, 7 Feb 2023 09:30:24 -0500 Received: from xry111.site (xry111.site [89.208.246.23]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7446C3E094 for ; Tue, 7 Feb 2023 06:29:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1675780183; bh=RYBYXvEQBpvZRGVnp3C9q/sR/G9+cBK9ZT5Bd5Q4dAM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lfQjViy2EWnOISabLACPA1LSAWZaRUqpClDQ0Af7sEP/2vNvGGnd4C1GkFr2cM9no 0GmMGoAQjjnnKEQUc0CEErzaAzaCOsDLtmG+vAVYofeCqTzC7TkWgefkv5Jq5CE0Ot Tzh6ohtZa/3hneP43fB9L/+8b1FUrXkjGD3FT6os= Received: from xry111-x57s1.. (unknown [IPv6:240e:358:11cc:4100:dc73:854d:832e:2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) (Authenticated sender: xry111@xry111.site) by xry111.site (Postfix) with ESMTPSA id 653C165DC6; Tue, 7 Feb 2023 09:29:37 -0500 (EST) From: Xi Ruoyao To: Youling Tang , Huacai Chen , Jinyang He Cc: Xuerui Wang , loongarch@lists.linux.dev, linux-kernel@vger.kernel.org, Xi Ruoyao Subject: [PATCH v2 2/5] LoongArch: Use la.pcrel instead of la.abs for exception handlers Date: Tue, 7 Feb 2023 22:28:19 +0800 Message-Id: <20230207142822.52172-3-xry111@xry111.site> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230207142822.52172-1-xry111@xry111.site> References: <20230207142822.52172-1-xry111@xry111.site> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_PASS,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1757183072336989952?= X-GMAIL-MSGID: =?utf-8?q?1757183072336989952?= It's needed to build the kernel as a PIE, or the linker will complain. For the consideration about performance, we copy the exception handlers to a dedicated 64 KB area for each CPU. So, the PC-relative offset calculated at link time will be incorrect and we need to relocate the exception handlers after copying them. For the simplicity, we don't use the ELF R_LARCH_* relocations, but code an relocation entry as simply (offset_in_the_handler, symbol_addr). For each exception handler, we also code the number of relocation entries. Then we can use the relocation information to fix up the handlers after copying them. Signed-off-by: Xi Ruoyao --- arch/loongarch/include/asm/setup.h | 6 +- arch/loongarch/include/asm/stackframe.h | 3 +- arch/loongarch/kernel/genex.S | 40 ++++++- arch/loongarch/kernel/traps.c | 138 ++++++++++++++++++++---- arch/loongarch/mm/tlb.c | 23 ++-- arch/loongarch/mm/tlbex.S | 69 ++++++++++-- 6 files changed, 234 insertions(+), 45 deletions(-) diff --git a/arch/loongarch/include/asm/setup.h b/arch/loongarch/include/asm/setup.h index 72ead58039f3..f0a2b34365f1 100644 --- a/arch/loongarch/include/asm/setup.h +++ b/arch/loongarch/include/asm/setup.h @@ -11,6 +11,9 @@ #define VECSIZE 0x200 +struct handler_reloc; + +extern struct handler_reloc *eentry_reloc[]; extern unsigned long eentry; extern unsigned long tlbrentry; extern char init_command_line[COMMAND_LINE_SIZE]; @@ -18,7 +21,8 @@ extern void tlb_init(int cpu); extern void cpu_cache_init(void); extern void cache_error_setup(void); extern void per_cpu_trap_init(int cpu); -extern void set_handler(unsigned long offset, void *addr, unsigned long len); +extern void set_handler(unsigned long exccode, void *addr); extern void set_merr_handler(unsigned long offset, void *addr, unsigned long len); +extern void reloc_handler(unsigned long handler, struct handler_reloc *rel); #endif /* __SETUP_H */ diff --git a/arch/loongarch/include/asm/stackframe.h b/arch/loongarch/include/asm/stackframe.h index 7deb043ce387..bbec1e56b61b 100644 --- a/arch/loongarch/include/asm/stackframe.h +++ b/arch/loongarch/include/asm/stackframe.h @@ -77,7 +77,8 @@ * new value in sp. */ .macro get_saved_sp docfi=0 - la.abs t1, kernelsp + /* The label is used for generating reloc tables for handlers */ +514: la.pcrel t1, t0, kernelsp #ifdef CONFIG_SMP csrrd t0, PERCPU_BASE_KS LONG_ADD t1, t1, t0 diff --git a/arch/loongarch/kernel/genex.S b/arch/loongarch/kernel/genex.S index 7e5c293ed89f..005a10fe5a50 100644 --- a/arch/loongarch/kernel/genex.S +++ b/arch/loongarch/kernel/genex.S @@ -34,7 +34,7 @@ SYM_FUNC_END(__arch_cpu_idle) SYM_FUNC_START(handle_vint) BACKUP_T0T1 SAVE_ALL - la.abs t1, __arch_cpu_idle +0: la.pcrel t1, t2, __arch_cpu_idle LONG_L t0, sp, PT_ERA /* 32 byte rollback region */ ori t0, t0, 0x1f @@ -43,11 +43,25 @@ SYM_FUNC_START(handle_vint) LONG_S t0, sp, PT_ERA 1: move a0, sp move a1, sp - la.abs t0, do_vint +2: la.pcrel t0, t2, do_vint jirl ra, t0, 0 RESTORE_ALL_AND_RET SYM_FUNC_END(handle_vint) +SYM_DATA_START(rel_handle_vint) +LONG 3 + +LONG 514b - handle_vint +LONG kernelsp + +LONG 0b - handle_vint +LONG __arch_cpu_idle + +LONG 2b - handle_vint +LONG do_vint + +SYM_DATA_END(rel_handle_vint) + SYM_FUNC_START(except_vec_cex) b cache_parity_error SYM_FUNC_END(except_vec_cex) @@ -72,12 +86,24 @@ SYM_FUNC_END(except_vec_cex) SAVE_ALL build_prep_\prep move a0, sp - la.abs t0, do_\handler + 667: + la.pcrel t0, t1, do_\handler jirl ra, t0, 0 668: RESTORE_ALL_AND_RET SYM_FUNC_END(handle_\exception) SYM_DATA(unwind_hint_\exception, .word 668b - 666b) + + SYM_DATA_START(rel_handle_\exception) + LONG 2 + + LONG 514b - 666b + LONG kernelsp + + LONG 667b - 666b + LONG do_\handler + + SYM_DATA_END(rel_handle_\exception) .endm BUILD_HANDLER ade ade badv @@ -93,6 +119,12 @@ SYM_FUNC_END(except_vec_cex) BUILD_HANDLER reserved reserved none /* others */ SYM_FUNC_START(handle_sys) - la.abs t0, handle_syscall + la.pcrel t0, t1, handle_syscall jr t0 SYM_FUNC_END(handle_sys) + +SYM_DATA_START(rel_handle_sys) +LONG 1 +LONG 0 +LONG handle_syscall +SYM_DATA_END(rel_handle_sys) diff --git a/arch/loongarch/kernel/traps.c b/arch/loongarch/kernel/traps.c index 547ab6843d14..b47cd5ccace3 100644 --- a/arch/loongarch/kernel/traps.c +++ b/arch/loongarch/kernel/traps.c @@ -62,6 +62,107 @@ extern asmlinkage void handle_reserved(void); extern asmlinkage void handle_watch(void); extern asmlinkage void handle_vint(void); +struct handler_reloc_entry { + unsigned long offset; + unsigned long sym; +}; + +struct handler_reloc { + unsigned long cnt; + struct handler_reloc_entry entries[]; +}; + +extern struct handler_reloc rel_handle_tlb_load; +extern struct handler_reloc rel_handle_tlb_store; +extern struct handler_reloc rel_handle_tlb_modify; +extern struct handler_reloc rel_handle_tlb_protect; +extern struct handler_reloc rel_handle_ade; +extern struct handler_reloc rel_handle_ale; +extern struct handler_reloc rel_handle_sys; +extern struct handler_reloc rel_handle_bp; +extern struct handler_reloc rel_handle_ri; +extern struct handler_reloc rel_handle_fpu; +extern struct handler_reloc rel_handle_lsx; +extern struct handler_reloc rel_handle_lasx; +extern struct handler_reloc rel_handle_fpe; +extern struct handler_reloc rel_handle_lbt; +extern struct handler_reloc rel_handle_watch; +extern struct handler_reloc rel_handle_reserved; +extern struct handler_reloc rel_handle_vint; + +struct handler_reloc *eentry_reloc[128] = { + [0] = NULL, /* merr handler */ + [EXCCODE_TLBL] = &rel_handle_tlb_load, + [EXCCODE_TLBS] = &rel_handle_tlb_store, + [EXCCODE_TLBI] = &rel_handle_tlb_load, + [EXCCODE_TLBM] = &rel_handle_tlb_modify, + [EXCCODE_TLBNR] = &rel_handle_tlb_protect, + [EXCCODE_TLBNX] = &rel_handle_tlb_protect, + [EXCCODE_TLBPE] = &rel_handle_tlb_protect, + [EXCCODE_ADE] = &rel_handle_ade, + [EXCCODE_ALE] = &rel_handle_ale, + [EXCCODE_SYS] = &rel_handle_sys, + [EXCCODE_BP] = &rel_handle_bp, + [EXCCODE_INE] = &rel_handle_ri, + [EXCCODE_IPE] = &rel_handle_ri, + [EXCCODE_FPDIS] = &rel_handle_fpu, + [EXCCODE_LSXDIS] = &rel_handle_lsx, + [EXCCODE_LASXDIS] = &rel_handle_lasx, + [EXCCODE_FPE] = &rel_handle_fpe, + [EXCCODE_BTDIS] = &rel_handle_lbt, + [EXCCODE_WATCH] = &rel_handle_watch, + [(EXCCODE_WATCH + 1) ... (EXCCODE_INT_START - 1)] = &rel_handle_reserved, + [EXCCODE_INT_START ... (EXCCODE_INT_END - 1)] = &rel_handle_vint, +}; + +void reloc_handler(unsigned long handler, struct handler_reloc *rel) +{ + if (!rel) + return; + + for (unsigned long i = 0; i < rel->cnt; i++) { + unsigned long pc = handler + rel->entries[i].offset; + unsigned long v = rel->entries[i].sym; + /* Use s32 for a sign-extension deliberately. */ + s32 offset_hi20 = (void *)((v + 0x800) & ~0xfff) - + (void *)(pc & ~0xfff); + unsigned long anchor = (pc & ~0xfff) + offset_hi20; + ptrdiff_t offset_rem = (void *)v - (void *)anchor; + union loongarch_instruction *insn = + (union loongarch_instruction *)pc; + + insn[1].reg2i12_format.immediate = v & 0xfff; + v = offset_hi20 >> 12; + insn[0].reg1i20_format.immediate = v & 0xfffff; + v = offset_rem >> 32; + insn[2].reg1i20_format.immediate = v & 0xfffff; + v = offset_rem >> 52; + insn[3].reg2i12_format.immediate = v & 0xfff; + } +} + +/* Install CPU exception handler */ +static void do_set_handler(unsigned long exccode, void *addr, + struct handler_reloc *rel) +{ + unsigned long dest_addr = eentry + exccode * VECSIZE; + + memcpy((void *)dest_addr, addr, VECSIZE); + reloc_handler(dest_addr, rel); + local_flush_icache_range(dest_addr, dest_addr + VECSIZE); +} + +/* Install CPU exception handler, with the reloc table from eentry_reloc */ +void set_handler(unsigned long exccode, void *addr) +{ + do_set_handler(exccode, addr, eentry_reloc[exccode]); +} + +static void set_handler_reserved(unsigned long exccode) +{ + do_set_handler(exccode, handle_reserved, &rel_handle_reserved); +} + static void show_backtrace(struct task_struct *task, const struct pt_regs *regs, const char *loglvl, bool user) { @@ -781,19 +882,12 @@ void per_cpu_trap_init(int cpu) /* Initialise exception handlers */ if (cpu == 0) for (i = 0; i < 64; i++) - set_handler(i * VECSIZE, handle_reserved, VECSIZE); + set_handler_reserved(i); tlb_init(cpu); cpu_cache_init(); } -/* Install CPU exception handler */ -void set_handler(unsigned long offset, void *addr, unsigned long size) -{ - memcpy((void *)(eentry + offset), addr, size); - local_flush_icache_range(eentry + offset, eentry + offset + size); -} - static const char panic_null_cerr[] = "Trying to set NULL cache error exception handler\n"; @@ -818,20 +912,20 @@ void __init trap_init(void) /* Set interrupt vector handler */ for (i = EXCCODE_INT_START; i < EXCCODE_INT_END; i++) - set_handler(i * VECSIZE, handle_vint, VECSIZE); - - set_handler(EXCCODE_ADE * VECSIZE, handle_ade, VECSIZE); - set_handler(EXCCODE_ALE * VECSIZE, handle_ale, VECSIZE); - set_handler(EXCCODE_SYS * VECSIZE, handle_sys, VECSIZE); - set_handler(EXCCODE_BP * VECSIZE, handle_bp, VECSIZE); - set_handler(EXCCODE_INE * VECSIZE, handle_ri, VECSIZE); - set_handler(EXCCODE_IPE * VECSIZE, handle_ri, VECSIZE); - set_handler(EXCCODE_FPDIS * VECSIZE, handle_fpu, VECSIZE); - set_handler(EXCCODE_LSXDIS * VECSIZE, handle_lsx, VECSIZE); - set_handler(EXCCODE_LASXDIS * VECSIZE, handle_lasx, VECSIZE); - set_handler(EXCCODE_FPE * VECSIZE, handle_fpe, VECSIZE); - set_handler(EXCCODE_BTDIS * VECSIZE, handle_lbt, VECSIZE); - set_handler(EXCCODE_WATCH * VECSIZE, handle_watch, VECSIZE); + set_handler(i, handle_vint); + + set_handler(EXCCODE_ADE, handle_ade); + set_handler(EXCCODE_ALE, handle_ale); + set_handler(EXCCODE_SYS, handle_sys); + set_handler(EXCCODE_BP, handle_bp); + set_handler(EXCCODE_INE, handle_ri); + set_handler(EXCCODE_IPE, handle_ri); + set_handler(EXCCODE_FPDIS, handle_fpu); + set_handler(EXCCODE_LSXDIS, handle_lsx); + set_handler(EXCCODE_LASXDIS, handle_lasx); + set_handler(EXCCODE_FPE, handle_fpe); + set_handler(EXCCODE_BTDIS, handle_lbt); + set_handler(EXCCODE_WATCH, handle_watch); cache_error_setup(); diff --git a/arch/loongarch/mm/tlb.c b/arch/loongarch/mm/tlb.c index 8bad6b0cff59..6f70aab7202a 100644 --- a/arch/loongarch/mm/tlb.c +++ b/arch/loongarch/mm/tlb.c @@ -253,7 +253,6 @@ static void output_pgtable_bits_defines(void) #ifdef CONFIG_NUMA unsigned long pcpu_handlers[NR_CPUS]; #endif -extern long exception_handlers[VECSIZE * 128 / sizeof(long)]; void setup_tlb_handler(int cpu) { @@ -264,19 +263,20 @@ void setup_tlb_handler(int cpu) if (cpu == 0) { memcpy((void *)tlbrentry, handle_tlb_refill, 0x80); local_flush_icache_range(tlbrentry, tlbrentry + 0x80); - set_handler(EXCCODE_TLBI * VECSIZE, handle_tlb_load, VECSIZE); - set_handler(EXCCODE_TLBL * VECSIZE, handle_tlb_load, VECSIZE); - set_handler(EXCCODE_TLBS * VECSIZE, handle_tlb_store, VECSIZE); - set_handler(EXCCODE_TLBM * VECSIZE, handle_tlb_modify, VECSIZE); - set_handler(EXCCODE_TLBNR * VECSIZE, handle_tlb_protect, VECSIZE); - set_handler(EXCCODE_TLBNX * VECSIZE, handle_tlb_protect, VECSIZE); - set_handler(EXCCODE_TLBPE * VECSIZE, handle_tlb_protect, VECSIZE); + set_handler(EXCCODE_TLBI, handle_tlb_load); + set_handler(EXCCODE_TLBL, handle_tlb_load); + set_handler(EXCCODE_TLBS, handle_tlb_store); + set_handler(EXCCODE_TLBM, handle_tlb_modify); + set_handler(EXCCODE_TLBNR, handle_tlb_protect); + set_handler(EXCCODE_TLBNX, handle_tlb_protect); + set_handler(EXCCODE_TLBPE, handle_tlb_protect); } #ifdef CONFIG_NUMA else { void *addr; + unsigned long addr_ul; struct page *page; - const int vec_sz = sizeof(exception_handlers); + const int vec_sz = VECSIZE * 128; if (pcpu_handlers[cpu]) return; @@ -286,8 +286,11 @@ void setup_tlb_handler(int cpu) return; addr = page_address(page); + addr_ul = (unsigned long)addr; pcpu_handlers[cpu] = (unsigned long)addr; - memcpy((void *)addr, (void *)eentry, vec_sz); + memcpy(addr, (void *)eentry, vec_sz); + for (unsigned long i = 0; i < 128; i++) + reloc_handler(addr_ul + i * VECSIZE, eentry_reloc[i]); local_flush_icache_range((unsigned long)addr, (unsigned long)addr + vec_sz); csr_write64(pcpu_handlers[cpu], LOONGARCH_CSR_EENTRY); csr_write64(pcpu_handlers[cpu], LOONGARCH_CSR_MERRENTRY); diff --git a/arch/loongarch/mm/tlbex.S b/arch/loongarch/mm/tlbex.S index 3dd2a9615cd9..044c2190771a 100644 --- a/arch/loongarch/mm/tlbex.S +++ b/arch/loongarch/mm/tlbex.S @@ -39,11 +39,21 @@ SYM_FUNC_START(handle_tlb_protect) move a1, zero csrrd a2, LOONGARCH_CSR_BADV REG_S a2, sp, PT_BVADDR - la.abs t0, do_page_fault +1: la.pcrel t0, t1, do_page_fault jirl ra, t0, 0 RESTORE_ALL_AND_RET SYM_FUNC_END(handle_tlb_protect) +SYM_DATA_START(rel_handle_tlb_protect) + LONG 2 + + LONG 514b - handle_tlb_protect + LONG kernelsp + + LONG 1b - handle_tlb_protect + LONG do_page_fault +SYM_DATA_END(rel_handle_tlb_protect) + SYM_FUNC_START(handle_tlb_load) csrwr t0, EXCEPTION_KS0 csrwr t1, EXCEPTION_KS1 @@ -115,7 +125,8 @@ smp_pgtable_change_load: #ifdef CONFIG_64BIT vmalloc_load: - la.abs t1, swapper_pg_dir + /* The first insn of vmalloc_done_load overwrites ra */ +1: la.pcrel t1, ra, swapper_pg_dir b vmalloc_done_load #endif @@ -186,10 +197,24 @@ tlb_huge_update_load: nopage_tlb_load: dbar 0 csrrd ra, EXCEPTION_KS2 - la.abs t0, tlb_do_page_fault_0 +2: la.pcrel t0, t1, tlb_do_page_fault_0 jr t0 SYM_FUNC_END(handle_tlb_load) +SYM_DATA_START(rel_handle_tlb_load) +#ifdef CONFIG_64BIT + LONG 2 + + LONG 1b - handle_tlb_load + LONG swapper_pg_dir +#else + LONG 1 +#endif + + LONG 2b - handle_tlb_load + LONG tlb_do_page_fault_0 +SYM_DATA_END(rel_handle_tlb_load) + SYM_FUNC_START(handle_tlb_store) csrwr t0, EXCEPTION_KS0 csrwr t1, EXCEPTION_KS1 @@ -262,7 +287,8 @@ smp_pgtable_change_store: #ifdef CONFIG_64BIT vmalloc_store: - la.abs t1, swapper_pg_dir + /* The first insn of vmalloc_done_store overwrites ra */ +1: la.pcrel t1, ra, swapper_pg_dir b vmalloc_done_store #endif @@ -335,10 +361,24 @@ tlb_huge_update_store: nopage_tlb_store: dbar 0 csrrd ra, EXCEPTION_KS2 - la.abs t0, tlb_do_page_fault_1 +2: la.pcrel t0, t1, tlb_do_page_fault_1 jr t0 SYM_FUNC_END(handle_tlb_store) +SYM_DATA_START(rel_handle_tlb_store) +#ifdef CONFIG_64BIT + LONG 2 + + LONG 1b - handle_tlb_store + LONG swapper_pg_dir +#else + LONG 1 +#endif + + LONG 2b - handle_tlb_store + LONG tlb_do_page_fault_1 +SYM_DATA_END(rel_handle_tlb_store) + SYM_FUNC_START(handle_tlb_modify) csrwr t0, EXCEPTION_KS0 csrwr t1, EXCEPTION_KS1 @@ -410,7 +450,8 @@ smp_pgtable_change_modify: #ifdef CONFIG_64BIT vmalloc_modify: - la.abs t1, swapper_pg_dir + /* The first insn of vmalloc_done_modify overwrites ra */ +1: la.pcrel t1, ra, swapper_pg_dir b vmalloc_done_modify #endif @@ -482,10 +523,24 @@ tlb_huge_update_modify: nopage_tlb_modify: dbar 0 csrrd ra, EXCEPTION_KS2 - la.abs t0, tlb_do_page_fault_1 +2: la.pcrel t0, t1, tlb_do_page_fault_1 jr t0 SYM_FUNC_END(handle_tlb_modify) +SYM_DATA_START(rel_handle_tlb_modify) +#ifdef CONFIG_64BIT + LONG 2 + + LONG 1b - handle_tlb_modify + LONG swapper_pg_dir +#else + LONG 1 +#endif + + LONG 2b - handle_tlb_modify + LONG tlb_do_page_fault_1 +SYM_DATA_END(rel_handle_tlb_modify) + SYM_FUNC_START(handle_tlb_refill) csrwr t0, LOONGARCH_CSR_TLBRSAVE csrrd t0, LOONGARCH_CSR_PGD From patchwork Tue Feb 7 14:28:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xi Ruoyao X-Patchwork-Id: 53945 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:2388:b0:96:219d:e725 with SMTP id i8csp4044738dyf; Tue, 7 Feb 2023 06:33:31 -0800 (PST) X-Google-Smtp-Source: AK7set+k0H5g0eOyydEmpeYJpZxhcESalxtpz/+M6kg9kdk51GeQ0tAY8QD4Z5PyXb1vme2n4TGa X-Received: by 2002:aa7:98db:0:b0:56c:232e:395e with SMTP id e27-20020aa798db000000b0056c232e395emr3371710pfm.15.1675780411202; Tue, 07 Feb 2023 06:33:31 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1675780411; cv=none; d=google.com; s=arc-20160816; b=s4JDO0sAhT2f3GevOLhL/H1KEP933utkivKmpdI5T4oTnXgSDfFPFWDzuALJgvqBgX 41PIcxD9nP5TmHCUvBv4O5ZwSAp9lRMnLyYRN3E+gNs/On7wIzXYzG6kzaW60wqGrKB9 qOA/nl+CAktTDRIvy4+ZxvQL29yjj2W91CvfzRFIyVn2AQIjNTOmPC/R8EiTxHQpsD4Q O5QOhYb+SIa04B5te16/y7oDhLQ5dgcCqS9yot+TZrCeuazKe+WO0d5mRV0FA+y1aBjN moyrGZhasmT3J9PPO3lO3q5+Ox65HVMBK2ZUHcEdhwRz8aQ6n0EjhkqHZDUnoIDCia2O PWZQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=ZuGuzjN2+oE5xugu7vcx6vOEAyf4vmlGElo38yU/fy4=; b=x+W3V1mHc4S6XhzGlWvZCzWZyJEjPKEGN3Kai37CXbf+P6lVpsafQ86F4/RlySPRaf MI7KCglOC0/VQKI4fj/JVBXJm5RzhKSSnJ+Lfcvzm8S7SyicOYuQbYnSeAL/DWJH6m9r RH270x0NJqXsaJynDNj2hwBcmIA03VKQxgagUxscTkDnt0SacMAkIwsZVKtpan4CDtzx IzhNHPZQwX973COe2VKl7X/DqFvViwjTXBi6UcmxAPH7XESAlyyT78AglehfPnsk0bHN zyZZFzx1UKs0kVeArUU9B1Q2YIKf7F4c2drNvt+PKxsMmkfy7udhNGH7m1cBrt/9nlyM yzbw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@xry111.site header.s=default header.b=SxCinsc9; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=xry111.site Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id b185-20020a62cfc2000000b005a7c835ed44si1642379pfg.112.2023.02.07.06.33.18; Tue, 07 Feb 2023 06:33:31 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@xry111.site header.s=default header.b=SxCinsc9; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=xry111.site Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231206AbjBGOdC (ORCPT + 99 others); Tue, 7 Feb 2023 09:33:02 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44612 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232194AbjBGObB (ORCPT ); Tue, 7 Feb 2023 09:31:01 -0500 Received: from xry111.site (xry111.site [IPv6:2001:470:683e::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0C3F43D092 for ; Tue, 7 Feb 2023 06:29:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1675780189; bh=W9Fri07rSLvFzK88TTPRH5yOkj10Mz0KpXTA31lQPHk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SxCinsc9t5H0OBxUO98edPYsoJl2ESh7ep3lPHDWIM7A91qliL1TqDhkfbQ865ADQ vrkqZ6/KspgCZDW1d5bDFMdVW3OFDLDGiFkY23yHkXOxgs6VlkCO4wSFf5klooul5V NsnmXm39jE+0kCaXHS49yu/pgsyFiraOOrz6DoPo= Received: from xry111-x57s1.. (unknown [IPv6:240e:358:11cc:4100:dc73:854d:832e:2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) (Authenticated sender: xry111@xry111.site) by xry111.site (Postfix) with ESMTPSA id C87C265DC8; Tue, 7 Feb 2023 09:29:44 -0500 (EST) From: Xi Ruoyao To: Youling Tang , Huacai Chen , Jinyang He Cc: Xuerui Wang , loongarch@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH v2 3/5] LoongArch: Add JUMP_LINK_ADDR macro implementation to avoid using la.abs Date: Tue, 7 Feb 2023 22:28:20 +0800 Message-Id: <20230207142822.52172-4-xry111@xry111.site> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230207142822.52172-1-xry111@xry111.site> References: <20230207142822.52172-1-xry111@xry111.site> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_PASS,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1757183120501615701?= X-GMAIL-MSGID: =?utf-8?q?1757183120501615701?= From: Youling Tang Add JUMP_LINK_ADDR macro implementation to avoid using la.abs. Signed-off-by: Youling Tang --- arch/loongarch/include/asm/stackframe.h | 8 ++++++++ arch/loongarch/kernel/head.S | 10 ++++------ arch/loongarch/power/suspend_asm.S | 5 ++--- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/arch/loongarch/include/asm/stackframe.h b/arch/loongarch/include/asm/stackframe.h index bbec1e56b61b..cd8240858599 100644 --- a/arch/loongarch/include/asm/stackframe.h +++ b/arch/loongarch/include/asm/stackframe.h @@ -217,4 +217,12 @@ RESTORE_SP_AND_RET \docfi .endm +/* Jump to the virtual address of the link. */ + .macro JUMP_LINK_ADDR + li.d t0, CACHE_BASE + pcaddi t1, 0 + or t0, t0, t1 + jirl zero, t0, 0xc + .endm + #endif /* _ASM_STACKFRAME_H */ diff --git a/arch/loongarch/kernel/head.S b/arch/loongarch/kernel/head.S index aa6181714ec3..e8a4bf9d7599 100644 --- a/arch/loongarch/kernel/head.S +++ b/arch/loongarch/kernel/head.S @@ -52,9 +52,8 @@ SYM_CODE_START(kernel_entry) # kernel entry point /* We might not get launched at the address the kernel is linked to, so we jump there. */ - la.abs t0, 0f - jr t0 -0: + JUMP_LINK_ADDR + /* Enable PG */ li.w t0, 0xb0 # PLV=0, IE=0, PG=1 csrwr t0, LOONGARCH_CSR_CRMD @@ -106,9 +105,8 @@ SYM_CODE_START(smpboot_entry) li.d t0, CSR_DMW1_INIT # CA, PLV0 csrwr t0, LOONGARCH_CSR_DMWIN1 - la.abs t0, 0f - jr t0 -0: + JUMP_LINK_ADDR + /* Enable PG */ li.w t0, 0xb0 # PLV=0, IE=0, PG=1 csrwr t0, LOONGARCH_CSR_CRMD diff --git a/arch/loongarch/power/suspend_asm.S b/arch/loongarch/power/suspend_asm.S index eb2675642f9f..596a682a7924 100644 --- a/arch/loongarch/power/suspend_asm.S +++ b/arch/loongarch/power/suspend_asm.S @@ -78,9 +78,8 @@ SYM_INNER_LABEL(loongarch_wakeup_start, SYM_L_GLOBAL) li.d t0, CSR_DMW1_INIT # CA, PLV0 csrwr t0, LOONGARCH_CSR_DMWIN1 - la.abs t0, 0f - jr t0 -0: + JUMP_LINK_ADDR + la.pcrel t0, acpi_saved_sp ld.d sp, t0, 0 SETUP_WAKEUP From patchwork Tue Feb 7 14:28:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xi Ruoyao X-Patchwork-Id: 53946 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:2388:b0:96:219d:e725 with SMTP id i8csp4044970dyf; Tue, 7 Feb 2023 06:33:47 -0800 (PST) X-Google-Smtp-Source: AK7set/VzCU36PZA6Dwq1nus4/J+s+5LtksYNPQvGvAfw21JxqbEE1d8qGqIg8I7T+UWvfwGAcH3 X-Received: by 2002:a17:903:2285:b0:199:190c:3c20 with SMTP id b5-20020a170903228500b00199190c3c20mr3320425plh.38.1675780427114; Tue, 07 Feb 2023 06:33:47 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1675780427; cv=none; d=google.com; s=arc-20160816; b=wWVgxcbuvMXZB3qUgdWGHGpar7R+0YzpDp3SNdl+8KbSYoYo595Rrpa4RegTNbkDKb U/Xep58JjoeeVEWjMUQ547epArnYWIE9jvNdajqrpe83ULM6gQ4z7iIrZks81fQmPR6U C2A9SxQClf21+YwtQq7Lggen2elpmTntSN3nb3GLg2FaVe25hGpi0bAnriW9rmOfjmwL I/UaqXL0S/xxhunnT75by+/fG/pLqGBsjyRGoa1LfiJwxgo0iGRl5NyeL6Cf40pP9yEJ i+HeCbZil1JzuNF2l3slcubSfGILWbITKKoW62IDbHXZHS2sdmkJTQyVtmaYeqWx4R0Y 8Itw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=5F/BRMSO5l6e/FjDqAsVJniiskz5jCvgYoQ9HnVBHfw=; b=Xrcs2DToqF2bDtEyqBzjQ1HlO3PUv0HQPp5SAk/K7UF0CgTdc1y9g/JL0H55TVPDxp hi6Sn5zquIaGmSk6REmTqJvJRO3Q3N4bEcnkPcC3bgR+HU08nPY/Eq7O+5xMRK7dPz5l UNGTRCXKOoyeRCK+LwR8Hs9SYsrdLvFtz6uTV1CZrgF/SU+UjVwXd8Z/cx8wlGHogUJw gzll0Sa020hkKoCj/qdWIE2v/j6+jf9R0wvvvArrusu+Og1x9l8uvosD54uXGipB5w7k g0fm/SlE9tUFKK2HgMC9zeVS3yhnLlI96LnlVxtJWrG5ih4SIN9lcSpfZceh1bhYF/aF X3MQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@xry111.site header.s=default header.b=VCLDtTgx; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=xry111.site Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id ij14-20020a170902ab4e00b0019609a4f16dsi5615346plb.461.2023.02.07.06.33.34; Tue, 07 Feb 2023 06:33:47 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@xry111.site header.s=default header.b=VCLDtTgx; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=xry111.site Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232773AbjBGOda (ORCPT + 99 others); Tue, 7 Feb 2023 09:33:30 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44914 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232654AbjBGOca (ORCPT ); Tue, 7 Feb 2023 09:32:30 -0500 Received: from xry111.site (xry111.site [89.208.246.23]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B2DE13E622 for ; Tue, 7 Feb 2023 06:29:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1675780196; bh=nlJeQcH9bLNkq4Rv5ErUKAPNwfRRUDDEcLljcjwu/kQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VCLDtTgxKl/kdxS2vgR6LfVavG6bj2lh5f5DGlQ46OOUIm4W00sPcIZQP+ffz5GzC McRd5BakDuuE8jfwuAnn8sZrTXucgjrRNt2/QbvJH8Uxd7FlHzvlAc/khrjpfSuqCx d/o74cLviFcL51sk0675a9NShdqvxR5EOc4wljw0= Received: from xry111-x57s1.. (unknown [IPv6:240e:358:11cc:4100:dc73:854d:832e:2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) (Authenticated sender: xry111@xry111.site) by xry111.site (Postfix) with ESMTPSA id 1454065DC9; Tue, 7 Feb 2023 09:29:49 -0500 (EST) From: Xi Ruoyao To: Youling Tang , Huacai Chen , Jinyang He Cc: Xuerui Wang , loongarch@lists.linux.dev, linux-kernel@vger.kernel.org, Xi Ruoyao Subject: [PATCH v2 4/5] LoongArch: Add support for kernel relocation Date: Tue, 7 Feb 2023 22:28:21 +0800 Message-Id: <20230207142822.52172-5-xry111@xry111.site> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230207142822.52172-1-xry111@xry111.site> References: <20230207142822.52172-1-xry111@xry111.site> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_PASS,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1757183137093570398?= X-GMAIL-MSGID: =?utf-8?q?1757183137093570398?= From: Youling Tang arch/loongarch/kernel/relocate.c contains the functions necessary to relocate the kernel elsewhere in memory. The kernel makes a copy of itself at the new address. It uses the relocation table inserted by the relocs tool to fix symbol references within the new image. If copy/relocation is successful then the entry point of the new kernel is returned, otherwise fall back to starting the kernel in place. Signed-off-by: Youling Tang Signed-off-by: Xi Ruoyao # Fix compiler warnings --- arch/loongarch/Kconfig | 15 +++++ arch/loongarch/Makefile | 5 ++ arch/loongarch/kernel/Makefile | 2 + arch/loongarch/kernel/head.S | 18 ++++++ arch/loongarch/kernel/relocate.c | 96 +++++++++++++++++++++++++++++ arch/loongarch/kernel/vmlinux.lds.S | 11 +++- 6 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 arch/loongarch/kernel/relocate.c diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig index 0e2427d4ee50..db83f71ba1c0 100644 --- a/arch/loongarch/Kconfig +++ b/arch/loongarch/Kconfig @@ -48,6 +48,7 @@ config LOONGARCH select ARCH_SUPPORTS_ATOMIC_RMW select ARCH_SUPPORTS_HUGETLBFS select ARCH_SUPPORTS_NUMA_BALANCING + select SYS_SUPPORTS_RELOCATABLE select ARCH_USE_BUILTIN_BSWAP select ARCH_USE_CMPXCHG_LOCKREF select ARCH_USE_QUEUED_RWLOCKS @@ -229,6 +230,11 @@ config SCHED_OMIT_FRAME_POINTER config AS_HAS_EXPLICIT_RELOCS def_bool $(as-instr,x:pcalau12i \$t0$(comma)%pc_hi20(x)) +config SYS_SUPPORTS_RELOCATABLE + bool + help + Selected if the platform supports relocating the kernel. + menu "Kernel type and options" source "kernel/Kconfig.hz" @@ -474,6 +480,15 @@ config PHYSICAL_START specified in the "crashkernel=YM@XM" command line boot parameter passed to the panic-ed kernel). +config RELOCATABLE + bool "Relocatable kernel" + depends on SYS_SUPPORTS_RELOCATABLE + help + This builds the kernel as a Position Independent Executable (PIE), + which retains all relocation metadata required to relocate the + kernel binary at runtime to a different virtual address than the + address it was linked at. + config SECCOMP bool "Enable seccomp to safely compute untrusted bytecode" depends on PROC_FS diff --git a/arch/loongarch/Makefile b/arch/loongarch/Makefile index 4402387d2755..27b5a70ff31c 100644 --- a/arch/loongarch/Makefile +++ b/arch/loongarch/Makefile @@ -71,6 +71,11 @@ KBUILD_AFLAGS_MODULE += -Wa,-mla-global-with-abs KBUILD_CFLAGS_MODULE += -fplt -Wa,-mla-global-with-abs,-mla-local-with-abs endif +ifeq ($(CONFIG_RELOCATABLE),y) +LDFLAGS_vmlinux += -static -pie --no-dynamic-linker -z notext +KBUILD_CFLAGS_KERNEL += -fPIE +endif + cflags-y += -ffreestanding cflags-y += $(call cc-option, -mno-check-zero-division) diff --git a/arch/loongarch/kernel/Makefile b/arch/loongarch/kernel/Makefile index c8cfbd562921..3341dd5f0926 100644 --- a/arch/loongarch/kernel/Makefile +++ b/arch/loongarch/kernel/Makefile @@ -31,6 +31,8 @@ endif obj-$(CONFIG_MODULES) += module.o module-sections.o obj-$(CONFIG_STACKTRACE) += stacktrace.o +obj-$(CONFIG_RELOCATABLE) += relocate.o + obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_SMP) += smp.o diff --git a/arch/loongarch/kernel/head.S b/arch/loongarch/kernel/head.S index e8a4bf9d7599..6db1549177ad 100644 --- a/arch/loongarch/kernel/head.S +++ b/arch/loongarch/kernel/head.S @@ -88,7 +88,25 @@ SYM_CODE_START(kernel_entry) # kernel entry point PTR_ADD sp, sp, tp set_saved_sp sp, t0, t1 +#ifdef CONFIG_RELOCATABLE + /* Copy kernel and apply the relocations */ + bl relocate_kernel + + /* Repoint the sp into the new kernel image */ + PTR_LI sp, (_THREAD_SIZE - 32 - PT_SIZE) + PTR_ADD sp, sp, tp + set_saved_sp sp, t0, t1 + PTR_ADDI sp, sp, -4 * SZREG # init stack pointer + + /* + * relocate_kernel returns the entry point either + * in the relocated kernel or the original if for + * some reason relocation failed. + */ + jr a0 +#else bl start_kernel +#endif ASM_BUG() SYM_CODE_END(kernel_entry) diff --git a/arch/loongarch/kernel/relocate.c b/arch/loongarch/kernel/relocate.c new file mode 100644 index 000000000000..9c61e03d3e91 --- /dev/null +++ b/arch/loongarch/kernel/relocate.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Support for Kernel relocation at boot time + * + * Copyright (C) 2023 Loongson Technology Corporation Limited + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define RELOCATED(x) ((void *)((long)x + offset)) + +extern long __rela_dyn_start; +extern long __rela_dyn_end; + +/* + * Choose a new address for the kernel, for now we'll hard + * code the destination. + */ +static inline void __init *determine_relocation_address(void) +{ + return (void *)(CACHE_BASE + 0x02000000); +} + +static inline int __init relocation_addr_valid(void *loc_new) +{ + if ((unsigned long)loc_new & 0x0000ffff) { + /* Inappropriately aligned new location */ + return 0; + } + if ((unsigned long)loc_new < (unsigned long)_end) { + /* New location overlaps original kernel */ + return 0; + } + return 1; +} + +void *__init relocate_kernel(void) +{ + Elf64_Rela *rela, *rela_end; + void *loc_new; + unsigned long kernel_length; + long offset = 0; + /* Default to original kernel entry point */ + void *kernel_entry = start_kernel; + + kernel_length = (long)(_end) - (long)(_text); + + loc_new = determine_relocation_address(); + + /* Sanity check relocation address */ + if (relocation_addr_valid(loc_new)) + offset = (unsigned long)loc_new - (unsigned long)(_text); + + if (offset) { + /* Copy the kernel to it's new location */ + memcpy(loc_new, _text, kernel_length); + + /* Sync the caches ready for execution of new kernel */ + __asm__ __volatile__ ( + "ibar 0 \t\n" + "dbar 0 \t\n"); + + rela = (Elf64_Rela *)RELOCATED(&__rela_dyn_start); + rela_end = (Elf64_Rela *)RELOCATED(&__rela_dyn_end); + + for ( ; rela < rela_end; rela++) { + Elf64_Addr addr = rela->r_offset; + Elf64_Addr relocated_addr = rela->r_addend; + + if (rela->r_info != R_LARCH_RELATIVE) + continue; + + if (relocated_addr >= VMLINUX_LOAD_ADDRESS) + relocated_addr = + (Elf64_Addr)RELOCATED(relocated_addr); + + *(Elf64_Addr *)RELOCATED(addr) = relocated_addr; + + } + + /* The current thread is now within the relocated image */ + __current_thread_info = RELOCATED(__current_thread_info); + + /* Return the new kernel's entry point */ + kernel_entry = RELOCATED(start_kernel); + } + + return kernel_entry; +} diff --git a/arch/loongarch/kernel/vmlinux.lds.S b/arch/loongarch/kernel/vmlinux.lds.S index 733b16e8d55d..aec0b6567d24 100644 --- a/arch/loongarch/kernel/vmlinux.lds.S +++ b/arch/loongarch/kernel/vmlinux.lds.S @@ -70,6 +70,8 @@ SECTIONS .plt : ALIGN(16) { *(.plt) } .got.plt : ALIGN(16) { *(.got.plt) } + .data.rel : { *(.data.rel*) } + . = ALIGN(PECOFF_SEGMENT_ALIGN); __init_begin = .; __inittext_begin = .; @@ -93,8 +95,6 @@ SECTIONS PERCPU_SECTION(1 << CONFIG_L1_CACHE_SHIFT) #endif - .rela.dyn : ALIGN(8) { *(.rela.dyn) *(.rela*) } - .init.bss : { *(.init.bss) } @@ -107,6 +107,12 @@ SECTIONS RO_DATA(4096) RW_DATA(1 << CONFIG_L1_CACHE_SHIFT, PAGE_SIZE, THREAD_SIZE) + .rela.dyn : ALIGN(8) { + __rela_dyn_start = .; + *(.rela.dyn) *(.rela*) + __rela_dyn_end = .; + } + .sdata : { *(.sdata) } @@ -133,6 +139,7 @@ SECTIONS DISCARDS /DISCARD/ : { + *(.dynamic .dynsym .dynstr .hash .gnu.hash) *(.gnu.attributes) *(.options) *(.eh_frame) From patchwork Tue Feb 7 14:28:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xi Ruoyao X-Patchwork-Id: 53949 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:2388:b0:96:219d:e725 with SMTP id i8csp4046369dyf; Tue, 7 Feb 2023 06:35:35 -0800 (PST) X-Google-Smtp-Source: AK7set/wcsjsBrO85yrzFUs5E0suYLs1HcfSX/T//iUUpIiiCtHjmKZ437u/D8vul7MLBzNxL5P7 X-Received: by 2002:a17:902:ecc4:b0:199:2a8d:d682 with SMTP id a4-20020a170902ecc400b001992a8dd682mr3132734plh.51.1675780535731; Tue, 07 Feb 2023 06:35:35 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1675780535; cv=none; d=google.com; s=arc-20160816; b=TupnFEGGmrXjnNteYwVMMYl6qetNBvxq1SZ1QlSdzZSjzGFzWXkQvGgkHb8jMWIrmw Rg6r3PQmlqAlX0CO3k0R0FxJEY5UeI/z/WI5qRp3iTOCXjnmyUqLS0z0QMD9Sitfe8Jt b6u/JIZ8x4tb38qlMOZm6uTAzvtuEaJjKrQ5X02kjFgcylnyeLxyLcbVu8XjTX6m//Q0 ikXZ77B2yd3QCot6fBYa/dMADuEDptMv0KrV7xUtEYIY+oiqtexvo4UIQSst0RelkmkY h1b15xVykwhF+X7bO03wcFjuuRaDL2aeoWivg9z2y0ONbmxfqK2jPiZ2Kalh0fAD/0iU gHYA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=1AP7xvkusJnzoxNcI5s3wu8i1VRenhY8iS7tvcJR7fY=; b=aTcg/fmQiGpNgrZmw/egdxzbq86JaVQSECjeTMTpvON0RubVi9nKPdKUune8JAVQ60 K+7KDyZHKbtqidZaS3/aUm6/6oVdazcacLGPrtXIp1jBcwy+fk/P1Tz4ISWegyuFTnOE lyS6/UUyW16Lkjw0LVe+MpOjLMb+7AAp2QT9EUiy/j9Dzu3Fu7K8+dkvWQMfdKumGDxA C4JQ4R03uRjyLS6MnKVC7n0yIyZTo4AqF+1i+6KqpovJGkWkJ/6f+LTA8y8oALWXhOBM C15Yz+7JVvijOhChghxdzXPmv1wVlSMEM4gpNGgDumT6cnhrP96SctYZpPk6tHfm/cKm P0EA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@xry111.site header.s=default header.b="DB6T/rgR"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=xry111.site Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id q3-20020a17090311c300b00188a7401d89si16468316plh.481.2023.02.07.06.35.22; Tue, 07 Feb 2023 06:35:35 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@xry111.site header.s=default header.b="DB6T/rgR"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=xry111.site Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232781AbjBGOdn (ORCPT + 99 others); Tue, 7 Feb 2023 09:33:43 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44600 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232782AbjBGOcy (ORCPT ); Tue, 7 Feb 2023 09:32:54 -0500 Received: from xry111.site (xry111.site [89.208.246.23]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3164A3E635 for ; Tue, 7 Feb 2023 06:30:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1675780204; bh=bYU8i2vMnFWlU7t8bvGKvgBRgI3/rqYbEk0nKv8UPc8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DB6T/rgR/D1PBLoQu7/6ZZbYa/q0dP02qSY3OZG9phC2MLiiZyOF0873zkMOum+z8 lf9WSbzcAb549qBYJ3WzJujD2HV7Zqh+tGeaen2GREHF3tGNcxmutODkeunmMAGgE6 UXXrQLjnRWYL54jd8O3nagbsw+oGbkVABQKWs6eo= Received: from xry111-x57s1.. (unknown [IPv6:240e:358:11cc:4100:dc73:854d:832e:2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) (Authenticated sender: xry111@xry111.site) by xry111.site (Postfix) with ESMTPSA id A369E65DC6; Tue, 7 Feb 2023 09:29:57 -0500 (EST) From: Xi Ruoyao To: Youling Tang , Huacai Chen , Jinyang He Cc: Xuerui Wang , loongarch@lists.linux.dev, linux-kernel@vger.kernel.org, Xi Ruoyao Subject: [PATCH v2 5/5] LoongArch: Add support for kernel address space layout randomization (KASLR) Date: Tue, 7 Feb 2023 22:28:22 +0800 Message-Id: <20230207142822.52172-6-xry111@xry111.site> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230207142822.52172-1-xry111@xry111.site> References: <20230207142822.52172-1-xry111@xry111.site> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_PASS,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1757183251076088034?= X-GMAIL-MSGID: =?utf-8?q?1757183251076088034?= From: Youling Tang This patch adds support for relocating the kernel to a random address. Entropy is derived from the banner, which will change every build and random_get_entropy() which should provide additional runtime entropy. The kernel is relocated by up to RANDOMIZE_BASE_MAX_OFFSET bytes from its link address. Because relocation happens so early in the kernel boot, the amount of physical memory has not yet been determined. This means the only way to limit relocation within the available memory is via Kconfig. Limit the maximum value of RANDOMIZE_BASE_MAX_OFFSET to 256M(0x10000000) because our memory layout has many holes. KERNELOFFSET (kaslr_offset) is added to vmcoreinfo in the future, for crash --kaslr support. Signed-off-by: Youling Tang Signed-off-by: Xi Ruoyao # Use arch_initcall --- arch/loongarch/Kconfig | 22 ++++++ arch/loongarch/include/asm/page.h | 6 ++ arch/loongarch/kernel/relocate.c | 115 ++++++++++++++++++++++++++++++ arch/loongarch/kernel/setup.c | 3 + 4 files changed, 146 insertions(+) diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig index db83f71ba1c0..4ceb16ce080a 100644 --- a/arch/loongarch/Kconfig +++ b/arch/loongarch/Kconfig @@ -489,6 +489,28 @@ config RELOCATABLE kernel binary at runtime to a different virtual address than the address it was linked at. +config RANDOMIZE_BASE + bool "Randomize the address of the kernel image (KASLR)" + depends on RELOCATABLE + help + Randomizes the physical and virtual address at which the + kernel image is loaded, as a security feature that + deters exploit attempts relying on knowledge of the location + of kernel internals. + + The kernel will be offset by up to RANDOMIZE_BASE_MAX_OFFSET. + + If unsure, say N. + +config RANDOMIZE_BASE_MAX_OFFSET + hex "Maximum KASLR offset" if EXPERT + depends on RANDOMIZE_BASE + range 0x0 0x10000000 if 64BIT + default "0x01000000" + help + When KASLR is active, this provides the maximum offset that will + be applied to the kernel image. + config SECCOMP bool "Enable seccomp to safely compute untrusted bytecode" depends on PROC_FS diff --git a/arch/loongarch/include/asm/page.h b/arch/loongarch/include/asm/page.h index 53f284a96182..6dda0d6271ca 100644 --- a/arch/loongarch/include/asm/page.h +++ b/arch/loongarch/include/asm/page.h @@ -106,6 +106,12 @@ extern int __virt_addr_valid(volatile void *kaddr); ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +extern unsigned long __kaslr_offset; +static inline unsigned long kaslr_offset(void) +{ + return __kaslr_offset; +} + #include #include diff --git a/arch/loongarch/kernel/relocate.c b/arch/loongarch/kernel/relocate.c index 9c61e03d3e91..351168b70b7a 100644 --- a/arch/loongarch/kernel/relocate.c +++ b/arch/loongarch/kernel/relocate.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -19,6 +20,70 @@ extern long __rela_dyn_start; extern long __rela_dyn_end; +#ifdef CONFIG_RANDOMIZE_BASE + +static inline __init unsigned long rotate_xor(unsigned long hash, + const void *area, size_t size) +{ + size_t i; + unsigned long *ptr = (unsigned long *)area; + + for (i = 0; i < size / sizeof(hash); i++) { + /* Rotate by odd number of bits and XOR. */ + hash = (hash << ((sizeof(hash) * 8) - 7)) | (hash >> 7); + hash ^= ptr[i]; + } + + return hash; +} + +static inline __init unsigned long get_random_boot(void) +{ + unsigned long entropy = random_get_entropy(); + unsigned long hash = 0; + + /* Attempt to create a simple but unpredictable starting entropy. */ + hash = rotate_xor(hash, linux_banner, strlen(linux_banner)); + + /* Add in any runtime entropy we can get */ + hash = rotate_xor(hash, &entropy, sizeof(entropy)); + + return hash; +} + +static inline __init bool kaslr_disabled(void) +{ + char *str; + + str = strstr(boot_command_line, "nokaslr"); + if (str == boot_command_line || (str > boot_command_line && *(str - 1) == ' ')) + return true; + + return false; +} + +/* Choose a new address for the kernel */ +static inline void __init *determine_relocation_address(void) +{ + unsigned long kernel_length; + void *dest = _text; + unsigned long offset; + + if (kaslr_disabled()) + return dest; + + kernel_length = (long)_end - (long)_text; + + offset = get_random_boot() << 16; + offset &= (CONFIG_RANDOMIZE_BASE_MAX_OFFSET - 1); + if (offset < kernel_length) + offset += ALIGN(kernel_length, 0xffff); + + return RELOCATED(dest); +} + +#else + /* * Choose a new address for the kernel, for now we'll hard * code the destination. @@ -28,6 +93,8 @@ static inline void __init *determine_relocation_address(void) return (void *)(CACHE_BASE + 0x02000000); } +#endif + static inline int __init relocation_addr_valid(void *loc_new) { if ((unsigned long)loc_new & 0x0000ffff) { @@ -41,6 +108,13 @@ static inline int __init relocation_addr_valid(void *loc_new) return 1; } +static inline void __init update_kaslr_offset(unsigned long *addr, long offset) +{ + unsigned long *new_addr = (unsigned long *)RELOCATED(addr); + + *new_addr = (unsigned long)offset; +} + void *__init relocate_kernel(void) { Elf64_Rela *rela, *rela_end; @@ -49,6 +123,10 @@ void *__init relocate_kernel(void) long offset = 0; /* Default to original kernel entry point */ void *kernel_entry = start_kernel; + char *cmdline = early_ioremap(fw_arg1, COMMAND_LINE_SIZE); + + /* Boot command line was passed in fw_arg1 */ + strscpy(boot_command_line, cmdline, COMMAND_LINE_SIZE); kernel_length = (long)(_end) - (long)(_text); @@ -90,7 +168,44 @@ void *__init relocate_kernel(void) /* Return the new kernel's entry point */ kernel_entry = RELOCATED(start_kernel); + + /* Error may occur before, so keep it at last */ + update_kaslr_offset(&__kaslr_offset, offset); } return kernel_entry; } + +/* + * Show relocation information on panic. + */ +static void show_kernel_relocation(const char *level) +{ + if (__kaslr_offset > 0) { + printk(level); + pr_cont("Kernel relocated offset @ 0x%lx\n", __kaslr_offset); + pr_cont(" .text @ 0x%lx\n", (unsigned long)&_text); + pr_cont(" .data @ 0x%lx\n", (unsigned long)&_sdata); + pr_cont(" .bss @ 0x%lx\n", (unsigned long)&__bss_start); + } +} + +static int kernel_location_notifier_fn(struct notifier_block *self, + unsigned long v, void *p) +{ + show_kernel_relocation(KERN_EMERG); + return NOTIFY_DONE; +} + +static struct notifier_block kernel_location_notifier = { + .notifier_call = kernel_location_notifier_fn +}; + +static int __init register_kernel_offset_dumper(void) +{ + atomic_notifier_chain_register(&panic_notifier_list, + &kernel_location_notifier); + return 0; +} + +arch_initcall(register_kernel_offset_dumper); diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c index 4344502c0b31..b2ba2741945c 100644 --- a/arch/loongarch/kernel/setup.c +++ b/arch/loongarch/kernel/setup.c @@ -82,6 +82,9 @@ static struct resource code_resource = { .name = "Kernel code", }; static struct resource data_resource = { .name = "Kernel data", }; static struct resource bss_resource = { .name = "Kernel bss", }; +unsigned long __kaslr_offset __ro_after_init; +EXPORT_SYMBOL(__kaslr_offset); + const char *get_system_type(void) { return "generic-loongson-machine";