On Mon, Jan 23, 2023 at 4:21 PM Alexandre Ghiti <alexghiti@xxxxxxxxxxxx> wrote: > > 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. > > Also, as those params are treated very early in the boot process and we > use standard device tree functions that may be kasan instrumented, we > only enable them for !KASAN configurations. > > Reviewed-by: Björn Töpel <bjorn@xxxxxxxxxx> > Signed-off-by: Alexandre Ghiti <alexghiti@xxxxxxxxxxxx> Looks good to me. Reviewed-by: Anup Patel <anup@xxxxxxxxxxxxxx> Regards, Anup > --- > > v3: > - Massage commit log to make no4lvl clearer, as asked by Conor > - Add a note to kernel-parameters.txt regarding the impossibility to use > those parameters when KASAN is enabled, as suggested by Conor > - Add RB from Björn > > v2: > - Honor CMDLINE_EXTEND and CMDLINE_FORCE as noticed by Björn > > .../admin-guide/kernel-parameters.txt | 9 ++- > arch/riscv/mm/init.c | 72 +++++++++++++++++-- > 2 files changed, 74 insertions(+), 7 deletions(-) > > diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt > index 6cfa6e3996cf..fd647412ec91 100644 > --- a/Documentation/admin-guide/kernel-parameters.txt > +++ b/Documentation/admin-guide/kernel-parameters.txt > @@ -3578,8 +3578,15 @@ > 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. > + Note: On RISC-V, this can't be used when KASAN is > + enabled. > + > + no5lvl [X86-64,RISCV] Disable 5-level paging mode. Forces > kernel to use 4-level paging instead. > + Note: On RISC-V, this can't be used when KASAN is > + enabled. > > nofsgsbase [X86] Disables FSGSBASE instructions. > > diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c > index 478d6763a01a..10f99fa74368 100644 > --- a/arch/riscv/mm/init.c > +++ b/arch/riscv/mm/init.c > @@ -746,17 +746,77 @@ static void __init disable_pgtable_l4(void) > satp_mode = SATP_MODE_39; > } > > +#ifndef CONFIG_KASAN > +static __init bool match_noXlvl(const char *cmdline) > +{ > + if (strstr(cmdline, "no5lvl")) { > + disable_pgtable_l5(); > + } else if (strstr(cmdline, "no4lvl")) { > + disable_pgtable_l5(); > + disable_pgtable_l4(); > + return true; > + } > + > + return false; > +} > + > +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); > +#endif > + > /* > * 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; > + > +#ifndef CONFIG_KASAN > + /* > + * The below fdt functions are kasan instrumented, since at this point > + * there is no mapping for the kasan shadow memory, this can't be used > + * when kasan is enabled. > + */ > + int chosen_node; > + unsigned int fdt_cmdline_size = 0; > + > + if (!IS_ENABLED(CONFIG_CMDLINE_FORCE)) { > + chosen_node = fdt_path_offset((void *)dtb_pa, "/chosen"); > + if (chosen_node >= 0) { > + const char *fdt_cmdline; > + > + fdt_cmdline = fdt_getprop((void *)dtb_pa, chosen_node, > + "bootargs", NULL); > + if (fdt_cmdline) { > + if (match_noXlvl(fdt_cmdline)) > + return; > + fdt_cmdline_size = strlen(fdt_cmdline); > + } > + } > + } > + > + if (IS_ENABLED(CONFIG_CMDLINE_EXTEND) || > + IS_ENABLED(CONFIG_CMDLINE_FORCE) || > + fdt_cmdline_size == 0 /* CONFIG_CMDLINE_FALLBACK */) { > + if (match_noXlvl(CONFIG_CMDLINE)) > + return; > + } > +#endif > > create_p4d_mapping(early_p4d, > set_satp_mode_pmd, (uintptr_t)early_pud, > @@ -775,7 +835,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; > @@ -786,9 +847,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; > } > @@ -979,7 +1039,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 > > kernel_map.va_pa_offset = PAGE_OFFSET - kernel_map.phys_addr; > -- > 2.37.2 >