Received: by 2002:a05:6358:11c7:b0:104:8066:f915 with SMTP id i7csp128558rwl; Tue, 28 Mar 2023 22:28:15 -0700 (PDT) X-Google-Smtp-Source: AKy350azX0eBwhw5/3wwhjIgqzQ1p7d2k8bI51+ZLbInTuH0TPAuhW/J6JmgBs79DfoGI9c3qSuD X-Received: by 2002:a17:907:c249:b0:932:fc34:88e with SMTP id tj9-20020a170907c24900b00932fc34088emr18901620ejc.52.1680067695659; Tue, 28 Mar 2023 22:28:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680067695; cv=none; d=google.com; s=arc-20160816; b=JjjLP9fcM8PN6B3T3zsK7MMU/T4Bv3RXhRG56FmWSU7u2AUxYGT9NVmIsdcR17Lig6 Nz0nmNipdgf4IE3kV+AydgicqmYOzezf7qdfOfj7KbJdHbYEBJNGFIY50kpr9c8+kUQf Wj28nBnDWEn7ZpKo9E4SN6SUbViIzaUh9+7veAvze67fuoPOwZwpYXow20QZy+BYxAke MPVROqbQuC4HwQB1/irJ2bmoqthNN40bkMRPOnwSswFeZDVYLKf16FSYLSbSNich/tWO 3M+jHx8qc67z9v8tMcTKSpgsnAF4VU99bSqyqU+cedj8gyRpi29nWV+tcphAbgKJoGZw l0mw== 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=O8+K1sPfEhtQoj9C6bXF5OUwtH/iy1EwbeVuSRaFkcs=; b=GZfjIObZ2bEmHMTfATe4ifRv94AnqKaFCa/Wje8Qeu9FkmC8SjplnTUIQXj1FtQCcm jqVeRRheCIi7YF/cvLyNWcsMskm81k3hdmhgY7HoCDQPZWD4VEjd4hDmx8etZgv0Ralu etr16zbXlVgoNoFcgNFEQLGofXJAJ30U+r4pap7CctC+duIpyB3gT3kH/RDH+s8PzU0c FAZAfm0WhKeDdexenNPSixzIJR2zQfjaMRRV7p0zRM6ApZAo6QQMULPP+e3I7nj9Gp0u 4ENdVanEZKOErR5CsE4pJSaZ1C8cZ3wTJ3eg3aWE8NNMRL5eIbQ1vp8Q6HIb77yM210E 5qgQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@rivosinc-com.20210112.gappssmtp.com header.s=20210112 header.b=GIlpVVXD; 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 Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id h23-20020a170906261700b0092beae94d7dsi27923276ejc.67.2023.03.28.22.27.50; Tue, 28 Mar 2023 22:28:15 -0700 (PDT) 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=@rivosinc-com.20210112.gappssmtp.com header.s=20210112 header.b=GIlpVVXD; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229580AbjC2FLA (ORCPT + 99 others); Wed, 29 Mar 2023 01:11:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48776 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229436AbjC2FK7 (ORCPT ); Wed, 29 Mar 2023 01:10:59 -0400 Received: from mail-wm1-x331.google.com (mail-wm1-x331.google.com [IPv6:2a00:1450:4864:20::331]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CAC8412C for ; Tue, 28 Mar 2023 22:10:57 -0700 (PDT) Received: by mail-wm1-x331.google.com with SMTP id bg13-20020a05600c3c8d00b003ef90adc168so1011274wmb.5 for ; Tue, 28 Mar 2023 22:10:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20210112.gappssmtp.com; s=20210112; t=1680066656; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=O8+K1sPfEhtQoj9C6bXF5OUwtH/iy1EwbeVuSRaFkcs=; b=GIlpVVXDNU5KaVtyEyf3nWdmc3BUyieH/qn24ittRAE+N8P+ydUXEUdTE7yO5vfDXe NLlPCkG56knGG8YIsQrpwcwohc4HuzgtKcv5o3ZIwx5G52is+ZAsayJGfcy5eWiKvPeM N/eOSoaw9gTrjuyCrYp5hl6qWoqOvErBmTiRzSopzCMX/2Zprfsrrj1KecmBPly7UHAJ uVfZqvVn7rg9lUP/y8WePJ2W0AVA+naeRTgSCESQMB1h+ET7uAS41mnBOIX5/ieYEqNC A19StdEeQTBqHklyRhYWmAzEVPkwXkquIuhKEXT8PqahIwBAP1l34Olz1DWKwPkDo5I6 y8ig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680066656; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=O8+K1sPfEhtQoj9C6bXF5OUwtH/iy1EwbeVuSRaFkcs=; b=R19y3YI/Ffy7Gc4W6NahQOszZHa2pd7ZSQEKMzYvGdIgqZjAQ3wI5RjLU0dJL6vQ79 obuMum1sJUzYrrKUkA05X0I/lndokkxJH5yf28Y5HXszOvee0VSpjhbKngjSYTmmoWfN NePNHMALn5Yw61TmC+s3bDVQBsYvZKHp0g+8z/G5NJkQuwMyHTd9oP0w7iNcFjhSQBIZ 54tVecFw36ShMevGhqbuoP1k8nF6++H2K4kIkQDIh1g6DcG6izwu7Kt/j8RQ/PPRqDyS YIIVDFyAPkN8xNGYx4xw1NPYVDaeOowgv1ZrY6Wx+ThgukNZvb/5wzJwMwF6O91Ndl7V TKeA== X-Gm-Message-State: AO0yUKUN7tL2N3ICzZ7UikDn5LpZ8e3VKfEuTwPkINihSWlLnmKj+lHB KEUQjaDIHN7Nk1wxO2Qy5tdpyw== X-Received: by 2002:a7b:ce08:0:b0:3ed:9a37:acbf with SMTP id m8-20020a7bce08000000b003ed9a37acbfmr13638533wmc.31.1680066656209; Tue, 28 Mar 2023 22:10:56 -0700 (PDT) Received: from alex-rivos.ba.rivosinc.com (amontpellier-656-1-456-62.w92-145.abo.wanadoo.fr. [92.145.124.62]) by smtp.gmail.com with ESMTPSA id v6-20020a5d6106000000b002c55521903bsm28989427wrt.51.2023.03.28.22.10.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Mar 2023 22:10:55 -0700 (PDT) From: Alexandre Ghiti To: Jonathan Corbet , Paul Walmsley , Palmer Dabbelt , Albert Ou , Conor Dooley , Ard Biesheuvel , =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org Cc: Alexandre Ghiti , =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= Subject: [PATCH v9 1/1] riscv: Allow to downgrade paging mode from the command line Date: Wed, 29 Mar 2023 07:09:51 +0200 Message-Id: <20230329050951.66085-2-alexghiti@rivosinc.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20230329050951.66085-1-alexghiti@rivosinc.com> References: <20230329050951.66085-1-alexghiti@rivosinc.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=0.0 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=unavailable 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 Add 2 early command line parameters that allow to downgrade satp mode (using the same naming as x86): - "no5lvl": use a 4-level page table (down from sv57 to sv48) - "no4lvl": use a 3-level page table (down from sv57/sv48 to sv39) Note that going through the device tree to get the kernel command line works with ACPI too since the efi stub creates a device tree anyway with the command line. In KASAN kernels, we can't use the libfdt that early in the boot process since we are not ready to execute instrumented functions. So instead of using the "generic" libfdt, we compile our own versions of those functions that are not instrumented and that are prefixed so that they do not conflict with the generic ones. We also need the non-instrumented versions of the string functions and the prefixed versions of memcpy/memmove. This is largely inspired by commit aacd149b6238 ("arm64: head: avoid relocating the kernel twice for KASLR") from which I removed compilation flags that were not relevant to RISC-V at the moment (LTO, SCS, pie). Signed-off-by: Alexandre Ghiti Tested-by: Björn Töpel Reviewed-by: Björn Töpel --- .../admin-guide/kernel-parameters.txt | 5 +- arch/riscv/kernel/Makefile | 2 + arch/riscv/kernel/pi/Makefile | 39 ++++++++++++ arch/riscv/kernel/pi/cmdline_early.c | 62 +++++++++++++++++++ arch/riscv/kernel/vmlinux.lds.S | 8 +++ arch/riscv/lib/memcpy.S | 2 + arch/riscv/lib/memmove.S | 2 + arch/riscv/lib/strlen.S | 1 + arch/riscv/mm/init.c | 36 +++++++++-- 9 files changed, 150 insertions(+), 7 deletions(-) create mode 100644 arch/riscv/kernel/pi/Makefile create mode 100644 arch/riscv/kernel/pi/cmdline_early.c diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 6221a1d057dd..accc400b43f1 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -3576,7 +3576,10 @@ emulation library even if a 387 maths coprocessor is present. - no5lvl [X86-64] Disable 5-level paging mode. Forces + no4lvl [RISCV] Disable 4-level and 5-level paging modes. Forces + kernel to use 3-level paging instead. + + no5lvl [X86-64,RISCV] Disable 5-level paging mode. Forces kernel to use 4-level paging instead. nofsgsbase [X86] Disables FSGSBASE instructions. diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile index 4cf303a779ab..aa22f87faeae 100644 --- a/arch/riscv/kernel/Makefile +++ b/arch/riscv/kernel/Makefile @@ -89,3 +89,5 @@ obj-$(CONFIG_EFI) += efi.o obj-$(CONFIG_COMPAT) += compat_syscall_table.o obj-$(CONFIG_COMPAT) += compat_signal.o obj-$(CONFIG_COMPAT) += compat_vdso/ + +obj-$(CONFIG_64BIT) += pi/ diff --git a/arch/riscv/kernel/pi/Makefile b/arch/riscv/kernel/pi/Makefile new file mode 100644 index 000000000000..42c58f4ab53b --- /dev/null +++ b/arch/riscv/kernel/pi/Makefile @@ -0,0 +1,39 @@ +# SPDX-License-Identifier: GPL-2.0 +# This file was copied from arm64/kernel/pi/Makefile. + +KBUILD_CFLAGS := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \ + -Os -DDISABLE_BRANCH_PROFILING $(DISABLE_STACKLEAK_PLUGIN) \ + $(call cc-option,-mbranch-protection=none) \ + -I$(srctree)/scripts/dtc/libfdt -fno-stack-protector \ + -D__DISABLE_EXPORTS -ffreestanding \ + -fno-asynchronous-unwind-tables -fno-unwind-tables \ + $(call cc-option,-fno-addrsig) + +KBUILD_CFLAGS += -mcmodel=medany + +CFLAGS_cmdline_early.o += -D__NO_FORTIFY +CFLAGS_lib-fdt_ro.o += -D__NO_FORTIFY + +GCOV_PROFILE := n +KASAN_SANITIZE := n +KCSAN_SANITIZE := n +UBSAN_SANITIZE := n +KCOV_INSTRUMENT := n + +$(obj)/%.pi.o: OBJCOPYFLAGS := --prefix-symbols=__pi_ \ + --remove-section=.note.gnu.property \ + --prefix-alloc-sections=.init +$(obj)/%.pi.o: $(obj)/%.o FORCE + $(call if_changed,objcopy) + +$(obj)/lib-%.o: $(srctree)/lib/%.c FORCE + $(call if_changed_rule,cc_o_c) + +$(obj)/string.o: $(srctree)/lib/string.c FORCE + $(call if_changed_rule,cc_o_c) + +$(obj)/ctype.o: $(srctree)/lib/ctype.c FORCE + $(call if_changed_rule,cc_o_c) + +obj-y := cmdline_early.pi.o string.pi.o ctype.pi.o lib-fdt.pi.o lib-fdt_ro.pi.o +extra-y := $(patsubst %.pi.o,%.o,$(obj-y)) diff --git a/arch/riscv/kernel/pi/cmdline_early.c b/arch/riscv/kernel/pi/cmdline_early.c new file mode 100644 index 000000000000..05652d13c746 --- /dev/null +++ b/arch/riscv/kernel/pi/cmdline_early.c @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include +#include +#include +#include +#include +#include + +static char early_cmdline[COMMAND_LINE_SIZE]; + +/* + * Declare the functions that are exported (but prefixed) here so that LLVM + * does not complain it lacks the 'static' keyword (which, if added, makes + * LLVM complain because the function is actually unused in this file). + */ +u64 set_satp_mode_from_cmdline(uintptr_t dtb_pa); + +static char *get_early_cmdline(uintptr_t dtb_pa) +{ + const char *fdt_cmdline = NULL; + unsigned int fdt_cmdline_size = 0; + int chosen_node; + + if (!IS_ENABLED(CONFIG_CMDLINE_FORCE)) { + chosen_node = fdt_path_offset((void *)dtb_pa, "/chosen"); + if (chosen_node >= 0) { + fdt_cmdline = fdt_getprop((void *)dtb_pa, chosen_node, + "bootargs", NULL); + if (fdt_cmdline) { + fdt_cmdline_size = strlen(fdt_cmdline); + strscpy(early_cmdline, fdt_cmdline, + COMMAND_LINE_SIZE); + } + } + } + + if (IS_ENABLED(CONFIG_CMDLINE_EXTEND) || + IS_ENABLED(CONFIG_CMDLINE_FORCE) || + fdt_cmdline_size == 0 /* CONFIG_CMDLINE_FALLBACK */) { + strncat(early_cmdline, CONFIG_CMDLINE, + COMMAND_LINE_SIZE - fdt_cmdline_size); + } + + return early_cmdline; +} + +static u64 match_noXlvl(char *cmdline) +{ + if (strstr(cmdline, "no4lvl")) + return SATP_MODE_48; + else if (strstr(cmdline, "no5lvl")) + return SATP_MODE_57; + + return 0; +} + +u64 set_satp_mode_from_cmdline(uintptr_t dtb_pa) +{ + char *cmdline = get_early_cmdline(dtb_pa); + + return match_noXlvl(cmdline); +} diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S index 615ff5842690..b12a843ad426 100644 --- a/arch/riscv/kernel/vmlinux.lds.S +++ b/arch/riscv/kernel/vmlinux.lds.S @@ -83,6 +83,14 @@ SECTIONS /* Start of init data section */ __init_data_begin = .; INIT_DATA_SECTION(16) + + /* Those sections result from the compilation of kernel/pi/string.c */ + .init.pidata : { + *(.init.srodata.cst8*) + *(.init__bug_table*) + *(.init.sdata*) + } + .init.bss : { *(.init.bss) /* from the EFI stub */ } diff --git a/arch/riscv/lib/memcpy.S b/arch/riscv/lib/memcpy.S index 51ab716253fa..1a40d01a9543 100644 --- a/arch/riscv/lib/memcpy.S +++ b/arch/riscv/lib/memcpy.S @@ -106,3 +106,5 @@ WEAK(memcpy) 6: ret END(__memcpy) +SYM_FUNC_ALIAS(__pi_memcpy, __memcpy) +SYM_FUNC_ALIAS(__pi___memcpy, __memcpy) diff --git a/arch/riscv/lib/memmove.S b/arch/riscv/lib/memmove.S index e0609e1f0864..838ff2022fe3 100644 --- a/arch/riscv/lib/memmove.S +++ b/arch/riscv/lib/memmove.S @@ -314,3 +314,5 @@ return_from_memmove: SYM_FUNC_END(memmove) SYM_FUNC_END(__memmove) +SYM_FUNC_ALIAS(__pi_memmove, __memmove) +SYM_FUNC_ALIAS(__pi___memmove, __memmove) diff --git a/arch/riscv/lib/strlen.S b/arch/riscv/lib/strlen.S index 15bb8f3aa959..9d0055616f7b 100644 --- a/arch/riscv/lib/strlen.S +++ b/arch/riscv/lib/strlen.S @@ -131,3 +131,4 @@ strlen_zbb: .option pop #endif SYM_FUNC_END(strlen) +SYM_FUNC_ALIAS(__pi_strlen, strlen) diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index bce899b180cd..3ad771571c2d 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -746,6 +746,8 @@ static __init pgprot_t pgprot_from_va(uintptr_t va) #endif /* CONFIG_STRICT_KERNEL_RWX */ #if defined(CONFIG_64BIT) && !defined(CONFIG_XIP_KERNEL) +u64 __pi_set_satp_mode_from_cmdline(uintptr_t dtb_pa); + static void __init disable_pgtable_l5(void) { pgtable_l5_enabled = false; @@ -760,17 +762,39 @@ static void __init disable_pgtable_l4(void) satp_mode = SATP_MODE_39; } +static int __init print_no4lvl(char *p) +{ + pr_info("Disabled 4-level and 5-level paging"); + return 0; +} +early_param("no4lvl", print_no4lvl); + +static int __init print_no5lvl(char *p) +{ + pr_info("Disabled 5-level paging"); + return 0; +} +early_param("no5lvl", print_no5lvl); + /* * There is a simple way to determine if 4-level is supported by the * underlying hardware: establish 1:1 mapping in 4-level page table mode * then read SATP to see if the configuration was taken into account * meaning sv48 is supported. */ -static __init void set_satp_mode(void) +static __init void set_satp_mode(uintptr_t dtb_pa) { u64 identity_satp, hw_satp; uintptr_t set_satp_mode_pmd = ((unsigned long)set_satp_mode) & PMD_MASK; - bool check_l4 = false; + u64 satp_mode_cmdline = __pi_set_satp_mode_from_cmdline(dtb_pa); + + if (satp_mode_cmdline == SATP_MODE_57) { + disable_pgtable_l5(); + } else if (satp_mode_cmdline == SATP_MODE_48) { + disable_pgtable_l5(); + disable_pgtable_l4(); + return; + } create_p4d_mapping(early_p4d, set_satp_mode_pmd, (uintptr_t)early_pud, @@ -789,7 +813,8 @@ static __init void set_satp_mode(void) retry: create_pgd_mapping(early_pg_dir, set_satp_mode_pmd, - check_l4 ? (uintptr_t)early_pud : (uintptr_t)early_p4d, + pgtable_l5_enabled ? + (uintptr_t)early_p4d : (uintptr_t)early_pud, PGDIR_SIZE, PAGE_TABLE); identity_satp = PFN_DOWN((uintptr_t)&early_pg_dir) | satp_mode; @@ -800,9 +825,8 @@ static __init void set_satp_mode(void) local_flush_tlb_all(); if (hw_satp != identity_satp) { - if (!check_l4) { + if (pgtable_l5_enabled) { disable_pgtable_l5(); - check_l4 = true; memset(early_pg_dir, 0, PAGE_SIZE); goto retry; } @@ -1031,7 +1055,7 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) #endif #if defined(CONFIG_64BIT) && !defined(CONFIG_XIP_KERNEL) - set_satp_mode(); + set_satp_mode(dtb_pa); #endif /* -- 2.37.2