riscv: mm: Fixup & Optimize COMPAT mode
Subsystems (2)
v4 cover riscv: mm: Fixup & Optimize COMPAT mode
From: Guo Ren <[email protected]>
When the task is in COMPAT mode, the TASK_SIZE should be 2GB, so STACK_TOP_MAX and arch_get_mmap_end must be limited to 2 GB. This series fixes the problem made by commit: add2cc6b6515 ("RISC-V: mm: Restrict address space for sv39,sv48,sv57") and optimizes the related coding convention of TASK_SIZE.
Changelog:
v4:
- Add "Reviewed-by" tags
v3:
https://lore.kernel.org/linux-riscv/[email protected]/
- Remove wrong modification of arch_get_mmap_end
- Remove is_compat_task optimization
- Update comment log
v2:
https://lore.kernel.org/linux-riscv/[email protected]/
- Separate rename from fixup
- Add STACK_TOP_MAX fixup for compat
- Add Cleanup & rename patches
v1:
https://lore.kernel.org/linux-riscv/[email protected]/
Guo Ren (4):
riscv: mm: Fixup compat mode boot failure
riscv: mm: Fixup compat arch_get_mmap_end
riscv: mm: Remove unused TASK_SIZE_MIN
riscv: mm: Optimize TASK_SIZE definition
arch/riscv/include/asm/pgtable.h | 7 +++---- arch/riscv/include/asm/processor.h | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-)
Signature · 1 line
2.40.1
PATCH v4 1/4 riscv: mm: Fixup compat mode boot failure
From: Guo Ren <[email protected]>
In COMPAT mode, the STACK_TOP is DEFAULT_MAP_WINDOW (0x80000000), but the TASK_SIZE is 0x7fff000. When the user stack is upon 0x7fff000, it will cause a user segment fault. Sometimes, it would cause boot failure when the whole rootfs is rv32.
Freeing unused kernel image (initmem) memory: 2236K
Run /sbin/init as init process
Starting init: /sbin/init exists but couldn't execute it (error -14) Run /etc/init as init process
...
Increase the TASK_SIZE to cover STACK_TOP.
--- arch/riscv/include/asm/pgtable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/riscv/include/asm/pgtable.h +1 -1
@@ -881,7 +881,7 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte)#define TASK_SIZE_MIN (PGDIR_SIZE_L3 * PTRS_PER_PGD / 2)#ifdef CONFIG_COMPAT -#define TASK_SIZE_32 (_AC(0x80000000, UL) - PAGE_SIZE) +#define TASK_SIZE_32 (_AC(0x80000000, UL))#define TASK_SIZE (test_thread_flag(TIF_32BIT) ? \ TASK_SIZE_32 : TASK_SIZE_64)#else
Signature · 1 line
2.40.1
PATCH v4 2/4 riscv: mm: Fixup compat arch_get_mmap_end
In reply to [email protected]From: Guo Ren <[email protected]>
When the task is in COMPAT mode, the arch_get_mmap_end should be 2GB, not TASK_SIZE_64. The TASK_SIZE has contained is_compat_mode() detection, so change the definition of STACK_TOP_MAX to TASK_SIZE directly.
--- arch/riscv/include/asm/processor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/riscv/include/asm/processor.h +1 -1
@@ -16,7 +16,7 @@#ifdef CONFIG_64BIT #define DEFAULT_MAP_WINDOW (UL(1) << (MMAP_VA_BITS - 1)) -#define STACK_TOP_MAX TASK_SIZE_64 +#define STACK_TOP_MAX TASK_SIZE#define arch_get_mmap_end (addr, len, flags) \ ({ \
Signature · 1 line
2.40.1
PATCH v4 3/4 riscv: mm: Remove unused TASK_SIZE_MIN
In reply to [email protected]From: Guo Ren <[email protected]>
Remove TASK_SIZE_MIN because it's not used anymore.
--- arch/riscv/include/asm/pgtable.h | 2 -- 1 file changed, 2 deletions(-)
arch/riscv/include/asm/pgtable.h +0 -2
@@ -878,7 +878,6 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte)*/ #ifdef CONFIG_64BIT #define TASK_SIZE_64 (PGDIR_SIZE * PTRS_PER_PGD / 2) -#define TASK_SIZE_MIN (PGDIR_SIZE_L3 * PTRS_PER_PGD / 2)#ifdef CONFIG_COMPAT #define TASK_SIZE_32 (_AC(0x80000000, UL))
@@ -890,7 +889,6 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte)#else #define TASK_SIZE FIXADDR_START -#define TASK_SIZE_MIN TASK_SIZE#endif #else /* CONFIG_MMU */
Signature · 1 line
2.40.1
PATCH v4 4/4 riscv: mm: Optimize TASK_SIZE definition
In reply to [email protected]From: Guo Ren <[email protected]>
Unify the TASK_SIZE definition with VA_BITS for better readability. Add COMPAT mode user address space info in the comment.
--- arch/riscv/include/asm/pgtable.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
arch/riscv/include/asm/pgtable.h +3 -2
@@ -866,6 +866,7 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte)* Note that PGDIR_SIZE must evenly divide TASK_SIZE. * Task size is: * - 0x9fc00000 (~2.5GB) for RV32. +* - 0x80000000 ( 2GB) for RV64 compat mode * - 0x4000000000 ( 256GB) for RV64 using SV39 mmu * - 0x800000000000 ( 128TB) for RV64 using SV48 mmu * - 0x100000000000000 ( 64PB) for RV64 using SV57 mmu
@@ -877,10 +878,10 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte)* Similarly for SV57, bits 63–57 must be equal to bit 56. */ #ifdef CONFIG_64BIT -#define TASK_SIZE_64 (PGDIR_SIZE * PTRS_PER_PGD / 2) +#define TASK_SIZE_64 (UL(1) << (VA_BITS - 1))#ifdef CONFIG_COMPAT -#define TASK_SIZE_32 (_AC(0x80000000, UL)) +#define TASK_SIZE_32 (UL(1) << (VA_BITS_SV32 - 1))#define TASK_SIZE (test_thread_flag(TIF_32BIT) ? \ TASK_SIZE_32 : TASK_SIZE_64)#else
Signature · 1 line
2.40.1