Commit 3d2403fd authored by Mark Rutland's avatar Mark Rutland Committed by Catalin Marinas
Browse files

arm64: uaccess: remove set_fs()



Now that the uaccess primitives dont take addr_limit into account, we
have no need to manipulate this via set_fs() and get_fs(). Remove
support for these, along with some infrastructure this renders
redundant.

We no longer need to flip UAO to access kernel memory under KERNEL_DS,
and head.S unconditionally clears UAO for all kernel configurations via
an ERET in init_kernel_el. Thus, we don't need to dynamically flip UAO,
nor do we need to context-switch it. However, we still need to adjust
PAN during SDEI entry.

Masking of __user pointers no longer needs to use the dynamic value of
addr_limit, and can use a constant derived from the maximum possible
userspace task size. A new TASK_SIZE_MAX constant is introduced for
this, which is also used by core code. In configurations supporting
52-bit VAs, this may include a region of unusable VA space above a
48-bit TTBR0 limit, but never includes any portion of TTBR1.

Note that TASK_SIZE_MAX is an exclusive limit, while USER_DS and
KERNEL_DS were inclusive limits, and is converted to a mask by
subtracting one.

As the SDEI entry code repurposes the otherwise unnecessary
pt_regs::orig_addr_limit field to store the TTBR1 of the interrupted
context, for now we rename that to pt_regs::sdei_ttbr1. In future we can
consider factoring that out.

Signed-off-by: default avatarMark Rutland <mark.rutland@arm.com>
Acked-by: default avatarJames Morse <james.morse@arm.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Will Deacon <will@kernel.org>
Link: https://lore.kernel.org/r/20201202131558.39270-10-mark.rutland@arm.com


Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent 7b90dc40
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -195,7 +195,6 @@ config ARM64
	select PCI_SYSCALL if PCI
	select POWER_RESET
	select POWER_SUPPLY
	select SET_FS
	select SPARSE_IRQ
	select SWIOTLB
	select SYSCTL_EXCEPTION_TRACE
+0 −1
Original line number Diff line number Diff line
@@ -10,6 +10,5 @@
#include <linux/sched.h>

extern unsigned long arch_align_stack(unsigned long sp);
void uao_thread_switch(struct task_struct *next);

#endif	/* __ASM_EXEC_H */
+1 −3
Original line number Diff line number Diff line
@@ -8,9 +8,6 @@
#ifndef __ASM_PROCESSOR_H
#define __ASM_PROCESSOR_H

#define KERNEL_DS		UL(-1)
#define USER_DS			((UL(1) << VA_BITS) - 1)

/*
 * On arm64 systems, unaligned accesses by the CPU are cheap, and so there is
 * no point in shifting all network buffers by 2 bytes just to make some IP
@@ -48,6 +45,7 @@

#define DEFAULT_MAP_WINDOW_64	(UL(1) << VA_BITS_MIN)
#define TASK_SIZE_64		(UL(1) << vabits_actual)
#define TASK_SIZE_MAX		(UL(1) << VA_BITS)

#ifdef CONFIG_COMPAT
#if defined(CONFIG_ARM64_64K_PAGES) && defined(CONFIG_KUSER_HELPERS)
+1 −2
Original line number Diff line number Diff line
@@ -193,8 +193,7 @@ struct pt_regs {
	s32 syscallno;
	u32 unused2;
#endif

	u64 orig_addr_limit;
	u64 sdei_ttbr1;
	/* Only valid when ARM64_HAS_IRQ_PRIO_MASKING is enabled. */
	u64 pmr_save;
	u64 stackframe[2];
+0 −4
Original line number Diff line number Diff line
@@ -18,14 +18,11 @@ struct task_struct;
#include <asm/stack_pointer.h>
#include <asm/types.h>

typedef unsigned long mm_segment_t;

/*
 * low level task data that entry.S needs immediate access to.
 */
struct thread_info {
	unsigned long		flags;		/* low level flags */
	mm_segment_t		addr_limit;	/* address limit */
#ifdef CONFIG_ARM64_SW_TTBR0_PAN
	u64			ttbr0;		/* saved TTBR0_EL1 */
#endif
@@ -119,7 +116,6 @@ void arch_release_task_struct(struct task_struct *tsk);
{									\
	.flags		= _TIF_FOREIGN_FPSTATE,				\
	.preempt_count	= INIT_PREEMPT_COUNT,				\
	.addr_limit	= KERNEL_DS,					\
	INIT_SCS							\
}

Loading