Unverified Commit 728e7ea2 authored by Palmer Dabbelt's avatar Palmer Dabbelt
Browse files

Merge patch series "riscv: Introduce compat-mode helpers & improve arch_get_mmap_end()"

Leonardo Bras <leobras@redhat.com> says:

I just saw the opportunity of optimizing the helper is_compat_task() by
introducing a compile-time test, and it made possible to remove some
 #ifdef's without any loss of performance.

I also saw the possibility of removing the direct check of task flags from
general code, and concentrated it in asm/compat.h by creating a few more
helpers, which in the end helped optimize code.

arch_get_mmap_end() just got a simple improvement and some extra docs.

* b4-shazam-merge:
  riscv: Introduce set_compat_task() in asm/compat.h
  riscv: Introduce is_compat_thread() into compat.h
  riscv: add compile-time test into is_compat_task()
  riscv: Replace direct thread flag check with is_compat_task()
  riscv: Improve arch_get_mmap_end() macro

Link: https://lore.kernel.org/r/20240103160024.70305-2-leobras@redhat.com


Signed-off-by: default avatarPalmer Dabbelt <palmer@rivosinc.com>
parents 700c2d9b 2a8986fc
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -14,9 +14,28 @@

static inline int is_compat_task(void)
{
	if (!IS_ENABLED(CONFIG_COMPAT))
		return 0;

	return test_thread_flag(TIF_32BIT);
}

static inline int is_compat_thread(struct thread_info *thread)
{
	if (!IS_ENABLED(CONFIG_COMPAT))
		return 0;

	return test_ti_thread_flag(thread, TIF_32BIT);
}

static inline void set_compat_task(bool is_compat)
{
	if (is_compat)
		set_thread_flag(TIF_32BIT);
	else
		clear_thread_flag(TIF_32BIT);
}

struct compat_user_regs_struct {
	compat_ulong_t pc;
	compat_ulong_t ra;
+2 −9
Original line number Diff line number Diff line
@@ -53,13 +53,9 @@ extern bool compat_elf_check_arch(Elf32_Ehdr *hdr);
#define ELF_ET_DYN_BASE		((DEFAULT_MAP_WINDOW / 3) * 2)

#ifdef CONFIG_64BIT
#ifdef CONFIG_COMPAT
#define STACK_RND_MASK		(test_thread_flag(TIF_32BIT) ? \
#define STACK_RND_MASK		(is_compat_task() ? \
				 0x7ff >> (PAGE_SHIFT - 12) : \
				 0x3ffff >> (PAGE_SHIFT - 12))
#else
#define STACK_RND_MASK		(0x3ffff >> (PAGE_SHIFT - 12))
#endif
#endif

/*
@@ -139,10 +135,7 @@ do { \
#ifdef CONFIG_COMPAT

#define SET_PERSONALITY(ex)					\
do {    if ((ex).e_ident[EI_CLASS] == ELFCLASS32)		\
		set_thread_flag(TIF_32BIT);			\
	else							\
		clear_thread_flag(TIF_32BIT);			\
do {	set_compat_task((ex).e_ident[EI_CLASS] == ELFCLASS32);	\
	if (personality(current->personality) != PER_LINUX32)	\
		set_personality(PER_LINUX |			\
			(current->personality & (~PER_MASK)));	\
+2 −8
Original line number Diff line number Diff line
@@ -127,16 +127,10 @@
#define VA_USER_SV48 (UL(1) << (VA_BITS_SV48 - 1))
#define VA_USER_SV57 (UL(1) << (VA_BITS_SV57 - 1))

#ifdef CONFIG_COMPAT
#define MMAP_VA_BITS_64 ((VA_BITS >= VA_BITS_SV48) ? VA_BITS_SV48 : VA_BITS)
#define MMAP_MIN_VA_BITS_64 (VA_BITS_SV39)
#define MMAP_VA_BITS (is_compat_task() ? VA_BITS_SV32 : MMAP_VA_BITS_64)
#define MMAP_MIN_VA_BITS (is_compat_task() ? VA_BITS_SV32 : MMAP_MIN_VA_BITS_64)
#else
#define MMAP_VA_BITS ((VA_BITS >= VA_BITS_SV48) ? VA_BITS_SV48 : VA_BITS)
#define MMAP_MIN_VA_BITS (VA_BITS_SV39)
#endif /* CONFIG_COMPAT */

#else
#include <asm/pgtable-32.h>
#endif /* CONFIG_64BIT */
@@ -877,8 +871,8 @@ 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))
#define TASK_SIZE	(test_thread_flag(TIF_32BIT) ? \
#define TASK_SIZE_32	(_AC(0x80000000, UL) - PAGE_SIZE)
#define TASK_SIZE	(is_compat_task() ? \
			 TASK_SIZE_32 : TASK_SIZE_64)
#else
#define TASK_SIZE	TASK_SIZE_64
+8 −4
Original line number Diff line number Diff line
@@ -14,12 +14,17 @@

#include <asm/ptrace.h>

/*
 * addr is a hint to the maximum userspace address that mmap should provide, so
 * this macro needs to return the largest address space available so that
 * mmap_end < addr, being mmap_end the top of that address space.
 * See Documentation/arch/riscv/vm-layout.rst for more details.
 */
#define arch_get_mmap_end(addr, len, flags)			\
({								\
	unsigned long mmap_end;					\
	typeof(addr) _addr = (addr);				\
	if ((_addr) == 0 ||					\
	    (IS_ENABLED(CONFIG_COMPAT) && is_compat_task()) ||	\
	if ((_addr) == 0 || is_compat_task() ||			\
	    ((_addr + len) > BIT(VA_BITS - 1)))			\
		mmap_end = STACK_TOP_MAX;			\
	else							\
@@ -33,8 +38,7 @@
	typeof(addr) _addr = (addr);				\
	typeof(base) _base = (base);				\
	unsigned long rnd_gap = DEFAULT_MAP_WINDOW - (_base);	\
	if ((_addr) == 0 ||					\
	    (IS_ENABLED(CONFIG_COMPAT) && is_compat_task()) ||	\
	if ((_addr) == 0 || is_compat_task() || 		\
	    ((_addr + len) > BIT(VA_BITS - 1)))			\
		mmap_base = (_base);				\
	else							\
+3 −3
Original line number Diff line number Diff line
@@ -377,14 +377,14 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,

	return ret;
}
#else
static const struct user_regset_view compat_riscv_user_native_view = {};
#endif /* CONFIG_COMPAT */

const struct user_regset_view *task_user_regset_view(struct task_struct *task)
{
#ifdef CONFIG_COMPAT
	if (test_tsk_thread_flag(task, TIF_32BIT))
	if (is_compat_thread(&task->thread_info))
		return &compat_riscv_user_native_view;
	else
#endif
		return &riscv_user_native_view;
}