From 8db6f937f4e76d9dd23795311fc14f0a5c0ac119 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 29 Apr 2021 17:05:00 +0200 Subject: [PATCH 1/4] riscv: Only extend kernel reservation if mapped read-only When the kernel mapping was moved outside of the linear mapping, the kernel memory reservation was increased, to take into account mapping granularity. However, this is done unconditionally, regardless of whether the kernel memory is mapped read-only or not. If this extension is not needed, up to 2 MiB may be lost, which has a big impact on e.g. Canaan K210 (64-bit nommu) platforms with only 8 MiB of RAM. Reclaim the lost memory by only extending the reserved region when needed, i.e. depending on a simplified version of the conditional logic around the call to protect_kernel_linear_mapping_text_rodata(). Fixes: 2bfc6cd81bd17e43 ("riscv: Move kernel mapping outside of linear mapping") Signed-off-by: Geert Uytterhoeven Tested-by: Alexandre Ghiti Signed-off-by: Palmer Dabbelt --- arch/riscv/mm/init.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index dfb5e4f7a670..1ec98d97b67f 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -135,11 +135,16 @@ void __init setup_bootmem(void) /* * Reserve from the start of the kernel to the end of the kernel - * and make sure we align the reservation on PMD_SIZE since we will + */ +#if defined(CONFIG_64BIT) && defined(CONFIG_STRICT_KERNEL_RWX) + /* + * Make sure we align the reservation on PMD_SIZE since we will * map the kernel in the linear mapping as read-only: we do not want * any allocation to happen between _end and the next pmd aligned page. */ - memblock_reserve(vmlinux_start, (vmlinux_end - vmlinux_start + PMD_SIZE - 1) & PMD_MASK); + vmlinux_end = (vmlinux_end + PMD_SIZE - 1) & PMD_MASK; +#endif + memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start); /* * memblock allocator is not aware of the fact that last 4K bytes of From 0e0d4992517fba81ecbceb5b71d2851f1208a02b Mon Sep 17 00:00:00 2001 From: Vincent Chen Date: Thu, 29 Apr 2021 00:58:36 -0700 Subject: [PATCH 2/4] riscv: enable SiFive errata CIP-453 and CIP-1200 Kconfig only if CONFIG_64BIT=y The corresponding hardware issues of CONFIG_ERRATA_SIFIVE_CIP_453 and CONFIG_ERRATA_SIFIVE_CIP_1200 only exist in the SiFive 64bit CPU cores. Therefore, these two errata are required only if CONFIG_64BIT=y Reported-by: kernel test robot Signed-off-by: Vincent Chen Fixes: bff3ff525460 ("riscv: sifive: Apply errata "cip-1200" patch") Fixes: 800149a77c2c ("riscv: sifive: Apply errata "cip-453" patch") Signed-off-by: Palmer Dabbelt --- arch/riscv/Kconfig.erratas | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/riscv/Kconfig.erratas b/arch/riscv/Kconfig.erratas index d5d03ae8d685..b44d6ecdb46e 100644 --- a/arch/riscv/Kconfig.erratas +++ b/arch/riscv/Kconfig.erratas @@ -21,7 +21,7 @@ config ERRATA_SIFIVE config ERRATA_SIFIVE_CIP_453 bool "Apply SiFive errata CIP-453" - depends on ERRATA_SIFIVE + depends on ERRATA_SIFIVE && 64BIT default y help This will apply the SiFive CIP-453 errata to add sign extension @@ -32,7 +32,7 @@ config ERRATA_SIFIVE_CIP_453 config ERRATA_SIFIVE_CIP_1200 bool "Apply SiFive errata CIP-1200" - depends on ERRATA_SIFIVE + depends on ERRATA_SIFIVE && 64BIT default y help This will apply the SiFive CIP-1200 errata to repalce all From 8d91b097335892bfbc9fd5783e80e25f0fb5bb2b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 29 Apr 2021 17:10:04 +0200 Subject: [PATCH 3/4] riscv: Consistify protect_kernel_linear_mapping_text_rodata() use The various uses of protect_kernel_linear_mapping_text_rodata() are not consistent: - Its definition depends on "64BIT && !XIP_KERNEL", - Its forward declaration depends on MMU, - Its single caller depends on "STRICT_KERNEL_RWX && 64BIT && MMU && !XIP_KERNEL". Fix this by settling on the dependencies of the caller, which can be simplified as STRICT_KERNEL_RWX depends on "MMU && !XIP_KERNEL". Provide a dummy definition, as the caller is protected by "IS_ENABLED(CONFIG_STRICT_KERNEL_RWX)" instead of "#ifdef CONFIG_STRICT_KERNEL_RWX". Signed-off-by: Geert Uytterhoeven Tested-by: Alexandre Ghiti Signed-off-by: Palmer Dabbelt --- arch/riscv/include/asm/set_memory.h | 7 ++++++- arch/riscv/kernel/setup.c | 2 -- arch/riscv/mm/init.c | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/riscv/include/asm/set_memory.h b/arch/riscv/include/asm/set_memory.h index a9c56776fa0e..086f757e8ba3 100644 --- a/arch/riscv/include/asm/set_memory.h +++ b/arch/riscv/include/asm/set_memory.h @@ -17,7 +17,6 @@ int set_memory_x(unsigned long addr, int numpages); int set_memory_nx(unsigned long addr, int numpages); int set_memory_rw_nx(unsigned long addr, int numpages); void protect_kernel_text_data(void); -void protect_kernel_linear_mapping_text_rodata(void); #else static inline int set_memory_ro(unsigned long addr, int numpages) { return 0; } static inline int set_memory_rw(unsigned long addr, int numpages) { return 0; } @@ -27,6 +26,12 @@ static inline void protect_kernel_text_data(void) {} static inline int set_memory_rw_nx(unsigned long addr, int numpages) { return 0; } #endif +#if defined(CONFIG_64BIT) && defined(CONFIG_STRICT_KERNEL_RWX) +void protect_kernel_linear_mapping_text_rodata(void); +#else +static inline void protect_kernel_linear_mapping_text_rodata(void) {} +#endif + int set_direct_map_invalid_noflush(struct page *page); int set_direct_map_default_noflush(struct page *page); bool kernel_page_present(struct page *page); diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index 7b31779101f6..03901d3a8b02 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -293,9 +293,7 @@ void __init setup_arch(char **cmdline_p) if (IS_ENABLED(CONFIG_STRICT_KERNEL_RWX)) { protect_kernel_text_data(); -#if defined(CONFIG_64BIT) && defined(CONFIG_MMU) && !defined(CONFIG_XIP_KERNEL) protect_kernel_linear_mapping_text_rodata(); -#endif } #ifdef CONFIG_SWIOTLB diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index 1ec98d97b67f..4faf8bd157ea 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -645,7 +645,7 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) #endif } -#if defined(CONFIG_64BIT) && !defined(CONFIG_XIP_KERNEL) +#if defined(CONFIG_64BIT) && defined(CONFIG_STRICT_KERNEL_RWX) void protect_kernel_linear_mapping_text_rodata(void) { unsigned long text_start = (unsigned long)lm_alias(_start); From beaf5ae15a13d835a01e30c282c8325ce0f1eb7e Mon Sep 17 00:00:00 2001 From: Rouven Czerwinski Date: Sat, 1 May 2021 20:53:58 +0200 Subject: [PATCH 4/4] riscv: remove unused handle_exception symbol Since commit 79b1feba5455 ("RISC-V: Setup exception vector early") exception vectors are setup early and the handle_exception symbol from the asm files is no longer referenced in traps.c. Remove it. Signed-off-by: Rouven Czerwinski Signed-off-by: Palmer Dabbelt --- arch/riscv/kernel/traps.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c index 07fdded10c21..0721b9798595 100644 --- a/arch/riscv/kernel/traps.c +++ b/arch/riscv/kernel/traps.c @@ -25,8 +25,6 @@ int show_unhandled_signals = 1; -extern asmlinkage void handle_exception(void); - static DEFINE_SPINLOCK(die_lock); void die(struct pt_regs *regs, const char *str)